mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-09-18 09:29:24 +00:00
Moved bar to bottom of workbench
made gray made scrolling work on search results made scrollbars all look the same
This commit is contained in:
parent
f3d66c189f
commit
da212cc120
@ -1,5 +1,4 @@
|
|||||||
import React, { Suspense } from "react";
|
import React, { Suspense } from "react";
|
||||||
import { ScrollArea } from "@mantine/core";
|
|
||||||
import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider";
|
import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider";
|
||||||
import { FileContextProvider } from "./contexts/FileContext";
|
import { FileContextProvider } from "./contexts/FileContext";
|
||||||
import { NavigationProvider } from "./contexts/NavigationContext";
|
import { NavigationProvider } from "./contexts/NavigationContext";
|
||||||
@ -42,9 +41,7 @@ export default function App() {
|
|||||||
<ToolWorkflowProvider>
|
<ToolWorkflowProvider>
|
||||||
<SidebarProvider>
|
<SidebarProvider>
|
||||||
<RightRailProvider>
|
<RightRailProvider>
|
||||||
<ScrollArea h="100vh" scrollbarSize={6} scrollHideDelay={1000}>
|
<HomePage />
|
||||||
<HomePage />
|
|
||||||
</ScrollArea>
|
|
||||||
</RightRailProvider>
|
</RightRailProvider>
|
||||||
</SidebarProvider>
|
</SidebarProvider>
|
||||||
</ToolWorkflowProvider>
|
</ToolWorkflowProvider>
|
||||||
|
@ -454,7 +454,6 @@ const FileEditor = ({
|
|||||||
multiple={true}
|
multiple={true}
|
||||||
maxSize={2 * 1024 * 1024 * 1024}
|
maxSize={2 * 1024 * 1024 * 1024}
|
||||||
style={{
|
style={{
|
||||||
height: '100vh',
|
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderRadius: 0,
|
borderRadius: 0,
|
||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent'
|
||||||
@ -462,7 +461,7 @@ const FileEditor = ({
|
|||||||
activateOnClick={false}
|
activateOnClick={false}
|
||||||
activateOnDrag={true}
|
activateOnDrag={true}
|
||||||
>
|
>
|
||||||
<Box pos="relative" h="100vh" style={{ overflow: 'auto' }}>
|
<Box pos="relative" style={{ overflow: 'auto' }}>
|
||||||
<LoadingOverlay visible={false} />
|
<LoadingOverlay visible={false} />
|
||||||
|
|
||||||
<Box p="md" pt="xl">
|
<Box p="md" pt="xl">
|
||||||
@ -563,7 +562,7 @@ const FileEditor = ({
|
|||||||
color="blue"
|
color="blue"
|
||||||
mt="md"
|
mt="md"
|
||||||
onClose={() => setStatus(null)}
|
onClose={() => setStatus(null)}
|
||||||
style={{ position: 'fixed', bottom: 20, right: 20, zIndex: 10001 }}
|
style={{ position: 'fixed', bottom: 40, right: 80, zIndex: 10001 }}
|
||||||
>
|
>
|
||||||
{status}
|
{status}
|
||||||
</Notification>
|
</Notification>
|
||||||
|
21
frontend/src/components/layout/Workbench.css
Normal file
21
frontend/src/components/layout/Workbench.css
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.workbench-scrollable {
|
||||||
|
overflow-y: auto !important;
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workbench-scrollable::-webkit-scrollbar {
|
||||||
|
width: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workbench-scrollable::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workbench-scrollable::-webkit-scrollbar-thumb {
|
||||||
|
background-color: var(--mantine-color-gray-4);
|
||||||
|
border-radius: 0.1875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workbench-scrollable::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color: var(--mantine-color-gray-5);
|
||||||
|
}
|
@ -4,9 +4,10 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { useRainbowThemeContext } from '../shared/RainbowThemeProvider';
|
import { useRainbowThemeContext } from '../shared/RainbowThemeProvider';
|
||||||
import { useToolWorkflow } from '../../contexts/ToolWorkflowContext';
|
import { useToolWorkflow } from '../../contexts/ToolWorkflowContext';
|
||||||
import { useFileHandler } from '../../hooks/useFileHandler';
|
import { useFileHandler } from '../../hooks/useFileHandler';
|
||||||
import { useFileState, useFileActions } from '../../contexts/FileContext';
|
import { useFileState } from '../../contexts/FileContext';
|
||||||
import { useNavigationState, useNavigationActions } from '../../contexts/NavigationContext';
|
import { useNavigationState, useNavigationActions } from '../../contexts/NavigationContext';
|
||||||
import { useToolManagement } from '../../hooks/useToolManagement';
|
import { useToolManagement } from '../../hooks/useToolManagement';
|
||||||
|
import './Workbench.css';
|
||||||
|
|
||||||
import TopControls from '../shared/TopControls';
|
import TopControls from '../shared/TopControls';
|
||||||
import FileEditor from '../fileEditor/FileEditor';
|
import FileEditor from '../fileEditor/FileEditor';
|
||||||
@ -14,6 +15,7 @@ import PageEditor from '../pageEditor/PageEditor';
|
|||||||
import PageEditorControls from '../pageEditor/PageEditorControls';
|
import PageEditorControls from '../pageEditor/PageEditorControls';
|
||||||
import Viewer from '../viewer/Viewer';
|
import Viewer from '../viewer/Viewer';
|
||||||
import LandingPage from '../shared/LandingPage';
|
import LandingPage from '../shared/LandingPage';
|
||||||
|
import Footer from '../shared/Footer';
|
||||||
|
|
||||||
// No props needed - component uses contexts directly
|
// No props needed - component uses contexts directly
|
||||||
export default function Workbench() {
|
export default function Workbench() {
|
||||||
@ -22,7 +24,6 @@ export default function Workbench() {
|
|||||||
|
|
||||||
// Use context-based hooks to eliminate all prop drilling
|
// Use context-based hooks to eliminate all prop drilling
|
||||||
const { state } = useFileState();
|
const { state } = useFileState();
|
||||||
const { actions } = useFileActions();
|
|
||||||
const { workbench: currentView } = useNavigationState();
|
const { workbench: currentView } = useNavigationState();
|
||||||
const { actions: navActions } = useNavigationActions();
|
const { actions: navActions } = useNavigationActions();
|
||||||
const setCurrentView = navActions.setWorkbench;
|
const setCurrentView = navActions.setWorkbench;
|
||||||
@ -37,10 +38,10 @@ export default function Workbench() {
|
|||||||
} = useToolWorkflow();
|
} = useToolWorkflow();
|
||||||
|
|
||||||
const { handleToolSelect } = useToolWorkflow();
|
const { handleToolSelect } = useToolWorkflow();
|
||||||
|
|
||||||
// Get navigation state - this is the source of truth
|
// Get navigation state - this is the source of truth
|
||||||
const { selectedTool: selectedToolId } = useNavigationState();
|
const { selectedTool: selectedToolId } = useNavigationState();
|
||||||
|
|
||||||
// Get tool registry to look up selected tool
|
// Get tool registry to look up selected tool
|
||||||
const { toolRegistry } = useToolManagement();
|
const { toolRegistry } = useToolManagement();
|
||||||
const selectedTool = selectedToolId ? toolRegistry[selectedToolId] : null;
|
const selectedTool = selectedToolId ? toolRegistry[selectedToolId] : null;
|
||||||
@ -142,7 +143,7 @@ export default function Workbench() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
className="flex-1 h-screen min-w-80 relative flex flex-col"
|
className="flex-1 h-full min-w-80 relative flex flex-col"
|
||||||
style={
|
style={
|
||||||
isRainbowMode
|
isRainbowMode
|
||||||
? {} // No background color in rainbow mode
|
? {} // No background color in rainbow mode
|
||||||
@ -158,7 +159,7 @@ export default function Workbench() {
|
|||||||
|
|
||||||
{/* Main content area */}
|
{/* Main content area */}
|
||||||
<Box
|
<Box
|
||||||
className="flex-1 min-h-0 relative z-10"
|
className="flex-1 min-h-0 relative z-10 workbench-scrollable "
|
||||||
style={{
|
style={{
|
||||||
transition: 'opacity 0.15s ease-in-out',
|
transition: 'opacity 0.15s ease-in-out',
|
||||||
marginTop: '1rem',
|
marginTop: '1rem',
|
||||||
@ -166,6 +167,8 @@ export default function Workbench() {
|
|||||||
>
|
>
|
||||||
{renderMainContent()}
|
{renderMainContent()}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
<Footer analyticsEnabled />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -683,11 +683,11 @@ const PageEditor = ({
|
|||||||
const displayedPages = displayDocument?.pages || [];
|
const displayedPages = displayDocument?.pages || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box pos="relative" h="100vh" pt={40} style={{ overflow: 'auto' }} data-scrolling-container="true">
|
<Box pos="relative" h='100%' pt={40} style={{ overflow: 'auto' }} data-scrolling-container="true">
|
||||||
<LoadingOverlay visible={globalProcessing && !mergedPdfDocument} />
|
<LoadingOverlay visible={globalProcessing && !mergedPdfDocument} />
|
||||||
|
|
||||||
{!mergedPdfDocument && !globalProcessing && activeFileIds.length === 0 && (
|
{!mergedPdfDocument && !globalProcessing && activeFileIds.length === 0 && (
|
||||||
<Center h="100vh">
|
<Center h='100%'>
|
||||||
<Stack align="center" gap="md">
|
<Stack align="center" gap="md">
|
||||||
<Text size="lg" c="dimmed">📄</Text>
|
<Text size="lg" c="dimmed">📄</Text>
|
||||||
<Text c="dimmed">No PDF files loaded</Text>
|
<Text c="dimmed">No PDF files loaded</Text>
|
||||||
|
@ -39,7 +39,7 @@ interface PageEditorControlsProps {
|
|||||||
selectionMode: boolean;
|
selectionMode: boolean;
|
||||||
selectedPageIds: string[];
|
selectedPageIds: string[];
|
||||||
displayDocument?: { pages: { id: string; pageNumber: number }[] };
|
displayDocument?: { pages: { id: string; pageNumber: number }[] };
|
||||||
|
|
||||||
// Split state (for tooltip logic)
|
// Split state (for tooltip logic)
|
||||||
splitPositions?: Set<number>;
|
splitPositions?: Set<number>;
|
||||||
totalPages?: number;
|
totalPages?: number;
|
||||||
@ -70,40 +70,40 @@ const PageEditorControls = ({
|
|||||||
if (!splitPositions || !totalPages || selectedPageIds.length === 0) {
|
if (!splitPositions || !totalPages || selectedPageIds.length === 0) {
|
||||||
return "Split Selected";
|
return "Split Selected";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert selected pages to split positions (same logic as handleSplit)
|
// Convert selected pages to split positions (same logic as handleSplit)
|
||||||
const selectedPageNumbers = displayDocument ? selectedPageIds.map(id => {
|
const selectedPageNumbers = displayDocument ? selectedPageIds.map(id => {
|
||||||
const page = displayDocument.pages.find(p => p.id === id);
|
const page = displayDocument.pages.find(p => p.id === id);
|
||||||
return page?.pageNumber || 0;
|
return page?.pageNumber || 0;
|
||||||
}).filter(num => num > 0) : [];
|
}).filter(num => num > 0) : [];
|
||||||
const selectedSplitPositions = selectedPageNumbers.map(pageNum => pageNum - 1).filter(pos => pos < totalPages - 1);
|
const selectedSplitPositions = selectedPageNumbers.map(pageNum => pageNum - 1).filter(pos => pos < totalPages - 1);
|
||||||
|
|
||||||
if (selectedSplitPositions.length === 0) {
|
if (selectedSplitPositions.length === 0) {
|
||||||
return "Split Selected";
|
return "Split Selected";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smart toggle logic: follow the majority, default to adding splits if equal
|
// Smart toggle logic: follow the majority, default to adding splits if equal
|
||||||
const existingSplitsCount = selectedSplitPositions.filter(pos => splitPositions.has(pos)).length;
|
const existingSplitsCount = selectedSplitPositions.filter(pos => splitPositions.has(pos)).length;
|
||||||
const noSplitsCount = selectedSplitPositions.length - existingSplitsCount;
|
const noSplitsCount = selectedSplitPositions.length - existingSplitsCount;
|
||||||
|
|
||||||
// Remove splits only if majority already have splits
|
// Remove splits only if majority already have splits
|
||||||
// If equal (50/50), default to adding splits
|
// If equal (50/50), default to adding splits
|
||||||
const willRemoveSplits = existingSplitsCount > noSplitsCount;
|
const willRemoveSplits = existingSplitsCount > noSplitsCount;
|
||||||
|
|
||||||
if (willRemoveSplits) {
|
if (willRemoveSplits) {
|
||||||
return existingSplitsCount === selectedSplitPositions.length
|
return existingSplitsCount === selectedSplitPositions.length
|
||||||
? "Remove All Selected Splits"
|
? "Remove All Selected Splits"
|
||||||
: "Remove Selected Splits";
|
: "Remove Selected Splits";
|
||||||
} else {
|
} else {
|
||||||
return existingSplitsCount === 0
|
return existingSplitsCount === 0
|
||||||
? "Split Selected"
|
? "Split Selected"
|
||||||
: "Complete Selected Splits";
|
: "Complete Selected Splits";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate page break tooltip text
|
// Calculate page break tooltip text
|
||||||
const getPageBreakTooltip = () => {
|
const getPageBreakTooltip = () => {
|
||||||
return selectedPageIds.length > 0
|
return selectedPageIds.length > 0
|
||||||
? `Insert ${selectedPageIds.length} Page Break${selectedPageIds.length > 1 ? 's' : ''}`
|
? `Insert ${selectedPageIds.length} Page Break${selectedPageIds.length > 1 ? 's' : ''}`
|
||||||
: "Insert Page Breaks";
|
: "Insert Page Breaks";
|
||||||
};
|
};
|
||||||
@ -141,7 +141,7 @@ const PageEditorControls = ({
|
|||||||
flexWrap: 'wrap',
|
flexWrap: 'wrap',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
padding: "1rem",
|
padding: "1rem",
|
||||||
paddingBottom: "2rem"
|
paddingBottom: "1rem"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Flex, Text } from '@mantine/core';
|
import { Flex } from '@mantine/core';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useCookieConsent } from '../../hooks/useCookieConsent';
|
import { useCookieConsent } from '../../hooks/useCookieConsent';
|
||||||
@ -16,7 +16,6 @@ export default function Footer({
|
|||||||
privacyPolicy = '/privacy',
|
privacyPolicy = '/privacy',
|
||||||
termsAndConditions = '/terms',
|
termsAndConditions = '/terms',
|
||||||
accessibilityStatement = 'accessibility',
|
accessibilityStatement = 'accessibility',
|
||||||
cookiePolicy = 'cookie',
|
|
||||||
analyticsEnabled = false
|
analyticsEnabled = false
|
||||||
}: FooterProps) {
|
}: FooterProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -24,36 +23,19 @@ export default function Footer({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
|
height: 'var(--footer-height)',
|
||||||
zIndex: 999999,
|
zIndex: 999999,
|
||||||
backgroundColor: 'var(--mantine-color-gray-1)',
|
backgroundColor: 'var(--mantine-color-gray-1)',
|
||||||
borderTop: '1px solid var(--mantine-color-gray-3)',
|
borderTop: '1px solid var(--mantine-color-gray-2)',
|
||||||
paddingBottom: '0.5rem',
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
}}>
|
}}>
|
||||||
<Flex pt='sm' gap="md"
|
<Flex gap="md"
|
||||||
justify="center"
|
justify="center"
|
||||||
align="center"
|
align="center"
|
||||||
direction="row"
|
direction="row"
|
||||||
wrap="wrap"
|
|
||||||
px="lg"
|
|
||||||
style={{ fontSize: '0.75rem' }}>
|
style={{ fontSize: '0.75rem' }}>
|
||||||
<a
|
|
||||||
className="footer-link px-3"
|
|
||||||
id="licenses"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
href="/licenses"
|
|
||||||
>
|
|
||||||
{t('licenses.nav', 'Licenses')}
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
className="footer-link px-3"
|
|
||||||
id="releases"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
href="/releases"
|
|
||||||
>
|
|
||||||
{t('releases.footer', 'Releases')}
|
|
||||||
</a>
|
|
||||||
<a
|
<a
|
||||||
className="footer-link px-3"
|
className="footer-link px-3"
|
||||||
id="survey"
|
id="survey"
|
||||||
@ -103,7 +85,6 @@ export default function Footer({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,13 @@ const LandingPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container size="70rem" p={0} h="102%" className="flex items-center justify-center" style={{ position: 'relative' }}>
|
<Container size="70rem" p={0} h="100%" className="flex items-center justify-center" style={{ position: 'relative' }}>
|
||||||
{/* White PDF Page Background */}
|
{/* White PDF Page Background */}
|
||||||
<Dropzone
|
<Dropzone
|
||||||
onDrop={handleFileDrop}
|
onDrop={handleFileDrop}
|
||||||
accept={["application/pdf", "application/zip", "application/x-zip-compressed"]}
|
accept={["application/pdf", "application/zip", "application/x-zip-compressed"]}
|
||||||
multiple={true}
|
multiple={true}
|
||||||
className="w-4/5 flex items-center justify-center h-[95vh]"
|
className="w-4/5 flex items-center justify-center h-[95%]"
|
||||||
style={{
|
style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: '50%',
|
left: '50%',
|
||||||
|
@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { useToolSections } from '../../hooks/useToolSections';
|
import { useToolSections } from '../../hooks/useToolSections';
|
||||||
import SubcategoryHeader from './shared/SubcategoryHeader';
|
import SubcategoryHeader from './shared/SubcategoryHeader';
|
||||||
import NoToolsFound from './shared/NoToolsFound';
|
import NoToolsFound from './shared/NoToolsFound';
|
||||||
|
import "./toolPicker/ToolPicker.css";
|
||||||
|
|
||||||
interface SearchResultsProps {
|
interface SearchResultsProps {
|
||||||
filteredTools: [string, ToolRegistryEntry][];
|
filteredTools: [string, ToolRegistryEntry][];
|
||||||
@ -21,11 +22,12 @@ const SearchResults: React.FC<SearchResultsProps> = ({ filteredTools, onSelect }
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack p="sm" gap="xs">
|
<Stack p="sm" gap="xs"
|
||||||
|
className="tool-picker-scrollable">
|
||||||
{searchGroups.map(group => (
|
{searchGroups.map(group => (
|
||||||
<Box key={group.subcategoryId} w="100%">
|
<Box key={group.subcategoryId} w="100%">
|
||||||
<SubcategoryHeader label={getSubcategoryLabel(t, group.subcategoryId)} />
|
<SubcategoryHeader label={getSubcategoryLabel(t, group.subcategoryId)} />
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
{group.tools.map(({ id, tool }) => (
|
{group.tools.map(({ id, tool }) => (
|
||||||
<ToolButton
|
<ToolButton
|
||||||
key={id}
|
key={id}
|
||||||
|
@ -72,17 +72,15 @@ export default function ToolPanel() {
|
|||||||
|
|
||||||
{searchQuery.trim().length > 0 ? (
|
{searchQuery.trim().length > 0 ? (
|
||||||
// Searching view (replaces both picker and content)
|
// Searching view (replaces both picker and content)
|
||||||
<div className="flex-1 flex flex-col">
|
<div className="flex-1 flex flex-col overflow-y-auto">
|
||||||
<div className="flex-1 min-h-0">
|
|
||||||
<SearchResults
|
<SearchResults
|
||||||
filteredTools={filteredTools}
|
filteredTools={filteredTools}
|
||||||
onSelect={handleToolSelect}
|
onSelect={handleToolSelect}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
) : leftPanelView === 'toolPicker' ? (
|
) : leftPanelView === 'toolPicker' ? (
|
||||||
// Tool Picker View
|
// Tool Picker View
|
||||||
<div className="flex-1 flex flex-col">
|
<div className="flex-1 flex flex-col overflow-auto">
|
||||||
<ToolPicker
|
<ToolPicker
|
||||||
selectedToolKey={selectedToolKey}
|
selectedToolKey={selectedToolKey}
|
||||||
onSelect={handleToolSelect}
|
onSelect={handleToolSelect}
|
||||||
|
@ -91,7 +91,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
h="100vh"
|
h="100%"
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
.tool-picker-scrollable {
|
.tool-picker-scrollable {
|
||||||
overflow-y: auto !important;
|
overflow-y: auto !important;
|
||||||
overflow-x: hidden !important;
|
overflow-x: hidden !important;
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: var(--mantine-color-gray-4) transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-picker-scrollable::-webkit-scrollbar {
|
.tool-picker-scrollable::-webkit-scrollbar {
|
||||||
|
@ -439,7 +439,7 @@ const Viewer = ({
|
|||||||
}, [pageImages]);
|
}, [pageImages]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box style={{ position: 'relative', height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
<Box style={{ position: 'relative', height: '100%', display: 'flex', flexDirection: 'column' }}>
|
||||||
{/* Close Button - Only show in preview mode */}
|
{/* Close Button - Only show in preview mode */}
|
||||||
{onClose && previewFile && (
|
{onClose && previewFile && (
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
@ -558,7 +558,7 @@ const Viewer = ({
|
|||||||
radius="xl xl 0 0"
|
radius="xl xl 0 0"
|
||||||
shadow="sm"
|
shadow="sm"
|
||||||
p={12}
|
p={12}
|
||||||
pb={24}
|
pb={12}
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
body {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||||
sans-serif;
|
sans-serif;
|
||||||
@ -12,9 +18,14 @@ code {
|
|||||||
monospace;
|
monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CSS Variables */
|
||||||
|
:root {
|
||||||
|
--footer-height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Footer link styling - make buttons and links look identical */
|
/* Footer link styling - make buttons and links look identical */
|
||||||
.footer-link {
|
.footer-link {
|
||||||
color: var(--mantine-color-blue-6);
|
color: var(--mantine-color-gray-6);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: color 0.2s ease;
|
transition: color 0.2s ease;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -39,12 +39,12 @@ export default function HomePage() {
|
|||||||
// Note: File selection limits are now handled directly by individual tools
|
// Note: File selection limits are now handled directly by individual tools
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex flex-col">
|
<div className="h-screen overflow-hidden">
|
||||||
<Group
|
<Group
|
||||||
align="flex-start"
|
align="flex-start"
|
||||||
gap={0}
|
gap={0}
|
||||||
|
h="100%"
|
||||||
className="flex-nowrap flex"
|
className="flex-nowrap flex"
|
||||||
style={{ minHeight: '100vh' }}
|
|
||||||
>
|
>
|
||||||
<QuickAccessBar
|
<QuickAccessBar
|
||||||
ref={quickAccessRef} />
|
ref={quickAccessRef} />
|
||||||
@ -53,7 +53,6 @@ export default function HomePage() {
|
|||||||
<RightRail />
|
<RightRail />
|
||||||
<FileManager selectedTool={selectedTool as any /* FIX ME */} />
|
<FileManager selectedTool={selectedTool as any /* FIX ME */} />
|
||||||
</Group>
|
</Group>
|
||||||
<Footer analyticsEnabled />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user