Files
nobat724_front/.claude/prompt/fix-doctor-free-turn-disabled.md
T

173 lines
7.3 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# رفع نمایش نوبت آزاد و دکمه نوبت برای پزشک با نوبت‌دهی غیرفعال
## پروژه
`nobat724_front` (سایت عمومی — فقط نمایش؛ backend از قبل `free_turn` و `active` صحیح برمی‌گرداند)
## زمینه
Backend (`clinicpro`) برای هر پزشک دو فیلد می‌فرستد:
- `active` (boolean) = `activeDoctorAppointment && has_schedule`
- `free_turn` (string) = نزدیک‌ترین روز/ساعت کاری (مثل `دوشنبه 09:0013:00`)، یا اگر نوبت‌دهی آنلاین خاموش باشد `"نوبت‌دهی آنلاین غیرفعال است"`.
سایت عمومی این دو فیلد را در سه جا نمایش می‌دهد و الان رفتارش ناقص است.
## مشکل / هدف
۱. در کارت لیست `/doctors` و در باکس نوبت‌دهی صفحه‌ی پزشک، متن نوبت آزاد باید با پیشوند **«اولین نوبت آزاد:»** نمایش داده شود (مثلاً `اولین نوبت آزاد: دوشنبه 09:00–13:00`).
۲. اگر پزشک نوبت‌دهی آنلاینش خاموش است (`active === false`)، به‌جای `free_turn` باید **«نوبت‌دهی غیرفعال است»** نوشته شود.
۳. در صفحه‌ی پزشک (`/doctor/{uuid}`) بخش «نوبت دهی»، اگر `active === false` دکمه‌ی **«دریافت نوبت»** باید **disabled** شود (نه لینک فعال به `/appointment`).
## فایل‌های مرتبط
| فایل | نقش |
|------|-----|
| `app/component/ItemDoctor.js` | کارت پزشک در لیست `/doctors` — متن `free_turn` |
| `components/doctor/appointmentList/ItemAppointment.js` | باکس نوبت‌دهی دسکتاپ صفحه پزشک — متن + دکمه |
| `components/doctor/appointmentList/index.js` | نوار نوبت‌دهی موبایل (`fixed bottom`) — متن + دکمه |
## وضعیت فعلی
### `app/component/ItemDoctor.js` (حوالی خط ۸۴)
```jsx
<CustomLoading loading={loading} width={150} height={20}>
<p
className={`text-[12px] font-medium rounded w-fit p-1.5 ml-[52px]
${Number(doctor?.active)
? "bg-[rgba(5,_186,_88,_0.04)] text-[#05BA58]"
: "bg-[rgba(211,_47,_47,_0.04)] text-[#D32F2F]"
}`}
>
{doctor?.free_turn}
</p>
</CustomLoading>
```
مشکل: متن خام `free_turn` بدون پیشوند «اولین نوبت آزاد».
### `components/doctor/appointmentList/ItemAppointment.js` (خط ۳۶–۵۸)
```jsx
<div className="flex mt-5 gap-2 items-center justify-between">
<div className="flex items-start justify-start gap-1">
<GreenCalendarTurn />
<TextLoading width={100} height={15} loading={loading}>
<p className="text-[#05BA58] text-[12px] font-medium">
{turn?.free_turn
? ` ${turn?.free_turn}`
: "نوبت ندارد"}
</p>
</TextLoading>
</div>
<Link href={loading ? "#" : `/appointment/${doctorSlug}`}>
<Button
variant="contained"
className="!py-2 !px-3 xl:!px-6 gap-1"
disabled={loading}
>
دریافت نوبت
<div className="w-[20px] h-[20px]">
<ArrowLeftD />
</div>
</Button>
</Link>
</div>
```
مشکل: پیشوند ندارد؛ دکمه فقط با `loading` غیرفعال می‌شود، نه با `active === false`.
### `components/doctor/appointmentList/index.js` (نوار موبایل، خط ۱۶–۳۴)
```jsx
<div className="fixed lg:hidden ... flex items-center justify-between">
<p className="text-[#05BA58] text-[11px] font-normal">
{doctor && doctor?.free_turn}
</p>
<Link href={`/appointment/${doctorSlug}`}>
<Button variant="contained" className="!py-2 !px-4 gap-1 !text-[14px] !font-medium">
دریافت نوبت
<div className="w-[20px] h-[20px]"><ArrowLeftD /></div>
</Button>
</Link>
</div>
```
مشکل: پیشوند ندارد؛ دکمه هیچ‌وقت با `active === false` غیرفعال نمی‌شود.
## وظایف
### ۱. کارت لیست — `app/component/ItemDoctor.js`
متن `free_turn` را با پیشوند نشان بده؛ اگر `active` خاموش بود متن «نوبت‌دهی غیرفعال است».
```jsx
{Number(doctor?.active) && doctor?.free_turn
? `اولین نوبت آزاد: ${doctor.free_turn}`
: "نوبت‌دهی غیرفعال است"}
```
رنگ سبز/قرمز موجود حفظ شود (بر اساس `Number(doctor?.active)`).
### ۲. باکس دسکتاپ — `components/doctor/appointmentList/ItemAppointment.js`
اول یک متغیر در ابتدای کامپوننت:
```jsx
function ItemAppointment({ turn, loading, doctorSlug }) {
const bookingDisabled = !loading && turn?.active === false;
return (
```
متن:
```jsx
<p className="text-[#05BA58] text-[12px] font-medium">
{bookingDisabled || !turn?.free_turn
? "نوبت‌دهی غیرفعال است"
: `اولین نوبت آزاد: ${turn.free_turn}`}
</p>
```
دکمه — وقتی `bookingDisabled` بود disabled و بدون `<Link>`:
```jsx
{bookingDisabled ? (
<Button variant="contained" className="!py-2 !px-3 xl:!px-6 gap-1" disabled>
نوبتدهی غیرفعال
</Button>
) : (
<Link href={loading ? "#" : `/appointment/${doctorSlug}`}>
<Button variant="contained" className="!py-2 !px-3 xl:!px-6 gap-1" disabled={loading}>
دریافت نوبت
<div className="w-[20px] h-[20px]"><ArrowLeftD /></div>
</Button>
</Link>
)}
```
### ۳. نوار موبایل — `components/doctor/appointmentList/index.js`
متن:
```jsx
<p className="text-[#05BA58] text-[11px] font-normal">
{doctor?.active === false || !doctor?.free_turn
? "نوبت‌دهی غیرفعال است"
: `اولین نوبت آزاد: ${doctor.free_turn}`}
</p>
```
دکمه:
```jsx
{doctor?.active === false ? (
<Button variant="contained" className="!py-2 !px-4 gap-1 !text-[14px] !font-medium" disabled>
نوبتدهی غیرفعال
</Button>
) : (
<Link href={`/appointment/${doctorSlug}`}>
<Button variant="contained" className="!py-2 !px-4 gap-1 !text-[14px] !font-medium">
دریافت نوبت
<div className="w-[20px] h-[20px]"><ArrowLeftD /></div>
</Button>
</Link>
)}
```
## نکات مهم
- `active` از API نوع boolean است؛ در `ItemDoctor.js` با `Number(doctor?.active)` چک می‌شود (الگوی موجود را نگه‌دار)، در باقی جاها مستقیم `=== false`.
- در حالت `loading` (اسکلتون) نباید «نوبت‌دهی غیرفعال» نشان داده شود؛ برای همین `bookingDisabled = !loading && turn?.active === false`.
- backend از قبل پیام `"نوبت‌دهی آنلاین غیرفعال است"` در `free_turn` می‌فرستد — ولی frontend نباید به متن backend وابسته باشد؛ بر اساس فیلد boolean `active` تصمیم بگیر (پایدارتر).
- تست با پزشک `7db9be49-db71-4ec5-add6-24f890b4ad29` (در DB محلی باید `active_doctor_appointment=0` شود تا غیرفعال شود). پزشک غیرفعال در لیست `/doctors` اصلاً نمی‌آید (فیلتر backend)، پس باگ کارت لیست فقط برای پزشکانی که `active:false` ولی همچنان در نتیجه هستند مهم است.
- بعد از تغییر: `npm run build` بدون خطا.