From 37484f64f90cb05fc05e6f9afcf44bd045fbb84a Mon Sep 17 00:00:00 2001 From: Reece Date: Tue, 15 Jul 2025 12:41:45 +0100 Subject: [PATCH] Viewer fixes with multi file support --- frontend/src/components/viewer/Viewer.tsx | 94 +++++++++++++++-------- 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/frontend/src/components/viewer/Viewer.tsx b/frontend/src/components/viewer/Viewer.tsx index 79e214320..065ce5824 100644 --- a/frontend/src/components/viewer/Viewer.tsx +++ b/frontend/src/components/viewer/Viewer.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState, useRef, useCallback } from "react"; -import { Paper, Stack, Text, ScrollArea, Loader, Center, Button, Group, NumberInput, useMantineTheme, ActionIcon, Box } from "@mantine/core"; +import { Paper, Stack, Text, ScrollArea, Loader, Center, Button, Group, NumberInput, useMantineTheme, ActionIcon, Box, Tabs } from "@mantine/core"; import { getDocument, GlobalWorkerOptions } from "pdfjs-dist"; import { useTranslation } from "react-i18next"; import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew"; @@ -150,12 +150,24 @@ const Viewer = ({ const theme = useMantineTheme(); // Get current file from FileContext - const { getCurrentFile, getCurrentProcessedFile, clearAllFiles, addFiles } = useFileContext(); + const { getCurrentFile, getCurrentProcessedFile, clearAllFiles, addFiles, activeFiles } = useFileContext(); const currentFile = getCurrentFile(); const processedFile = getCurrentProcessedFile(); // Convert File to FileWithUrl format for viewer const pdfFile = useFileWithUrl(currentFile); + + // Tab management for multiple files + const [activeTab, setActiveTab] = useState("0"); + + // Reset PDF state when switching tabs + const handleTabChange = (newTab: string) => { + setActiveTab(newTab); + setNumPages(0); + setPageImages([]); + setCurrentPage(null); + setLoading(true); + }; const [numPages, setNumPages] = useState(0); const [pageImages, setPageImages] = useState([]); const [loading, setLoading] = useState(false); @@ -165,7 +177,20 @@ const Viewer = ({ const pageRefs = useRef<(HTMLImageElement | null)[]>([]); - // Use preview file if available, otherwise use context file + // Get files with URLs for tabs - we'll need to create these individually + const file0WithUrl = useFileWithUrl(activeFiles[0]); + const file1WithUrl = useFileWithUrl(activeFiles[1]); + const file2WithUrl = useFileWithUrl(activeFiles[2]); + const file3WithUrl = useFileWithUrl(activeFiles[3]); + const file4WithUrl = useFileWithUrl(activeFiles[4]); + + const filesWithUrls = React.useMemo(() => { + return [file0WithUrl, file1WithUrl, file2WithUrl, file3WithUrl, file4WithUrl] + .slice(0, activeFiles.length) + .filter(Boolean); + }, [file0WithUrl, file1WithUrl, file2WithUrl, file3WithUrl, file4WithUrl, activeFiles.length]); + + // Use preview file if available, otherwise use active tab file const effectiveFile = React.useMemo(() => { if (previewFile) { // Validate the preview file @@ -179,9 +204,11 @@ const Viewer = ({ return { file: previewFile, url: null }; } else { - return pdfFile; + // Use the file from the active tab + const tabIndex = parseInt(activeTab); + return filesWithUrls[tabIndex] || null; } - }, [previewFile, pdfFile]); + }, [previewFile, filesWithUrls, activeTab]); const scrollAreaRef = useRef(null); const pdfDocRef = useRef(null); @@ -422,33 +449,38 @@ const Viewer = ({ {!effectiveFile ? (
- - {t("viewer.noPdfLoaded", "No PDF loaded. Click to upload a PDF.")} - - + Error: No file provided to viewer
- ) : loading ? ( -
- -
) : ( + <> + {/* Tabs for multiple files */} + {activeFiles.length > 1 && !previewFile && ( + + handleTabChange(value || "0")}> + + {activeFiles.map((file, index) => ( + + {file.name.length > 20 ? `${file.name.substring(0, 20)}...` : file.name} + + ))} + + + + )} + + {loading ? ( +
+ +
+ ) : ( + )} + )}