2025-05-21 21:47:44 +01:00
|
|
|
import React, { useState, useCallback, useEffect } from "react";
|
2025-05-29 17:26:32 +01:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2025-05-21 21:47:44 +01:00
|
|
|
import { useSearchParams } from "react-router-dom";
|
2025-06-05 21:59:18 +01:00
|
|
|
import { useToolParams } from "../hooks/useToolParams";
|
2025-05-21 21:47:44 +01:00
|
|
|
import AddToPhotosIcon from "@mui/icons-material/AddToPhotos";
|
|
|
|
import ContentCutIcon from "@mui/icons-material/ContentCut";
|
|
|
|
import ZoomInMapIcon from "@mui/icons-material/ZoomInMap";
|
2025-06-05 21:59:18 +01:00
|
|
|
import { Group, Paper, Box, Button, useMantineTheme, useMantineColorScheme } from "@mantine/core";
|
2025-05-21 21:47:44 +01:00
|
|
|
|
|
|
|
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";
|
2025-06-05 21:59:18 +01:00
|
|
|
import TopControls from "../components/TopControls";
|
|
|
|
import ToolRenderer from "../components/ToolRenderer";
|
|
|
|
import styles from "../styles/HomePage.module.css";
|
2025-05-21 21:47:44 +01:00
|
|
|
|
|
|
|
type ToolRegistryEntry = {
|
|
|
|
icon: React.ReactNode;
|
|
|
|
name: string;
|
|
|
|
component: React.ComponentType<any>;
|
|
|
|
view: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
type ToolRegistry = {
|
|
|
|
[key: string]: ToolRegistryEntry;
|
|
|
|
};
|
|
|
|
|
2025-05-29 17:26:32 +01:00
|
|
|
// Base tool registry without translations
|
|
|
|
const baseToolRegistry = {
|
|
|
|
split: { icon: <ContentCutIcon />, component: SplitPdfPanel, view: "viewer" },
|
|
|
|
compress: { icon: <ZoomInMapIcon />, component: CompressPdfPanel, view: "viewer" },
|
|
|
|
merge: { icon: <AddToPhotosIcon />, component: MergePdfPanel, view: "fileManager" },
|
2025-05-21 21:47:44 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2025-05-27 19:22:26 +01:00
|
|
|
|
2025-05-21 21:47:44 +01:00
|
|
|
export default function HomePage() {
|
2025-05-29 17:26:32 +01:00
|
|
|
const { t } = useTranslation();
|
2025-06-05 21:59:18 +01:00
|
|
|
const [searchParams] = useSearchParams();
|
2025-05-27 19:22:26 +01:00
|
|
|
const theme = useMantineTheme();
|
2025-05-28 22:18:19 +01:00
|
|
|
const { colorScheme, toggleColorScheme } = useMantineColorScheme();
|
2025-05-21 21:47:44 +01:00
|
|
|
|
|
|
|
// Core app state
|
2025-06-05 21:59:18 +01:00
|
|
|
const [selectedToolKey, setSelectedToolKey] = useState<string>(searchParams.get("t") || "split");
|
|
|
|
const [currentView, setCurrentView] = useState<string>(searchParams.get("v") || "viewer");
|
2025-05-21 21:47:44 +01:00
|
|
|
const [pdfFile, setPdfFile] = useState<any>(null);
|
|
|
|
const [files, setFiles] = useState<any[]>([]);
|
|
|
|
const [downloadUrl, setDownloadUrl] = useState<string | null>(null);
|
2025-05-27 19:22:26 +01:00
|
|
|
const [sidebarsVisible, setSidebarsVisible] = useState(true);
|
|
|
|
|
2025-06-05 21:59:18 +01:00
|
|
|
// URL parameter management
|
|
|
|
const { toolParams, updateParams } = useToolParams(selectedToolKey, currentView);
|
2025-05-21 21:47:44 +01:00
|
|
|
|
2025-06-05 21:59:18 +01:00
|
|
|
// Create translated tool registry
|
|
|
|
const toolRegistry: ToolRegistry = {
|
|
|
|
split: { ...baseToolRegistry.split, name: t("home.split.title", "Split PDF") },
|
|
|
|
compress: { ...baseToolRegistry.compress, name: t("home.compressPdfs.title", "Compress PDF") },
|
|
|
|
merge: { ...baseToolRegistry.merge, name: t("home.merge.title", "Merge PDFs") },
|
|
|
|
};
|
2025-05-27 19:22:26 +01:00
|
|
|
|
2025-05-21 21:47:44 +01:00
|
|
|
|
|
|
|
// Handle tool selection
|
|
|
|
const handleToolSelect = useCallback(
|
|
|
|
(id: string) => {
|
|
|
|
setSelectedToolKey(id);
|
|
|
|
if (toolRegistry[id]?.view) setCurrentView(toolRegistry[id].view);
|
|
|
|
},
|
|
|
|
[toolRegistry]
|
|
|
|
);
|
|
|
|
|
|
|
|
const selectedTool = toolRegistry[selectedToolKey];
|
|
|
|
|
|
|
|
return (
|
2025-05-28 21:43:02 +01:00
|
|
|
<Group
|
|
|
|
align="flex-start"
|
|
|
|
gap={0}
|
2025-06-05 21:59:18 +01:00
|
|
|
className={styles.container}
|
2025-05-28 21:43:02 +01:00
|
|
|
>
|
2025-05-21 21:47:44 +01:00
|
|
|
{/* Left: Tool Picker */}
|
2025-05-27 19:22:26 +01:00
|
|
|
{sidebarsVisible && (
|
2025-05-28 21:43:02 +01:00
|
|
|
<Box
|
2025-06-05 21:59:18 +01:00
|
|
|
className={`${styles.leftSidebar} ${
|
|
|
|
colorScheme === "dark" ? styles.leftSidebarDark : styles.leftSidebarLight
|
|
|
|
}`}
|
2025-05-28 21:43:02 +01:00
|
|
|
>
|
|
|
|
<ToolPicker
|
|
|
|
selectedToolKey={selectedToolKey}
|
|
|
|
onSelect={handleToolSelect}
|
|
|
|
toolRegistry={toolRegistry}
|
|
|
|
/>
|
|
|
|
</Box>
|
2025-05-27 19:22:26 +01:00
|
|
|
)}
|
2025-05-21 21:47:44 +01:00
|
|
|
|
2025-05-28 21:43:02 +01:00
|
|
|
{/* Middle: Main View */}
|
2025-05-21 21:47:44 +01:00
|
|
|
<Box
|
2025-06-05 21:59:18 +01:00
|
|
|
className={`${styles.mainContent} ${
|
|
|
|
colorScheme === "dark" ? styles.mainContentDark : styles.mainContentLight
|
|
|
|
}`}
|
2025-05-21 21:47:44 +01:00
|
|
|
>
|
2025-06-05 21:59:18 +01:00
|
|
|
{/* Top Controls */}
|
|
|
|
<TopControls
|
|
|
|
currentView={currentView}
|
|
|
|
setCurrentView={setCurrentView}
|
|
|
|
/>
|
2025-05-28 21:43:02 +01:00
|
|
|
{/* Main content area */}
|
2025-05-27 19:22:26 +01:00
|
|
|
<Paper
|
|
|
|
radius="0 0 xl xl"
|
|
|
|
shadow="sm"
|
|
|
|
p={0}
|
2025-06-05 21:59:18 +01:00
|
|
|
className={styles.mainPaper}
|
2025-05-27 19:22:26 +01:00
|
|
|
>
|
2025-06-05 21:59:18 +01:00
|
|
|
<Box className={styles.mainPaperInner}>
|
2025-05-27 19:22:26 +01:00
|
|
|
{(currentView === "viewer" || currentView === "pageEditor") && !pdfFile ? (
|
|
|
|
<FileManager
|
|
|
|
files={files}
|
|
|
|
setFiles={setFiles}
|
|
|
|
setPdfFile={setPdfFile}
|
|
|
|
setCurrentView={setCurrentView}
|
|
|
|
/>
|
|
|
|
) : currentView === "viewer" ? (
|
|
|
|
<Viewer
|
|
|
|
pdfFile={pdfFile}
|
|
|
|
setPdfFile={setPdfFile}
|
|
|
|
sidebarsVisible={sidebarsVisible}
|
|
|
|
setSidebarsVisible={setSidebarsVisible}
|
|
|
|
/>
|
|
|
|
) : currentView === "pageEditor" ? (
|
|
|
|
<PageEditor
|
|
|
|
file={pdfFile}
|
|
|
|
setFile={setPdfFile}
|
|
|
|
downloadUrl={downloadUrl}
|
|
|
|
setDownloadUrl={setDownloadUrl}
|
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
<FileManager
|
|
|
|
files={files}
|
|
|
|
setFiles={setFiles}
|
|
|
|
setPdfFile={setPdfFile}
|
|
|
|
setCurrentView={setCurrentView}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Box>
|
|
|
|
</Paper>
|
2025-05-21 21:47:44 +01:00
|
|
|
</Box>
|
2025-05-28 21:43:02 +01:00
|
|
|
|
2025-05-21 21:47:44 +01:00
|
|
|
{/* Right: Tool Interaction */}
|
2025-05-27 19:22:26 +01:00
|
|
|
{sidebarsVisible && (
|
|
|
|
<Box
|
2025-06-05 21:59:18 +01:00
|
|
|
className={`${styles.rightSidebar} ${
|
|
|
|
colorScheme === "dark" ? styles.rightSidebarDark : styles.rightSidebarLight
|
|
|
|
}`}
|
2025-05-27 19:22:26 +01:00
|
|
|
>
|
2025-06-05 21:59:18 +01:00
|
|
|
<ToolRenderer
|
|
|
|
selectedToolKey={selectedToolKey}
|
|
|
|
selectedTool={selectedTool}
|
|
|
|
pdfFile={pdfFile}
|
|
|
|
files={files}
|
|
|
|
downloadUrl={downloadUrl}
|
|
|
|
setDownloadUrl={setDownloadUrl}
|
|
|
|
toolParams={toolParams}
|
|
|
|
updateParams={updateParams}
|
|
|
|
/>
|
2025-05-27 19:22:26 +01:00
|
|
|
</Box>
|
|
|
|
)}
|
2025-05-28 21:43:02 +01:00
|
|
|
|
|
|
|
{/* Sidebar toggle button */}
|
2025-05-27 19:22:26 +01:00
|
|
|
<Button
|
|
|
|
variant="light"
|
|
|
|
color="blue"
|
|
|
|
size="xs"
|
2025-06-05 21:59:18 +01:00
|
|
|
className={styles.sidebarToggle}
|
2025-05-28 21:43:02 +01:00
|
|
|
onClick={() => setSidebarsVisible((v) => !v)}
|
2025-05-21 21:47:44 +01:00
|
|
|
>
|
2025-05-29 17:26:32 +01:00
|
|
|
{t("sidebar.toggle", sidebarsVisible ? "Hide Sidebars" : "Show Sidebars")}
|
2025-05-27 19:22:26 +01:00
|
|
|
</Button>
|
2025-05-21 21:47:44 +01:00
|
|
|
</Group>
|
|
|
|
);
|
|
|
|
}
|