mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-02 18:45:21 +00:00
Added structure for filemanager
This commit is contained in:
parent
8881f19b03
commit
777708b0a2
@ -1,6 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { RainbowThemeProvider } from './components/shared/RainbowThemeProvider';
|
import { RainbowThemeProvider } from './components/shared/RainbowThemeProvider';
|
||||||
import { FileContextProvider } from './contexts/FileContext';
|
import { FileContextProvider } from './contexts/FileContext';
|
||||||
|
import { FilesModalProvider } from './contexts/FilesModalContext';
|
||||||
|
import FileUploadModal from './components/shared/FileUploadModal';
|
||||||
import HomePage from './pages/HomePage';
|
import HomePage from './pages/HomePage';
|
||||||
|
|
||||||
// Import global styles
|
// Import global styles
|
||||||
@ -11,7 +13,10 @@ export default function App() {
|
|||||||
return (
|
return (
|
||||||
<RainbowThemeProvider>
|
<RainbowThemeProvider>
|
||||||
<FileContextProvider enableUrlSync={true} enablePersistence={true}>
|
<FileContextProvider enableUrlSync={true} enablePersistence={true}>
|
||||||
<HomePage />
|
<FilesModalProvider>
|
||||||
|
<HomePage />
|
||||||
|
<FileUploadModal />
|
||||||
|
</FilesModalProvider>
|
||||||
</FileContextProvider>
|
</FileContextProvider>
|
||||||
</RainbowThemeProvider>
|
</RainbowThemeProvider>
|
||||||
);
|
);
|
||||||
|
29
frontend/src/components/shared/FileUploadModal.tsx
Normal file
29
frontend/src/components/shared/FileUploadModal.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Modal } from '@mantine/core';
|
||||||
|
import FileUploadSelector from './FileUploadSelector';
|
||||||
|
import { useFilesModalContext } from '../../contexts/FilesModalContext';
|
||||||
|
|
||||||
|
const FileUploadModal: React.FC = () => {
|
||||||
|
const { isFilesModalOpen, closeFilesModal, onFileSelect, onFilesSelect } = useFilesModalContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
opened={isFilesModalOpen}
|
||||||
|
onClose={closeFilesModal}
|
||||||
|
title="Upload Files"
|
||||||
|
size="xl"
|
||||||
|
centered
|
||||||
|
>
|
||||||
|
<FileUploadSelector
|
||||||
|
title="Upload Files"
|
||||||
|
subtitle="Choose files from storage or upload new files"
|
||||||
|
onFileSelect={onFileSelect}
|
||||||
|
onFilesSelect={onFilesSelect}
|
||||||
|
accept={["application/pdf"]}
|
||||||
|
supportedExtensions={["pdf"]}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FileUploadModal;
|
30
frontend/src/components/shared/LandingPage.tsx
Normal file
30
frontend/src/components/shared/LandingPage.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Container, Stack, Text, Button } from '@mantine/core';
|
||||||
|
import FolderIcon from '@mui/icons-material/FolderRounded';
|
||||||
|
import { useFilesModalContext } from '../../contexts/FilesModalContext';
|
||||||
|
|
||||||
|
interface LandingPageProps {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LandingPage = ({ title }: LandingPageProps) => {
|
||||||
|
const { openFilesModal } = useFilesModalContext();
|
||||||
|
return (
|
||||||
|
<Container size="lg" p="xl" h="100%" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||||
|
<Stack align="center" gap="lg">
|
||||||
|
<Text size="xl" fw={500} c="dimmed">
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
<Button
|
||||||
|
leftSection={<FolderIcon />}
|
||||||
|
size="lg"
|
||||||
|
onClick={openFilesModal}
|
||||||
|
>
|
||||||
|
Open Files
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LandingPage;
|
@ -11,6 +11,7 @@ import { useRainbowThemeContext } from "./RainbowThemeProvider";
|
|||||||
import rainbowStyles from '../../styles/rainbow.module.css';
|
import rainbowStyles from '../../styles/rainbow.module.css';
|
||||||
import AppConfigModal from './AppConfigModal';
|
import AppConfigModal from './AppConfigModal';
|
||||||
import { useIsOverflowing } from '../../hooks/useIsOverflowing';
|
import { useIsOverflowing } from '../../hooks/useIsOverflowing';
|
||||||
|
import { useFilesModalContext } from '../../contexts/FilesModalContext';
|
||||||
import './QuickAccessBar.css';
|
import './QuickAccessBar.css';
|
||||||
|
|
||||||
interface QuickAccessBarProps {
|
interface QuickAccessBarProps {
|
||||||
@ -30,6 +31,7 @@ interface ButtonConfig {
|
|||||||
isRound?: boolean;
|
isRound?: boolean;
|
||||||
size?: 'sm' | 'md' | 'lg' | 'xl';
|
size?: 'sm' | 'md' | 'lg' | 'xl';
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
|
type?: 'navigation' | 'modal' | 'action'; // navigation = main nav, modal = triggers modal, action = other actions
|
||||||
}
|
}
|
||||||
|
|
||||||
function NavHeader({
|
function NavHeader({
|
||||||
@ -111,11 +113,16 @@ const QuickAccessBar = ({
|
|||||||
readerMode,
|
readerMode,
|
||||||
}: QuickAccessBarProps) => {
|
}: QuickAccessBarProps) => {
|
||||||
const { isRainbowMode } = useRainbowThemeContext();
|
const { isRainbowMode } = useRainbowThemeContext();
|
||||||
|
const { openFilesModal, isFilesModalOpen } = useFilesModalContext();
|
||||||
const [configModalOpen, setConfigModalOpen] = useState(false);
|
const [configModalOpen, setConfigModalOpen] = useState(false);
|
||||||
const [activeButton, setActiveButton] = useState<string>('tools');
|
const [activeButton, setActiveButton] = useState<string>('tools');
|
||||||
const scrollableRef = useRef<HTMLDivElement>(null);
|
const scrollableRef = useRef<HTMLDivElement>(null);
|
||||||
const isOverflow = useIsOverflowing(scrollableRef);
|
const isOverflow = useIsOverflowing(scrollableRef);
|
||||||
|
|
||||||
|
const handleFilesButtonClick = () => {
|
||||||
|
openFilesModal();
|
||||||
|
};
|
||||||
|
|
||||||
const buttonConfigs: ButtonConfig[] = [
|
const buttonConfigs: ButtonConfig[] = [
|
||||||
{
|
{
|
||||||
id: 'read',
|
id: 'read',
|
||||||
@ -124,6 +131,7 @@ const QuickAccessBar = ({
|
|||||||
tooltip: 'Read documents',
|
tooltip: 'Read documents',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
isRound: false,
|
isRound: false,
|
||||||
|
type: 'navigation',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setActiveButton('read');
|
setActiveButton('read');
|
||||||
onReaderToggle();
|
onReaderToggle();
|
||||||
@ -139,6 +147,7 @@ const QuickAccessBar = ({
|
|||||||
tooltip: 'Sign your document',
|
tooltip: 'Sign your document',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
isRound: false,
|
isRound: false,
|
||||||
|
type: 'navigation',
|
||||||
onClick: () => setActiveButton('sign')
|
onClick: () => setActiveButton('sign')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -148,6 +157,7 @@ const QuickAccessBar = ({
|
|||||||
tooltip: 'Automate workflows',
|
tooltip: 'Automate workflows',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
isRound: false,
|
isRound: false,
|
||||||
|
type: 'navigation',
|
||||||
onClick: () => setActiveButton('automate')
|
onClick: () => setActiveButton('automate')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -157,7 +167,8 @@ const QuickAccessBar = ({
|
|||||||
tooltip: 'Manage files',
|
tooltip: 'Manage files',
|
||||||
isRound: true,
|
isRound: true,
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
onClick: () => setActiveButton('files')
|
type: 'modal',
|
||||||
|
onClick: handleFilesButtonClick
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'activity',
|
id: 'activity',
|
||||||
@ -169,6 +180,7 @@ const QuickAccessBar = ({
|
|||||||
tooltip: 'View activity and analytics',
|
tooltip: 'View activity and analytics',
|
||||||
isRound: true,
|
isRound: true,
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
type: 'navigation',
|
||||||
onClick: () => setActiveButton('activity')
|
onClick: () => setActiveButton('activity')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -177,6 +189,7 @@ const QuickAccessBar = ({
|
|||||||
icon: <SettingsIcon sx={{ fontSize: "1rem" }} />,
|
icon: <SettingsIcon sx={{ fontSize: "1rem" }} />,
|
||||||
tooltip: 'Configure settings',
|
tooltip: 'Configure settings',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
type: 'modal',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setConfigModalOpen(true);
|
setConfigModalOpen(true);
|
||||||
}
|
}
|
||||||
@ -190,8 +203,16 @@ const QuickAccessBar = ({
|
|||||||
return config.isRound ? CIRCULAR_BORDER_RADIUS : ROUND_BORDER_RADIUS;
|
return config.isRound ? CIRCULAR_BORDER_RADIUS : ROUND_BORDER_RADIUS;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isButtonActive = (config: ButtonConfig): boolean => {
|
||||||
|
return (
|
||||||
|
(config.type === 'navigation' && activeButton === config.id) ||
|
||||||
|
(config.type === 'modal' && config.id === 'files' && isFilesModalOpen) ||
|
||||||
|
(config.type === 'modal' && config.id === 'config' && configModalOpen)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getButtonStyle = (config: ButtonConfig) => {
|
const getButtonStyle = (config: ButtonConfig) => {
|
||||||
const isActive = activeButton === config.id;
|
const isActive = isButtonActive(config);
|
||||||
|
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
return {
|
return {
|
||||||
@ -202,7 +223,7 @@ const QuickAccessBar = ({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inactive state - use consistent inactive colors
|
// Inactive state for all buttons
|
||||||
return {
|
return {
|
||||||
backgroundColor: 'var(--icon-inactive-bg)',
|
backgroundColor: 'var(--icon-inactive-bg)',
|
||||||
color: 'var(--icon-inactive-color)',
|
color: 'var(--icon-inactive-color)',
|
||||||
@ -254,13 +275,13 @@ const QuickAccessBar = ({
|
|||||||
variant="subtle"
|
variant="subtle"
|
||||||
onClick={config.onClick}
|
onClick={config.onClick}
|
||||||
style={getButtonStyle(config)}
|
style={getButtonStyle(config)}
|
||||||
className={activeButton === config.id ? 'activeIconScale' : ''}
|
className={isButtonActive(config) ? 'activeIconScale' : ''}
|
||||||
>
|
>
|
||||||
<span className="iconContainer">
|
<span className="iconContainer">
|
||||||
{config.icon}
|
{config.icon}
|
||||||
</span>
|
</span>
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
<span className={`button-text ${activeButton === config.id ? 'active' : 'inactive'}`}>
|
<span className={`button-text ${isButtonActive(config) ? 'active' : 'inactive'}`}>
|
||||||
{config.name}
|
{config.name}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -281,30 +302,28 @@ const QuickAccessBar = ({
|
|||||||
<div className="spacer" />
|
<div className="spacer" />
|
||||||
|
|
||||||
{/* Config button at the bottom */}
|
{/* Config button at the bottom */}
|
||||||
<Tooltip label="Configure settings" position="right">
|
{buttonConfigs
|
||||||
<div className="flex flex-col items-center gap-1">
|
.filter(config => config.id === 'config')
|
||||||
<ActionIcon
|
.map(config => (
|
||||||
size="lg"
|
<Tooltip key={config.id} label={config.tooltip} position="right">
|
||||||
variant="subtle"
|
<div className="flex flex-col items-center gap-1">
|
||||||
onClick={() => {
|
<ActionIcon
|
||||||
setConfigModalOpen(true);
|
size={config.size || 'lg'}
|
||||||
}}
|
variant="subtle"
|
||||||
style={{
|
onClick={config.onClick}
|
||||||
backgroundColor: 'var(--icon-inactive-bg)',
|
style={getButtonStyle(config)}
|
||||||
color: 'var(--icon-inactive-color)',
|
className={isButtonActive(config) ? 'activeIconScale' : ''}
|
||||||
border: 'none',
|
>
|
||||||
borderRadius: '8px',
|
<span className="iconContainer">
|
||||||
}}
|
{config.icon}
|
||||||
>
|
</span>
|
||||||
<span className="iconContainer">
|
</ActionIcon>
|
||||||
<SettingsIcon sx={{ fontSize: "1rem" }} />
|
<span className={`button-text ${isButtonActive(config) ? 'active' : 'inactive'}`}>
|
||||||
</span>
|
{config.name}
|
||||||
</ActionIcon>
|
</span>
|
||||||
<span className="config-button-text">
|
</div>
|
||||||
Config
|
</Tooltip>
|
||||||
</span>
|
))}
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
30
frontend/src/contexts/FilesModalContext.tsx
Normal file
30
frontend/src/contexts/FilesModalContext.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import React, { createContext, useContext } from 'react';
|
||||||
|
import { useFilesModal, UseFilesModalReturn } from '../hooks/useFilesModal';
|
||||||
|
import { useFileHandler } from '../hooks/useFileHandler';
|
||||||
|
|
||||||
|
interface FilesModalContextType extends UseFilesModalReturn {}
|
||||||
|
|
||||||
|
const FilesModalContext = createContext<FilesModalContextType | null>(null);
|
||||||
|
|
||||||
|
export const FilesModalProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||||
|
const { addToActiveFiles, addMultipleFiles } = useFileHandler();
|
||||||
|
|
||||||
|
const filesModal = useFilesModal({
|
||||||
|
onFileSelect: addToActiveFiles,
|
||||||
|
onFilesSelect: addMultipleFiles,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FilesModalContext.Provider value={filesModal}>
|
||||||
|
{children}
|
||||||
|
</FilesModalContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useFilesModalContext = () => {
|
||||||
|
const context = useContext(FilesModalContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error('useFilesModalContext must be used within FilesModalProvider');
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
27
frontend/src/hooks/useFileHandler.ts
Normal file
27
frontend/src/hooks/useFileHandler.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { useCallback } from 'react';
|
||||||
|
import { useFileContext } from '../contexts/FileContext';
|
||||||
|
|
||||||
|
export const useFileHandler = () => {
|
||||||
|
const { activeFiles, addFiles } = useFileContext();
|
||||||
|
|
||||||
|
const addToActiveFiles = useCallback(async (file: File) => {
|
||||||
|
const exists = activeFiles.some(f => f.name === file.name && f.size === file.size);
|
||||||
|
if (!exists) {
|
||||||
|
await addFiles([file]);
|
||||||
|
}
|
||||||
|
}, [activeFiles, addFiles]);
|
||||||
|
|
||||||
|
const addMultipleFiles = useCallback(async (files: File[]) => {
|
||||||
|
const newFiles = files.filter(file =>
|
||||||
|
!activeFiles.some(f => f.name === file.name && f.size === file.size)
|
||||||
|
);
|
||||||
|
if (newFiles.length > 0) {
|
||||||
|
await addFiles(newFiles);
|
||||||
|
}
|
||||||
|
}, [activeFiles, addFiles]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
addToActiveFiles,
|
||||||
|
addMultipleFiles,
|
||||||
|
};
|
||||||
|
};
|
57
frontend/src/hooks/useFilesModal.ts
Normal file
57
frontend/src/hooks/useFilesModal.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { useState, useCallback } from 'react';
|
||||||
|
|
||||||
|
export interface UseFilesModalReturn {
|
||||||
|
isFilesModalOpen: boolean;
|
||||||
|
openFilesModal: () => void;
|
||||||
|
closeFilesModal: () => void;
|
||||||
|
onFileSelect?: (file: File) => void;
|
||||||
|
onFilesSelect?: (files: File[]) => void;
|
||||||
|
onModalClose?: () => void;
|
||||||
|
setOnModalClose: (callback: () => void) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UseFilesModalProps {
|
||||||
|
onFileSelect?: (file: File) => void;
|
||||||
|
onFilesSelect?: (files: File[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useFilesModal = ({
|
||||||
|
onFileSelect,
|
||||||
|
onFilesSelect
|
||||||
|
}: UseFilesModalProps = {}): UseFilesModalReturn => {
|
||||||
|
const [isFilesModalOpen, setIsFilesModalOpen] = useState(false);
|
||||||
|
const [onModalClose, setOnModalClose] = useState<(() => void) | undefined>();
|
||||||
|
|
||||||
|
const openFilesModal = useCallback(() => {
|
||||||
|
setIsFilesModalOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const closeFilesModal = useCallback(() => {
|
||||||
|
setIsFilesModalOpen(false);
|
||||||
|
onModalClose?.();
|
||||||
|
}, [onModalClose]);
|
||||||
|
|
||||||
|
const handleFileSelect = useCallback((file: File) => {
|
||||||
|
onFileSelect?.(file);
|
||||||
|
closeFilesModal();
|
||||||
|
}, [onFileSelect, closeFilesModal]);
|
||||||
|
|
||||||
|
const handleFilesSelect = useCallback((files: File[]) => {
|
||||||
|
onFilesSelect?.(files);
|
||||||
|
closeFilesModal();
|
||||||
|
}, [onFilesSelect, closeFilesModal]);
|
||||||
|
|
||||||
|
const setModalCloseCallback = useCallback((callback: () => void) => {
|
||||||
|
setOnModalClose(() => callback);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isFilesModalOpen,
|
||||||
|
openFilesModal,
|
||||||
|
closeFilesModal,
|
||||||
|
onFileSelect: handleFileSelect,
|
||||||
|
onFilesSelect: handleFilesSelect,
|
||||||
|
onModalClose,
|
||||||
|
setOnModalClose: setModalCloseCallback,
|
||||||
|
};
|
||||||
|
};
|
@ -1,9 +1,10 @@
|
|||||||
import React, { useState, useCallback, useEffect} from "react";
|
import React, { useState, useCallback, useEffect, useRef } from "react";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useFileContext } from "../contexts/FileContext";
|
import { useFileContext } from "../contexts/FileContext";
|
||||||
import { FileSelectionProvider, useFileSelection } from "../contexts/FileSelectionContext";
|
import { FileSelectionProvider, useFileSelection } from "../contexts/FileSelectionContext";
|
||||||
import { useToolManagement } from "../hooks/useToolManagement";
|
import { useToolManagement } from "../hooks/useToolManagement";
|
||||||
import { Group, Box, Button, Container } from "@mantine/core";
|
import { useFileHandler } from "../hooks/useFileHandler";
|
||||||
|
import { Group, Box, Button } from "@mantine/core";
|
||||||
import { useRainbowThemeContext } from "../components/shared/RainbowThemeProvider";
|
import { useRainbowThemeContext } from "../components/shared/RainbowThemeProvider";
|
||||||
import { PageEditorFunctions } from "../types/pageEditor";
|
import { PageEditorFunctions } from "../types/pageEditor";
|
||||||
import rainbowStyles from '../styles/rainbow.module.css';
|
import rainbowStyles from '../styles/rainbow.module.css';
|
||||||
@ -14,17 +15,18 @@ import FileEditor from "../components/fileEditor/FileEditor";
|
|||||||
import PageEditor from "../components/pageEditor/PageEditor";
|
import PageEditor from "../components/pageEditor/PageEditor";
|
||||||
import PageEditorControls from "../components/pageEditor/PageEditorControls";
|
import PageEditorControls from "../components/pageEditor/PageEditorControls";
|
||||||
import Viewer from "../components/viewer/Viewer";
|
import Viewer from "../components/viewer/Viewer";
|
||||||
import FileUploadSelector from "../components/shared/FileUploadSelector";
|
|
||||||
import ToolRenderer from "../components/tools/ToolRenderer";
|
import ToolRenderer from "../components/tools/ToolRenderer";
|
||||||
import QuickAccessBar from "../components/shared/QuickAccessBar";
|
import QuickAccessBar from "../components/shared/QuickAccessBar";
|
||||||
|
import LandingPage from "../components/shared/LandingPage";
|
||||||
|
|
||||||
function HomePageContent() {
|
function HomePageContent() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isRainbowMode } = useRainbowThemeContext();
|
const { isRainbowMode } = useRainbowThemeContext();
|
||||||
|
|
||||||
const fileContext = useFileContext();
|
const fileContext = useFileContext();
|
||||||
const { activeFiles, currentView, currentMode, setCurrentView, addFiles } = fileContext;
|
const { activeFiles, currentView, setCurrentView } = fileContext;
|
||||||
const { setMaxFiles, setIsToolMode, setSelectedFiles } = useFileSelection();
|
const { setMaxFiles, setIsToolMode, setSelectedFiles } = useFileSelection();
|
||||||
|
const { addToActiveFiles } = useFileHandler();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
selectedToolKey,
|
selectedToolKey,
|
||||||
@ -77,12 +79,6 @@ function HomePageContent() {
|
|||||||
setCurrentView(view as any);
|
setCurrentView(view as any);
|
||||||
}, [setCurrentView]);
|
}, [setCurrentView]);
|
||||||
|
|
||||||
const addToActiveFiles = useCallback(async (file: File) => {
|
|
||||||
const exists = activeFiles.some(f => f.name === file.name && f.size === file.size);
|
|
||||||
if (!exists) {
|
|
||||||
await addFiles([file]);
|
|
||||||
}
|
|
||||||
}, [activeFiles, addFiles]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -183,25 +179,12 @@ function HomePageContent() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{!activeFiles[0] ? (
|
{!activeFiles[0] ? (
|
||||||
<Container size="lg" p="xl" h="100%" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<LandingPage
|
||||||
<FileUploadSelector
|
title={currentView === "viewer"
|
||||||
title={currentView === "viewer"
|
? t("fileUpload.selectPdfToView", "Select a PDF to view")
|
||||||
? t("fileUpload.selectPdfToView", "Select a PDF to view")
|
: t("fileUpload.selectPdfToEdit", "Select a PDF to edit")
|
||||||
: t("fileUpload.selectPdfToEdit", "Select a PDF to edit")
|
}
|
||||||
}
|
/>
|
||||||
subtitle={t("fileUpload.chooseFromStorage", "Choose a file from storage or upload a new PDF")}
|
|
||||||
onFileSelect={(file) => {
|
|
||||||
addToActiveFiles(file);
|
|
||||||
}}
|
|
||||||
onFilesSelect={(files) => {
|
|
||||||
files.forEach(addToActiveFiles);
|
|
||||||
}}
|
|
||||||
accept={["application/pdf"]}
|
|
||||||
loading={false}
|
|
||||||
showRecentFiles={true}
|
|
||||||
maxRecentFiles={8}
|
|
||||||
/>
|
|
||||||
</Container>
|
|
||||||
) : currentView === "fileEditor" ? (
|
) : currentView === "fileEditor" ? (
|
||||||
<FileEditor
|
<FileEditor
|
||||||
toolMode={!!selectedToolKey}
|
toolMode={!!selectedToolKey}
|
||||||
@ -271,22 +254,9 @@ function HomePageContent() {
|
|||||||
selectedToolKey={selectedToolKey}
|
selectedToolKey={selectedToolKey}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Container size="lg" p="xl" h="100%" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<LandingPage
|
||||||
<FileUploadSelector
|
title="File Management"
|
||||||
title="File Management"
|
/>
|
||||||
subtitle="Choose files from storage or upload new PDFs"
|
|
||||||
onFileSelect={(file) => {
|
|
||||||
addToActiveFiles(file);
|
|
||||||
}}
|
|
||||||
onFilesSelect={(files) => {
|
|
||||||
files.forEach(addToActiveFiles);
|
|
||||||
}}
|
|
||||||
accept={["application/pdf"]}
|
|
||||||
loading={false}
|
|
||||||
showRecentFiles={true}
|
|
||||||
maxRecentFiles={8}
|
|
||||||
/>
|
|
||||||
</Container>
|
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user