62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import React, { useEffect } from 'react';
|
|
import { Navigate, useNavigate, useParams } from 'react-router-dom';
|
|
|
|
import { useAppShell } from '../appShellContext';
|
|
import type { Identifier } from '../types/identifiers';
|
|
|
|
interface DocumentViewerRouteContext {
|
|
previewWorkspaceDocument?: { id?: Identifier } | null;
|
|
ensurePreviewData?: (documentId: Identifier, options?: Record<string, unknown>) => Promise<unknown>;
|
|
notifyApiError?: (error: unknown, message?: string) => void;
|
|
}
|
|
|
|
const DocumentViewerRoute: React.FC = () => {
|
|
const {
|
|
previewWorkspaceDocument,
|
|
ensurePreviewData,
|
|
notifyApiError,
|
|
} = useAppShell() as DocumentViewerRouteContext;
|
|
const { documentId } = useParams();
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
if (!documentId) {
|
|
navigate('/documents', { replace: true });
|
|
return;
|
|
}
|
|
|
|
let cancelled = false;
|
|
|
|
const hydrate = async () => {
|
|
try {
|
|
await ensurePreviewData?.(documentId);
|
|
} catch (error) {
|
|
if (cancelled) {
|
|
return;
|
|
}
|
|
notifyApiError?.(error, 'Failed to open document preview.');
|
|
navigate('/documents', { replace: true });
|
|
}
|
|
};
|
|
|
|
hydrate();
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [documentId, ensurePreviewData, notifyApiError, navigate]);
|
|
|
|
if (!documentId) {
|
|
return <Navigate to="/documents" replace />;
|
|
}
|
|
|
|
const previewId = previewWorkspaceDocument?.id;
|
|
if (!previewWorkspaceDocument || String(previewId) !== String(documentId)) {
|
|
return <div className="document-viewer__message">Loading preview…</div>;
|
|
}
|
|
|
|
return <Navigate to="/documents" replace />;
|
|
};
|
|
|
|
export default DocumentViewerRoute;
|