preview pdf
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useMutation, useSuspenseQuery } from "@tanstack/react-query";
|
||||
import { useMutation, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { AlertModal } from "@/components/modal/alert-modal";
|
||||
import { Icons } from "@/components/icons";
|
||||
@@ -76,6 +76,7 @@ import {
|
||||
import {
|
||||
downloadApprovedQuotationPdf,
|
||||
downloadQuotationCustomerPackage,
|
||||
generateApprovedQuotationPdf,
|
||||
} from "../api/service";
|
||||
import type {
|
||||
QuotationAttachmentMutationPayload,
|
||||
@@ -814,7 +815,8 @@ export function QuotationDetail({
|
||||
canDownloadCustomerPackage: boolean;
|
||||
canGenerateApprovedPdf: boolean;
|
||||
}) {
|
||||
const { data } = useSuspenseQuery(quotationByIdOptions(quotationId));
|
||||
const queryClient = useQueryClient();
|
||||
const { data } = useSuspenseQuery(quotationByIdOptions(quotationId));
|
||||
const { data: itemsData } = useSuspenseQuery(
|
||||
quotationItemsOptions(quotationId),
|
||||
);
|
||||
@@ -1064,21 +1066,39 @@ export function QuotationDetail({
|
||||
toast.error(message);
|
||||
},
|
||||
});
|
||||
const downloadApprovedPdf = useMutation({
|
||||
mutationFn: async () => downloadApprovedQuotationPdf(quotationId),
|
||||
onSuccess: ({ blob, fileName }) => {
|
||||
downloadBlobFile(blob, fileName);
|
||||
toast.success("Approved PDF downloaded successfully");
|
||||
const downloadApprovedPdf = useMutation({
|
||||
mutationFn: async () => downloadApprovedQuotationPdf(quotationId),
|
||||
onSuccess: ({ blob, fileName }) => {
|
||||
downloadBlobFile(blob, fileName);
|
||||
toast.success("Approved PDF downloaded successfully");
|
||||
},
|
||||
onError: (error) =>
|
||||
toast.error(
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "Failed to download approved PDF",
|
||||
),
|
||||
});
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "Failed to download approved PDF",
|
||||
),
|
||||
});
|
||||
const createApprovedPdf = useMutation({
|
||||
mutationFn: async () => generateApprovedQuotationPdf(quotationId),
|
||||
onSuccess: async ({ blob, fileName }) => {
|
||||
await Promise.all([
|
||||
queryClient.invalidateQueries({ queryKey: quotationKeys.detail(quotationId) }),
|
||||
queryClient.invalidateQueries({ queryKey: quotationKeys.lists() }),
|
||||
queryClient.invalidateQueries({ queryKey: quotationDocumentKeys.data(quotationId) }),
|
||||
queryClient.invalidateQueries({ queryKey: quotationDocumentKeys.preview(quotationId) }),
|
||||
]);
|
||||
setCustomerPackageError(null);
|
||||
downloadBlobFile(blob, fileName);
|
||||
toast.success("Approved PDF generated successfully");
|
||||
},
|
||||
onError: (error) =>
|
||||
toast.error(
|
||||
error instanceof Error ? error.message : "Failed to generate approved PDF",
|
||||
),
|
||||
});
|
||||
|
||||
const branchMap = useMemo(
|
||||
const branchMap = useMemo(
|
||||
() => new Map(referenceData.branches.map((item) => [item.id, item.name])),
|
||||
[referenceData.branches],
|
||||
);
|
||||
@@ -1134,7 +1154,7 @@ export function QuotationDetail({
|
||||
? customerPackageError
|
||||
: hasOfficialDocument
|
||||
? "Generate the package from the approved PDF and active document library files."
|
||||
: "Customer package requires an approved PDF before it can be generated.";
|
||||
: "Customer package requires an approved PDF before it can be generated. Generate the official PDF first.";
|
||||
const canReviseByStatus = [
|
||||
"accepted",
|
||||
"rejected",
|
||||
@@ -2044,13 +2064,24 @@ export function QuotationDetail({
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{canGenerateCustomerPackage ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
isLoading={generateCustomerPackage.isPending}
|
||||
onClick={() =>
|
||||
customerPackage
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{canGenerateApprovedPdf && !hasOfficialDocument ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
isLoading={createApprovedPdf.isPending}
|
||||
onClick={() => createApprovedPdf.mutate()}
|
||||
>
|
||||
<Icons.badgeCheck className="mr-2 h-4 w-4" />
|
||||
Generate Official PDF
|
||||
</Button>
|
||||
) : null}
|
||||
{canGenerateCustomerPackage ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
disabled={!hasOfficialDocument}
|
||||
isLoading={generateCustomerPackage.isPending}
|
||||
onClick={() =>
|
||||
customerPackage
|
||||
? setConfirmRegenerateOpen(true)
|
||||
: generateCustomerPackage.mutate({
|
||||
quotationId,
|
||||
@@ -2134,13 +2165,24 @@ export function QuotationDetail({
|
||||
customer-deliverable package.
|
||||
</CardDescription>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{canGenerateCustomerPackage ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
isLoading={generateCustomerPackage.isPending}
|
||||
onClick={() =>
|
||||
customerPackage
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{canGenerateApprovedPdf && !hasOfficialDocument ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
isLoading={createApprovedPdf.isPending}
|
||||
onClick={() => createApprovedPdf.mutate()}
|
||||
>
|
||||
<Icons.badgeCheck className="mr-2 h-4 w-4" />
|
||||
Generate Official PDF
|
||||
</Button>
|
||||
) : null}
|
||||
{canGenerateCustomerPackage ? (
|
||||
<Button
|
||||
variant="outline"
|
||||
disabled={!hasOfficialDocument}
|
||||
isLoading={generateCustomerPackage.isPending}
|
||||
onClick={() =>
|
||||
customerPackage
|
||||
? setConfirmRegenerateOpen(true)
|
||||
: generateCustomerPackage.mutate({
|
||||
quotationId,
|
||||
|
||||
Reference in New Issue
Block a user