# تدریسینو — فرانتِ اپِ ریاضی اپِ وبِ موبایل‌محورِ تدریسینو (React + TypeScript + Vite + Tailwind). بک‌اندش ریپوی جداست (`Tadrisino/MathApp`)؛ قراردادِ API در `/api/docs/` همان بک‌اند است. ## راه‌اندازی ```bash npm install npm run dev # http://localhost:5173 ``` در حالتِ توسعه، درخواست‌های `/api` از خودِ Vite به بک‌اند پاس داده می‌شوند، پس CORS مطرح نیست. پیش‌فرض بک‌اندِ محلی است (`python manage.py runserver` روی پورتِ ۸۰۰۰). بدونِ بک‌اندِ محلی، یک فایلِ `.env.development.local` بسازید: ```bash VITE_DEV_PROXY_TARGET=https://mathapi.tadrisino2.ir ``` ⚠️ آن‌وقت هر کاری در اپ بکنید روی دیتابیسِ واقعی نوشته می‌شود. | دستور | کار | |---|---| | `npm run dev` | سرورِ توسعه | | `npm run typecheck` | بررسیِ نوع‌ها (strict) | | `npm run build` | type-check و بعد build در `dist/` | | `npm run preview` | اجرای همان build | ## آدرسِ بک‌اند و عوض کردنِ دامنه دامنه هیچ‌جای کد نیامده. آدرسِ API به این ترتیب خوانده می‌شود (`src/config.ts`): 1. **`dist/config.js`** (از `public/config.js`) — در زمانِ اجرا. بعد از build هم روی سرور قابلِ ویرایش است و build دوباره نمی‌خواهد. 2. **`VITE_API_BASE_URL`** — در زمانِ build، از `.env.production`. 3. **`/api`** — هم‌دامنه، وقتی nginxِ دامنه‌ی فرانت مسیرِ `/api` را به بک‌اند پراکسی کند. برای جابه‌جایی دامنه: - **سریع، بدونِ build:** روی سرور در `dist/config.js` بنویسید `apiBaseUrl: "https://api.new-domain.ir/api"` و کشِ CDN را برای همین فایل پاک کنید. - **ماندگار:** خطِ `VITE_API_BASE_URL` در `.env.production` را عوض کنید و build بگیرید. - **سمتِ بک‌اند** هم دامنه‌ی تازه‌ی فرانت باید مجاز باشد (`FRONTEND_URL` در `.env` بک‌اند). جزئیات در `docs/operations.md` همان ریپو. ## دیپلوی روی سرور (`~/mathapp_frontend_new`، که nginxِ `math.tadrisino2.ir` از `dist/`ش سرو می‌کند): ```bash ./deploy.sh # fetch، npm ci، type-check، build در dist.next و جابه‌جاییِ بی‌وقفه ``` buildِ قبلی در `dist.prev` می‌ماند (برگشت: `rm -rf dist && mv dist.prev dist`)، و `dist/config.js`ِ ویرایش‌شده روی سرور به buildِ تازه منتقل می‌شود. جای دیگر: `npm ci && npm run build` و سرو کردنِ `dist/`. اپ مسیرِ جدا (route) ندارد و همه‌چیز از `/` بار می‌شود؛ فقط `index.html` و `config.js` نباید طولانی کش شوند (باقیِ فایل‌ها نامِ hashدار دارند). درگاهِ پرداخت کاربر را به `/?orderId=…&status=…` برمی‌گرداند و لینکِ دعوت `/?ref=CODE` است؛ هر دو را خودِ اپ می‌خواند. ## ساختار ``` src/ config.ts آدرسِ API (بالا را ببینید) api/ تنها درِ ارتباط با سرور — هیچ جای دیگر fetch نمی‌زند http.ts timeout، تکرارِ GET، refreshِ تک‌نسخه‌ای، SSE index.ts یک تابع برای هر اندپوینت types.ts شکلِ پاسخ‌ها، از روی پاسخِ واقعیِ سرور app/ App (جریانِ ورود) و MainApp (تب‌ها و صفحه‌ها) nav/ ناوبریِ پشته‌ای، هماهنگ با دکمه‌ی back گوشی state/ داده‌ی مشترک (پروفایل، نقشه، …) و گفتگوی دستیار screens/ یک فایل برای هر صفحه components/ اجزای مشترک (سربرگ، برگه‌ی پایین، …) mascots/ سه‌یار: سیگما، دلتا، پی lib/ اعدادِ فارسی، تاریخِ شمسی، صدا، localStorage ``` قاعده‌ها: - **اعداد:** برای نمایش `toFa`، برای ورودی `digitsOnly` (کیبوردِ فارسی ارقامِ `۰-۹` می‌فرستد و `\d` در JS آن‌ها را نمی‌شناسد). - **رنگ‌ها** در `src/styles/index.css` (`@theme`) تعریف شده‌اند: `bg-coral`، `text-ink`، … - **خطا:** پیامِ کاربر همیشه از `friendlyError` می‌آید، نه متنِ خامِ سرور. - **کلاینت را از حافظه ننویسید.** قرارداد را از `/api/docs/` بک‌اند بخوانید و تغییرِ `types.ts` را با پاسخِ واقعیِ سرور بسنجید.