diff --git a/.claude/prompt/dashboard-tabs-real-data.md b/.claude/prompt/dashboard-tabs-real-data.md new file mode 100644 index 0000000..d5b38eb --- /dev/null +++ b/.claude/prompt/dashboard-tabs-real-data.md @@ -0,0 +1,139 @@ +# اتصال دقیق همه‌ی تب‌های داشبورد کاربر به داده‌ی واقعی backend + +## پروژه + +`nobat724_front` — سایت عمومی. **frontend-only**؛ همه‌ی endpointهای لازم در backend موجودند (پروفایل، نوبت‌های کاربر، پرداخت‌ها). تب‌هایی که backend ندارند (نظرات/پیام‌ها) باید empty-state درست نشان دهند، نه داده‌ی جعلی. + +## زمینه + +`/dashboard` شش تب دارد (`components/dashboard/userAccount/index.js`): +۱. **حساب کاربری** (DetailUser → اطلاعات عمومی + سوابق پزشکی: بیماری‌ها/آلرژی/داروها/جراحی/سابقه‌خانوادگی/بستگان) +۲. **نوبت‌های من** (Turns) +۳. **تراکنش‌های من** (Transactions) +۴. **نظرات من** (Comments) +۵. **پیام‌ها** (Messages) +۶. **خروج** + +وضعیت فعلی بعد از رفع‌های اخیر: +- نوبت‌ها → `GET /api/v1/appointments/user` (وصل شده) +- تراکنش‌ها → `GET /api/v1/my/payments` (وصل شده) +- حساب کاربری → `getUserProfile(userUuid)` لود می‌شود ولی **مپینگ فیلدها چند ایراد دارد** (بیمه، سوابق پزشکی) و کامل round-trip نمی‌شود. +- نظرات/پیام‌ها → از `user.comments`/`user.messages` که `buildPatientUser` همیشه `[]` می‌گذارد؛ **هیچ endpoint کاربری برای این دو در backend نیست** (تأییدشده: فقط `/comments/{doctorUuid}` و admin؛ messages اصلاً نیست). + +## مشکل / هدف + +۱. تب **حساب کاربری** را درست لود و ذخیره کن: مپینگ صحیح بیمه و سوابق پزشکی (`other`)، استفاده از `uuid` پروفایل برای PATCH. +۲. تب‌های **نوبت‌ها/تراکنش‌ها** را تأیید کن (شکل پاسخ، empty-state، تاریخ شمسی، مبلغ). +۳. تب‌های **نظرات/پیام‌ها**: چون backend ندارند، empty-state تمیز نشان بده (نه crash، نه داده‌ی ساختگی). در گزارش ذکر کن که نیاز به endpoint backend دارند (cross-repo آینده). + +## فایل‌های مرتبط + +| فایل | نقش | +|------|-----| +| `components/dashboard/userAccount/detailUser/information/index.js` | لود پروفایل برای فرم اطلاعات + سوابق | +| `components/dashboard/userAccount/detailUser/index.js` | PATCH ذخیره (`patchUserProfile(usedKeys, information?.uuid)`) | +| `components/dashboard/userAccount/detailUser/function.js` | `setNewData` (تغییر سوابق پزشکی) | +| `helper/index.js` | `removeAdditionalKeysDashboard`, `changeDateType` | +| `components/dashboard/userAccount/sidebars/turns/index.js` | نوبت‌ها (وصل‌شده — تأیید) | +| `components/dashboard/userAccount/sidebars/transactions/index.js` | تراکنش‌ها (وصل‌شده — تأیید) | +| `components/dashboard/userAccount/sidebars/comments/index.js` | `user.comments` | +| `components/dashboard/userAccount/sidebars/messages/index.js` | `user.messages` | +| `lib/representationAdapters.js` | `buildPatientUser` | +| `clinicpro/docs/api/user-profile.md` | قرارداد پروفایل + فیلد `other` | + +## وضعیت فعلی (کد واقعی) + +### مپینگ غلط بیمه در `information/index.js` + +```js +const profile = res?.data?.data; +// ... +let changedData = { ...profile }; +changedData.basic_insurance = [Number(profile?.basic_insurance?.id)]; // ❌ backend فیلد basic_insurance_id (عدد) می‌دهد، نه object با .id → [NaN] +changedData.prev_data = true; +changedData = changeDateType(changedData, false); +setInformation(changedData); +``` + +> پاسخ پروفایل backend (از `toArray`): `basic_insurance_id`, `supplementary_insurance_id` (اعداد یا null)، نه `basic_insurance.id`. همچنین سوابق پزشکی در `other` است (`{ disease, allergies, medications, surgeries, family_history, relatives }`). + +### قرارداد backend (از `user-profile.md` و entity `toArray`) + +```json +{ + "uuid": "...", "user_uuid": "...", + "label": "...", "family": "...", "national_code": "...", "gender": "male", + "date_of_birth": null, "fathers_name": null, "blood_type": null, + "marital_status": null, "education": null, "job": null, "address": null, + "home_phone": null, "work_phone": null, + "insurance_id": null, "basic_insurance_id": 1, "supplementary_insurance_id": null, + "other": { "disease": [...], "allergies": [...], "medications": [...], "surgeries": [...], "family_history": [...], "relatives": [...] }, + "description": null, "sharing_with_user": false +} +``` +> پاسخ دوبار تودرتو است → `res.data.data`. + +### ذخیره در `detailUser/index.js` + +```js +const updateData = () => { + const usedKays = removeAdditionalKeysDashboard(information); + request.patchUserProfile(usedKays, information?.uuid, Cookies.get("access_token")) // arg سوم نادیده گرفته می‌شود + .then(...).catch(...); +}; +``` + +## وظایف + +### ۱. مپینگ درست پروفایل هنگام لود (`information/index.js`) + +- بیمه را از فیلد درست بخوان (نه `.id`): + +```js +let changedData = { ...profile }; +changedData.basic_insurance = profile?.basic_insurance_id ? [profile.basic_insurance_id] : []; +changedData.supplementary_insurance = profile?.supplementary_insurance_id ? [profile.supplementary_insurance_id] : []; +changedData.other = profile?.other ?? { disease, allergies: [], medications: [], surgeries: [], family_history: [], relatives: [] }; +changedData.prev_data = true; +changedData = changeDateType(changedData, false); +setInformation(changedData); +``` + +- اطمینان حاصل کن `changedData.uuid = profile.uuid` (uuid پروفایل) حفظ می‌شود تا `patchUserProfile(..., information.uuid)` درست کار کند. +- `hasProfileData` فعلی (`label || family || national_code`) قابل‌قبول است؛ ولی چون backend حالا پروفایل خالی lazy-create می‌کند، پروفایل همیشه `uuid` دارد — برای تشخیص «پر بودن» همان منطق فیلد محتوا را نگه‌دار، ولی `uuid` را حتی در حالت خالی هم در `information` بگذار تا PATCH کار کند: + +```js +} else { + setInformation({ + uuid: profile?.uuid, // ✅ تا ذخیره ممکن باشد + prev_data: false, + other: { disease, allergies: [], medications: [], surgeries: [], family_history: [], relatives: [] }, + }); +} +``` + +### ۲. تأیید ذخیره (سوابق پزشکی → `other`) + +- `removeAdditionalKeysDashboard(information)` باید payloadی بسازد که شامل `other` (سوابق) و فیلدهای پروفایل باشد و کلیدهای اضافی frontend (مثل `prev_data`) را حذف کند. بررسی کن خروجی با آنچه backend `hydrate` می‌پذیرد هم‌خوان است (`name`/`label`, `family`, `national_code`, `gender`, `basic_insurance`, `supplementary_insurance`, `other`, ...). +- بعد از PATCH موفق، `information.uuid` را از پاسخ به‌روز نگه‌دار (اگر backend پروفایل جدید برگرداند). +- arg سوم `patchUserProfile` (access_token) زائد است (interceptor خودش توکن می‌زند) — حذفش کن یا بگذار (بی‌اثر). ترجیحاً امضای تابع را تمیز نگه‌دار. + +### ۳. تأیید تب‌های نوبت‌ها و تراکنش‌ها + +- **نوبت‌ها** (`turns/index.js`): پاسخ `appointments/user` دوبار تودرتو است → `res.data.data` (آرایه). تأیید کن کارت‌ها (`turns/Card.js`, `List.js`) فیلدهای واقعی نوبت (`slot_start`, `status`, `doctor`, `patient_name`) را می‌خوانند؛ تاریخ شمسی با `moment-jalaali`، وضعیت‌ها به فارسی map شوند. اگر کارت فیلدهای mock قدیمی می‌خواند، با شکل واقعی `Appointment.toArray()` هم‌خوان کن. +- **تراکنش‌ها** (`transactions/index.js`): پاسخ `my/payments` paginated است → `res.data` آرایه، `res.meta.totalPages`. تأیید کن `Card.js`/`List.js` فیلدهای واقعی پرداخت (`amount_rials`, `status`, `gateway`, `type`, `created_at`) را می‌خوانند؛ مبلغ ریال→تومان با جداکننده‌ی فارسی، وضعیت‌ها فارسی. +- **empty-state:** اگر آرایه خالی بود، پیام «موردی یافت نشد» (نه crash، نه اسپینر بی‌پایان). + +### ۴. تب‌های نظرات و پیام‌ها (بدون backend) + +- چون endpoint کاربری وجود ندارد، `Comments`/`Messages` از `user.comments`/`user.messages` (همیشه `[]`) می‌خوانند → empty-state تمیز نشان بده: «نظری ثبت نکرده‌اید» / «پیامی ندارید». مطمئن شو روی آرایه‌ی خالی crash نمی‌کنند (`user.comments?.map`، گارد طول). +- **داده‌ی جعلی نساز.** در گزارش پایانی ذکر کن که این دو تب برای داده‌ی واقعی نیاز به endpoint backend دارند (پرامپت cross-repo جداگانه در آینده). + +## نکات مهم + +- **هیچ تغییر backend در این پرامپت نیست.** پروفایل/نوبت/پرداخت همه آماده‌اند؛ نظرات/پیام‌ها عمداً empty می‌مانند. +- **double-nesting:** `user-profile` و `appointments/user` → `res.data.data`؛ `my/payments` → paginated (`res.data` + `res.meta`). هرکدام را درست مصرف کن (با pitfallهای قبلی یکدست). +- **uuid پروفایل برای PATCH:** `information.uuid` باید uuid پروفایل باشد (از `res.data.data.uuid`)، نه user-uuid. +- **سوابق پزشکی = `other`:** همه‌ی sub-tabها (allergies/medications/...) داخل `information.other` کار می‌کنند و با PATCH `other` ذخیره می‌شوند. +- **Jalali/RTL/مبلغ:** تاریخ‌ها شمسی، مبالغ ریال→تومان با جداکننده‌ی فارسی، timestampها یونیکس. +- **تست:** `npm run build`؛ سپس دستی با کاربر `09210651788` (پروفایل خالی + ۱ نوبت): تب حساب کاربری فرم خالی قابل‌ویرایش و ذخیره؛ تب نوبت‌ها ۱ نوبت با تاریخ/وضعیت درست؛ تب تراکنش‌ها empty-state؛ نظرات/پیام‌ها empty-state بدون crash. سپس commit per-tab. diff --git a/components/dashboard/userAccount/detailUser/information/index.js b/components/dashboard/userAccount/detailUser/information/index.js index 13fe284..b90bcaa 100644 --- a/components/dashboard/userAccount/detailUser/information/index.js +++ b/components/dashboard/userAccount/detailUser/information/index.js @@ -35,12 +35,22 @@ function Information({ information, setInformation }) { if (hasProfileData) { let changedData = { ...profile }; - changedData.basic_insurance = [Number(profile?.basic_insurance?.id)]; + changedData.basic_insurance = profile?.basic_insurance_id ? [profile.basic_insurance_id] : []; + changedData.supplementary_insurance = profile?.supplementary_insurance_id ? [profile.supplementary_insurance_id] : []; + changedData.other = profile?.other ?? { + disease, + allergies: [], + medications: [], + surgeries: [], + family_history: [], + relatives: [], + }; changedData.prev_data = true; changedData = changeDateType(changedData, false); setInformation(changedData); } else { setInformation({ + uuid: profile?.uuid, prev_data: false, other: { disease: disease,