Files
hamed b494473e40 feat: رفع لینک /doctor/undefined و متمایزسازی صفحهٔ اصلی شهرها
- ایجاد پرامپت برای رفع خطای 404 ناشی از لینک `/doctor/undefined` در سایت‌های بهبهان و یاسوج.
- افزودن کامپوننت `CityHighlights` برای نمایش محتوای یکتا و آمار پزشکان و تخصص‌های پرمراجعه در صفحهٔ اصلی هر شهر.
- به‌روزرسانی تست‌های مربوط به کامپوننت‌های `ItemDoctor` و `CityHighlights` برای اطمینان از عدم وجود لینک‌های نامعتبر و نمایش صحیح اطلاعات.
- ایجاد سند جدید برای مستندسازی خطاهای Search Console که باگ نیستند و نیاز به رفع ندارند.
- افزودن تست‌های واحد برای توابع `buildCityIntro` و دیگر توابع مرتبط با تولید متن یکتا برای صفحات لیست.
2026-08-08 19:14:50 +03:30

117 lines
4.7 KiB
JavaScript

import { memo } from "react";
import { Button } from "@mui/material";
import Link from "next/link";
import CustomLoading from "./loading/Custom";
import TextLoading from "./loading/Text";
import CircularLoading from "./loading/Circular";
import DoctorAvatar from "./DoctorAvatar";
import SpecialtyChips from "./SpecialtyChips";
// Icons
import ArrowLeftD from "@/components/icons/ArrowLeftD";
import ClockD from "@/components/icons/ClockD";
import LikeD from "@/components/icons/LikeD";
import PointD from "@/components/icons/PointD";
function ItemDoctor({ doctor, loading, setDoctors, priority = false }) {
// بدون uuid لینکی وجود ندارد. اسکلتِ بارگذاری آبجکتِ بی‌uuid می‌دهد و پیش از این
// شش `<a href="/doctor/undefined">` در HTML می‌نشست؛ Googlebot همان را crawl می‌کرد
// و ۴۰۴ می‌گرفت (گزارش Search Console، ۳۰ ژوئیه).
const href = doctor?.uuid ? `/doctor/${doctor.uuid}` : null;
const label = doctor?.display_name || doctor?.name;
const handleLoading = () => {
setDoctors((prevDoctors) =>
prevDoctors.map((item) =>
item.id === doctor.id
? { ...item, loading: true }
: { ...item, loading: false }
)
);
};
return (
<li className="p-4 relative rounded-lg bg-[#FFF] border border-[#EFEFEF]">
{/* Detail Doctor */}
<div className="flex items-center justify-start gap-2.5">
<CircularLoading loading={loading} width={66} height={66}>
<DoctorAvatar
doctor={doctor}
size={72}
className="w-[64px] md:w-[68px] lg:w-[72px] h-[64px] md:h-[68px] lg:h-[72px]"
priority={priority}
/>
</CircularLoading>
<div className="flex flex-col items-start justify-center gap-2">
<TextLoading loading={loading} width={90} height={15}>
{href ? (
<Link href={href}>
<p className="text-[#3B3B3B] text-[14px] font-bold">{label}</p>
</Link>
) : (
<p className="text-[#3B3B3B] text-[14px] font-bold">{label}</p>
)}
</TextLoading>
<TextLoading loading={loading} width={120} height={15}>
<SpecialtyChips specialties={doctor?.specialties} />
</TextLoading>
<CustomLoading loading={loading} width={100} height={25}>
<div className="flex rounded items-center justify-start gap-2">
<div className="p-1 bg-[#F8F8FF] flex items-center rounded-[4px] gap-0.5">
<LikeD />
<p className="text-[#616161] text-[12px] font-normal">
{doctor?.satisfaction}%
</p>
</div>
<div className="p-1 bg-[#F8F8FF] flex items-center rounded-[4px] gap-0.5">
<PointD />
<p className="text-[#616161] text-[12px] font-normal">
{doctor?.point}
</p>
</div>
</div>
</CustomLoading>
</div>
</div>
{/* Hours of work */}
<div className="flex my-4 items-center justify-start gap-0.5">
<ClockD />
<TextLoading loading={loading} width={150} height={15}>
<p className="text-[#616161] text-[12px] font-normal">
ساعت کاری: {doctor?.hours_of_work}
</p>
</TextLoading>
</div>
<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]" }`}
>
{Number(doctor?.active) && doctor?.free_turn
? `اولین نوبت آزاد: ${doctor.free_turn}`
: "نوبت‌دهی غیرفعال است"}
</p>
</CustomLoading>
{/* Arrow — روی کارتِ بدون uuid (اسکلت بارگذاری) اصلاً رندر نمی‌شود؛ دکمه‌ای که
به جایی نمی‌رود، هم بی‌معناست هم لینکِ شکسته در HTML می‌گذارد. */}
{href && (
<Link href={href} aria-label={`مشاهده پروفایل ${label || "پزشک"}`}>
<Button
variant="contained"
onClick={handleLoading}
disabled={doctor?.loading}
aria-label={`مشاهده پروفایل ${label || "پزشک"}`}
className="!p-[14px] !absolute !left-4 !bottom-4 !rounded-full !w-fit"
>
<div className={doctor && doctor.loading ? "opacity-0" : ""}>
<ArrowLeftD />
</div>
</Button>
</Link>
)}
</li>
);
}
export default memo(ItemDoctor);