Files
nobat724_front/components/doctor/poster/PosterLight.js
T

223 lines
8.6 KiB
JavaScript
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.
"use client";
import { useEffect, useState } from "react";
import DoctorAvatar from "@/app/component/DoctorAvatar";
import QrImg from "./QrImg";
import SiteLogo from "@/components/common/SiteLogo";
import { getStateInfoClient } from "@/lib/getStateInfoClient";
import { posterSpecialtyLine, splitSpecialties } from "@/lib/specialtyDisplay";
import { doctorTitle } from "@/helper";
import StarDI from "@/components/icons/StarDI";
import { FEATURES } from "@/config/features";
const ACCENT = "#16528C";
const ACCENT_LIGHT = "#2E77C4";
const ORANGE = "#F17732";
function PosterLight({ data, onQrReady }) {
const [city, setCity] = useState(null);
useEffect(() => {
const { matchedCity } = getStateInfoClient();
setCity(matchedCity || null);
}, []);
// قرینهٔ پوستر تیره — همان دلیل: برش عددیِ ثابت با نام‌های بلند از کادر بیرون می‌زد.
const { primary, rest } = splitSpecialties(data?.specialties);
const subSpecialties = posterSpecialtyLine(rest, 78);
const services = (data?.expertise ?? []).filter((s) => s?.name);
const shownServices = services.slice(0, 8);
const moreServices = services.length - shownServices.length;
const rawAddress = data?.address?.[0]?.address;
const address =
rawAddress && rawAddress.length > 120
? `${rawAddress.slice(0, 120).trimEnd()}…`
: rawAddress;
const phones = (data?.address ?? [])
.map((a) => a?.phone)
.filter(Boolean)
.slice(0, 2);
const badges = [
Number(data?.experience) > 0 && { label: `${data.experience} سال تجربه` },
FEATURES.posterRatings && (data?.point ?? 0) > 0 && { icon: <StarDI />, label: `امتیاز ${data.point}` },
FEATURES.posterRatings && (data?.satisfaction ?? 0) > 0 && { label: `${data.satisfaction}% رضایت بیماران` },
].filter(Boolean);
return (
<div
dir="rtl"
className="relative w-[1080px] h-[1527px] overflow-hidden flex flex-col bg-[#F6F9FD] text-center"
>
{/* top brand band */}
<div
className="relative flex items-center justify-center py-[36px]"
style={{
background: `linear-gradient(135deg, ${ACCENT} 0%, ${ACCENT_LIGHT} 100%)`,
}}
>
<div className="flex items-center gap-[16px]">
<span className="flex items-center justify-center w-[72px] h-[72px] rounded-full bg-white">
<SiteLogo city={city} className="h-[48px] w-[48px]" />
</span>
<div className="flex flex-col items-start">
<span className="text-white text-[32px] font-extrabold leading-tight">
{city?.site_name || "نوبت ۷۲۴"}
</span>
<span className="text-[#CFE2F6] text-[19px] font-medium" dir="ltr">
{city?.domain || "nobat724.com"}
</span>
</div>
</div>
</div>
{/* بالا-چین می‌ماند تا آواتار روی نوار بالایی سوار بماند؛ فاصلهٔ اضافیِ کاغذ A4
به‌صورت فضای خالی بالای فوتر می‌نشیند، نه بین آواتار و نوار. */}
<div className="flex-1 px-[72px] pb-[40px] flex flex-col items-center">
{/* avatar overlapping band */}
<div className="-mt-[8px] pt-[40px]">
<div
className="rounded-full p-[7px] bg-white"
style={{ boxShadow: "0 12px 40px rgba(22,82,140,.18)" }}
>
<DoctorAvatar
doctor={data}
size={230}
priority
className="rounded-full !object-cover w-[230px] h-[230px]"
/>
</div>
</div>
<h1 className="mt-[28px] text-[#12365C] text-[48px] font-extrabold leading-tight">
{doctorTitle(data?.name)}
</h1>
{primary && (
<div className="w-full flex justify-center mt-[16px]">
<span className="flex items-center shrink-0 rounded-full bg-[#E3EEF9] px-[20px] py-[9px]">
<span className="text-[#16528C] text-[23px] font-semibold leading-none whitespace-nowrap">
{primary.name}
</span>
</span>
</div>
)}
{/* زیرتخصص‌ها یک خط متنی — در چاپ نه کلیک هست نه Popover. */}
{subSpecialties.text && (
<p className="w-full mt-[12px] max-h-[80px] overflow-hidden text-[#3E6E9E] text-[20px] font-medium leading-[40px]">
{subSpecialties.text}
{subSpecialties.hidden > 0 && ` و ${subSpecialties.hidden} تخصص دیگر`}
</p>
)}
{badges.length > 0 && (
<div className="w-full flex flex-wrap justify-center items-center gap-[14px] mt-[22px]">
{badges.map((b, i) => (
<span key={i} className="flex items-center shrink-0 gap-[8px]">
{i > 0 && <span className="text-[#B8CCE0] text-[22px]">·</span>}
{b.icon}
<span className="text-[#4A6B8C] text-[22px] font-medium leading-none whitespace-nowrap">
{b.label}
</span>
</span>
))}
</div>
)}
{data?.medical_system_code && (
<p className="mt-[12px] text-[#7A93AC] text-[20px]">
کد نظام پزشکی:{" "}
<span dir="ltr" className="font-semibold text-[#4A6B8C]">
{data.medical_system_code}
</span>
</p>
)}
{/* services */}
{shownServices.length > 0 && (
<div className="w-full mt-[36px] rounded-[24px] bg-white border border-[#E2ECF5] p-[32px]">
<p className="text-[#12365C] text-[26px] font-bold mb-[20px]">خدمات</p>
<div className="flex flex-wrap justify-center gap-x-[12px] gap-y-[14px]">
{shownServices.map((s, i) => (
<span
key={i}
className="flex items-center gap-[10px] rounded-full bg-[#F6F9FD] border border-[#E2ECF5] px-[18px] py-[10px]"
>
<span
className="w-[9px] h-[9px] rounded-full shrink-0"
style={{ background: ORANGE }}
/>
<span className="text-[#33526F] text-[22px] leading-none whitespace-nowrap">
{s.name}
</span>
</span>
))}
{moreServices > 0 && (
<span className="text-[#7A93AC] text-[22px]">
+ {moreServices} خدمت دیگر
</span>
)}
</div>
</div>
)}
{/* address / phone */}
{(address || phones.length > 0) && (
<div className="w-full mt-[24px] rounded-[24px] bg-white border border-[#E2ECF5] p-[32px]">
{address && (
<p className="text-[#33526F] text-[23px] leading-[1.7] line-clamp-2">
<span className="font-bold text-[#12365C]">آدرس: </span>
{address}
</p>
)}
{phones.length > 0 && (
<p className={`text-[#33526F] text-[23px] ${address ? "mt-[16px]" : ""}`}>
<span className="font-bold text-[#12365C]">تلفن: </span>
{phones.map((p, i) => (
<span key={i} dir="ltr" className="font-semibold">
{p}
{i < phones.length - 1 ? " | " : ""}
</span>
))}
</p>
)}
</div>
)}
</div>
{/* footer */}
<div
className="relative mt-[28px] flex items-center justify-between px-[72px] py-[32px]"
style={{
background: `linear-gradient(135deg, ${ACCENT} 0%, ${ACCENT_LIGHT} 100%)`,
}}
>
<div className="flex items-center gap-[24px]">
<div className="rounded-[18px] bg-white p-[14px]">
<QrImg onReady={onQrReady} size={150} />
</div>
<div className="flex flex-col items-start">
<span className="text-white text-[28px] font-bold">
رزرو نوبت آنلاین اسکن کنید
</span>
<span className="text-[#CFE2F6] text-[21px] mt-[8px]" dir="ltr">
{city?.domain || "nobat724.com"}
</span>
</div>
</div>
<div
className="flex items-center rounded-full px-[26px] py-[13px]"
style={{ background: ORANGE }}
>
<span className="text-white text-[22px] font-bold leading-none">
نوبتدهی ۲۴ ساعته
</span>
</div>
</div>
</div>
);
}
export default PosterLight;