Fetch active specialties with number_of_doctors from GET /api/v1/specialties/doctor-counts (scoped to the current city via matchedCity.id) instead of the static specialties.json, so each specialty card shows the real doctor count. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.4 KiB
نمایش تعداد پزشکان هر تخصص در صفحه /specialties
پروژه
nobat724_front (سایت عمومی).
Cross-repo: وابسته به endpoint بکاند
GET /api/v1/specialties/doctor-counts?city_id=<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 از قبل تعداد را نشان میدهد (فقط داده ندارد):
<p className="text-[#7E7E7E] text-[14px] font-medium">
{data.number_of_doctors} پزشک
</p>
components/specialties/index.js:
import specialtiesData from "@/data/specialties.json";
const [filteredSpecialties, setFilteredSpecialties] = useState(specialtiesData);
const handleSearch = (value) => setFilteredSpecialties(searchOnList(specialtiesData, value, "name"));
app/specialties/page.js:
function Specialties() {
return (<Layout name="/specialties"><SpecialtiesPage /></Layout>);
}
پاسخ بکاند GET /api/v1/specialties/doctor-counts?city_id=<id>: { success, data: { data: [ {id, name, slug, parent_id, number_of_doctors, ...} ] } } (double-nested — success(['data'=>...])).
وظایف
۱. wrapper در services/response.js
getSpecialtyDoctorCounts: (cityId) =>
api.get(`api/v1/specialties/doctor-counts`, { params: { city_id: cityId } }),
۲. پاسدادن city id از صفحهی server به کامپوننت client
در app/specialties/page.js:
import { getStateInfo } from "@/lib/getStateInfo";
async function Specialties() {
const { matchedCity } = await getStateInfo();
return (
<Layout name="/specialties">
<SpecialtiesPage cityId={matchedCity?.id ?? null} />
</Layout>
);
}
(صفحه باید 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 هم همه را داشت، رفتار را حفظ کن.
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>) — مطمئن شوidدر پاسخ API همان است که/doctorsباspecialty_id/specialtiesمیپذیرد. - App Router؛
generateMetadataوgetStateInfoالگوی موجود؛ RTL/Vazir. - بعد از تغییر:
npm run buildبدون خطا؛ روی/specialtiesتعداد واقعی پزشکانِ شهر زیر هر تخصص دیده شود؛ جستجو همچنان کار کند.