Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Resource Letter printing issue #10230

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ead2748
fix resource letter print crash
AdityaJ2305 Jan 28, 2025
ba863cf
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 28, 2025
4b8a91b
add TFunction
AdityaJ2305 Jan 28, 2025
cd6483d
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 28, 2025
1c5d08b
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 28, 2025
93d64db
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 28, 2025
0f5dbde
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 28, 2025
28475eb
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 28, 2025
55678e7
Empty-Commit
AdityaJ2305 Jan 28, 2025
e15333b
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 29, 2025
0587ace
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 29, 2025
228d699
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 29, 2025
d011d26
created new print comp for resource letter
AdityaJ2305 Jan 29, 2025
f508df5
replace classNames with cn
AdityaJ2305 Jan 29, 2025
d93c32f
rm data from top
AdityaJ2305 Jan 29, 2025
0c752bc
Empty-Commit
AdityaJ2305 Jan 29, 2025
6ef544d
Empty-Commit
AdityaJ2305 Jan 29, 2025
1479600
Empty-Commit
AdityaJ2305 Jan 29, 2025
57c7113
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 30, 2025
d3c7da5
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 30, 2025
3bbea07
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 30, 2025
600a6c5
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 30, 2025
634d585
Merge branch 'develop' into resources_print_screen_crash
AdityaJ2305 Jan 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/CAREUI/misc/PrintPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ReactNode } from "react";
import { useTranslation } from "react-i18next";

import { cn } from "@/lib/utils";

import CareIcon from "@/CAREUI/icons/CareIcon";
import {
ZoomControls,
Expand All @@ -14,8 +16,6 @@ import Page from "@/components/Common/Page";

import useBreakpoints from "@/hooks/useBreakpoints";

import { classNames } from "@/Utils/utils";

type Props = {
children: ReactNode;
disabled?: boolean;
Expand All @@ -41,7 +41,7 @@ export default function PrintPreview(props: Props) {
<ZoomTransform className="origin-top-left bg-white p-10 text-sm shadow-2xl transition-all duration-200 ease-in-out lg:origin-top print:transform-none">
<div
id="section-to-print"
className={classNames("w-full", props.className)}
className={cn("w-full", props.className)}
>
{props.children}
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/Routers/routes/ResourceRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import View from "@/components/Common/View";
import PrintResourceLetter from "@/components/Resource/PrintResourceLetter";
import BoardView from "@/components/Resource/ResourceBoard";
import ResourceDetails from "@/components/Resource/ResourceDetails";
import { ResourceDetailsUpdate } from "@/components/Resource/ResourceDetailsUpdate";
Expand All @@ -10,6 +11,7 @@ const ResourceRoutes: AppRoutes = {
"/resource": () => <View name="resource" board={BoardView} list={ListView} />,
"/resource/:id": ({ id }) => <ResourceDetails id={id} />,
"/resource/:id/update": ({ id }) => <ResourceDetailsUpdate id={id} />,
"/resource/:id/print": ({ id }) => <PrintResourceLetter id={id} />,
};

export default ResourceRoutes;
129 changes: 129 additions & 0 deletions src/components/Resource/PrintResourceLetter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { useQuery } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";

import PrintPreview from "@/CAREUI/misc/PrintPreview";

import Loading from "@/components/Common/Loading";

import { RESOURCE_CATEGORY_CHOICES } from "@/common/constants";

import routes from "@/Utils/request/api";
import query from "@/Utils/request/query";
import { formatDateTime, formatName } from "@/Utils/utils";

export default function PrintResourceLetter({ id }: { id: string }) {
const { t } = useTranslation();

const { data, isLoading } = useQuery({
queryKey: ["resource_request_letter", id],
queryFn: query(routes.getResourceDetails, {
pathParams: { id: id },
}),
});

if (isLoading || !data) {
return <Loading />;
}
return (
<PrintPreview title={t("request_letter")}>
<div className="min-h-screen bg-white">
<div className="mx-4 p-4 lg:mx-20">
{/* Header */}
<div className="mb-8 text-center">
<div className="text-2xl font-bold">{t("request_letter")}</div>
<div className="mt-2 text-sm text-gray-600">
{t("reference_no")}: {data.id}
</div>
</div>

{/* Date */}
<div className="mb-6 text-right">
<div className="font-semibold">
{t("date")}: {formatDateTime(data.created_date)}
</div>
</div>

{/* From Address */}
<div className="mb-6">
<div className="font-semibold">{t("From")}:</div>
<div className="mt-1">{data.origin_facility.name}</div>
</div>

{/* Subject Line */}
<div className="mb-6">
<div className="font-semibold">
{t("subject")}: {t("request_for")} {data.title}
</div>
</div>

{/* Main Content */}
<div className="mb-6 leading-relaxed">
<p className="mb-4">
{t("request_the_following_resource")}
{data.emergency ? t("on_emergency_basis") : ""}:
</p>

<div className="mb-4 ml-4">
<div>
<span className="font-semibold">{t("request_title")}:</span>{" "}
{data.title}
</div>
<div>
<span className="font-semibold">{t("category")}:</span>{" "}
{RESOURCE_CATEGORY_CHOICES.find(
(item) => item.id === data.category,
)?.text || "--"}
</div>
<div>
<span className="font-semibold">{t("quantity_required")}:</span>{" "}
{data.requested_quantity}
</div>
<div className="mt-2">
<span className="font-semibold">
{t("reason_for_request")}:
</span>
<p className="mt-1">{data.reason || "--"}</p>
</div>
</div>

{/* Status Section */}
<div className="mb-4">
<span className="font-semibold">{t("current_status")}: </span>
<span className="rounded bg-gray-100 px-2 py-1">
{data.status}
</span>
</div>
</div>

{/* Signature Section */}
<div className="mt-12 flex justify-between">
<div>
<div className="mb-20">
<div className="font-semibold">{t("requested_by")}:</div>
<div>{formatName(data.created_by)}</div>
<div className="text-sm text-gray-600">
{formatDateTime(data.created_date)}
</div>
</div>
</div>

{data.status !== "PENDING" && (
<div>
<div className="mb-20">
<div className="font-semibold">
{data.status === "REJECTED" ? t("rejected") : t("approved")}{" "}
{t("by")}:
</div>
<div>{formatName(data.updated_by)}</div>
<div className="text-sm text-gray-600">
{formatDateTime(data.modified_date)}
</div>
</div>
</div>
)}
</div>
</div>
</div>
</PrintPreview>
);
}
142 changes: 10 additions & 132 deletions src/components/Resource/ResourceDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
import { navigate } from "raviger";
import { useState } from "react";
import { useTranslation } from "react-i18next";

import CareIcon from "@/CAREUI/icons/CareIcon";
Expand All @@ -17,10 +17,9 @@ import CommentSection from "@/components/Resource/ResourceCommentSection";
import { RESOURCE_CATEGORY_CHOICES } from "@/common/constants";

import routes from "@/Utils/request/api";
import useTanStackQueryInstead from "@/Utils/request/useQuery";
import query from "@/Utils/request/query";
import { formatDateTime, formatName } from "@/Utils/utils";
import { PatientModel } from "@/types/emr/patient";
import { ResourceRequest } from "@/types/resourceRequest/resourceRequest";

function PatientCard({ patient }: { patient: PatientModel }) {
const { t } = useTranslation();
Expand Down Expand Up @@ -103,119 +102,17 @@ function FacilityCard({
);
}

const RequestLetter = (data: ResourceRequest) => {
const { t } = useTranslation();
return (
<div id="section-to-print" className="print bg-white">
<div className="mx-4 p-4 lg:mx-20">
{/* Header */}
<div className="mb-8 text-center">
<div className="text-2xl font-bold">{t("request_letter")}</div>
<div className="mt-2 text-sm text-gray-600">
{t("reference_no")}: {data.id}
</div>
</div>

{/* Date */}
<div className="mb-6 text-right">
<div className="font-semibold">
{t("date")}: {formatDateTime(data.created_date)}
</div>
</div>

{/* From Address */}
<div className="mb-6">
<div className="font-semibold">{t("from")}:</div>
<div className="mt-1">{data.origin_facility.name}</div>
</div>

{/* Subject Line */}
<div className="mb-6">
<div className="font-semibold">
{t("subject")}: {t("request_for")} {data.title}
</div>
</div>

{/* Main Content */}
<div className="mb-6 leading-relaxed">
<p className="mb-4">
{t("request_the_following_resource")}
{data.emergency ? t("on_emergency_basis") : ""}:
</p>

<div className="mb-4 ml-4">
<div>
<span className="font-semibold">{t("request_title")}:</span>{" "}
{data.title}
</div>
<div>
<span className="font-semibold">{t("category")}:</span>{" "}
{RESOURCE_CATEGORY_CHOICES.find(
(item) => item.id === data.category,
)?.text || "--"}
</div>
<div>
<span className="font-semibold">{t("quantity_required")}:</span>{" "}
{data.requested_quantity}
</div>
<div className="mt-2">
<span className="font-semibold">{t("reason_for_request")}:</span>
<p className="mt-1">{data.reason || "--"}</p>
</div>
</div>

{/* Status Section */}
<div className="mb-4">
<span className="font-semibold">{t("current_status")}: </span>
<span className="rounded bg-gray-100 px-2 py-1">{data.status}</span>
</div>
</div>

{/* Signature Section */}
<div className="mt-12 flex justify-between">
<div>
<div className="mb-20">
<div className="font-semibold">{t("requested_by")}:</div>
<div>{formatName(data.created_by)}</div>
<div className="text-sm text-gray-600">
{formatDateTime(data.created_date)}
</div>
</div>
</div>

{data.status !== "PENDING" && (
<div>
<div className="mb-20">
<div className="font-semibold">
{data.status === "REJECTED" ? t("rejected") : t("approved")}
{t("by")}:
</div>
<div>{formatName(data.updated_by)}</div>
<div className="text-sm text-gray-600">
{formatDateTime(data.modified_date)}
</div>
</div>
</div>
)}
</div>
</div>
</div>
);
};

export default function ResourceDetails(props: { id: string }) {
const [isPrintMode, setIsPrintMode] = useState(false);
const { t } = useTranslation();
const { data, loading } = useTanStackQueryInstead(routes.getResourceDetails, {
pathParams: { id: props.id },
onResponse: ({ res, data }) => {
if (!res && !data) {
navigate("/not-found");
}
},

const { data, isLoading } = useQuery({
queryKey: ["resource_request", props.id],
queryFn: query(routes.getResourceDetails, {
pathParams: { id: props.id },
}),
});

if (loading || !data) {
if (isLoading || !data) {
return <Loading />;
}

Expand All @@ -230,7 +127,7 @@ export default function ResourceDetails(props: { id: string }) {
<div className="flex items-center justify-between">
<div className="flex flex-wrap gap-2 w-full">
<Button
onClick={() => setIsPrintMode(true)}
onClick={() => navigate(`/resource/${props.id}/print`)}
className="w-full sm:w-auto"
>
<CareIcon icon="l-file-alt" className="mr-2 h-4 w-4" />
Expand Down Expand Up @@ -371,25 +268,6 @@ export default function ResourceDetails(props: { id: string }) {
</CardContent>
</Card>
</div>

{/* Print Mode */}
{isPrintMode && (
<div className="fixed inset-0 z-50 bg-white">
<div className="mx-auto max-w-4xl p-4">
<div className="mb-4 flex justify-end gap-2">
<Button onClick={() => window.print()}>
<CareIcon icon="l-print" className="mr-2 h-4 w-4" />
{t("print")}
</Button>
<Button variant="outline" onClick={() => setIsPrintMode(false)}>
<CareIcon icon="l-times" className="mr-2 h-4 w-4" />
{t("close")}
</Button>
</div>
{RequestLetter(data)}
</div>
</div>
)}
</Page>
);
}
3 changes: 3 additions & 0 deletions src/style/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,9 @@ button:disabled,
}

@media print {
@page {
margin-top: 0;
}
body * {
visibility: hidden;
}
Expand Down
Loading