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