diff --git a/frontend/src/components/shared/RightRail.tsx b/frontend/src/components/shared/RightRail.tsx index 835c80272..ed492caa5 100644 --- a/frontend/src/components/shared/RightRail.tsx +++ b/frontend/src/components/shared/RightRail.tsx @@ -32,7 +32,8 @@ export default function RightRail() { const topButtons = useMemo(() => buttons.filter(b => (b.section || 'top') === 'top' && (b.visible ?? true)), [buttons]); // Access PageEditor functions for page-editor-specific actions - const { pageEditorFunctions } = useToolWorkflow(); + const { pageEditorFunctions, toolPanelMode, leftPanelView } = useToolWorkflow(); + const disableForFullscreen = toolPanelMode === 'fullscreen' && leftPanelView === 'toolPicker'; // CSV input state for page selection const [csvInput, setCsvInput] = useState(""); @@ -183,13 +184,13 @@ export default function RightRail() { <>
{topButtons.map(btn => ( - + actions[btn.id]?.()} - disabled={btn.disabled || allButtonsDisabled} + disabled={btn.disabled || allButtonsDisabled || disableForFullscreen} > {btn.icon} @@ -207,7 +208,7 @@ export default function RightRail() { >
{/* Search */} - +
@@ -215,7 +216,7 @@ export default function RightRail() { variant="subtle" radius="md" className="right-rail-icon" - disabled={currentView !== 'viewer' || allButtonsDisabled} + disabled={currentView !== 'viewer' || allButtonsDisabled || disableForFullscreen} aria-label={typeof t === 'function' ? t('rightRail.search', 'Search PDF') : 'Search PDF'} > @@ -235,7 +236,7 @@ export default function RightRail() { {/* Pan Mode */} - + {/* Rotate Left */} - + { viewerContext?.rotationActions.rotateBackward(); }} - disabled={currentView !== 'viewer' || allButtonsDisabled} + disabled={currentView !== 'viewer' || allButtonsDisabled || disableForFullscreen} > {/* Rotate Right */} - + { viewerContext?.rotationActions.rotateForward(); }} - disabled={currentView !== 'viewer' || allButtonsDisabled} + disabled={currentView !== 'viewer' || allButtonsDisabled || disableForFullscreen} > {/* Sidebar Toggle */} - + { viewerContext?.toggleThumbnailSidebar(); }} - disabled={currentView !== 'viewer' || allButtonsDisabled} + disabled={currentView !== 'viewer' || allButtonsDisabled || disableForFullscreen} > @@ -309,14 +310,14 @@ export default function RightRail() { >
{/* Select All Button */} - +
@@ -324,14 +325,14 @@ export default function RightRail() { {/* Deselect All Button */} - +
@@ -340,7 +341,7 @@ export default function RightRail() { {/* Select by Numbers - page editor only, with animated presence */} {pageControlsMounted && ( - +
@@ -350,7 +351,7 @@ export default function RightRail() { variant="subtle" radius="md" className="right-rail-icon" - disabled={!pageControlsVisible || totalItems === 0 || allButtonsDisabled} + disabled={!pageControlsVisible || totalItems === 0 || allButtonsDisabled || disableForFullscreen} aria-label={typeof t === 'function' ? t('rightRail.selectByNumber', 'Select by Page Numbers') : 'Select by Page Numbers'} > @@ -377,7 +378,7 @@ export default function RightRail() { {/* Delete Selected Pages - page editor only, with animated presence */} {pageControlsMounted && ( - +
@@ -386,7 +387,7 @@ export default function RightRail() { radius="md" className="right-rail-icon" onClick={() => { pageEditorFunctions?.handleDelete?.(); }} - disabled={!pageControlsVisible || (pageEditorFunctions?.selectedPageIds?.length || 0) === 0 || allButtonsDisabled} + disabled={!pageControlsVisible || (pageEditorFunctions?.selectedPageIds?.length || 0) === 0 || allButtonsDisabled || disableForFullscreen} aria-label={typeof t === 'function' ? t('rightRail.deleteSelected', 'Delete Selected Pages') : 'Delete Selected Pages'} > @@ -399,7 +400,7 @@ export default function RightRail() { {/* Export Selected Pages - page editor only */} {pageControlsMounted && ( - +
{ pageEditorFunctions?.onExportSelected?.(); }} - disabled={!pageControlsVisible || (pageEditorFunctions?.selectedPageIds?.length || 0) === 0 || pageEditorFunctions?.exportLoading || allButtonsDisabled} + disabled={!pageControlsVisible || (pageEditorFunctions?.selectedPageIds?.length || 0) === 0 || pageEditorFunctions?.exportLoading || allButtonsDisabled || disableForFullscreen} aria-label={typeof t === 'function' ? t('rightRail.exportSelected', 'Export Selected Pages') : 'Export Selected Pages'} > @@ -418,7 +419,7 @@ export default function RightRail() { )} {/* Close (File Editor: Close Selected | Page Editor: Close PDF) */} - +
@@ -465,7 +466,7 @@ export default function RightRail() { currentView === 'pageEditor' ? t('rightRail.exportAll', 'Export PDF') : (selectedCount > 0 ? t('rightRail.downloadSelected', 'Download Selected Files') : t('rightRail.downloadAll', 'Download All')) - } position="left" offset={12} arrow> + } position="left" offset={12} arrow portalTarget={document.body}>
diff --git a/frontend/src/components/shared/rightRail/ViewerAnnotationControls.tsx b/frontend/src/components/shared/rightRail/ViewerAnnotationControls.tsx index 92b778e44..e0844a6d5 100644 --- a/frontend/src/components/shared/rightRail/ViewerAnnotationControls.tsx +++ b/frontend/src/components/shared/rightRail/ViewerAnnotationControls.tsx @@ -10,6 +10,7 @@ import { useFileState, useFileContext } from '../../../contexts/FileContext'; import { generateThumbnailWithMetadata } from '../../../utils/thumbnailUtils'; import { createProcessedFile } from '../../../contexts/file/fileActions'; import { createStirlingFile, createNewStirlingFileStub } from '../../../types/fileContext'; +import { useToolWorkflow } from '../../../contexts/ToolWorkflowContext'; interface ViewerAnnotationControlsProps { currentView: string; @@ -17,6 +18,8 @@ interface ViewerAnnotationControlsProps { export default function ViewerAnnotationControls({ currentView }: ViewerAnnotationControlsProps) { const { t } = useTranslation(); + const { toolPanelMode, leftPanelView } = useToolWorkflow(); + const disableForFullscreen = toolPanelMode === 'fullscreen' && leftPanelView === 'toolPicker'; const [selectedColor, setSelectedColor] = useState('#000000'); const [isColorPickerOpen, setIsColorPickerOpen] = useState(false); const [isHoverColorPickerOpen, setIsHoverColorPickerOpen] = useState(false); @@ -42,7 +45,7 @@ export default function ViewerAnnotationControls({ currentView }: ViewerAnnotati return ( <> {/* Annotation Visibility Toggle */} - + { viewerContext?.toggleAnnotationsVisibility(); }} - disabled={currentView !== 'viewer' || viewerContext?.isAnnotationMode} + disabled={currentView !== 'viewer' || viewerContext?.isAnnotationMode || disableForFullscreen} > @@ -119,7 +122,7 @@ export default function ViewerAnnotationControls({ currentView }: ViewerAnnotati
) : ( // When inactive: Show "Draw" tooltip - + @@ -145,7 +148,7 @@ export default function ViewerAnnotationControls({ currentView }: ViewerAnnotati )} {/* Save PDF with Annotations */} - + diff --git a/frontend/src/components/tools/FullscreenToolList.tsx b/frontend/src/components/tools/FullscreenToolList.tsx index a662364b2..a52ec569c 100644 --- a/frontend/src/components/tools/FullscreenToolList.tsx +++ b/frontend/src/components/tools/FullscreenToolList.tsx @@ -11,7 +11,7 @@ import HotkeyDisplay from '../hotkeys/HotkeyDisplay'; import { useToolWorkflow } from '../../contexts/ToolWorkflowContext'; import StarRoundedIcon from '@mui/icons-material/StarRounded'; import StarBorderRoundedIcon from '@mui/icons-material/StarBorderRounded'; -import HistoryRoundedIcon from '@mui/icons-material/HistoryRounded'; +import ThumbUpRoundedIcon from '@mui/icons-material/ThumbUpRounded'; import Badge from '../shared/Badge'; import './ToolPanel.css'; @@ -34,22 +34,12 @@ const FullscreenToolList = ({ }: FullscreenToolListProps) => { const { t } = useTranslation(); const { hotkeys } = useHotkeys(); - const { toolRegistry, recentTools, favoriteTools, toggleFavorite, isFavorite, fullscreenToolSettings } = useToolWorkflow(); + const { toolRegistry, favoriteTools, toggleFavorite, isFavorite } = useToolWorkflow(); const { sections, searchGroups } = useToolSections(filteredTools, searchQuery); const tooltipPortalTarget = typeof document !== 'undefined' ? document.body : undefined; - // Prepare recent and favorite tool items - const recentToolItems = useMemo(() => { - return recentTools - .map((toolId) => { - const tool = toolRegistry[toolId]; - return tool ? { id: toolId, tool } : null; - }) - .filter(Boolean) - .slice(0, 6); // Show max 6 recent tools - }, [recentTools, toolRegistry]); const favoriteToolItems = useMemo(() => { return favoriteTools @@ -60,8 +50,16 @@ const FullscreenToolList = ({ .filter(Boolean); }, [favoriteTools, toolRegistry]); - // Show recent/favorites section only when not searching - const showRecentFavorites = searchQuery.trim().length === 0 && (recentToolItems.length > 0 || favoriteToolItems.length > 0); + const quickSection = useMemo(() => sections.find(section => section.key === 'quick'), [sections]); + const recommendedItems = useMemo(() => { + if (!quickSection) return [] as Array<{ id: string, tool: ToolRegistryEntry }>; + const items: Array<{ id: string, tool: ToolRegistryEntry }> = []; + quickSection.subcategories.forEach(sc => sc.tools.forEach(t => items.push(t))); + return items.slice(0, 5); + }, [quickSection]); + + // Show recommended/favorites section only when not searching + const showRecentFavorites = searchQuery.trim().length === 0 && ((recommendedItems.length > 0) || favoriteToolItems.length > 0); const subcategoryGroups = useMemo(() => { if (searchQuery.trim().length > 0) { @@ -88,16 +86,10 @@ const FullscreenToolList = ({ const getItemClasses = (isDetailed: boolean) => { const base = isDetailed ? 'tool-panel__fullscreen-item--detailed' : ''; - const border = fullscreenToolSettings.toolItemBorder === 'hidden' ? 'tool-panel__fullscreen-item--no-border' : ''; - const hover = `tool-panel__fullscreen-item--hover-${fullscreenToolSettings.hoverIntensity}`; - return [base, border, hover].filter(Boolean).join(' '); + return base; }; const getIconBackground = (categoryColor: string, isDetailed: boolean) => { - if (fullscreenToolSettings.iconBackground === 'none' || fullscreenToolSettings.iconBackground === 'hover') { - return 'transparent'; - } - const baseColor = isDetailed ? 'var(--fullscreen-bg-icon-detailed)' : 'var(--fullscreen-bg-icon-compact)'; const blend1 = isDetailed ? '18%' : '15%'; const blend2 = isDetailed ? '8%' : '6%'; @@ -109,12 +101,6 @@ const FullscreenToolList = ({ }; const getIconStyle = () => { - if (fullscreenToolSettings.iconColorScheme === 'monochrome') { - return { filter: 'grayscale(1) opacity(0.8)' }; - } - if (fullscreenToolSettings.iconColorScheme === 'vibrant') { - return { filter: 'saturate(1.5) brightness(1.1)' }; - } return {}; }; @@ -157,16 +143,7 @@ const FullscreenToolList = ({ // Detailed view if (showDescriptions) { const iconBg = getIconBackground(categoryColor, true); - const iconClasses = fullscreenToolSettings.iconBackground === 'hover' - ? 'tool-panel__fullscreen-icon tool-panel__fullscreen-icon--hover-bg' - : 'tool-panel__fullscreen-icon'; - - const hoverBgDetailed = fullscreenToolSettings.iconBackground === 'hover' - ? `linear-gradient(135deg, - color-mix(in srgb, ${categoryColor} 18%, var(--fullscreen-bg-icon-detailed)), - color-mix(in srgb, ${categoryColor} 8%, var(--fullscreen-bg-icon-detailed)) - )` - : undefined; + const iconClasses = 'tool-panel__fullscreen-icon'; return (
{tools.length} diff --git a/frontend/src/components/tools/FullscreenToolSettings.tsx b/frontend/src/components/tools/FullscreenToolSettings.tsx deleted file mode 100644 index 0f1170f76..000000000 --- a/frontend/src/components/tools/FullscreenToolSettings.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import { ActionIcon, Drawer, Radio, SegmentedControl, Stack, Text } from '@mantine/core'; -import { useTranslation } from 'react-i18next'; -import TuneRoundedIcon from '@mui/icons-material/TuneRounded'; -import { useState } from 'react'; - -export interface FullscreenToolStyleSettings { - iconBackground: 'none' | 'hover' | 'always'; - iconColorScheme: 'colored' | 'vibrant' | 'monochrome'; - sectionTitleColor: 'colored' | 'neutral'; - headerIconColor: 'colored' | 'monochrome'; - headerBadgeColor: 'colored' | 'neutral'; - toolItemBorder: 'visible' | 'hidden'; - hoverIntensity: 'subtle' | 'moderate' | 'prominent'; -} - -export const defaultFullscreenToolSettings: FullscreenToolStyleSettings = { - iconBackground: 'always', - iconColorScheme: 'colored', - sectionTitleColor: 'colored', - headerIconColor: 'colored', - headerBadgeColor: 'colored', - toolItemBorder: 'visible', - hoverIntensity: 'moderate', -}; - -interface FullscreenToolSettingsProps { - settings: FullscreenToolStyleSettings; - onChange: (settings: FullscreenToolStyleSettings) => void; -} - -const FullscreenToolSettings = ({ settings, onChange }: FullscreenToolSettingsProps) => { - const { t } = useTranslation(); - const [opened, setOpened] = useState(false); - - const updateSetting = ( - key: K, - value: FullscreenToolStyleSettings[K] - ) => { - onChange({ ...settings, [key]: value }); - }; - - return ( - <> - setOpened(true)} - aria-label={t('toolPanel.fullscreen.settings.title', 'Customize appearance')} - style={{ color: 'var(--right-rail-icon)' }} - > - - - - setOpened(false)} - title={t('toolPanel.fullscreen.settings.title', 'Customize appearance')} - position="right" - size="md" - styles={{ - root: { zIndex: 1300 }, - overlay: { zIndex: 1300 }, - inner: { zIndex: 1300 }, - }} - > - -
- - {t('toolPanel.fullscreen.settings.iconBackground.label', 'Tool icon background')} - - - {t('toolPanel.fullscreen.settings.iconBackground.description', 'When to show colored backgrounds behind tool icons')} - - updateSetting('iconBackground', value as any)} - data={[ - { label: t('toolPanel.fullscreen.settings.iconBackground.none', 'None'), value: 'none' }, - { label: t('toolPanel.fullscreen.settings.iconBackground.hover', 'On hover'), value: 'hover' }, - { label: t('toolPanel.fullscreen.settings.iconBackground.always', 'Always'), value: 'always' }, - ]} - /> -
- -
- - {t('toolPanel.fullscreen.settings.iconColor.label', 'Tool icon color')} - - - {t('toolPanel.fullscreen.settings.iconColor.description', 'Color scheme for tool icons')} - - updateSetting('iconColorScheme', value as any)} - data={[ - { label: t('toolPanel.fullscreen.settings.iconColor.colored', 'Colored'), value: 'colored' }, - { label: t('toolPanel.fullscreen.settings.iconColor.vibrant', 'Vibrant'), value: 'vibrant' }, - { label: t('toolPanel.fullscreen.settings.iconColor.monochrome', 'Monochrome'), value: 'monochrome' }, - ]} - /> -
- -
- - {t('toolPanel.fullscreen.settings.sectionTitle.label', 'Section titles')} - - - {t('toolPanel.fullscreen.settings.sectionTitle.description', 'Color for category section titles')} - - updateSetting('sectionTitleColor', value as any)} - data={[ - { label: t('toolPanel.fullscreen.settings.sectionTitle.colored', 'Colored'), value: 'colored' }, - { label: t('toolPanel.fullscreen.settings.sectionTitle.neutral', 'Neutral'), value: 'neutral' }, - ]} - /> -
- -
- - {t('toolPanel.fullscreen.settings.headerIcon.label', 'Section header icons')} - - - {t('toolPanel.fullscreen.settings.headerIcon.description', 'Color for Favorites/Recent icons')} - - updateSetting('headerIconColor', value as any)} - data={[ - { label: t('toolPanel.fullscreen.settings.headerIcon.colored', 'Colored'), value: 'colored' }, - { label: t('toolPanel.fullscreen.settings.headerIcon.monochrome', 'Monochrome'), value: 'monochrome' }, - ]} - /> -
- -
- - {t('toolPanel.fullscreen.settings.headerBadge.label', 'Section header badges')} - - - {t('toolPanel.fullscreen.settings.headerBadge.description', 'Color for count badges in section headers')} - - updateSetting('headerBadgeColor', value as any)} - data={[ - { label: t('toolPanel.fullscreen.settings.headerBadge.colored', 'Colored'), value: 'colored' }, - { label: t('toolPanel.fullscreen.settings.headerBadge.neutral', 'Neutral'), value: 'neutral' }, - ]} - /> -
- -
- - {t('toolPanel.fullscreen.settings.border.label', 'Tool item borders')} - - - {t('toolPanel.fullscreen.settings.border.description', 'Show borders around tool items')} - - updateSetting('toolItemBorder', value as any)} - data={[ - { label: t('toolPanel.fullscreen.settings.border.visible', 'Visible'), value: 'visible' }, - { label: t('toolPanel.fullscreen.settings.border.hidden', 'Hidden'), value: 'hidden' }, - ]} - /> -
- -
- - {t('toolPanel.fullscreen.settings.hover.label', 'Hover effect intensity')} - - - {t('toolPanel.fullscreen.settings.hover.description', 'How prominent the hover effect should be')} - - updateSetting('hoverIntensity', value as any)} - > - - - - - - -
-
-
- - ); -}; - -export default FullscreenToolSettings; - - diff --git a/frontend/src/components/tools/FullscreenToolSurface.tsx b/frontend/src/components/tools/FullscreenToolSurface.tsx index a0ac59f9d..f56ec19a8 100644 --- a/frontend/src/components/tools/FullscreenToolSurface.tsx +++ b/frontend/src/components/tools/FullscreenToolSurface.tsx @@ -4,11 +4,9 @@ import ViewSidebarRoundedIcon from '@mui/icons-material/ViewSidebarRounded'; import { useTranslation } from 'react-i18next'; import ToolSearch from './toolPicker/ToolSearch'; import FullscreenToolList from './FullscreenToolList'; -import FullscreenToolSettings from './FullscreenToolSettings'; import { ToolRegistryEntry } from '../../data/toolsTaxonomy'; import { ToolId } from '../../types/toolId'; import { useFocusTrap } from '../../hooks/tools/useFocusTrap'; -import { useToolWorkflow } from '../../contexts/ToolWorkflowContext'; import { BASE_PATH } from '../../constants/app'; import './ToolPanel.css'; @@ -48,7 +46,6 @@ const FullscreenToolSurface = ({ }: FullscreenToolSurfaceProps) => { const { t } = useTranslation(); const { colorScheme } = useMantineColorScheme(); - const { fullscreenToolSettings, setFullscreenToolSettings } = useToolWorkflow(); const [isExiting, setIsExiting] = useState(false); const surfaceRef = useRef(null); @@ -104,10 +101,6 @@ const FullscreenToolSurface = ({ {brandAltText}
- { return favoriteTools @@ -79,24 +79,19 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa .filter((item: any) => item && (item.tool.component || item.tool.link || item.id === 'read' || item.id === 'multiTool')) as Array<{ id: string; tool: ToolRegistryEntry }>; }, [favoriteTools, toolRegistry]); - const recentToolItems = useMemo(() => { - return recentTools - .map((toolId) => { - const tool = (toolRegistry as any)[toolId as ToolId] as ToolRegistryEntry | undefined; - return tool ? { id: toolId as string, tool } : null; - }) - .filter(Boolean) - .slice(0, 5) as Array<{ id: string; tool: ToolRegistryEntry }>; // cap to 5 - }, [recentTools, toolRegistry]); - - const recommendedCount = useMemo(() => { - return favoriteToolItems.length + recentToolItems.length; - }, [favoriteToolItems.length, recentToolItems.length]); - const quickSection = useMemo( () => visibleSections.find(s => s.key === 'quick'), [visibleSections] ); + + const recommendedItems = useMemo(() => { + if (!quickSection) return [] as Array<{ id: string; tool: ToolRegistryEntry }>; + const items: Array<{ id: string; tool: ToolRegistryEntry }> = []; + quickSection.subcategories.forEach((sc: any) => sc.tools.forEach((toolEntry: any) => items.push(toolEntry))); + return items.slice(0, 5); + }, [quickSection]); + + const recommendedCount = useMemo(() => favoriteToolItems.length + recommendedItems.length, [favoriteToolItems.length, recommendedItems.length]); const allSection = useMemo( () => visibleSections.find(s => s.key === 'all'), [visibleSections] @@ -172,7 +167,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa }} onClick={() => scrollTo(quickAccessRef)} > - {t("toolPicker.recommended", "RECOMMENDED")} + {t("toolPicker.quickAccess", "QUICK ACCESS")} {recommendedCount} @@ -196,13 +191,13 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa
)} - {recentToolItems.length > 0 && ( + {recommendedItems.length > 0 && ( - +
- {recentToolItems.map(({ id, tool }) => ( + {recommendedItems.map(({ id, tool }) => ( )} - {/* Temporarily hide the rest of Recommended tools; show only Favourites and Recently used */} @@ -247,7 +241,7 @@ const ToolPicker = ({ selectedToolKey, onSelect, filteredTools, isSearching = fa - {allSection?.subcategories.map(sc => + {allSection?.subcategories.map((sc: any) => renderToolButtons(t, sc, selectedToolKey, onSelect, true, false) )} diff --git a/frontend/src/contexts/ToolWorkflowContext.tsx b/frontend/src/contexts/ToolWorkflowContext.tsx index 3d07392b5..8dc488bc3 100644 --- a/frontend/src/contexts/ToolWorkflowContext.tsx +++ b/frontend/src/contexts/ToolWorkflowContext.tsx @@ -9,20 +9,16 @@ import { PageEditorFunctions } from '../types/pageEditor'; import { ToolRegistryEntry, ToolRegistry } from '../data/toolsTaxonomy'; import { useNavigationActions, useNavigationState } from './NavigationContext'; import { ToolId, isValidToolId } from '../types/toolId'; -import { useNavigationUrlSync } from '../hooks/useUrlSync'; import { getDefaultWorkbench } from '../types/workbench'; import { filterToolRegistryByQuery } from '../utils/toolSearch'; import { useToolHistory } from '../hooks/tools/useToolHistory'; -import { FullscreenToolStyleSettings } from '../components/tools/FullscreenToolSettings'; import { ToolWorkflowState, TOOL_PANEL_MODE_STORAGE_KEY, - FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY, createInitialState, toolWorkflowReducer, ToolPanelMode, } from './toolWorkflow/state'; -import { usePreferences } from '../contexts/PreferencesContext'; // State interface // Types and reducer/state moved to './toolWorkflow/state' @@ -40,7 +36,6 @@ interface ToolWorkflowContextValue extends ToolWorkflowState { setLeftPanelView: (view: 'toolPicker' | 'toolContent' | 'hidden') => void; setReaderMode: (mode: boolean) => void; setToolPanelMode: (mode: ToolPanelMode) => void; - setFullscreenToolSettings: (settings: FullscreenToolStyleSettings) => void; setPreviewFile: (file: File | null) => void; setPageEditorFunctions: (functions: PageEditorFunctions | null) => void; setSearchQuery: (query: string) => void; @@ -80,7 +75,6 @@ interface ToolWorkflowProviderProps { export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { const [state, dispatch] = useReducer(toolWorkflowReducer, undefined, createInitialState); - const { preferences } = usePreferences(); // Store reset functions for tools const [toolResetFunctions, setToolResetFunctions] = React.useState void>>({}); @@ -129,10 +123,6 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { }, []); - const setFullscreenToolSettings = useCallback((settings: FullscreenToolStyleSettings) => { - dispatch({ type: 'SET_FULLSCREEN_TOOL_SETTINGS', payload: settings }); - }, []); - const setPreviewFile = useCallback((file: File | null) => { dispatch({ type: 'SET_PREVIEW_FILE', payload: file }); if (file) { @@ -148,7 +138,7 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { dispatch({ type: 'SET_SEARCH_QUERY', payload: query }); }, []); - React.useEffect(() => { + useEffect(() => { if (typeof window === 'undefined') { return; } @@ -156,24 +146,6 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { window.localStorage.setItem(TOOL_PANEL_MODE_STORAGE_KEY, state.toolPanelMode); }, [state.toolPanelMode]); - // Initialize tool panel mode from user preferences if no explicit localStorage preference exists yet - useEffect(() => { - if (typeof window === 'undefined') return; - const stored = window.localStorage.getItem(TOOL_PANEL_MODE_STORAGE_KEY); - if (stored === null && preferences?.defaultToolPanelMode && state.toolPanelMode !== preferences.defaultToolPanelMode) { - dispatch({ type: 'SET_TOOL_PANEL_MODE', payload: preferences.defaultToolPanelMode }); - } - }, [preferences?.defaultToolPanelMode]); - - React.useEffect(() => { - if (typeof window === 'undefined') { - return; - } - - const serialized = JSON.stringify(state.fullscreenToolSettings); - window.localStorage.setItem(FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY, serialized); - }, [state.fullscreenToolSettings]); - // Tool reset methods const registerToolReset = useCallback((toolId: string, resetFunction: () => void) => { setToolResetFunctions(prev => ({ ...prev, [toolId]: resetFunction })); @@ -253,15 +225,6 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { [state.sidebarsVisible, state.readerMode, state.leftPanelView] ); - // URL sync for proper tool navigation - useNavigationUrlSync( - navigationState.selectedTool, - handleToolSelect, - handleBackToTools, - toolRegistry as ToolRegistry, - true - ); - // Properly memoized context value const contextValue = useMemo((): ToolWorkflowContextValue => ({ // State @@ -276,7 +239,6 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { setLeftPanelView, setReaderMode, setToolPanelMode, - setFullscreenToolSettings, setPreviewFile, setPageEditorFunctions, setSearchQuery, @@ -313,7 +275,6 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { setLeftPanelView, setReaderMode, setToolPanelMode, - setFullscreenToolSettings, setPreviewFile, setPageEditorFunctions, setSearchQuery, @@ -343,7 +304,6 @@ export function ToolWorkflowProvider({ children }: ToolWorkflowProviderProps) { export function useToolWorkflow(): ToolWorkflowContextValue { const context = useContext(ToolWorkflowContext); if (!context) { - console.error('ToolWorkflowContext not found. Current stack:', new Error().stack); throw new Error('useToolWorkflow must be used within a ToolWorkflowProvider'); } diff --git a/frontend/src/contexts/toolWorkflow/state.ts b/frontend/src/contexts/toolWorkflow/state.ts index efc8d619a..dbf96c082 100644 --- a/frontend/src/contexts/toolWorkflow/state.ts +++ b/frontend/src/contexts/toolWorkflow/state.ts @@ -1,4 +1,3 @@ -import { FullscreenToolStyleSettings, defaultFullscreenToolSettings } from '../../components/tools/FullscreenToolSettings'; import { PageEditorFunctions } from '../../types/pageEditor'; // State & Modes @@ -10,9 +9,7 @@ export interface ToolWorkflowState { leftPanelView: 'toolPicker' | 'toolContent' | 'hidden'; readerMode: boolean; toolPanelMode: ToolPanelMode; - fullscreenToolSettings: FullscreenToolStyleSettings; - // File/Preview State previewFile: File | null; pageEditorFunctions: PageEditorFunctions | null; @@ -26,7 +23,6 @@ export type ToolWorkflowAction = | { type: 'SET_LEFT_PANEL_VIEW'; payload: 'toolPicker' | 'toolContent' | 'hidden' } | { type: 'SET_READER_MODE'; payload: boolean } | { type: 'SET_TOOL_PANEL_MODE'; payload: ToolPanelMode } - | { type: 'SET_FULLSCREEN_TOOL_SETTINGS'; payload: FullscreenToolStyleSettings } | { type: 'SET_PREVIEW_FILE'; payload: File | null } | { type: 'SET_PAGE_EDITOR_FUNCTIONS'; payload: PageEditorFunctions | null } | { type: 'SET_SEARCH_QUERY'; payload: string } @@ -34,7 +30,6 @@ export type ToolWorkflowAction = // Storage keys export const TOOL_PANEL_MODE_STORAGE_KEY = 'toolPanelModePreference'; -export const FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY = 'fullscreenToolStyleSettings'; export const getStoredToolPanelMode = (): ToolPanelMode => { if (typeof window === 'undefined') { @@ -49,24 +44,7 @@ export const getStoredToolPanelMode = (): ToolPanelMode => { return 'sidebar'; }; -export const getStoredFullscreenToolSettings = (): FullscreenToolStyleSettings => { - if (typeof window === 'undefined') { - return defaultFullscreenToolSettings; - } - - try { - const storedNew = window.localStorage.getItem(FULLSCREEN_TOOL_SETTINGS_STORAGE_KEY); - if (storedNew) { - return { ...defaultFullscreenToolSettings, ...JSON.parse(storedNew) }; - } - } catch (e) { - console.error('Failed to parse fullscreen tool settings:', e); - } - - return defaultFullscreenToolSettings; -}; - -export const baseState: Omit = { +export const baseState: Omit = { sidebarsVisible: true, leftPanelView: 'toolPicker', readerMode: false, @@ -78,7 +56,6 @@ export const baseState: Omit ({ ...baseState, toolPanelMode: getStoredToolPanelMode(), - fullscreenToolSettings: getStoredFullscreenToolSettings(), }); export function toolWorkflowReducer(state: ToolWorkflowState, action: ToolWorkflowAction): ToolWorkflowState { @@ -91,8 +68,6 @@ export function toolWorkflowReducer(state: ToolWorkflowState, action: ToolWorkfl return { ...state, readerMode: action.payload }; case 'SET_TOOL_PANEL_MODE': return { ...state, toolPanelMode: action.payload }; - case 'SET_FULLSCREEN_TOOL_SETTINGS': - return { ...state, fullscreenToolSettings: action.payload }; case 'SET_PREVIEW_FILE': return { ...state, previewFile: action.payload }; case 'SET_PAGE_EDITOR_FUNCTIONS': @@ -103,7 +78,6 @@ export function toolWorkflowReducer(state: ToolWorkflowState, action: ToolWorkfl return { ...baseState, toolPanelMode: state.toolPanelMode, - fullscreenToolSettings: state.fullscreenToolSettings, searchQuery: state.searchQuery, }; default: diff --git a/frontend/src/styles/theme.css b/frontend/src/styles/theme.css index 7fe29af55..cd895bd14 100644 --- a/frontend/src/styles/theme.css +++ b/frontend/src/styles/theme.css @@ -60,6 +60,10 @@ --category-color-automation: #ec4899; /* Pink for automation tools */ --category-color-developer: #6b7280; /* Gray for developer tools */ --category-color-default: #6b7280; /* Default gray */ + + /* Special section colors - consistent across light and dark modes */ + --special-color-favorites: #FFC107; /* Yellow/gold for favorites */ + --special-color-recommended: #1BB1D4; /* Cyan for recommended */ --color-yellow-500: #eab308; --color-yellow-600: #ca8a04; --color-yellow-700: #a16207; @@ -301,6 +305,10 @@ --category-color-developer: #6b7280; /* Gray for developer tools */ --category-color-default: #6b7280; /* Default gray */ + /* Special section colors - same as light mode for consistency */ + --special-color-favorites: #FFC107; /* Yellow/gold for favorites */ + --special-color-recommended: #1BB1D4; /* Cyan for recommended */ + /* Success (green) - dark */ --color-green-50: #052e16; --color-green-100: #064e3b;