# نمایش تعداد پزشکان هر تخصص در صفحه /specialties ## پروژه `nobat724_front` (سایت عمومی). > **Cross-repo:** وابسته به endpoint بک‌اند `GET /api/v1/specialties/doctor-counts?city_id=` (پرامپت `clinicpro/.claude/prompt/specialty-doctor-counts.md`). آن **اول** اجرا شود. ## زمینه صفحه‌ی `/specialties` کارت هر تخصص را از `data/specialties.json` (ثابت) رندر می‌کند و زیرش `{data.number_of_doctors} پزشک` می‌نویسد — اما `specialties.json` فیلد `number_of_doctors` ندارد، پس همیشه خالی است. باید تعداد واقعی پزشکانِ هر تخصص **در شهرِ دامنه‌ی جاری** از API گرفته و نمایش داده شود. شهر از subdomain تشخیص داده می‌شود: server-side با `getStateInfo()` → `matchedCity.id` (همان city id بک‌اند). ## مشکل / هدف صفحه به‌جای json ثابت، لیست تخصص‌ها را با `number_of_doctors` از endpoint جدید (با `city_id` شهر جاری) بگیرد و نمایش دهد. ## فایل‌های مرتبط | فایل | نقش | |------|-----| | `app/specialties/page.js` | Server Component — `matchedCity.id` را از `getStateInfo` بگیر و به صفحه بده | | `components/specialties/index.js` | `"use client"` — fetch count از API به‌جای json ثابت | | `components/specialties/list/ItemSpecialties.js` | نمایش `data.number_of_doctors` (موجود — تغییر لازم ندارد) | | `services/response.js` | افزودن wrapper `getSpecialtyDoctorCounts(cityId)` | ## وضعیت فعلی (کد واقعی) `ItemSpecialties.js` از قبل تعداد را نشان می‌دهد (فقط داده ندارد): ```jsx

{data.number_of_doctors} پزشک

``` `components/specialties/index.js`: ```jsx import specialtiesData from "@/data/specialties.json"; const [filteredSpecialties, setFilteredSpecialties] = useState(specialtiesData); const handleSearch = (value) => setFilteredSpecialties(searchOnList(specialtiesData, value, "name")); ``` `app/specialties/page.js`: ```jsx function Specialties() { return (); } ``` پاسخ بک‌اند `GET /api/v1/specialties/doctor-counts?city_id=`: `{ success, data: { data: [ {id, name, slug, parent_id, number_of_doctors, ...} ] } }` (double-nested — `success(['data'=>...])`). ## وظایف ### ۱. wrapper در `services/response.js` ```js getSpecialtyDoctorCounts: (cityId) => api.get(`api/v1/specialties/doctor-counts`, { params: { city_id: cityId } }), ``` ### ۲. پاس‌دادن city id از صفحه‌ی server به کامپوننت client در `app/specialties/page.js`: ```jsx import { getStateInfo } from "@/lib/getStateInfo"; async function Specialties() { const { matchedCity } = await getStateInfo(); return ( ); } ``` (صفحه باید `async` شود؛ `generateMetadata` موجود دست‌نخورده.) ### ۳. fetch در `components/specialties/index.js` - prop `cityId` بگیر. - در `useEffect` (mount / تغییر cityId) `request.getSpecialtyDoctorCounts(cityId)` را صدا بزن، `res.data.data` را در state بگذار. - تا رسیدن داده، می‌توان از `specialties.json` به‌عنوان نمایش اولیه استفاده کرد (یا اسکلت)، ولی منبعِ نهایی API است. - جستجو روی همان لیستِ API اعمال شود (`searchOnList(list, value, "name")`). - فقط تخصص‌های ریشه (یا همان رفتار فعلی) نمایش داده شوند؛ اگر API همه را می‌دهد و قبلاً json هم همه را داشت، رفتار را حفظ کن. ```jsx const [all, setAll] = useState([]); const [filtered, setFiltered] = useState([]); useEffect(() => { request.getSpecialtyDoctorCounts(cityId) .then((res) => { const items = res?.data?.data ?? []; setAll(items); setFiltered(items); }) .catch(() => { setAll([]); setFiltered([]); }); }, [cityId]); const handleSearch = (value) => setFiltered(searchOnList(all, value, "name")); ``` ### ۴. `ItemSpecialties.js` بدون تغییر ساختار؛ فقط مطمئن شو `data.number_of_doctors` (که حالا از API می‌آید) و `data.id` (برای لینک `/doctors?specialties=`) درست‌اند. اگر `number_of_doctors` صفر بود، «۰ پزشک» نمایش داده شود (یا در صورت تمایل پنهان شود). ## نکات مهم - پاسخ double-nested است → `res.data.data`. - `matchedCity?.id` ممکن است `null` باشد (دامنه‌ی ناشناخته) → بدون `city_id` ارسال شود؛ بک‌اند شمارش سراسری می‌دهد (fallback). - لینک کارت تخصص از `data.id` استفاده می‌کند (`/doctors?specialties=`) — مطمئن شو `id` در پاسخ API همان است که `/doctors` با `specialty_id`/`specialties` می‌پذیرد. - App Router؛ `generateMetadata` و `getStateInfo` الگوی موجود؛ RTL/Vazir. - بعد از تغییر: `npm run build` بدون خطا؛ روی `/specialties` تعداد واقعی پزشکانِ شهر زیر هر تخصص دیده شود؛ جستجو همچنان کار کند.