feat(frontend): visual design overhaul — Inter font, softer cards/shadows, red-themed profile banner, modern typography hierarchy, and refreshed color palette
This commit is contained in:
@@ -129,8 +129,8 @@ export function DataTable<T>({
|
||||
return (
|
||||
<Paper>
|
||||
{showToolbar && (
|
||||
<Box sx={{ p: 2, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2 }}>
|
||||
{title && <Typography variant="h6">{title}</Typography>}
|
||||
<Box sx={{ px: 2.5, py: 2, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2 }}>
|
||||
{title && <Typography variant="h6" fontWeight={700}>{title}</Typography>}
|
||||
<Box sx={{ flex: 1 }} />
|
||||
{searchEnabled && (
|
||||
<TextField
|
||||
@@ -138,11 +138,11 @@ export function DataTable<T>({
|
||||
placeholder={searchPlaceholder}
|
||||
value={search}
|
||||
onChange={(e) => { setSearch(e.target.value); setPage(0); }}
|
||||
sx={{ maxWidth: 300 }}
|
||||
sx={{ maxWidth: 280, '& .MuiOutlinedInput-root': { bgcolor: 'rgba(0,0,0,0.02)' } }}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon fontSize="small" />
|
||||
<SearchIcon fontSize="small" sx={{ color: 'text.disabled' }} />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -30,29 +30,32 @@ export const StatCard: React.FC<StatCardProps> = ({
|
||||
) : (
|
||||
<Box display="flex" alignItems="center">
|
||||
<Box sx={{ flex: GOLDEN_RATIO }}>
|
||||
<Typography variant="caption" textTransform="uppercase" color="text.secondary">
|
||||
<Typography variant="caption" textTransform="uppercase" color="text.secondary" sx={{ letterSpacing: '0.06em', fontWeight: 600 }}>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography variant="h4" fontWeight={700}>
|
||||
<Typography variant="h3" fontWeight={800} sx={{ lineHeight: 1.1, mt: 0.5, letterSpacing: '-0.02em' }}>
|
||||
{value}
|
||||
</Typography>
|
||||
{trend && (
|
||||
<Typography
|
||||
variant="caption"
|
||||
color={trend.value >= 0 ? 'success.main' : 'error.main'}
|
||||
>
|
||||
{trend.value >= 0 ? '↑' : '↓'} {Math.abs(trend.value)}%
|
||||
{trend.label && ` ${trend.label}`}
|
||||
</Typography>
|
||||
<Box sx={{ display: 'inline-flex', alignItems: 'center', mt: 1, px: 1, py: 0.25, borderRadius: 1, bgcolor: trend.value >= 0 ? 'rgba(34,197,94,0.1)' : 'rgba(239,68,68,0.1)' }}>
|
||||
<Typography
|
||||
variant="caption"
|
||||
fontWeight={600}
|
||||
color={trend.value >= 0 ? 'success.main' : 'error.main'}
|
||||
>
|
||||
{trend.value >= 0 ? '↑' : '↓'} {Math.abs(trend.value)}%
|
||||
{trend.label && ` ${trend.label}`}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
<Box sx={{ flex: 1, display: 'flex', justifyContent: 'center' }}>
|
||||
<Box
|
||||
sx={{
|
||||
width: 56,
|
||||
height: 56,
|
||||
borderRadius: '50%',
|
||||
bgcolor: `${color}15`,
|
||||
width: 52,
|
||||
height: 52,
|
||||
borderRadius: 3,
|
||||
bgcolor: `${color}12`,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
Card,
|
||||
CardActionArea,
|
||||
CardContent,
|
||||
Divider,
|
||||
Skeleton,
|
||||
Typography,
|
||||
Alert,
|
||||
@@ -52,16 +51,24 @@ export const WidgetCard: React.FC<WidgetCardProps> = ({
|
||||
<Box
|
||||
sx={noPadding ? { px: 2.5, pt: 2.5 } : undefined}
|
||||
>
|
||||
<Box display="flex" alignItems="center" justifyContent="space-between" mb={2}>
|
||||
<Box display="flex" alignItems="center" gap={1}>
|
||||
{icon}
|
||||
<Typography variant="subtitle1" fontWeight={600}>
|
||||
<Box
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
mb={1.5}
|
||||
>
|
||||
<Box display="flex" alignItems="center" gap={0.75}>
|
||||
{icon && (
|
||||
<Box sx={{ color: 'text.secondary', display: 'flex', alignItems: 'center', '& > *': { fontSize: '1.1rem' } }}>
|
||||
{icon}
|
||||
</Box>
|
||||
)}
|
||||
<Typography variant="subtitle2" fontWeight={600} color="text.secondary" sx={{ textTransform: 'uppercase', fontSize: '0.6875rem', letterSpacing: '0.06em' }}>
|
||||
{title}
|
||||
</Typography>
|
||||
</Box>
|
||||
{action}
|
||||
</Box>
|
||||
<Divider sx={{ mb: 2 }} />
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -113,8 +120,7 @@ export const WidgetCard: React.FC<WidgetCardProps> = ({
|
||||
</Box>
|
||||
{footer && (
|
||||
<>
|
||||
<Divider sx={{ mt: 2 }} />
|
||||
<Box sx={{ pt: 1.5, ...(noPadding ? { px: 2.5, pb: 2.5 } : {}) }}>
|
||||
<Box sx={{ mt: 2, pt: 1.5, borderTop: '1px solid', borderColor: 'divider', ...(noPadding ? { mx: 2.5, pb: 2.5 } : {}) }}>
|
||||
{footer}
|
||||
</Box>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user