feat: integrate PdfPreviewModal across apps

This commit is contained in:
estifanos
2026-08-19 08:59:08 +00:00
parent 4d87d41e55
commit b860e57227
7 changed files with 118 additions and 38 deletions

View File

@@ -1,4 +1,4 @@
import { useCallback } from 'react';
import { useCallback, useState } from 'react';
import { notifications } from '@mantine/notifications';
import { useTranslation } from 'react-i18next';
import { extractErrorMessage } from '@ema-platform/api';
@@ -13,12 +13,14 @@ interface PreviewArgs {
/**
* Renders the editor's current contents, not the saved row, so unsaved edits
* are what you see. Opened as a blob so it never leaves a file behind.
* are what you see. Opened as a blob into `PdfPreviewModal` rather than a new
* tab, so the designer never loses their place.
*/
export function useTemplatePreview() {
const { t } = useTranslation();
const [previewUrl, setPreviewUrl] = useState<string | null>(null);
return useCallback(
const open = useCallback(
async ({ hbsSource, licenseTypeId, landscape }: PreviewArgs) => {
try {
// The preview returns a PDF stream, not JSON, so it bypasses RTK Query
@@ -38,10 +40,7 @@ export function useTemplatePreview() {
}),
});
if (!response.ok) throw new Error(await response.text());
const url = URL.createObjectURL(await response.blob());
window.open(url, '_blank', 'noopener');
// Give the new tab time to read it before revoking.
setTimeout(() => URL.revokeObjectURL(url), 60_000);
setPreviewUrl(URL.createObjectURL(await response.blob()));
} catch (err) {
notifications.show({
color: 'red',
@@ -52,4 +51,13 @@ export function useTemplatePreview() {
},
[t],
);
const close = useCallback(() => {
setPreviewUrl((current) => {
if (current) URL.revokeObjectURL(current);
return null;
});
}, []);
return { previewUrl, open, close };
}