expose the fields and endpoint the screens were missing

بعد از merge شدنِ PR اول، صفحه‌های اپ با API مقایسه شدند و چند چیز کم بود.
همه‌ی تغییراتِ بک‌اند افزایشی‌اند، پس کدِ فعلی نمی‌شکند — این فقط دسترسی به
آن‌ها را اضافه می‌کند.

grades() حالا lessonCount دارد: فهرستِ پایه‌ها تا دوازدهم می‌رود ولی محتوا
تا نهم است، و بدونِ این عدد کاربر پایه‌ی خالی را انتخاب می‌کند و صفحه‌ی
خالی می‌بیند بی‌آنکه بفهمد چرا.

home() در هر مبحث icon و color و در هر فصل blurb می‌دهد، تا رنگ‌ها لازم
نباشد در کد هاردکد بمانند.

nodes.lessons(nodeId) تازه است. home() فقط شناسه‌ی درس‌ها را می‌دهد، ولی
کارتِ نقشه‌ی مهارت عنوان، نوع (آزمون/ویدیو)، زیرنویس («۵ سوال» / «۱۲
دقیقه») و «انجام شد» می‌خواهد — بدونِ این، برای هر کارت یک درخواستِ intro
جدا لازم بود.

lessons.intro() متن را سه‌تکه می‌دهد: introText (توضیح)، example، و steps
(حلِ گام‌به‌گام)؛ به‌علاوه kind و videoUrl و durationMinutes.

profile.update({ age }) هم پذیرفته می‌شود چون صفحه‌ی ثبت‌نام سن می‌پرسد؛
سرور خودش به سالِ تولدِ شمسی تبدیل می‌کند.

هنوز هیچ فایلِ موجودی دست نخورده و پکیجی اضافه نشده. هر ۲۰ صدا در برابرِ
یک بک‌اندِ در حالِ اجرا تست شد.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 01:50:04 +03:30
parent 4705925022
commit 7dd457d2fc
3 changed files with 70 additions and 7 deletions

View File

@@ -14,8 +14,8 @@
import { ApiError, createHttpClient, localTokenStorage } from './client';
import type { ClientOptions, HttpClient, RequestOptions, Tokens } from './client';
import type {
AnswerResponse, AskResponse, Grade, HomeResponse, LessonIntro, Plan, Question,
ReportReason, ReportResponse, UserProfile,
AnswerResponse, AskResponse, Grade, HomeResponse, LessonIntro, NodeLessons, Plan,
Question, ReportReason, ReportResponse, UserProfile,
} from './types';
export { ApiError, localTokenStorage, createHttpClient };
@@ -66,8 +66,13 @@ export function createApi(options: ClientOptions = {}) {
/* ── کاربر ────────────────────────────────────────────────────────── */
profile: {
get: (opts?: RequestOptions) => http.get<UserProfile>('/user/profile', opts),
/**
* فقط فیلدهایی که می‌فرستید عوض می‌شوند. صفحه‌ی ثبت‌نام سن می‌پرسد، پس
* `age` هم پذیرفته می‌شود و سرور خودش به سالِ تولدِ شمسی تبدیلش می‌کند —
* `age` و `birthYear` را با هم نفرستید.
*/
update: (patch: Partial<Pick<UserProfile,
'name' | 'avatar' | 'birthYear' | 'parentPhone' | 'bio'>>) =>
'name' | 'avatar' | 'birthYear' | 'parentPhone' | 'bio'>> & { age?: number }) =>
http.patch<UserProfile>('/user/profile', patch),
setGrade: (gradeId: number) =>
http.post<{ success: boolean; gradeId: number }>('/user/grade', { gradeId }),
@@ -96,6 +101,16 @@ export function createApi(options: ClientOptions = {}) {
http.create<Record<string, unknown>>(`/lessons/${lessonId}/complete`, {}),
},
nodes: {
/**
* قدم‌های یک مبحث برای نقشه‌ی مهارت — عنوان، نوع، زیرنویس و «انجام شد».
* `home()` فقط شناسه‌ی درس‌ها را می‌دهد؛ بدونِ این، برای هر کارت یک
* درخواستِ intro جدا لازم بود.
*/
lessons: (nodeId: number | string, opts?: RequestOptions) =>
http.get<NodeLessons>(`/nodes/${nodeId}/lessons`, opts),
},
questions: {
/**
* ثبتِ پاسخ. مسیر زیرِ /questions است نه /lessons، و نامِ فیلد