parent
e430cb6a3a
commit
b21e00fc79
@ -0,0 +1,314 @@ |
||||
import { useState } from 'react'; |
||||
import type { ReactNode } from 'react'; |
||||
import { useLocation, useNavigate } from 'react-router-dom'; |
||||
import { |
||||
Box, |
||||
Drawer, |
||||
AppBar, |
||||
Toolbar, |
||||
List, |
||||
Typography, |
||||
Divider, |
||||
IconButton, |
||||
ListItem, |
||||
ListItemButton, |
||||
ListItemIcon, |
||||
ListItemText, |
||||
useTheme, |
||||
useMediaQuery, |
||||
Avatar, |
||||
Menu, |
||||
MenuItem, |
||||
Badge, |
||||
} from '@mui/material'; |
||||
import { |
||||
Menu as MenuIcon, |
||||
People, |
||||
QrCode, |
||||
PersonAdd, |
||||
CloudDownload, |
||||
Settings, |
||||
Logout, |
||||
NotificationsNone, |
||||
SearchRounded, |
||||
} from '@mui/icons-material'; |
||||
|
||||
const drawerWidth = 280; |
||||
|
||||
interface NavItem { |
||||
text: string; |
||||
icon: ReactNode; |
||||
path: string; |
||||
badge?: number; |
||||
} |
||||
|
||||
interface DashboardLayoutProps { |
||||
children: ReactNode; |
||||
} |
||||
|
||||
const DashboardLayout = ({ children }: DashboardLayoutProps) => { |
||||
const theme = useTheme(); |
||||
const isMobile = useMediaQuery(theme.breakpoints.down('lg')); |
||||
const [mobileOpen, setMobileOpen] = useState(false); |
||||
const [profileMenuAnchor, setProfileMenuAnchor] = useState<null | HTMLElement>(null); |
||||
const location = useLocation(); |
||||
const navigate = useNavigate(); |
||||
|
||||
const navItems: NavItem[] = [ |
||||
{ text: 'Contacts', icon: <People />, path: '/contacts' }, |
||||
{ text: 'Import', icon: <CloudDownload />, path: '/' }, |
||||
{ text: 'Invite', icon: <QrCode />, path: '/invite' }, |
||||
{ text: 'Join Network', icon: <PersonAdd />, path: '/onboarding' }, |
||||
]; |
||||
|
||||
const handleDrawerToggle = () => { |
||||
setMobileOpen(!mobileOpen); |
||||
}; |
||||
|
||||
const handleProfileMenuOpen = (event: React.MouseEvent<HTMLElement>) => { |
||||
setProfileMenuAnchor(event.currentTarget); |
||||
}; |
||||
|
||||
const handleProfileMenuClose = () => { |
||||
setProfileMenuAnchor(null); |
||||
}; |
||||
|
||||
const handleNavigation = (path: string) => { |
||||
navigate(path); |
||||
if (isMobile) { |
||||
setMobileOpen(false); |
||||
} |
||||
}; |
||||
|
||||
const isActiveRoute = (path: string) => { |
||||
if (path === '/' && location.pathname === '/') return true; |
||||
if (path !== '/' && location.pathname.startsWith(path)) return true; |
||||
return false; |
||||
}; |
||||
|
||||
const drawerContent = ( |
||||
<Box sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}> |
||||
<Box sx={{ p: 3, borderBottom: 1, borderColor: 'divider' }}> |
||||
<Typography variant="h6" sx={{ fontWeight: 700, color: 'primary.main' }}> |
||||
Network Manager |
||||
</Typography> |
||||
<Typography variant="body2" color="text.secondary"> |
||||
Personal Network Hub |
||||
</Typography> |
||||
</Box> |
||||
|
||||
<List sx={{ flex: 1, py: 2 }}> |
||||
{navItems.map((item) => ( |
||||
<ListItem key={item.text} disablePadding> |
||||
<ListItemButton |
||||
onClick={() => handleNavigation(item.path)} |
||||
selected={isActiveRoute(item.path)} |
||||
sx={{ |
||||
mx: 1, |
||||
borderRadius: 2, |
||||
minHeight: 48, |
||||
'&.Mui-selected': { |
||||
backgroundColor: 'primary.main', |
||||
color: 'primary.contrastText', |
||||
'&:hover': { |
||||
backgroundColor: 'primary.dark', |
||||
}, |
||||
'& .MuiListItemIcon-root': { |
||||
color: 'primary.contrastText', |
||||
}, |
||||
}, |
||||
}} |
||||
> |
||||
<ListItemIcon sx={{ minWidth: 40 }}> |
||||
{item.badge ? ( |
||||
<Badge badgeContent={item.badge} color="error"> |
||||
{item.icon} |
||||
</Badge> |
||||
) : ( |
||||
item.icon |
||||
)} |
||||
</ListItemIcon> |
||||
<ListItemText
|
||||
primary={item.text} |
||||
primaryTypographyProps={{ |
||||
fontSize: '0.875rem', |
||||
fontWeight: isActiveRoute(item.path) ? 600 : 500, |
||||
}} |
||||
/> |
||||
</ListItemButton> |
||||
</ListItem> |
||||
))} |
||||
</List> |
||||
|
||||
<Divider /> |
||||
|
||||
<List sx={{ py: 2 }}> |
||||
<ListItem disablePadding> |
||||
<ListItemButton |
||||
onClick={() => handleNavigation('/settings')} |
||||
sx={{ |
||||
mx: 1, |
||||
borderRadius: 2, |
||||
minHeight: 48, |
||||
}} |
||||
> |
||||
<ListItemIcon sx={{ minWidth: 40 }}> |
||||
<Settings /> |
||||
</ListItemIcon> |
||||
<ListItemText
|
||||
primary="Settings" |
||||
primaryTypographyProps={{ |
||||
fontSize: '0.875rem', |
||||
fontWeight: 500, |
||||
}} |
||||
/> |
||||
</ListItemButton> |
||||
</ListItem> |
||||
</List> |
||||
</Box> |
||||
); |
||||
|
||||
return ( |
||||
<Box sx={{ display: 'flex', height: '100vh' }}> |
||||
<AppBar |
||||
position="fixed" |
||||
sx={{ |
||||
width: { lg: `calc(100% - ${drawerWidth}px)` }, |
||||
ml: { lg: `${drawerWidth}px` }, |
||||
backgroundColor: 'background.paper', |
||||
borderBottom: 1, |
||||
borderColor: 'divider', |
||||
boxShadow: 'none', |
||||
}} |
||||
> |
||||
<Toolbar sx={{ justifyContent: 'space-between' }}> |
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}> |
||||
<IconButton |
||||
color="inherit" |
||||
aria-label="open drawer" |
||||
edge="start" |
||||
onClick={handleDrawerToggle} |
||||
sx={{ mr: 2, display: { lg: 'none' } }} |
||||
> |
||||
<MenuIcon /> |
||||
</IconButton> |
||||
</Box> |
||||
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}> |
||||
<IconButton size="large" color="inherit"> |
||||
<SearchRounded /> |
||||
</IconButton> |
||||
<IconButton size="large" color="inherit"> |
||||
<Badge badgeContent={3} color="error"> |
||||
<NotificationsNone /> |
||||
</Badge> |
||||
</IconButton> |
||||
<IconButton |
||||
size="large" |
||||
edge="end" |
||||
aria-label="account of current user" |
||||
aria-haspopup="true" |
||||
onClick={handleProfileMenuOpen} |
||||
color="inherit" |
||||
> |
||||
<Avatar |
||||
sx={{ width: 32, height: 32 }} |
||||
alt="Profile" |
||||
src="/static/images/avatar/2.jpg" |
||||
> |
||||
U |
||||
</Avatar> |
||||
</IconButton> |
||||
</Box> |
||||
</Toolbar> |
||||
</AppBar> |
||||
|
||||
<Box |
||||
component="nav" |
||||
sx={{ width: { lg: drawerWidth }, flexShrink: { lg: 0 } }} |
||||
> |
||||
<Drawer |
||||
variant={isMobile ? 'temporary' : 'permanent'} |
||||
open={isMobile ? mobileOpen : true} |
||||
onClose={handleDrawerToggle} |
||||
ModalProps={{ |
||||
keepMounted: true, |
||||
}} |
||||
sx={{ |
||||
'& .MuiDrawer-paper': { |
||||
boxSizing: 'border-box', |
||||
width: drawerWidth, |
||||
borderRight: 1, |
||||
borderColor: 'divider', |
||||
}, |
||||
}} |
||||
> |
||||
{drawerContent} |
||||
</Drawer> |
||||
</Box> |
||||
|
||||
<Box |
||||
component="main" |
||||
sx={{ |
||||
flexGrow: 1, |
||||
width: { lg: `calc(100% - ${drawerWidth}px)` }, |
||||
minHeight: '100vh', |
||||
backgroundColor: 'background.default', |
||||
}} |
||||
> |
||||
<Toolbar /> |
||||
<Box sx={{ p: 3, height: 'calc(100vh - 64px)', overflow: 'auto' }}> |
||||
{children} |
||||
</Box> |
||||
</Box> |
||||
|
||||
<Menu |
||||
anchorEl={profileMenuAnchor} |
||||
open={Boolean(profileMenuAnchor)} |
||||
onClose={handleProfileMenuClose} |
||||
onClick={handleProfileMenuClose} |
||||
PaperProps={{ |
||||
elevation: 0, |
||||
sx: { |
||||
overflow: 'visible', |
||||
filter: 'drop-shadow(0px 2px 8px rgba(0,0,0,0.32))', |
||||
mt: 1.5, |
||||
'& .MuiAvatar-root': { |
||||
width: 32, |
||||
height: 32, |
||||
ml: -0.5, |
||||
mr: 1, |
||||
}, |
||||
'&::before': { |
||||
content: '""', |
||||
display: 'block', |
||||
position: 'absolute', |
||||
top: 0, |
||||
right: 14, |
||||
width: 10, |
||||
height: 10, |
||||
bgcolor: 'background.paper', |
||||
transform: 'translateY(-50%) rotate(45deg)', |
||||
zIndex: 0, |
||||
}, |
||||
}, |
||||
}} |
||||
transformOrigin={{ horizontal: 'right', vertical: 'top' }} |
||||
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} |
||||
> |
||||
<MenuItem onClick={handleProfileMenuClose}> |
||||
<Avatar /> My Profile |
||||
</MenuItem> |
||||
<MenuItem onClick={handleProfileMenuClose}> |
||||
<Settings sx={{ mr: 1 }} /> Settings |
||||
</MenuItem> |
||||
<Divider /> |
||||
<MenuItem onClick={handleProfileMenuClose}> |
||||
<Logout sx={{ mr: 1 }} /> Logout |
||||
</MenuItem> |
||||
</Menu> |
||||
</Box> |
||||
); |
||||
}; |
||||
|
||||
export default DashboardLayout; |
@ -0,0 +1,384 @@ |
||||
import { createTheme, alpha } from '@mui/material/styles'; |
||||
import type { PaletteMode } from '@mui/material'; |
||||
|
||||
// Custom color palette inspired by professional dashboards
|
||||
const colors = { |
||||
primary: { |
||||
50: '#e8f4fd', |
||||
100: '#d1e9fb', |
||||
200: '#a3d2f7', |
||||
300: '#75bcf3', |
||||
400: '#47a5ef', |
||||
500: '#1976d2', // Main brand color
|
||||
600: '#155a9f', |
||||
700: '#10436c', |
||||
800: '#0a2d39', |
||||
900: '#051616', |
||||
}, |
||||
secondary: { |
||||
50: '#fce4ec', |
||||
100: '#f8bbd9', |
||||
200: '#f48fb1', |
||||
300: '#f06292', |
||||
400: '#ec407a', |
||||
500: '#dc004e', // Accent color
|
||||
600: '#c2185b', |
||||
700: '#ad1457', |
||||
800: '#880e4f', |
||||
900: '#560e2e', |
||||
}, |
||||
neutral: { |
||||
50: '#fafafa', |
||||
100: '#f5f5f5', |
||||
200: '#eeeeee', |
||||
300: '#e0e0e0', |
||||
400: '#bdbdbd', |
||||
500: '#9e9e9e', |
||||
600: '#757575', |
||||
700: '#616161', |
||||
800: '#424242', |
||||
900: '#212121', |
||||
}, |
||||
success: { |
||||
50: '#e8f5e8', |
||||
100: '#c8e6c9', |
||||
200: '#a5d6a7', |
||||
300: '#81c784', |
||||
400: '#66bb6a', |
||||
500: '#4caf50', |
||||
600: '#43a047', |
||||
700: '#388e3c', |
||||
800: '#2e7d32', |
||||
900: '#1b5e20', |
||||
}, |
||||
warning: { |
||||
50: '#fff8e1', |
||||
100: '#ffecb3', |
||||
200: '#ffe082', |
||||
300: '#ffd54f', |
||||
400: '#ffca28', |
||||
500: '#ffc107', |
||||
600: '#ffb300', |
||||
700: '#ffa000', |
||||
800: '#ff8f00', |
||||
900: '#ff6f00', |
||||
}, |
||||
error: { |
||||
50: '#ffebee', |
||||
100: '#ffcdd2', |
||||
200: '#ef9a9a', |
||||
300: '#e57373', |
||||
400: '#ef5350', |
||||
500: '#f44336', |
||||
600: '#e53935', |
||||
700: '#d32f2f', |
||||
800: '#c62828', |
||||
900: '#b71c1c', |
||||
}, |
||||
}; |
||||
|
||||
// Enhanced theme configuration
|
||||
export const createAppTheme = (mode: PaletteMode) => { |
||||
const isDark = mode === 'dark'; |
||||
|
||||
return createTheme({ |
||||
palette: { |
||||
mode, |
||||
primary: { |
||||
main: colors.primary[500], |
||||
light: colors.primary[300], |
||||
dark: colors.primary[700], |
||||
contrastText: '#ffffff', |
||||
}, |
||||
secondary: { |
||||
main: colors.secondary[500], |
||||
light: colors.secondary[300], |
||||
dark: colors.secondary[700], |
||||
contrastText: '#ffffff', |
||||
}, |
||||
success: { |
||||
main: colors.success[500], |
||||
light: colors.success[300], |
||||
dark: colors.success[700], |
||||
}, |
||||
warning: { |
||||
main: colors.warning[500], |
||||
light: colors.warning[300], |
||||
dark: colors.warning[700], |
||||
}, |
||||
error: { |
||||
main: colors.error[500], |
||||
light: colors.error[300], |
||||
dark: colors.error[700], |
||||
}, |
||||
background: { |
||||
default: isDark ? '#0a1929' : '#f8fafc', |
||||
paper: isDark ? '#1e293b' : '#ffffff', |
||||
}, |
||||
text: { |
||||
primary: isDark ? '#e2e8f0' : '#334155', |
||||
secondary: isDark ? '#94a3b8' : '#64748b', |
||||
}, |
||||
divider: isDark ? alpha('#e2e8f0', 0.08) : alpha('#334155', 0.08), |
||||
action: { |
||||
hover: isDark ? alpha('#e2e8f0', 0.04) : alpha('#334155', 0.04), |
||||
selected: isDark ? alpha('#e2e8f0', 0.08) : alpha('#334155', 0.08), |
||||
}, |
||||
}, |
||||
typography: { |
||||
fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif', |
||||
h1: { |
||||
fontSize: '2.5rem', |
||||
fontWeight: 700, |
||||
lineHeight: 1.2, |
||||
letterSpacing: '-0.02em', |
||||
}, |
||||
h2: { |
||||
fontSize: '2rem', |
||||
fontWeight: 600, |
||||
lineHeight: 1.3, |
||||
letterSpacing: '-0.01em', |
||||
}, |
||||
h3: { |
||||
fontSize: '1.75rem', |
||||
fontWeight: 600, |
||||
lineHeight: 1.3, |
||||
letterSpacing: '-0.01em', |
||||
}, |
||||
h4: { |
||||
fontSize: '1.5rem', |
||||
fontWeight: 600, |
||||
lineHeight: 1.4, |
||||
letterSpacing: '-0.005em', |
||||
}, |
||||
h5: { |
||||
fontSize: '1.25rem', |
||||
fontWeight: 600, |
||||
lineHeight: 1.4, |
||||
}, |
||||
h6: { |
||||
fontSize: '1.125rem', |
||||
fontWeight: 600, |
||||
lineHeight: 1.4, |
||||
}, |
||||
subtitle1: { |
||||
fontSize: '1rem', |
||||
fontWeight: 500, |
||||
lineHeight: 1.5, |
||||
}, |
||||
subtitle2: { |
||||
fontSize: '0.875rem', |
||||
fontWeight: 500, |
||||
lineHeight: 1.5, |
||||
}, |
||||
body1: { |
||||
fontSize: '1rem', |
||||
fontWeight: 400, |
||||
lineHeight: 1.6, |
||||
}, |
||||
body2: { |
||||
fontSize: '0.875rem', |
||||
fontWeight: 400, |
||||
lineHeight: 1.6, |
||||
}, |
||||
button: { |
||||
fontSize: '0.875rem', |
||||
fontWeight: 500, |
||||
lineHeight: 1.5, |
||||
textTransform: 'none' as const, |
||||
}, |
||||
caption: { |
||||
fontSize: '0.75rem', |
||||
fontWeight: 400, |
||||
lineHeight: 1.5, |
||||
}, |
||||
overline: { |
||||
fontSize: '0.75rem', |
||||
fontWeight: 500, |
||||
lineHeight: 1.5, |
||||
textTransform: 'uppercase' as const, |
||||
letterSpacing: '0.08em', |
||||
}, |
||||
}, |
||||
spacing: 8, |
||||
shape: { |
||||
borderRadius: 12, |
||||
}, |
||||
shadows: [ |
||||
'none', |
||||
'0px 1px 3px rgba(0, 0, 0, 0.04), 0px 1px 2px rgba(0, 0, 0, 0.06)', |
||||
'0px 2px 4px rgba(0, 0, 0, 0.04), 0px 2px 3px rgba(0, 0, 0, 0.06)', |
||||
'0px 3px 6px rgba(0, 0, 0, 0.04), 0px 3px 4px rgba(0, 0, 0, 0.06)', |
||||
'0px 4px 8px rgba(0, 0, 0, 0.04), 0px 4px 6px rgba(0, 0, 0, 0.06)', |
||||
'0px 6px 12px rgba(0, 0, 0, 0.04), 0px 6px 8px rgba(0, 0, 0, 0.06)', |
||||
'0px 8px 16px rgba(0, 0, 0, 0.04), 0px 8px 12px rgba(0, 0, 0, 0.06)', |
||||
'0px 12px 24px rgba(0, 0, 0, 0.04), 0px 12px 18px rgba(0, 0, 0, 0.06)', |
||||
'0px 16px 32px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.06)', |
||||
'0px 24px 48px rgba(0, 0, 0, 0.04), 0px 24px 36px rgba(0, 0, 0, 0.06)', |
||||
'0px 32px 64px rgba(0, 0, 0, 0.04), 0px 32px 48px rgba(0, 0, 0, 0.06)', |
||||
'0px 40px 80px rgba(0, 0, 0, 0.04), 0px 40px 60px rgba(0, 0, 0, 0.06)', |
||||
'0px 48px 96px rgba(0, 0, 0, 0.04), 0px 48px 72px rgba(0, 0, 0, 0.06)', |
||||
'0px 56px 112px rgba(0, 0, 0, 0.04), 0px 56px 84px rgba(0, 0, 0, 0.06)', |
||||
'0px 64px 128px rgba(0, 0, 0, 0.04), 0px 64px 96px rgba(0, 0, 0, 0.06)', |
||||
'0px 72px 144px rgba(0, 0, 0, 0.04), 0px 72px 108px rgba(0, 0, 0, 0.06)', |
||||
'0px 80px 160px rgba(0, 0, 0, 0.04), 0px 80px 120px rgba(0, 0, 0, 0.06)', |
||||
'0px 88px 176px rgba(0, 0, 0, 0.04), 0px 88px 132px rgba(0, 0, 0, 0.06)', |
||||
'0px 96px 192px rgba(0, 0, 0, 0.04), 0px 96px 144px rgba(0, 0, 0, 0.06)', |
||||
'0px 104px 208px rgba(0, 0, 0, 0.04), 0px 104px 156px rgba(0, 0, 0, 0.06)', |
||||
'0px 112px 224px rgba(0, 0, 0, 0.04), 0px 112px 168px rgba(0, 0, 0, 0.06)', |
||||
'0px 120px 240px rgba(0, 0, 0, 0.04), 0px 120px 180px rgba(0, 0, 0, 0.06)', |
||||
'0px 128px 256px rgba(0, 0, 0, 0.04), 0px 128px 192px rgba(0, 0, 0, 0.06)', |
||||
'0px 136px 272px rgba(0, 0, 0, 0.04), 0px 136px 204px rgba(0, 0, 0, 0.06)', |
||||
'0px 144px 288px rgba(0, 0, 0, 0.04), 0px 144px 216px rgba(0, 0, 0, 0.06)', |
||||
], |
||||
components: { |
||||
MuiCssBaseline: { |
||||
styleOverrides: { |
||||
'*': { |
||||
boxSizing: 'border-box', |
||||
}, |
||||
html: { |
||||
MozOsxFontSmoothing: 'grayscale', |
||||
WebkitFontSmoothing: 'antialiased', |
||||
display: 'flex', |
||||
flexDirection: 'column', |
||||
minHeight: '100%', |
||||
width: '100%', |
||||
}, |
||||
body: { |
||||
display: 'flex', |
||||
flex: '1 1 auto', |
||||
flexDirection: 'column', |
||||
minHeight: '100%', |
||||
width: '100%', |
||||
}, |
||||
'#root': { |
||||
display: 'flex', |
||||
flex: '1 1 auto', |
||||
flexDirection: 'column', |
||||
height: '100%', |
||||
width: '100%', |
||||
}, |
||||
}, |
||||
}, |
||||
MuiButton: { |
||||
styleOverrides: { |
||||
root: { |
||||
borderRadius: 8, |
||||
padding: '8px 16px', |
||||
fontWeight: 500, |
||||
fontSize: '0.875rem', |
||||
lineHeight: 1.5, |
||||
textTransform: 'none', |
||||
boxShadow: 'none', |
||||
'&:hover': { |
||||
boxShadow: 'none', |
||||
}, |
||||
'&:active': { |
||||
boxShadow: 'none', |
||||
}, |
||||
}, |
||||
contained: { |
||||
'&:hover': { |
||||
boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.08), 0px 2px 3px rgba(0, 0, 0, 0.12)', |
||||
}, |
||||
}, |
||||
}, |
||||
}, |
||||
MuiCard: { |
||||
styleOverrides: { |
||||
root: { |
||||
borderRadius: 12, |
||||
boxShadow: '0px 1px 3px rgba(0, 0, 0, 0.04), 0px 1px 2px rgba(0, 0, 0, 0.06)', |
||||
border: `1px solid ${isDark ? alpha('#e2e8f0', 0.08) : alpha('#334155', 0.08)}`, |
||||
'&:hover': { |
||||
boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.08), 0px 4px 6px rgba(0, 0, 0, 0.12)', |
||||
}, |
||||
}, |
||||
}, |
||||
}, |
||||
MuiPaper: { |
||||
styleOverrides: { |
||||
root: { |
||||
borderRadius: 12, |
||||
border: `1px solid ${isDark ? alpha('#e2e8f0', 0.08) : alpha('#334155', 0.08)}`, |
||||
}, |
||||
}, |
||||
}, |
||||
MuiTextField: { |
||||
styleOverrides: { |
||||
root: { |
||||
'& .MuiOutlinedInput-root': { |
||||
borderRadius: 8, |
||||
backgroundColor: isDark ? alpha('#e2e8f0', 0.02) : alpha('#334155', 0.02), |
||||
'&:hover': { |
||||
backgroundColor: isDark ? alpha('#e2e8f0', 0.04) : alpha('#334155', 0.04), |
||||
}, |
||||
'&.Mui-focused': { |
||||
backgroundColor: isDark ? alpha('#e2e8f0', 0.04) : alpha('#334155', 0.04), |
||||
}, |
||||
}, |
||||
}, |
||||
}, |
||||
}, |
||||
MuiAppBar: { |
||||
styleOverrides: { |
||||
root: { |
||||
backgroundColor: isDark ? '#1e293b' : '#ffffff', |
||||
color: isDark ? '#e2e8f0' : '#334155', |
||||
boxShadow: 'none', |
||||
borderBottom: `1px solid ${isDark ? alpha('#e2e8f0', 0.08) : alpha('#334155', 0.08)}`, |
||||
}, |
||||
}, |
||||
}, |
||||
MuiDrawer: { |
||||
styleOverrides: { |
||||
paper: { |
||||
backgroundColor: isDark ? '#0f172a' : '#ffffff', |
||||
borderRight: `1px solid ${isDark ? alpha('#e2e8f0', 0.08) : alpha('#334155', 0.08)}`, |
||||
}, |
||||
}, |
||||
}, |
||||
MuiListItem: { |
||||
styleOverrides: { |
||||
root: { |
||||
borderRadius: 8, |
||||
margin: '2px 8px', |
||||
'&:hover': { |
||||
backgroundColor: isDark ? alpha('#e2e8f0', 0.04) : alpha('#334155', 0.04), |
||||
}, |
||||
'&.Mui-selected': { |
||||
backgroundColor: isDark ? alpha('#1976d2', 0.12) : alpha('#1976d2', 0.08), |
||||
'&:hover': { |
||||
backgroundColor: isDark ? alpha('#1976d2', 0.16) : alpha('#1976d2', 0.12), |
||||
}, |
||||
}, |
||||
}, |
||||
}, |
||||
}, |
||||
MuiTabs: { |
||||
styleOverrides: { |
||||
indicator: { |
||||
borderRadius: 2, |
||||
height: 3, |
||||
}, |
||||
}, |
||||
}, |
||||
MuiTab: { |
||||
styleOverrides: { |
||||
root: { |
||||
textTransform: 'none', |
||||
fontWeight: 500, |
||||
fontSize: '0.875rem', |
||||
minHeight: 48, |
||||
'&.Mui-selected': { |
||||
fontWeight: 600, |
||||
}, |
||||
}, |
||||
}, |
||||
}, |
||||
}, |
||||
}); |
||||
}; |
||||
|
||||
export default createAppTheme; |
Loading…
Reference in new issue