From 63e3035bacd8d4852de3ba9341e49173176c994d Mon Sep 17 00:00:00 2001 From: perf3ct Date: Thu, 10 Jul 2025 20:27:51 +0000 Subject: [PATCH] fix(client): correctly style the document details page for light/dark mode --- .../src/components/FileIntegrityDisplay.tsx | 39 +- .../src/components/ProcessingTimeline.tsx | 35 +- frontend/src/contexts/ThemeContext.tsx | 112 +++- frontend/src/pages/DocumentDetailsPage.tsx | 497 +++++++++--------- frontend/src/theme.ts | 28 + 5 files changed, 408 insertions(+), 303 deletions(-) diff --git a/frontend/src/components/FileIntegrityDisplay.tsx b/frontend/src/components/FileIntegrityDisplay.tsx index 1d10f3a..e432ccf 100644 --- a/frontend/src/components/FileIntegrityDisplay.tsx +++ b/frontend/src/components/FileIntegrityDisplay.tsx @@ -19,7 +19,8 @@ import { Error as ErrorIcon, Info as InfoIcon, } from '@mui/icons-material'; -import { modernTokens } from '../theme'; +import { useTheme } from '../contexts/ThemeContext'; +import { useTheme as useMuiTheme } from '@mui/material/styles'; interface FileIntegrityDisplayProps { fileHash?: string; @@ -43,6 +44,8 @@ const FileIntegrityDisplay: React.FC = ({ compact = false, }) => { const [copied, setCopied] = useState(false); + const { modernTokens } = useTheme(); + const theme = useMuiTheme(); const copyToClipboard = (text: string) => { navigator.clipboard.writeText(text); @@ -60,7 +63,7 @@ const FileIntegrityDisplay: React.FC = ({ return { status: 'unknown', icon: , - color: modernTokens.colors.neutral[500], + color: theme.palette.text.secondary, message: 'Hash not available', }; } @@ -70,7 +73,7 @@ const FileIntegrityDisplay: React.FC = ({ return { status: 'verified', icon: , - color: modernTokens.colors.success[500], + color: theme.palette.success.main, message: 'File integrity verified', }; } @@ -78,7 +81,7 @@ const FileIntegrityDisplay: React.FC = ({ return { status: 'warning', icon: , - color: modernTokens.colors.warning[500], + color: theme.palette.warning.main, message: 'Hash format unusual', }; }; @@ -107,8 +110,8 @@ const FileIntegrityDisplay: React.FC = ({ @@ -183,8 +186,8 @@ const FileIntegrityDisplay: React.FC = ({ {/* Header */} @@ -194,7 +197,7 @@ const FileIntegrityDisplay: React.FC = ({ sx={{ fontSize: 24, mr: 1.5, - color: modernTokens.colors.primary[500] + color: theme.palette.primary.main }} /> @@ -221,7 +224,7 @@ const FileIntegrityDisplay: React.FC = ({ sx={{ fontSize: 18, mr: 1, - color: modernTokens.colors.neutral[600] + color: theme.palette.text.secondary }} /> @@ -235,9 +238,9 @@ const FileIntegrityDisplay: React.FC = ({ display: 'flex', alignItems: 'center', p: 2, - backgroundColor: modernTokens.colors.neutral[100], + backgroundColor: theme.palette.action.hover, borderRadius: 1, - border: `1px solid ${modernTokens.colors.neutral[200]}`, + border: `1px solid ${theme.palette.divider}`, }} > = ({ flex: 1, wordBreak: 'break-all', fontSize: '0.8rem', - color: modernTokens.colors.neutral[700], + color: theme.palette.text.primary, }} > {fileHash} @@ -294,8 +297,8 @@ const FileIntegrityDisplay: React.FC = ({ size="small" sx={{ fontSize: '0.75rem', - backgroundColor: modernTokens.colors.neutral[100], - border: `1px solid ${modernTokens.colors.neutral[300]}`, + backgroundColor: theme.palette.action.hover, + border: `1px solid ${theme.palette.divider}`, }} /> @@ -329,9 +332,9 @@ const FileIntegrityDisplay: React.FC = ({ size="small" sx={{ fontSize: '0.75rem', - backgroundColor: modernTokens.colors.primary[50], - color: modernTokens.colors.primary[700], - border: `1px solid ${modernTokens.colors.primary[200]}`, + backgroundColor: theme.palette.primary.light, + color: theme.palette.primary.dark, + border: `1px solid ${theme.palette.primary.main}`, }} /> diff --git a/frontend/src/components/ProcessingTimeline.tsx b/frontend/src/components/ProcessingTimeline.tsx index 39161d0..81cd457 100644 --- a/frontend/src/components/ProcessingTimeline.tsx +++ b/frontend/src/components/ProcessingTimeline.tsx @@ -29,7 +29,8 @@ import { Schedule as ScheduleIcon, Person as PersonIcon, } from '@mui/icons-material'; -import { modernTokens } from '../theme'; +import { useTheme } from '../contexts/ThemeContext'; +import { useTheme as useMuiTheme } from '@mui/material/styles'; import { documentService } from '../services/api'; interface ProcessingTimelineProps { @@ -70,6 +71,8 @@ const ProcessingTimeline: React.FC = ({ const [expanded, setExpanded] = useState(!compact); const [retryHistory, setRetryHistory] = useState([]); const [loadingHistory, setLoadingHistory] = useState(false); + const { modernTokens } = useTheme(); + const theme = useMuiTheme(); const getStatusIcon = (type: string, status: string) => { switch (type) { @@ -90,13 +93,13 @@ const ProcessingTimeline: React.FC = ({ const getStatusColor = (status: string) => { switch (status) { case 'success': - return modernTokens.colors.success[500]; + return theme.palette.success.main; case 'error': - return modernTokens.colors.error[500]; + return theme.palette.error.main; case 'warning': - return modernTokens.colors.warning[500]; + return theme.palette.warning.main; default: - return modernTokens.colors.info[500]; + return theme.palette.info.main; } }; @@ -213,8 +216,8 @@ const ProcessingTimeline: React.FC = ({ @@ -223,7 +226,7 @@ const ProcessingTimeline: React.FC = ({ sx={{ fontSize: 18, mr: 1, - color: modernTokens.colors.primary[500] + color: theme.palette.primary.main }} /> @@ -274,8 +277,8 @@ const ProcessingTimeline: React.FC = ({ {/* Header */} @@ -297,7 +300,7 @@ const ProcessingTimeline: React.FC = ({ {ocrRetryCount > 0 && ( = ({ {index < events.length - 1 && ( )} @@ -347,7 +350,7 @@ const ProcessingTimeline: React.FC = ({ {event.metadata?.userId && ( - + User: {event.metadata.userId.substring(0, 8)}... @@ -366,7 +369,7 @@ const ProcessingTimeline: React.FC = ({ {/* Retry History Section */} {ocrRetryCount > 0 && ( - + - - - {ocrLoading ? ( - - - - Loading OCR analysis... - - - ) : ocrData ? ( - <> - {/* Enhanced OCR Stats */} - - {ocrData.ocr_confidence && ( - - - {Math.round(ocrData.ocr_confidence)}% - - - Confidence - - - )} - {ocrData.ocr_word_count && ( - - - {ocrData.ocr_word_count.toLocaleString()} - - - Words - - - )} - {ocrData.ocr_processing_time_ms && ( - - - {ocrData.ocr_processing_time_ms}ms - - - Processing Time - - - )} - - - {/* OCR Error Display */} - {ocrData.ocr_error && ( - - - OCR Processing Error - - {ocrData.ocr_error} - - )} - - {/* OCR Text Preview */} - - {ocrData.ocr_text ? ( - - {ocrData.ocr_text.length > 500 - ? `${ocrData.ocr_text.substring(0, 500)}...` - : ocrData.ocr_text - } - - ) : ( - - No OCR text available for this document. - - )} - - {ocrData.ocr_text && ocrData.ocr_text.length > 500 && ( - - - - )} - - - {/* Processing Info */} - {ocrData.ocr_completed_at && ( - - - ✅ Processing completed: {new Date(ocrData.ocr_completed_at).toLocaleString()} - - - )} - - ) : ( - - OCR text is available but failed to load. Try clicking the "View Full Text" button above. - - )} - - - - )} {/* OCR Text Dialog */} diff --git a/frontend/src/theme.ts b/frontend/src/theme.ts index bb72620..f3d0853 100644 --- a/frontend/src/theme.ts +++ b/frontend/src/theme.ts @@ -43,23 +43,51 @@ export const modernTokens = { }, success: { 50: '#f0fdf4', + 100: '#dcfce7', + 200: '#bbf7d0', + 300: '#86efac', + 400: '#4ade80', 500: '#22c55e', 600: '#16a34a', + 700: '#15803d', + 800: '#166534', + 900: '#14532d', }, warning: { 50: '#fffbeb', + 100: '#fef3c7', + 200: '#fde68a', + 300: '#fcd34d', + 400: '#fbbf24', 500: '#f59e0b', 600: '#d97706', + 700: '#b45309', + 800: '#92400e', + 900: '#78350f', }, error: { 50: '#fef2f2', + 100: '#fee2e2', + 200: '#fecaca', + 300: '#fca5a5', + 400: '#f87171', 500: '#ef4444', 600: '#dc2626', + 700: '#b91c1c', + 800: '#991b1b', + 900: '#7f1d1d', }, info: { 50: '#eff6ff', + 100: '#dbeafe', + 200: '#bfdbfe', + 300: '#93c5fd', + 400: '#60a5fa', 500: '#3b82f6', 600: '#2563eb', + 700: '#1d4ed8', + 800: '#1e40af', + 900: '#1e3a8a', }, }, shadows: {