Add watermark to public trust center documents

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-09-11 17:37:56 +02:00
parent b06bd113f3
commit c3ea7a3cd0
11 changed files with 558 additions and 184 deletions

View File

@@ -16,7 +16,6 @@ export interface TrustCenterAudit {
report: {
id: string;
filename: string;
downloadUrl: string | null;
} | null;
}
@@ -71,6 +70,12 @@ interface ExportDocumentPDFData {
};
}
interface ExportReportPDFData {
exportReportPDF: {
data: string;
};
}
interface CreateTrustCenterAccessData {
createTrustCenterAccess: {
trustCenterAccess: {
@@ -111,7 +116,13 @@ interface AcceptNonDisclosureAgreementVariables {
};
}
type GraphQLVariables = TrustCenterQueryVariables | ExportDocumentPDFVariables | CreateTrustCenterAccessVariables | AcceptNonDisclosureAgreementVariables | Record<string, never>;
interface ExportReportPDFVariables {
input: {
reportId: string;
};
}
type GraphQLVariables = TrustCenterQueryVariables | ExportDocumentPDFVariables | ExportReportPDFVariables | CreateTrustCenterAccessVariables | AcceptNonDisclosureAgreementVariables | Record<string, never>;
async function trustCenterGraphQLRequest<T = unknown>(
operationName: string,
@@ -189,7 +200,6 @@ const TRUST_CENTER_QUERY = `
report {
id
filename
downloadUrl
}
}
}
@@ -219,6 +229,16 @@ const EXPORT_DOCUMENT_PDF_MUTATION = `
}
`;
const EXPORT_REPORT_PDF_MUTATION = `
mutation PublicTrustCenterAuditsExportReportPDFMutation(
$input: ExportReportPDFInput!
) {
exportReportPDF(input: $input) {
data
}
}
`;
const CREATE_TRUST_CENTER_ACCESS_MUTATION = `
mutation PublicTrustCenterAccessRequestDialogMutation(
$input: CreateTrustCenterAccessInput!
@@ -304,6 +324,30 @@ export function useExportDocumentPDF() {
});
}
export function useExportReportPDF() {
return useMutation<ExportReportPDFData, Error, string>({
mutationFn: async (reportId: string) => {
const result = await trustCenterGraphQLRequest<ExportReportPDFData>(
"PublicTrustCenterAuditsExportReportPDFMutation",
EXPORT_REPORT_PDF_MUTATION,
{ input: { reportId } }
);
if (result.errors && result.errors.length > 0) {
throw new Error(
`GraphQL error: ${result.errors.map((e) => e.message).join(", ")}`
);
}
if (!result.data) {
throw new Error("No data returned from mutation");
}
return result.data;
},
});
}
export function useCreateTrustCenterAccess() {
return useMutation<CreateTrustCenterAccessData, Error, { trustCenterId: string; email: string; name: string }>({
mutationFn: async (input: { trustCenterId: string; email: string; name: string }) => {

View File

@@ -9,11 +9,13 @@ import {
Button,
IconArrowDown,
IconLock,
useToast,
} from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import { sprintf } from "@probo/helpers";
import { FrameworkLogo } from "/components/FrameworkLogo";
import { PublicTrustCenterAccessRequestDialog } from "./PublicTrustCenterAccessRequestDialog";
import { useExportReportPDF } from "../../hooks/useTrustCenterQueries";
import type { TrustCenterAudit } from "../pages/PublicTrustCenterPage";
type Props = {
@@ -30,6 +32,31 @@ export function PublicTrustCenterAudits({
trustCenterId
}: Props) {
const { __ } = useTranslate();
const { toast } = useToast();
const mutation = useExportReportPDF();
const handleDownload = (report: NonNullable<TrustCenterAudit["report"]>) => {
mutation.mutate(report.id, {
onSuccess: (data) => {
if (data.exportReportPDF?.data) {
const link = window.document.createElement("a");
link.href = data.exportReportPDF.data;
link.download = `${report.filename}`;
window.document.body.appendChild(link);
link.click();
window.document.body.removeChild(link);
}
},
onError: () => {
toast({
title: __("Download Failed"),
description: __("Unable to download the report. Please try again."),
variant: "error",
});
},
});
};
if (audits.length === 0) {
return (
@@ -67,8 +94,6 @@ export function PublicTrustCenterAudits({
<Tbody>
{audits.map((audit) => {
const hasReport = audit.report !== null;
const downloadUrl = audit.report?.downloadUrl;
const reportName = audit.report?.filename || __("Compliance Report");
return (
<Tr key={audit.id}>
@@ -102,25 +127,15 @@ export function PublicTrustCenterAudits({
trustCenterId={trustCenterId}
organizationName={organizationName}
/>
) : downloadUrl ? (
) : (
<Button
variant="secondary"
icon={IconArrowDown}
onClick={() => {
const link = document.createElement('a');
link.href = downloadUrl;
link.download = reportName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}}
onClick={() => handleDownload(audit.report!)}
disabled={mutation.isPending}
>
{__("Download")}
{mutation.isPending ? __("Downloading...") : __("Download")}
</Button>
) : (
<span className="text-txt-tertiary text-sm">
{__("Not available")}
</span>
)}
</Td>
</Tr>