import React, { useState, useCallback, useEffect } from "react"; import { useSearchParams } from "react-router-dom"; import AddToPhotosIcon from "@mui/icons-material/AddToPhotos"; import ContentCutIcon from "@mui/icons-material/ContentCut"; import ZoomInMapIcon from "@mui/icons-material/ZoomInMap"; import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; import VisibilityIcon from "@mui/icons-material/Visibility"; import EditNoteIcon from "@mui/icons-material/EditNote"; import { Group, SegmentedControl, Paper, Center, Box } from "@mantine/core"; import ToolPicker from "../components/ToolPicker"; import FileManager from "../components/FileManager"; import SplitPdfPanel from "../tools/Split"; import CompressPdfPanel from "../tools/Compress"; import MergePdfPanel from "../tools/Merge"; import PageEditor from "../components/PageEditor"; import Viewer from "../components/Viewer"; type ToolRegistryEntry = { icon: React.ReactNode; name: string; component: React.ComponentType; view: string; }; type ToolRegistry = { [key: string]: ToolRegistryEntry; }; const toolRegistry: ToolRegistry = { split: { icon: , name: "Split PDF", component: SplitPdfPanel, view: "viewer" }, compress: { icon: , name: "Compress PDF", component: CompressPdfPanel, view: "viewer" }, merge: { icon: , name: "Merge PDFs", component: MergePdfPanel, view: "fileManager" }, }; const VIEW_OPTIONS = [ { label: ( ), value: "viewer", }, { label: ( ), value: "pageEditor", }, { label: ( ), value: "fileManager", }, ]; export default function HomePage() { const [searchParams, setSearchParams] = useSearchParams(); // Core app state const [selectedToolKey, setSelectedToolKey] = useState(searchParams.get("tool") || "split"); const [currentView, setCurrentView] = useState(searchParams.get("view") || "viewer"); const [pdfFile, setPdfFile] = useState(null); const [files, setFiles] = useState([]); const [downloadUrl, setDownloadUrl] = useState(null); // Tool-specific parameters const [splitParams, setSplitParams] = useState({ mode: searchParams.get("splitMode") || "byPages", pages: searchParams.get("pages") || "", hDiv: searchParams.get("hDiv") || "0", vDiv: searchParams.get("vDiv") || "1", merge: searchParams.get("merge") === "true", splitType: searchParams.get("splitType") || "size", splitValue: searchParams.get("splitValue") || "", bookmarkLevel: searchParams.get("bookmarkLevel") || "0", includeMetadata: searchParams.get("includeMetadata") === "true", allowDuplicates: searchParams.get("allowDuplicates") === "true", }); // Update URL when core state changes useEffect(() => { const params = new URLSearchParams(searchParams); params.set("tool", selectedToolKey); params.set("view", currentView); setSearchParams(params, { replace: true }); }, [selectedToolKey, currentView, setSearchParams]); // Handle tool selection const handleToolSelect = useCallback( (id: string) => { setSelectedToolKey(id); if (toolRegistry[id]?.view) setCurrentView(toolRegistry[id].view); }, [toolRegistry] ); // Handle split parameter updates const updateSplitParams = useCallback((newParams: Partial) => { setSplitParams(prev => { const updated = { ...prev, ...newParams }; // Update URL with split params const params = new URLSearchParams(searchParams); // Clear old parameters when mode changes if (newParams.mode && newParams.mode !== prev.mode) { params.delete("pages"); params.delete("hDiv"); params.delete("vDiv"); params.delete("merge"); params.delete("splitType"); params.delete("splitValue"); params.delete("bookmarkLevel"); params.delete("includeMetadata"); params.delete("allowDuplicates"); } // Set the mode params.set("splitMode", updated.mode); // Set mode-specific parameters if (updated.mode === "byPages" && updated.pages) { params.set("pages", updated.pages); } else if (updated.mode === "bySections") { params.set("hDiv", updated.hDiv); params.set("vDiv", updated.vDiv); params.set("merge", String(updated.merge)); } else if (updated.mode === "bySizeOrCount") { params.set("splitType", updated.splitType); if (updated.splitValue) params.set("splitValue", updated.splitValue); } else if (updated.mode === "byChapters") { params.set("bookmarkLevel", updated.bookmarkLevel); params.set("includeMetadata", String(updated.includeMetadata)); params.set("allowDuplicates", String(updated.allowDuplicates)); } setSearchParams(params, { replace: true }); return updated; }); }, [searchParams, setSearchParams]); const selectedTool = toolRegistry[selectedToolKey]; // Tool component rendering const renderTool = () => { if (!selectedTool || !selectedTool.component) { return
Tool not found
; } // Pass appropriate props based on tool type if (selectedToolKey === "split") { return React.createElement(selectedTool.component, { file: pdfFile, setPdfFile, downloadUrl, setDownloadUrl, // Tool-specific params and update function params: splitParams, updateParams: updateSplitParams }); } // For other tools, pass standard props return React.createElement(selectedTool.component, { file: pdfFile, setPdfFile, files, setFiles, downloadUrl, setDownloadUrl, }); }; return ( {/* Left: Tool Picker */} {/* Middle: Main View (Viewer, Editor, Manager) */}
{(currentView === "viewer" || currentView === "pageEditor") && !pdfFile ? ( ) : currentView === "viewer" ? ( ) : currentView === "pageEditor" ? ( ) : ( )}
{/* Right: Tool Interaction */} {selectedTool && selectedTool.component && ( <> {renderTool()} )}
); }