From cc74744bbaa4f231a0021c7c7e412e0047085ee8 Mon Sep 17 00:00:00 2001 From: perf3ct Date: Fri, 13 Jun 2025 16:28:04 +0000 Subject: [PATCH] feat(client): make frontend a little more modern --- .../GlobalSearchBar/GlobalSearchBar.tsx | 257 +++++++++++++++--- frontend/src/components/Layout/AppLayout.tsx | 235 +++++++++++++--- 2 files changed, 406 insertions(+), 86 deletions(-) diff --git a/frontend/src/components/GlobalSearchBar/GlobalSearchBar.tsx b/frontend/src/components/GlobalSearchBar/GlobalSearchBar.tsx index 2007a53..d149f5f 100644 --- a/frontend/src/components/GlobalSearchBar/GlobalSearchBar.tsx +++ b/frontend/src/components/GlobalSearchBar/GlobalSearchBar.tsx @@ -375,19 +375,36 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { ), }} sx={{ - minWidth: 300, - maxWidth: 400, + minWidth: 320, + maxWidth: 420, '& .MuiOutlinedInput-root': { - backgroundColor: 'background.paper', - transition: 'all 0.2s ease-in-out', + background: 'linear-gradient(135deg, rgba(255,255,255,0.95) 0%, rgba(248,250,252,0.90) 100%)', + backdropFilter: 'blur(20px)', + border: '1px solid rgba(226,232,240,0.5)', + borderRadius: 3, + transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)', + boxShadow: '0 4px 16px rgba(0,0,0,0.04)', '&:hover': { - backgroundColor: 'background.paper', - borderColor: 'primary.main', + background: 'linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(248,250,252,0.95) 100%)', + borderColor: 'rgba(99,102,241,0.4)', + transform: 'translateY(-2px)', + boxShadow: '0 8px 32px rgba(99,102,241,0.15)', }, '&.Mui-focused': { - backgroundColor: 'background.paper', - borderColor: 'primary.main', + background: 'linear-gradient(135deg, rgba(255,255,255,1) 0%, rgba(248,250,252,0.98) 100%)', + borderColor: '#6366f1', borderWidth: 2, + transform: 'translateY(-2px)', + boxShadow: '0 12px 40px rgba(99,102,241,0.2)', + }, + '& .MuiInputBase-input': { + fontWeight: 500, + letterSpacing: '0.025em', + fontSize: '0.95rem', + '&::placeholder': { + color: 'rgba(148,163,184,0.8)', + fontWeight: 400, + }, }, }, }} @@ -423,20 +440,40 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { {({ TransitionProps }) => ( {(loading || isTyping) && ( - - - - + + + + + + {isTyping ? 'Searching as you type...' : 'Searching...'} @@ -461,18 +498,40 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { )} {!loading && !isTyping && query && results.length === 0 && ( - - + + No documents found for "{query}" - + Press Enter to search with advanced options {/* Smart suggestions for no results */} {suggestions.length > 0 && ( <> - + Try these suggestions: @@ -484,7 +543,21 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { variant="outlined" clickable onClick={() => handleSuggestionClick(suggestion)} - sx={{ fontSize: '0.7rem', height: 20 }} + sx={{ + fontSize: '0.7rem', + height: 24, + fontWeight: 500, + border: '1px solid rgba(99,102,241,0.3)', + background: 'linear-gradient(135deg, rgba(255,255,255,0.8) 0%, rgba(248,250,252,0.6) 100%)', + backdropFilter: 'blur(10px)', + transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)', + '&:hover': { + background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', + color: 'white', + transform: 'translateY(-2px)', + boxShadow: '0 8px 24px rgba(99,102,241,0.2)', + }, + }} /> ))} @@ -495,14 +568,35 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { {!loading && !isTyping && results.length > 0 && ( <> - - - + + + Quick Results - - {results.length} found - + + + {results.length} found + + @@ -512,10 +606,15 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { component="div" onClick={() => handleDocumentClick(doc)} sx={{ - py: 1, + py: 1.5, cursor: 'pointer', + borderRadius: 2, + mx: 1, + transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)', '&:hover': { - backgroundColor: 'action.hover', + background: 'linear-gradient(135deg, rgba(99,102,241,0.08) 0%, rgba(139,92,246,0.08) 100%)', + transform: 'translateX(4px)', + boxShadow: '0 4px 16px rgba(99,102,241,0.1)', }, }} > @@ -587,13 +686,30 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { {results.length >= 5 && ( - - + { saveRecentSearch(query); @@ -601,8 +717,20 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { navigate(`/search?q=${encodeURIComponent(query)}`); }} > - View all results for "{query}" - + + View all results for "{query}" + + )} @@ -610,8 +738,18 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { {!query && recentSearches.length > 0 && ( <> - - + + Recent Searches @@ -622,10 +760,15 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { component="div" onClick={() => handleRecentSearchClick(search)} sx={{ - py: 1, + py: 1.5, cursor: 'pointer', + borderRadius: 2, + mx: 1, + transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)', '&:hover': { - backgroundColor: 'action.hover', + background: 'linear-gradient(135deg, rgba(99,102,241,0.08) 0%, rgba(139,92,246,0.08) 100%)', + transform: 'translateX(4px)', + boxShadow: '0 4px 16px rgba(99,102,241,0.1)', }, }} > @@ -646,11 +789,28 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { )} {!query && recentSearches.length === 0 && ( - - + + Start typing to search documents - + Popular searches: @@ -664,9 +824,16 @@ const GlobalSearchBar: React.FC = ({ sx, ...props }) => { onClick={() => handlePopularSearchClick(search)} sx={{ fontSize: '0.75rem', + fontWeight: 500, + border: '1px solid rgba(99,102,241,0.3)', + background: 'linear-gradient(135deg, rgba(255,255,255,0.8) 0%, rgba(248,250,252,0.6) 100%)', + backdropFilter: 'blur(10px)', + transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)', '&:hover': { - backgroundColor: 'primary.light', - color: 'primary.contrastText', + background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', + color: 'white', + transform: 'translateY(-2px)', + boxShadow: '0 8px 24px rgba(99,102,241,0.2)', } }} /> diff --git a/frontend/src/components/Layout/AppLayout.tsx b/frontend/src/components/Layout/AppLayout.tsx index 7dadafb..bb76449 100644 --- a/frontend/src/components/Layout/AppLayout.tsx +++ b/frontend/src/components/Layout/AppLayout.tsx @@ -89,66 +89,145 @@ const AppLayout: React.FC = ({ children }) => { }; const drawer = ( - + {/* Logo Section */} - + - R + R + + + + Readur + + + AI Document Platform + - - Readur - - - Document Intelligence Platform - {/* Navigation */} - + {navigationItems.map((item) => { const isActive = location.pathname === item.path; const Icon = item.icon; return ( - + navigate(item.path)} sx={{ - borderRadius: 2, - minHeight: 48, - backgroundColor: isActive ? 'primary.main' : 'transparent', - color: isActive ? 'primary.contrastText' : 'text.primary', + borderRadius: 3, + minHeight: 52, + px: 2.5, + py: 1.5, + background: isActive + ? 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)' + : 'transparent', + color: isActive ? 'white' : 'text.primary', + position: 'relative', + overflow: 'hidden', + transition: 'all 0.2s ease-in-out', '&:hover': { - backgroundColor: isActive ? 'primary.dark' : 'action.hover', + backgroundColor: isActive ? 'transparent' : 'rgba(99,102,241,0.08)', + transform: isActive ? 'none' : 'translateX(4px)', + '&::before': isActive ? {} : { + content: '""', + position: 'absolute', + left: 0, + top: 0, + bottom: 0, + width: '3px', + background: 'linear-gradient(180deg, #6366f1 0%, #8b5cf6 100%)', + borderRadius: '0 2px 2px 0', + }, }, + '&::after': isActive ? { + content: '""', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + background: 'linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%)', + backdropFilter: 'blur(10px)', + } : {}, '& .MuiListItemIcon-root': { - color: isActive ? 'primary.contrastText' : 'text.secondary', + color: isActive ? 'white' : 'text.secondary', + minWidth: 36, + position: 'relative', + zIndex: 1, }, + '& .MuiListItemText-root': { + position: 'relative', + zIndex: 1, + }, + ...(isActive && { + boxShadow: '0 8px 32px rgba(99,102,241,0.3)', + }), }} > - - + + @@ -158,20 +237,40 @@ const AppLayout: React.FC = ({ children }) => { {/* User Info */} - - + + {user?.username?.charAt(0).toUpperCase()} - + {user?.username} = ({ children }) => { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', + fontSize: '0.75rem', + fontWeight: 500, }} > {user?.email} @@ -202,6 +303,10 @@ const AppLayout: React.FC = ({ children }) => { sx={{ width: { md: `calc(100% - ${drawerWidth}px)` }, ml: { md: `${drawerWidth}px` }, + background: 'linear-gradient(135deg, rgba(255,255,255,0.95) 0%, rgba(248,250,252,0.90) 100%)', + backdropFilter: 'blur(20px)', + borderBottom: '1px solid rgba(226,232,240,0.5)', + boxShadow: '0 4px 32px rgba(0,0,0,0.04)', }} > @@ -215,29 +320,77 @@ const AppLayout: React.FC = ({ children }) => { - + {navigationItems.find(item => item.path === location.pathname)?.text || 'Dashboard'} {/* Global Search Bar */} - + {/* Notifications */} - - - + + + {/* Profile Menu */} - +