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:
Connor Yoh 2025-08-29 12:25:01 +01:00
parent f3d66c189f
commit da212cc120
15 changed files with 82 additions and 73 deletions

View File

@ -1,5 +1,4 @@
import React, { Suspense } from "react";
import { ScrollArea } from "@mantine/core";
import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider";
import { FileContextProvider } from "./contexts/FileContext";
import { NavigationProvider } from "./contexts/NavigationContext";
@ -42,9 +41,7 @@ export default function App() {
<ToolWorkflowProvider>
<SidebarProvider>
<RightRailProvider>
<ScrollArea h="100vh" scrollbarSize={6} scrollHideDelay={1000}>
<HomePage />
</ScrollArea>
</RightRailProvider>
</SidebarProvider>
</ToolWorkflowProvider>

View File

@ -454,7 +454,6 @@ const FileEditor = ({
multiple={true}
maxSize={2 * 1024 * 1024 * 1024}
style={{
height: '100vh',
border: 'none',
borderRadius: 0,
backgroundColor: 'transparent'
@ -462,7 +461,7 @@ const FileEditor = ({
activateOnClick={false}
activateOnDrag={true}
>
<Box pos="relative" h="100vh" style={{ overflow: 'auto' }}>
<Box pos="relative" style={{ overflow: 'auto' }}>
<LoadingOverlay visible={false} />
<Box p="md" pt="xl">
@ -563,7 +562,7 @@ const FileEditor = ({
color="blue"
mt="md"
onClose={() => setStatus(null)}
style={{ position: 'fixed', bottom: 20, right: 20, zIndex: 10001 }}
style={{ position: 'fixed', bottom: 40, right: 80, zIndex: 10001 }}
>
{status}
</Notification>

View 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);
}

View File

@ -4,9 +4,10 @@ import { useTranslation } from 'react-i18next';
import { useRainbowThemeContext } from '../shared/RainbowThemeProvider';
import { useToolWorkflow } from '../../contexts/ToolWorkflowContext';
import { useFileHandler } from '../../hooks/useFileHandler';
import { useFileState, useFileActions } from '../../contexts/FileContext';
import { useFileState } from '../../contexts/FileContext';
import { useNavigationState, useNavigationActions } from '../../contexts/NavigationContext';
import { useToolManagement } from '../../hooks/useToolManagement';
import './Workbench.css';
import TopControls from '../shared/TopControls';
import FileEditor from '../fileEditor/FileEditor';
@ -14,6 +15,7 @@ import PageEditor from '../pageEditor/PageEditor';
import PageEditorControls from '../pageEditor/PageEditorControls';
import Viewer from '../viewer/Viewer';
import LandingPage from '../shared/LandingPage';
import Footer from '../shared/Footer';
// No props needed - component uses contexts directly
export default function Workbench() {
@ -22,7 +24,6 @@ export default function Workbench() {
// Use context-based hooks to eliminate all prop drilling
const { state } = useFileState();
const { actions } = useFileActions();
const { workbench: currentView } = useNavigationState();
const { actions: navActions } = useNavigationActions();
const setCurrentView = navActions.setWorkbench;
@ -142,7 +143,7 @@ export default function Workbench() {
return (
<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={
isRainbowMode
? {} // No background color in rainbow mode
@ -158,7 +159,7 @@ export default function Workbench() {
{/* Main content area */}
<Box
className="flex-1 min-h-0 relative z-10"
className="flex-1 min-h-0 relative z-10 workbench-scrollable "
style={{
transition: 'opacity 0.15s ease-in-out',
marginTop: '1rem',
@ -166,6 +167,8 @@ export default function Workbench() {
>
{renderMainContent()}
</Box>
<Footer analyticsEnabled />
</Box>
);
}

View File

@ -683,11 +683,11 @@ const PageEditor = ({
const displayedPages = displayDocument?.pages || [];
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} />
{!mergedPdfDocument && !globalProcessing && activeFileIds.length === 0 && (
<Center h="100vh">
<Center h='100%'>
<Stack align="center" gap="md">
<Text size="lg" c="dimmed">📄</Text>
<Text c="dimmed">No PDF files loaded</Text>

View File

@ -141,7 +141,7 @@ const PageEditorControls = ({
flexWrap: 'wrap',
justifyContent: 'center',
padding: "1rem",
paddingBottom: "2rem"
paddingBottom: "1rem"
}}
>

View File

@ -1,4 +1,4 @@
import { Flex, Text } from '@mantine/core';
import { Flex } from '@mantine/core';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useCookieConsent } from '../../hooks/useCookieConsent';
@ -16,7 +16,6 @@ export default function Footer({
privacyPolicy = '/privacy',
termsAndConditions = '/terms',
accessibilityStatement = 'accessibility',
cookiePolicy = 'cookie',
analyticsEnabled = false
}: FooterProps) {
const { t } = useTranslation();
@ -24,36 +23,19 @@ export default function Footer({
return (
<div style={{
height: 'var(--footer-height)',
zIndex: 999999,
backgroundColor: 'var(--mantine-color-gray-1)',
borderTop: '1px solid var(--mantine-color-gray-3)',
paddingBottom: '0.5rem',
borderTop: '1px solid var(--mantine-color-gray-2)',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
}}>
<Flex pt='sm' gap="md"
<Flex gap="md"
justify="center"
align="center"
direction="row"
wrap="wrap"
px="lg"
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
className="footer-link px-3"
id="survey"
@ -103,7 +85,6 @@ export default function Footer({
</button>
)}
</Flex>
</div>
);
}

View File

@ -36,13 +36,13 @@ const LandingPage = () => {
};
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 */}
<Dropzone
onDrop={handleFileDrop}
accept={["application/pdf", "application/zip", "application/x-zip-compressed"]}
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={{
position: 'absolute',
left: '50%',

View File

@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next';
import { useToolSections } from '../../hooks/useToolSections';
import SubcategoryHeader from './shared/SubcategoryHeader';
import NoToolsFound from './shared/NoToolsFound';
import "./toolPicker/ToolPicker.css";
interface SearchResultsProps {
filteredTools: [string, ToolRegistryEntry][];
@ -21,7 +22,8 @@ const SearchResults: React.FC<SearchResultsProps> = ({ filteredTools, onSelect }
}
return (
<Stack p="sm" gap="xs">
<Stack p="sm" gap="xs"
className="tool-picker-scrollable">
{searchGroups.map(group => (
<Box key={group.subcategoryId} w="100%">
<SubcategoryHeader label={getSubcategoryLabel(t, group.subcategoryId)} />

View File

@ -72,17 +72,15 @@ export default function ToolPanel() {
{searchQuery.trim().length > 0 ? (
// Searching view (replaces both picker and content)
<div className="flex-1 flex flex-col">
<div className="flex-1 min-h-0">
<div className="flex-1 flex flex-col overflow-y-auto">
<SearchResults
filteredTools={filteredTools}
onSelect={handleToolSelect}
/>
</div>
</div>
) : leftPanelView === 'toolPicker' ? (
// Tool Picker View
<div className="flex-1 flex flex-col">
<div className="flex-1 flex flex-col overflow-auto">
<ToolPicker
selectedToolKey={selectedToolKey}
onSelect={handleToolSelect}

View File

@ -91,7 +91,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa
return (
<Box
h="100vh"
h="100%"
style={{
display: "flex",
flexDirection: "column",

View File

@ -1,8 +1,6 @@
.tool-picker-scrollable {
overflow-y: auto !important;
overflow-x: hidden !important;
scrollbar-width: thin;
scrollbar-color: var(--mantine-color-gray-4) transparent;
}
.tool-picker-scrollable::-webkit-scrollbar {

View File

@ -439,7 +439,7 @@ const Viewer = ({
}, [pageImages]);
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 */}
{onClose && previewFile && (
<ActionIcon
@ -558,7 +558,7 @@ const Viewer = ({
radius="xl xl 0 0"
shadow="sm"
p={12}
pb={24}
pb={12}
style={{
display: "flex",
alignItems: "center",

View File

@ -1,5 +1,11 @@
body {
html, body {
margin: 0;
padding: 0;
height: 100%;
overflow-x: hidden;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
@ -12,9 +18,14 @@ code {
monospace;
}
/* CSS Variables */
:root {
--footer-height: 2rem;
}
/* Footer link styling - make buttons and links look identical */
.footer-link {
color: var(--mantine-color-blue-6);
color: var(--mantine-color-gray-6);
text-decoration: none;
transition: color 0.2s ease;
border: none;

View File

@ -39,12 +39,12 @@ export default function HomePage() {
// Note: File selection limits are now handled directly by individual tools
return (
<div className="min-h-screen flex flex-col">
<div className="h-screen overflow-hidden">
<Group
align="flex-start"
gap={0}
h="100%"
className="flex-nowrap flex"
style={{ minHeight: '100vh' }}
>
<QuickAccessBar
ref={quickAccessRef} />
@ -53,7 +53,6 @@ export default function HomePage() {
<RightRail />
<FileManager selectedTool={selectedTool as any /* FIX ME */} />
</Group>
<Footer analyticsEnabled />
</div>
);
}