From 4374ed5043f95033556a6c8d4f267ce9916cc664 Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Mon, 15 Jun 2026 09:12:51 +0330 Subject: [PATCH] feat(panel): connect representative panel and user dashboard to real API, removing mock data --- .../prompt/connect-panel-dashboard-to-api.md | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 .claude/prompt/connect-panel-dashboard-to-api.md diff --git a/.claude/prompt/connect-panel-dashboard-to-api.md b/.claude/prompt/connect-panel-dashboard-to-api.md new file mode 100644 index 0000000..a18cc9d --- /dev/null +++ b/.claude/prompt/connect-panel-dashboard-to-api.md @@ -0,0 +1,164 @@ +# اتصال پنل نماینده و داشبورد کاربر به API واقعی (حذف داده‌های mock) + +## پروژه + +`nobat724_front` — سایت عمومی نوبت‌دهی. این کار صرفاً frontend است و backend (`clinicpro`) تغییر نمی‌کند؛ همه‌ی endpointهای لازم از قبل در `clinicpro/docs/api/` مستند و آماده‌اند. + +## زمینه + +بخش عمده‌ی سایت عمومی (لیست/جزئیات پزشک، کلینیک، بلاگ، فرایند نوبت‌گیری، پرداخت، لاگین OTP) قبلاً از طریق `services/response.js` → `request.*` به API واقعی متصل است. اما دو ناحیه هنوز روی داده‌ی mock محلی کار می‌کنند و عملاً برای همه‌ی کاربران یک داده‌ی ثابت و ساختگی نشان می‌دهند: + +1. **پنل نماینده** (`app/panel/(layout)/*`) — از `data/information.json` تغذیه می‌شود (نام، آمار، نمودار درآمد، لیست نوبت پزشکان). +2. **داشبورد/حساب کاربری بیمار** (`components/dashboard/*`) — از `data/userData.json` و `data/bank.json` تغذیه می‌شود (پروفایل، نوبت‌ها، تراکنش‌ها). + +نکته‌ی مهم: layout پنل (`app/panel/(layout)/layout.js`) **همین حالا** `representationInfo` واقعی را server-side از `GET /api/v1/representation/{uuid}` می‌گیرد و به `Content` پاس می‌دهد، ولی `Content` و صفحات داخلی این prop را نادیده می‌گیرند و به‌جایش `information.json` را import می‌کنند. پس بخشی از کار «وصل‌کردن سیم‌های قطع‌شده»ی موجود است، نه ساختن از صفر. + +## مشکل / هدف + +پنل نماینده و داشبورد کاربر را به API واقعی وصل کن تا داده‌ی هر کاربر واقعی و مخصوص خودش باشد، و importهای `data/information.json`، `data/userData.json`، `data/bank.json` از مسیر render حذف شوند. + +این کار باید **مرحله‌به‌مرحله** انجام شود (یک قابلیت در هر مرحله: پیاده‌سازی → build/lint → تأیید → commit)، چون نواحی مستقل‌اند و ریسک رگرسیون در صفحات mock بالاست. + +## فایل‌های مرتبط + +| فایل | نقش | +|------|-----| +| `services/response.js` | لایه‌ی `request.*`؛ توابع موجود استفاده می‌شوند و توابع جدید representation dashboard اضافه می‌شود | +| `app/panel/(layout)/layout.js` | server-side؛ `representationInfo` را از API می‌گیرد و پاس می‌دهد (موجود — تغییر نمی‌کند) | +| `components/panel/Content.js` | `import Information from "@/data/information.json"` را حذف و `representationInfo` را مصرف کن | +| `app/panel/(layout)/dashboard/page.js` | mock `Information` را با داده‌ی واقعی representation dashboard جایگزین کن | +| `app/panel/(layout)/turns/page.js` | mock `Information` → نوبت‌های واقعی | +| `app/panel/(layout)/user-account/page.js` | mock `Information` + `Bank` → داده‌ی واقعی نماینده + حساب بانکی | +| `app/panel/(layout)/add-doctor/page.js` | mock `Information` → `representationInfo` | +| `components/dashboard/Content.js` | `import userData from "@/data/userData.json"` را با `user-profile` + appointments واقعی جایگزین کن | +| `components/dashboard/userAccount/sidebars/turns/index.js` | از قبل `request.*` دارد — صرفاً بررسی اتصال | +| `components/dashboard/userAccount/sidebars/transactions/index.js` | از قبل `request.*` دارد — صرفاً بررسی اتصال | +| `lib/auth.js` | `getUser()` server-side از کوکی (برای uuid/representation_uuid) | +| `clinicpro/docs/api/representation.md` | قرارداد endpointهای representation و dashboard ماهانه/سالانه | +| `clinicpro/docs/api/user-profile.md` | قرارداد پروفایل کاربر | + +## وضعیت فعلی + +### پنل: داده‌ی واقعی موجود است ولی نادیده گرفته می‌شود + +`app/panel/(layout)/layout.js` — این بخش درست است و حفظ می‌شود: + +```js +let representationInfo = null; +// ... +representationInfo = await fetchReq( + `${API_URL}/api/v1/representation/${representationUuid}`, + { headers: { Authorization: `Bearer ${accessToken.value}` } } +); +return ; +``` + +اما `components/panel/Content.js` آن را مصرف نمی‌کند و mock import می‌کند: + +```js +import Information from "@/data/information.json"; +// ... +function Content({ children, representationInfo }) { + // representationInfo دریافت می‌شود ولی فقط به UserDetail پاس داده می‌شود + // Header همچنان data={Information} (mock) می‌گیرد +``` + +و `app/panel/(layout)/dashboard/page.js` کاملاً mock است: + +```js +import DashboardPage from "@/components/panel/dashboard"; +import Information from "@/data/information.json"; +function Dashboard() { + return ; +} +``` + +### داشبورد کاربر: کاملاً mock + +`components/dashboard/Content.js`: + +```js +import userData from "@/data/userData.json"; +// ... + + + +``` + +### لایه‌ی API موجود (در `services/response.js`) + +این توابع از قبل آماده‌اند و باید استفاده شوند: + +```js +getRepresentationInfo: (uuid) => api.get(`api/v1/representation/${uuid}`, { requireAuth: true }), +getUserProfile: (uuid) => api.get(`/api/v1/user-profile/${uuid}`, { requireAuth: true }), +getMyAppointments: (userId, params) => api.get(`api/v1/appointment/my-appointments/${userId}`, { params, requireAuth: true }), +getMyPayments: (userId, params) => api.get(`api/v1/payment/my-payments/${userId}`, { params, requireAuth: true }), +``` + +توابع dashboard ماهانه/سالانه نماینده **هنوز نیستند** و باید اضافه شوند (endpointها در `representation.md` مستند است). + +## وظایف + +اجرای مرحله‌به‌مرحله؛ بعد از هر قابلیت `npm run lint && npm run build` و سپس commit جدا. + +### ۱. افزودن توابع representation dashboard به `services/response.js` + +طبق `clinicpro/docs/api/representation.md`: + +```js +getRepresentationDashboardMonthly: (uuid, year, month) => + api.get(`api/v1/representation/${uuid}/dashboard/monthly`, { + params: { year, month }, + requireAuth: true, + }), +getRepresentationDashboardYearly: (uuid, year) => + api.get(`api/v1/representation/${uuid}/dashboard/yearly`, { + params: { year }, + requireAuth: true, + }), +``` + +> پاسخ تک‌منبعی است: داده در `response.data` (پس از interceptor در `api.js` که `response.data` را برمی‌گرداند) → سپس `result.data` طبق envelope `{ success, data }`. + +### ۲. وصل‌کردن Header و UserDetail پنل به `representationInfo` + +در `components/panel/Content.js`: +- `import Information from "@/data/information.json"` را حذف کن. +- `representationInfo` (که از layout می‌آید) را به `
` و `` پاس بده. +- چون شکل `representationInfo` (فیلدهای `full_name`, `city_name`, `commission_percent`, `bank_account`, ...) با شکل mock (`name`, `detail`, `expertise`, `all_patients`, ...) فرق دارد، یک adapter کوچک بنویس که فیلدهای واقعی را به همان propهایی که `Header`/`UserDetail` انتظار دارند map کند. فیلدهای آماری که در API نیستند (مثل `todays_activities`) را از dashboard ماهانه پر کن یا حذف کن — توهم‌سازی داده ممنوع. + +### ۳. صفحه‌ی dashboard پنل با داده‌ی واقعی + +`app/panel/(layout)/dashboard/page.js`: +- این صفحه Server Component است. `representation_uuid` را از کوکی `userInfo` بخوان (مثل `layout.js`). +- `GET /api/v1/representation/{uuid}/dashboard/monthly?year=&month=` را با سال/ماه جلالی جاری فراخوانی کن (تبدیل به سال/ماه میلادی یا طبق چیزی که backend انتظار دارد — در `representation.md` پارامتر `year`/`month` عددی است؛ بررسی کن backend جلالی می‌خواهد یا میلادی، اگر مبهم بود همین‌جا توقف کن و بپرس). +- خروجی `stats` (`total_appointments`, `total_revenue_rials`, `commission_rials`, `daily[]`) را به `DashboardPage` بده. +- نمودار درآمد (`chart_amount_income` در mock) را از `daily[].revenue` یا از dashboard سالانه (`months[].revenue_rials`) بساز. + +### ۴. صفحات turns و user-account و add-doctor پنل + +- `turns/page.js`: لیست نوبت پزشکانِ نماینده — اگر endpoint اختصاصی نیست، از همان dashboard ماهانه (`daily`) یا توقف و پرسش. mock حذف شود. +- `user-account/page.js`: `bank_account` واقعی از `representationInfo` به‌جای `data/bank.json`؛ اطلاعات نماینده به‌جای `information.json`. +- `add-doctor/page.js`: `Information` mock فقط برای نمایش هدر استفاده می‌شود → با `representationInfo` جایگزین کن. + +### ۵. داشبورد/حساب کاربری بیمار با داده‌ی واقعی + +`components/dashboard/Content.js`: +- `import userData from "@/data/userData.json"` را حذف کن. +- `uuid` کاربر را از کوکی بخوان (یا از prop `logged`/`getUser`). +- پروفایل را با `request.getUserProfile(uuid)` بگیر (طبق `user-profile.md`). +- نوبت‌ها و تراکنش‌ها از قبل در `sidebars/turns/index.js` و `sidebars/transactions/index.js` با `request.getMyAppointments` / `request.getMyPayments` گرفته می‌شوند — صرفاً تأیید کن که `userId` درست پاس می‌شود و دیگر به `userData.json` وابسته نیستند. +- فیلدهای mock که معادل API ندارند را حذف کن (نه ساختن داده‌ی جعلی). + +## نکات مهم + +- **هیچ تغییری در backend لازم نیست.** اگر حین کار به endpoint غایبی برخوردی (مثلاً «لیست نوبت پزشکان یک نماینده»)، **متوقف شو و بپرس** — پرامپت جداگانه برای backend لازم می‌شود (cross-repo)؛ داده‌ی جعلی جایگزین نکن. +- **App Router:** صفحات پنل/داشبورد که داده‌ی server-side می‌خواهند باید Server Component بمانند و کوکی را با `cookies()` از `next/headers` بخوانند؛ کامپوننت‌های `"use client"` که `request.*` صدا می‌زنند uuid را به‌صورت prop بگیرند. همیشه `await params`/`await cookies()`. +- **Auth:** همه‌ی این endpointها `requireAuth` می‌خواهند؛ توابع `request.*` خودشان کوکی `access_token` را به‌صورت Bearer ضمیمه می‌کنند. در 401، `api.js` به‌صورت خودکار logout و redirect به `/login` می‌کند — رفتار موجود را خراب نکن. +- **Multi-domain:** این صفحات هم زیر subdomain شهر اجرا می‌شوند؛ هر `matchedCity`/`getStateInfo` موجود را حذف نکن. +- **شکل پاسخ:** envelope بک‌اند `{ success, data }` است. interceptor در `services/api.js` یک‌بار `response.data` را برمی‌گرداند، پس در فراخوانی‌ها داده‌ی واقعی در `result.data` است. این را با یک endpoint واقعی تأیید کن، نه با حدس. +- **Jalali/RTL:** تاریخ‌ها با `jalali-moment`/`dayjs` به شمسی نمایش داده شوند؛ مبالغ به ریال با جداکننده‌ی هزارگان فارسی. timestampهای API یونیکس هستند. +- **adapter جدا:** برای هر ناحیه یک تابع map کوچک بنویس (API → propهای کامپوننت موجود) تا کامپوننت‌های نمایشی دست‌نخورده بمانند و دیف کوچک شود. +- **تست:** بعد از هر قابلیت `npm run lint` و `npm run build`؛ build کامل خطاهای صفحه/متادیتا را آشکار می‌کند. سپس commit با پیام توصیفی فارسی/انگلیسی برای همان قابلیت. +- **فایل‌های mock:** فعلاً فایل‌های `data/*.json` را پاک نکن؛ فقط importشان را از مسیر render حذف کن (ممکن است جای دیگری مرجع داشته باشند). حذف نهایی فایل‌ها در یک commit جدا بعد از تأیید عدم استفاده.