# اتصال UI غنیِ نظرات/امتیاز صفحه پزشک به قرارداد جدید بک‌اند

## پروژه

`nobat724_front` (سایت عمومی).

> **Cross-repo:** این پرامپت به قرارداد غنیِ بک‌اند وابسته است که در `clinicpro/.claude/prompt/rating-multidimensional-and-rich-comments.md` تعریف شده. **آن پرامپت بک‌اند باید اول اجرا شود.**

## زمینه

UI غنیِ نظرات/امتیاز صفحه پزشک (چارت ۵‌بُعدی + دایره‌ی رضایت + ستاره‌ی کلی + نظرات با نام/عکس/لایک/دیسلایک/پاسخ) از قبل در کد وجود دارد و باید **حفظ** شود. این کامپوننت‌ها فیلدهایی می‌خوانند که بک‌اندِ ساده‌ی قبلی نمی‌داد؛ حالا بک‌اند قرارداد غنی را تأمین می‌کند و فرانت فقط باید درست به آن وصل شود (و چند نقص جزئی رفع شود).

> هشدار: یک تلاش قبلی این UI را به‌اشتباه «ساده‌سازی» کرد و سپس به HEAD برگردانده شد. UI غنی نباید ساده شود؛ فقط به قرارداد جدید وصل شود.

## قرارداد بک‌اند (مرجع — از پرامپت همتا)

- `GET /api/v1/rate/{uuid}` (عمومی) → `{ data: { point, satisfaction, averages:[{name,label,progress}] } }`
- `POST /api/v1/rate` (AUTH) ← `{ doctor_uuid, waiting_time_at_clinic, accuracy_of_diagnosis, doctor_behavior, clinic_cleanliness, doctor_expertise }` (هر کدام ۰–۱۰۰)
- `GET /api/v1/comments/{uuid}` (عمومی) → `{ data: { data: [ { uuid, comment, created, parent, author:{real_name,picture:[{url}]}, like_status:{like_count,dislike_count,current_user_like:{like,dislike}}, replies:[…] } ] } }`
- `POST /api/v1/comment` (AUTH) ← `{ doctor_uuid, comment, parent }`
- `POST /api/v1/like/{commentUuid}` (AUTH) ← `{ value: 1|-1 }` → `{ data: { like_count, dislike_count, current_user_like } }`
- `GET /api/v1/rate/{uuid}/eligibility` (AUTH) → `{ data: { eligible: bool } }` (قبلاً اضافه شده)
- گارد بک‌اند: ثبت نظر/امتیاز فقط برای کاربرِ دارای نوبت confirmed در ۳۰ روز گذشته → در غیر این صورت `403 ERR_RATING_NOT_ELIGIBLE`.

## فایل‌های مرتبط (UI موجود که باید وصل شود)

| فایل | نقش | اصلاح موردنیاز |
|---|---|---|
| `app/doctor/[slug]/page.js` | fetch server-side | علاوه بر comments، تجمیع امتیاز از `GET /rate/{uuid}` را fetch کن و به‌صورت prop بده |
| `components/doctor/index.js` → `detailDoctor/index.js` → `cards/comments/index.js` | زنجیره prop | `rateAggregate` (point/satisfaction/averages) را عبور بده |
| `cards/comments/chart/index.js` | چارت ۵‌بُعدی + ستاره | به‌جای `doctor.point/satisfaction/average_rate.averages` از prop `rateAggregate` بخوان |
| `cards/comments/chart/ProgressAll.js` | دایره‌ی رضایت | `satisfaction` را از `rateAggregate` بگیرد |
| `cards/comments/modal/ModalAnswer.js` | مودال ثبت | پیش‌بارگذاری امتیاز قبلی را حذف/سازگار کن؛ eligibility بررسی شود |
| `cards/comments/modal/content/index.js` | هدر مودال | عنوان hardcoded «دکتر مهران امینی» → `doctor?.name` |
| `cards/comments/modal/content/Form.js` | ثبت امتیاز+نظر | body امتیاز را با `doctor_uuid` بفرست (نه `doctor_id`)؛ مدیریت ۴۰۳/۴۰۱ |
| `app/component/comment/ItemUser.js` | رندر نظر | `data.created`→تاریخ، author/like_status/replies حفظ؛ لایک/دیسلایک به `postCommentsLike(uuid, value)` وصل شود |
| `app/component/comment/SendAnswer.js` | ثبت پاسخ | body را با `doctor_uuid` و `parent` بفرست |
| `services/response.js` | wrappers | `postDoctorRate` بدنه‌ی چندبُعدی؛ `postCommentsLike(uuid, value)`؛ `getRateEligibility` (موجود) |

## وظایف

### ۱. fetch تجمیع امتیاز در صفحه و عبور prop
در `app/doctor/[slug]/page.js` کنار fetch فعلیِ doctor/comments، تجمیع امتیاز را بگیر:
```jsx
const resRate = await axiosInstance.get(`${API_URL}/api/v1/rate/${doctor.uuid}`);
const rateAggregate = resRate?.data?.data ?? { point: 0, satisfaction: 0, averages: [] };
```
سپس `rateAggregate` را از `DoctorPage` → `DetailDoctor` → `Comments` → `Chart`/`ProgressAll` عبور بده.

### ۲. اتصال چارت به قرارداد جدید (`chart/index.js` + `ProgressAll.js`)
- `Chart` به‌جای `doctor?.average_rate?.averages` از `rateAggregate.averages` استفاده کند (همان شکل `{name,label,progress}` که `ProgressDetail` انتظار دارد).
- `امتیاز کلی کاربران: {rateAggregate.point} از ۵` و ستاره `value={rateAggregate.point}`.
- `{rateAggregate.satisfaction}% رضایت کاربران` و `ProgressAll` با `satisfaction={rateAggregate.satisfaction}`.
- ساختار/استایل و کامپوننت‌های `ProgressDetail`/`ProgressAll`/loadingها حفظ شوند.

### ۳. فرم ثبت امتیاز چندبُعدی (`Form.js` + `ModalAnswer.js` + `content/index.js`)
- ساختار ۵‌بُعدیِ موجود (`Rates` + `ProgressChange` + `comment.rate`) حفظ شود.
- body امتیاز با **`doctor_uuid`** ارسال شود (نه `doctor_id`):
  ```jsx
  request.postDoctorRate({
    doctor_uuid: doctor.uuid,
    waiting_time_at_clinic: rate[0].progress,
    accuracy_of_diagnosis:  rate[1].progress,
    doctor_behavior:        rate[2].progress,
    clinic_cleanliness:     rate[3].progress,
    doctor_expertise:       rate[4].progress,
  });
  ```
  (ترتیب ایندکس‌ها را با `progress_detail.json` تطبیق بده — همان مپ فعلیِ Form.)
- نظر با `doctor_uuid` ارسال شود: `postDoctorComment({ doctor_uuid: doctor.uuid, comment, parent: null })`.
- چون بک‌اند upsert است، `patchDoctorRate`/`defaultRate` لازم نیست؛ همیشه `postDoctorRate`.
- عنوان مودال hardcoded → `doctor?.name`.
- در `ModalAnswer`، اگر pre-load امتیاز قبلی مشکل‌ساز است حذفش کن (بک‌اند endpoint «امتیاز کاربر فعلی» ندارد؛ `getDoctorRate` حالا تجمیع برمی‌گرداند نه رأی کاربر) — فرم با مقدار اولیه‌ی صفر باز شود.
- مدیریت خطا: ۴۰۱ → «برای ثبت باید وارد شوید»؛ ۴۰۳ با `ERR_RATING_NOT_ELIGIBLE` → پیام واجد بودن؛ سایر → خطای عمومی. (با `alert`)

### ۴. لایک/دیسلایک واقعی (`ItemUser.js` + `services/response.js`)
- `postCommentsLike` را به `(commentUuid, value)` تغییر بده: `api.post(`api/v1/like/${uuid}`, { value }, { requireAuth: true })`.
- در `ItemUser`، هنگام کلیک لایک `value=1` و دیسلایک `value=-1` بفرست؛ از پاسخ `{like_count,dislike_count,current_user_like}` state محلی را به‌روز کن (به‌جای دستکاری دستیِ فعلی روی `data.like_status`).
- نمایش author/created/replies حفظ شود.

### ۵. ثبت پاسخ (`SendAnswer.js`)
- body را `{ doctor_uuid: doctor.uuid /* یا از data */, comment, parent: data.uuid }` کن (نه `doctor_id`).
- منبع `doctor.uuid` را در این کامپوننت بررسی کن؛ اگر در دسترس نیست، از prop عبور بده.

### ۶. wrapperها (`services/response.js`)
- `postDoctorRate(data)` → `POST api/v1/rate` با `requireAuth` (بدنه‌ی چندبُعدی؛ بدون تغییر امضا، فقط دیتای جدید).
- `getRateEligibility(uuid)` (موجود) حفظ شود.
- `getDoctorRate(uuid)` حالا تجمیع برمی‌گرداند — مصرف‌کننده‌ها (chart) باید `data.point/...` بخوانند.

## نکات مهم

- **UI غنی حفظ شود؛ ساده نکن.** فقط به قرارداد جدید وصل کن و نقص‌های جزئی (hardcode، `doctor_id`→`doctor_uuid`، toggle لایک) را رفع کن.
- `app/component/comment/*` بین صفحه پزشک و بلاگ مشترک است، اما فراخوانی آن در بلاگ (`components/blog/detail/index.js`) کامنت‌اوت است؛ پس تغییرات صفحه پزشک بلاگ را نمی‌شکند — ولی هنگام تغییر `ItemUser`/`Comment` این اشتراک را در نظر بگیر و چیزی که build بلاگ را بشکند وارد نکن.
- `current_user_like` در لیست عمومی همیشه false است (طبق تصمیم بک‌اند)؛ وضعیت واقعی پس از کلیک از پاسخ `toggleLike` می‌آید — UI را optimistic نگه‌دار.
- نظرات نیازمند تأیید ادمین‌اند؛ لیست لوکال ممکن است خالی باشد → empty-state، نه خطا.
- App Router + RTL + Vazir؛ کتابخانه‌ی جدید اضافه نکن.
- بعد از تغییر: `npm run build` بدون خطا؛ `/doctor/[slug]` و `/blog/[slug]` هر دو باید کامپایل شوند.
