import { doctorTitle } from "@/helper";
// Icons
import CopyBlueD from "@/components/icons/CopyBlueD";
import DownloadBlue from "@/components/icons/DownloadBlue";
import WhatsappBlueD from "@/components/icons/WhatsappBlueD";
import TelegramBlueD from "@/components/icons/TelegramBlueD";
import LinkedingBlueD from "@/components/icons/LinkedingBlueD";
// Packages
import { useState } from "react";
import { toPng } from "html-to-image";
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
import { Button } from "@mui/material";
import { toast } from "react-toastify";
const A4_WIDTH_MM = 210;
const A4_HEIGHT_MM = 297;
const VAZIR_WEIGHTS = [
[400, "Vazirmatn-RD-FD-Regular.ttf"],
[500, "Vazirmatn-RD-FD-Medium.ttf"],
[600, "Vazirmatn-RD-FD-SemiBold.ttf"],
[700, "Vazirmatn-RD-FD-Bold.ttf"],
[800, "Vazirmatn-RD-FD-ExtraBold.ttf"],
];
let vazirEmbedCssPromise;
const getVazirEmbedCss = () => {
vazirEmbedCssPromise ??= Promise.all(
VAZIR_WEIGHTS.map(async ([weight, file]) => {
const res = await fetch(`/fonts/vazir/${file}`);
const blob = await res.blob();
const dataUrl = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
return `@font-face{font-family:vazir;src:url(${dataUrl});font-weight:${weight};}`;
})
).then((faces) => faces.join("\n"));
return vazirEmbedCssPromise;
};
const waitForImages = async (element) => {
const imgs = Array.from(element.querySelectorAll("img"));
await Promise.all(
imgs.map((img) => {
if (img.complete && img.naturalWidth !== 0) {
return img.decode?.().catch(() => {}) ?? Promise.resolve();
}
return new Promise((resolve) => {
img.onload = () => resolve();
img.onerror = () => resolve();
});
})
);
};
function List({ hiddenRef, data, qrReady }) {
const [downloading, setDownloading] = useState(false);
const handleDownloadPDF = async () => {
const element = hiddenRef.current;
if (!element || downloading) return;
if (!qrReady) {
toast.info("در حال آمادهسازی پوستر، لحظهای صبر کنید...");
return;
}
setDownloading(true);
try {
await waitForImages(element);
let imgData;
let pxWidth;
let pxHeight;
try {
const fontEmbedCSS = await getVazirEmbedCss();
const options = {
pixelRatio: 2,
backgroundColor: "#ffffff",
style: { opacity: "1" },
fontEmbedCSS,
};
imgData = await toPng(element, options);
pxWidth = element.offsetWidth * 2;
pxHeight = element.offsetHeight * 2;
} catch {
const canvas = await html2canvas(element, {
backgroundColor: "#ffffff",
useCORS: true,
scale: 2,
imageTimeout: 15000,
});
imgData = canvas.toDataURL("image/png");
pxWidth = canvas.width;
pxHeight = canvas.height;
}
// کاغذ همیشه A4 است، نه اندازهای که از نسبت تصویر درمیآید: خروجی قبلی
// ۲۱۰×۲۶۲٫۵ میلیمتر بود و روی هیچ پرینتری A4 حساب نمیشد.
const pdf = new jsPDF({ orientation: "portrait", unit: "mm", format: "a4" });
// پوستر خودش نسبت A4 دارد، پس عملاً کل صفحه را پر میکند. این محاسبه تور
// ایمنی است تا اگر ابعاد پوستر روزی عوض شد، تصویر از کاغذ بیرون نزند.
let width = A4_WIDTH_MM;
let height = (pxHeight / pxWidth) * width;
if (height > A4_HEIGHT_MM) {
height = A4_HEIGHT_MM;
width = (pxWidth / pxHeight) * height;
}
pdf.addImage(
imgData,
"PNG",
(A4_WIDTH_MM - width) / 2,
(A4_HEIGHT_MM - height) / 2,
width,
height,
);
const safeName = (data?.name ?? "doctor").replace(/[\\/:*?"<>|]+/g, "-");
pdf.save(`poster-${safeName}.pdf`);
} catch {
toast.error("ساخت پوستر ناموفق بود، دوباره تلاش کنید");
} finally {
setDownloading(false);
}
};
const getShareUrl = () =>
typeof window !== "undefined" ? window.location.href : "";
const getShareText = () =>
data?.name ? `معرفی ${doctorTitle(data.name)} در نوبت 724` : "معرفی پزشک در نوبت 724";
const openShareWindow = (url) => {
if (typeof window !== "undefined") {
window.open(url, "_blank", "noopener,noreferrer");
}
};
const handleWhatsapp = () => {
const text = encodeURIComponent(`${getShareText()}\n${getShareUrl()}`);
openShareWindow(`https://wa.me/?text=${text}`);
};
const handleTelegram = () => {
const url = encodeURIComponent(getShareUrl());
const text = encodeURIComponent(getShareText());
openShareWindow(`https://t.me/share/url?url=${url}&text=${text}`);
};
const handleLinkedin = () => {
const url = encodeURIComponent(getShareUrl());
openShareWindow(
`https://www.linkedin.com/sharing/share-offsite/?url=${url}`
);
};
const handleCopyLink = async () => {
try {
await navigator.clipboard.writeText(getShareUrl());
toast.success("لینک کپی شد");
} catch {
toast.error("کپی لینک ناموفق بود");
}
};
const listIcons = [
{ name: "واتساپ", icon: