feat: implement FilePreviewModal to support image, video, and audio previews alongside PDFs

This commit is contained in:
estifanos
2026-08-28 10:45:06 +00:00
parent 3368c9bd3f
commit 32f5fb4590
7 changed files with 215 additions and 27 deletions

View File

@@ -60,7 +60,7 @@ function errorBody(err: unknown): PersonalDocumentError {
export function PersonalDocumentSlots({
onPreview,
}: {
onPreview: (preview: { url: string; title: string }) => void;
onPreview: (preview: { url: string; title: string; mimeType?: string | null }) => void;
}) {
const { t } = useTranslation();
const localized = useLocalized();
@@ -260,7 +260,12 @@ export function PersonalDocumentSlots({
c={file.url ? 'blue' : undefined}
truncate
onClick={() =>
file.url && onPreview({ url: file.url, title: file.originalName })
file.url &&
onPreview({
url: file.url,
title: file.originalName,
mimeType: file.mimeType,
})
}
>
{file.originalName}

View File

@@ -25,7 +25,7 @@ import {
} from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import { useDateDisplayer } from '@ema-platform/shared';
import { notify, PdfPreviewModal } from '@ema-platform/ui';
import { FilePreviewModal, notify } from '@ema-platform/ui';
import {
extractErrorMessage,
useGetAttachmentsQuery,
@@ -41,7 +41,8 @@ import {
import { LicenseCard, useRenewLicense } from '../../licensing/components/LicenseCard';
import { PersonalDocumentSlots } from '../components/PersonalDocumentSlots';
type Preview = { url: string; title: string };
/** What the viewer needs: the link, a caption, and how to render it. */
type Preview = { url: string; title: string; mimeType?: string | null };
const RECORD_STATUS_COLOR: Record<SeafarerRecordStatus, string> = {
SUBMITTED: 'blue',
@@ -85,7 +86,13 @@ function RecordFiles({
component="button"
type="button"
fz="xs"
onClick={() => onPreview({ url: file.url as string, title: file.originalName })}
onClick={() =>
onPreview({
url: file.url as string,
title: file.originalName,
mimeType: file.mimeType,
})
}
>
{file.originalName}
</Anchor>
@@ -434,11 +441,17 @@ export function DocumentVaultPage() {
</Tabs>
</Stack>
<PdfPreviewModal
<FilePreviewModal
opened={Boolean(preview)}
onClose={() => setPreview(null)}
url={preview?.url ?? ''}
title={preview?.title}
mimeType={preview?.mimeType}
labels={{
unsupported: t('documents.preview.unsupported'),
openInNewTab: t('documents.preview.openInNewTab'),
close: t('documents.preview.close'),
}}
/>
</Container>
);

View File

@@ -1320,6 +1320,11 @@ export const am: Translations = {
files: {
none: 'ምንም የተያያዘ ፋይል የለም።',
},
preview: {
unsupported: 'ይህ የፋይል አይነት እዚህ ሊታይ አይችልም። ለማውረድ በአዲስ ትር ይክፈቱት።',
openInNewTab: 'በአዲስ ትር ክፈት',
close: 'ዝጋ',
},
empty: {
licenses: 'እስካሁን የተሰጠዎት የምስክር ወረቀት ወይም ፈቃድ የለም።',
medical: 'እስካሁን በመዝገብ ላይ የሕክምና የምስክር ወረቀት የለም።',

View File

@@ -1323,6 +1323,12 @@ export const en = {
files: {
none: 'No files attached.',
},
preview: {
unsupported:
'This file type cannot be shown here. Open it in a new tab to download it.',
openInNewTab: 'Open in a new tab',
close: 'Close',
},
empty: {
licenses: 'No certificates or licences have been issued to you yet.',
medical: 'No medical certificates on file yet.',