refactor: implement PDF download functionality for appointment details in DetailLg and DetailSm components
This commit is contained in:
@@ -2,10 +2,20 @@ import { Button } from "@mui/material";
|
|||||||
import ModalDeleteComment from "./modal";
|
import ModalDeleteComment from "./modal";
|
||||||
import EditTurnsD from "@/components/icons/EditTurnsD";
|
import EditTurnsD from "@/components/icons/EditTurnsD";
|
||||||
import ArrowLeftD from "@/components/icons/ArrowLeftD";
|
import ArrowLeftD from "@/components/icons/ArrowLeftD";
|
||||||
|
import DownloadD from "@/components/icons/DownloadD";
|
||||||
|
|
||||||
function ButtonData({ loading }) {
|
function ButtonData({ loading, onDownload }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex mt-[48px] md:mt-0 items-center justify-center md:justify-end gap-[16px] sm:gap-[16px] md:gap-[20px] lg:gap-[24px]">
|
<div className="flex mt-[48px] md:mt-0 items-center justify-center md:justify-end gap-[16px] sm:gap-[16px] md:gap-[20px] lg:gap-[24px]">
|
||||||
|
{/* <Button
|
||||||
|
className="!rounded-[4px] !border !border-solid !border-[#D7D7D7] !shadow-none !gap-[4px] !py-[6px] md:!py-[7px] lg:!py-[8px] !px-[12px]"
|
||||||
|
disabled={loading}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={onDownload}
|
||||||
|
>
|
||||||
|
<DownloadD />
|
||||||
|
دانلود اطلاعات نوبت
|
||||||
|
</Button>
|
||||||
<ModalDeleteComment loading={loading} />
|
<ModalDeleteComment loading={loading} />
|
||||||
<Button
|
<Button
|
||||||
className="!rounded-[4px] !shadow-none !gap-[4px] !py-[6px] md:!py-[7px] lg:!py-[8px] !px-[12px]"
|
className="!rounded-[4px] !shadow-none !gap-[4px] !py-[6px] md:!py-[7px] lg:!py-[8px] !px-[12px]"
|
||||||
@@ -17,7 +27,7 @@ function ButtonData({ loading }) {
|
|||||||
<div className="mr-[4px]">
|
<div className="mr-[4px]">
|
||||||
<ArrowLeftD />
|
<ArrowLeftD />
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,51 @@ import DownloadD from "@/components/icons/DownloadD";
|
|||||||
import LocationClinic from "@/components/icons/LocationClinic";
|
import LocationClinic from "@/components/icons/LocationClinic";
|
||||||
import RoutingC from "@/components/icons/RoutingC";
|
import RoutingC from "@/components/icons/RoutingC";
|
||||||
import { Button } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import React from "react";
|
import React, { useRef } from "react";
|
||||||
import { convertTimestampToJalali, convertTimestampToTime } from "@/helper";
|
import { convertTimestampToJalali, convertTimestampToTime } from "@/helper";
|
||||||
|
import html2canvas from "html2canvas";
|
||||||
|
import jsPDF from "jspdf";
|
||||||
|
|
||||||
function DetailLg({ appointmentData, loading }) {
|
function DetailLg({ appointmentData, loading }) {
|
||||||
|
const detailsRef = useRef(null);
|
||||||
|
|
||||||
|
const handleDownloadPDF = async () => {
|
||||||
|
if (!detailsRef.current) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const canvas = await html2canvas(detailsRef.current, {
|
||||||
|
scale: 2,
|
||||||
|
useCORS: true,
|
||||||
|
logging: false,
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
});
|
||||||
|
|
||||||
|
const imgData = canvas.toDataURL("image/png");
|
||||||
|
const pdf = new jsPDF({
|
||||||
|
orientation: "portrait",
|
||||||
|
unit: "mm",
|
||||||
|
format: "a4",
|
||||||
|
});
|
||||||
|
|
||||||
|
const pdfWidth = pdf.internal.pageSize.getWidth();
|
||||||
|
const pdfHeight = pdf.internal.pageSize.getHeight();
|
||||||
|
|
||||||
|
const imgWidth = pdfWidth * 0.9; // 90% of page width
|
||||||
|
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
||||||
|
|
||||||
|
// Center horizontally and vertically
|
||||||
|
const xPosition = (pdfWidth - imgWidth) / 2;
|
||||||
|
const yPosition = (pdfHeight - imgHeight) / 2;
|
||||||
|
|
||||||
|
pdf.addImage(imgData, "PNG", xPosition, yPosition, imgWidth, imgHeight);
|
||||||
|
pdf.save(`appointment_${appointmentData?.uuid || Date.now()}.pdf`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error generating PDF:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="lg:mt-[18px] hidden md:block">
|
<div ref={detailsRef} className="lg:mt-[18px] hidden md:block">
|
||||||
<div className="flex md:mt-[24px] lg:mt-0 items-center justify-start gap-[8px] md:gap-[12px] lg:gap-[16px]">
|
<div className="flex md:mt-[24px] lg:mt-0 items-center justify-start gap-[8px] md:gap-[12px] lg:gap-[16px]">
|
||||||
<div className="flex flex-col items-start justify-center gap-[20px]">
|
<div className="flex flex-col items-start justify-center gap-[20px]">
|
||||||
<TextLoading loading={loading} width={70} height={18}>
|
<TextLoading loading={loading} width={70} height={18}>
|
||||||
@@ -94,9 +132,10 @@ function DetailLg({ appointmentData, loading }) {
|
|||||||
</li>
|
</li>
|
||||||
</TextLoading>
|
</TextLoading>
|
||||||
</ul>
|
</ul>
|
||||||
<Button
|
{/* <Button
|
||||||
className="!px-[12px] !hidden md:!flex !mt-[24px] !py-[8px] !border !border-solid !border-[#D7D7D7] !rounded-[4px] !w-fit !items-center !justify-center !gap-[4px]"
|
className="!px-[12px] !hidden md:!flex !mt-[24px] !py-[8px] !border !border-solid !border-[#D7D7D7] !rounded-[4px] !w-fit !items-center !justify-center !gap-[4px]"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
onClick={handleDownloadPDF}
|
||||||
>
|
>
|
||||||
<TextLoading loading={loading} width={150} height={18}>
|
<TextLoading loading={loading} width={150} height={18}>
|
||||||
<DownloadD />
|
<DownloadD />
|
||||||
@@ -104,7 +143,7 @@ function DetailLg({ appointmentData, loading }) {
|
|||||||
دانلود اطلاعات نوبت
|
دانلود اطلاعات نوبت
|
||||||
</p>
|
</p>
|
||||||
</TextLoading>
|
</TextLoading>
|
||||||
</Button>
|
</Button> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,52 @@
|
|||||||
import RoutingC from "@/components/icons/RoutingC";
|
import RoutingC from "@/components/icons/RoutingC";
|
||||||
import { Button } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import React from "react";
|
import React, { useRef } from "react";
|
||||||
import ButtonData from "./ButtonData";
|
import ButtonData from "./ButtonData";
|
||||||
import TextLoading from "@/app/component/loading/Text";
|
import TextLoading from "@/app/component/loading/Text";
|
||||||
import { convertTimestampToJalali } from "@/helper";
|
import { convertTimestampToJalali } from "@/helper";
|
||||||
|
import html2canvas from "html2canvas";
|
||||||
|
import jsPDF from "jspdf";
|
||||||
|
|
||||||
function DetailSm({ appointmentData, loading }) {
|
function DetailSm({ appointmentData, loading }) {
|
||||||
|
const detailsRef = useRef(null);
|
||||||
|
|
||||||
|
const handleDownloadPDF = async () => {
|
||||||
|
if (!detailsRef.current) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const canvas = await html2canvas(detailsRef.current, {
|
||||||
|
scale: 2,
|
||||||
|
useCORS: true,
|
||||||
|
logging: false,
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
});
|
||||||
|
|
||||||
|
const imgData = canvas.toDataURL("image/png");
|
||||||
|
const pdf = new jsPDF({
|
||||||
|
orientation: "portrait",
|
||||||
|
unit: "mm",
|
||||||
|
format: "a4",
|
||||||
|
});
|
||||||
|
|
||||||
|
const pdfWidth = pdf.internal.pageSize.getWidth();
|
||||||
|
const pdfHeight = pdf.internal.pageSize.getHeight();
|
||||||
|
|
||||||
|
const imgWidth = pdfWidth * 0.9; // 90% of page width
|
||||||
|
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
||||||
|
|
||||||
|
// Center horizontally and vertically
|
||||||
|
const xPosition = (pdfWidth - imgWidth) / 2;
|
||||||
|
const yPosition = (pdfHeight - imgHeight) / 2;
|
||||||
|
|
||||||
|
pdf.addImage(imgData, "PNG", xPosition, yPosition, imgWidth, imgHeight);
|
||||||
|
pdf.save(`appointment_${appointmentData?.uuid || Date.now()}.pdf`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error generating PDF:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-[20px] block md:hidden">
|
<div ref={detailsRef} className="mt-[20px] block md:hidden">
|
||||||
<div className="flex items-center justify-start gap-[8px]">
|
<div className="flex items-center justify-start gap-[8px]">
|
||||||
<div className="flex flex-col justify-center items-start gap-[8px]">
|
<div className="flex flex-col justify-center items-start gap-[8px]">
|
||||||
<TextLoading loading={loading} width={60} height={14}>
|
<TextLoading loading={loading} width={60} height={14}>
|
||||||
@@ -78,7 +116,7 @@ function DetailSm({ appointmentData, loading }) {
|
|||||||
</p>
|
</p>
|
||||||
</TextLoading>
|
</TextLoading>
|
||||||
</ul>
|
</ul>
|
||||||
<ButtonData loading={loading} />
|
<ButtonData loading={loading} onDownload={handleDownloadPDF} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user