AliReza eafee76a93 Smooth screen transitions: new screen waits hidden until its data arrives, no half-built flash
- Navigator stage: the next screen mounts hidden under the current one and is revealed only when its
  first data has arrived (ScreenGate held by useAsync/useGateHold), at most 450 ms; a thin top bar shows
  after 120 ms of waiting. Push slides from the left, back from the right, tabs only fade.
- Session cache (stale-while-revalidate) for screen GETs: revisited screens draw instantly.
- Home map and stats are fetched during the splash, so the first screen arrives complete.
- Entrance pop-ins (mascot, islands, lesson cards) run on first view only, not on every revisit.
- Shop status card shows placeholders instead of a wrong «نداری» while loading.
- Re-tapping the open tab scrolls to top instead of reloading; sheets close with a swipe down.
- Quiz: «۱ از ۴» instead of «۱/۴» (read as a fraction), varied praise, «N تا پشتِ هم درست»,
  growth-mindset copy after a weak round, zero-reward tiles hidden.
- Streak: a concrete next step when the streak is 0 or today is still empty.

Checked in headless Chrome against the local backend (frame captures at 150 ms and 700 ms latency,
rapid tab tapping, full quiz run). Not checked on a real phone or iOS Safari.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 17:55:47 +03:30
2026-10-07 19:04:45 +03:30
2026-10-07 19:04:45 +03:30
2026-08-16 12:18:41 +03:30

تدریسینو — فرانتِ اپِ ریاضی

اپِ وبِ موبایل‌محورِ تدریسینو (React + TypeScript + Vite + Tailwind). بک‌اندش ریپوی جداست (Tadrisino/MathApp)؛ قراردادِ API در /api/docs/ همان بک‌اند است.

راه‌اندازی

npm install
npm run dev          # http://localhost:5173

در حالتِ توسعه، درخواست‌های /api از خودِ Vite به بک‌اند پاس داده می‌شوند، پس CORS مطرح نیست. پیش‌فرض بک‌اندِ محلی است (python manage.py runserver روی پورتِ ۸۰۰۰). بدونِ بک‌اندِ محلی، یک فایلِ .env.development.local بسازید:

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/ش سرو می‌کند):

./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/             همراه‌ها: سیگما، دلتا، پی، تدی
  diagram/             شکلِ جوابِ دستیار: توصیفِ JSON از بک‌اند → SVG؛ همه‌ی مختصات این‌جا حساب می‌شود
                       (plane، shapes، expr، solid، charts، sets، misc، numberline). گالری: ?gallery فقط در dev
  lib/                 اعدادِ فارسی، تاریخِ شمسی، صدا، localStorage

قاعده‌ها:

  • اعداد: برای نمایش toFa، برای ورودی digitsOnly (کیبوردِ فارسی ارقامِ ۰-۹ می‌فرستد و \d در JS آن‌ها را نمی‌شناسد).
  • رنگ‌ها در src/styles/index.css (@theme) تعریف شده‌اند: bg-coral، text-ink، …
  • خطا: پیامِ کاربر همیشه از friendlyError می‌آید، نه متنِ خامِ سرور.
  • کلاینت را از حافظه ننویسید. قرارداد را از /api/docs/ بک‌اند بخوانید و تغییرِ types.ts را با پاسخِ واقعیِ سرور بسنجید.
Description
No description provided
Readme 2.4 MiB
Languages
TypeScript 94.4%
Kotlin 3.2%
CSS 1.2%
HTML 0.6%
Shell 0.4%
Other 0.2%