style(ui): update sidebar width to 230px and refactor StatCard layout
This commit is contained in:
+2
-2
@@ -123,7 +123,7 @@ Les ombres existent uniquement pour les éléments qui **flottent au-dessus** de
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Sidebar 240px │ Barre supérieure 48px │
|
||||
│ Sidebar 230px │ Barre supérieure 48px │
|
||||
│ ├─────────────────────────── │
|
||||
│ Logo │ │
|
||||
│ │ Zone de contenu │
|
||||
@@ -134,7 +134,7 @@ Les ombres existent uniquement pour les éléments qui **flottent au-dessus** de
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- **Sidebar** : fixe, 240px. Fond blanc (`#ffffff`). Séparée par une bordure droite.
|
||||
- **Sidebar** : fixe, 230px. Fond blanc (`#ffffff`). Séparée par une bordure droite.
|
||||
- **Barre supérieure** : fixe, 48px. Fond blanc. Fil d'Ariane à gauche, utilisateur à droite.
|
||||
- **Contenu** : gris très pâle (`#fafafa` / `neutral-50`). Les cartes et tableaux ont un fond blanc, ce qui crée naturellement la séparation visuelle sans avoir besoin de bordures de section.
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ const AdminSidebar = ({ isMobileMenuOpen, setIsMobileMenuOpen, appName, enabledM
|
||||
{/* Sidebar */}
|
||||
<div className={`
|
||||
${isMobileMenuOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'}
|
||||
fixed lg:static inset-y-0 left-0 z-40 w-[240px] bg-white dark:bg-black border-r border-neutral-200 dark:border-neutral-800/70 flex flex-col h-screen transition-transform duration-[120ms] ease-out
|
||||
fixed lg:static inset-y-0 left-0 z-40 w-[230px] bg-white dark:bg-black border-r border-neutral-200 dark:border-neutral-800/70 flex flex-col h-screen transition-transform duration-[120ms] ease-out
|
||||
`}>
|
||||
{/* Logo */}
|
||||
<Link href="/admin" className="px-4 h-12 flex items-center justify-start gap-2 border-b border-neutral-200 dark:border-neutral-800/70">
|
||||
|
||||
@@ -14,64 +14,44 @@ const StatCard = ({
|
||||
className = '',
|
||||
...props
|
||||
}) => {
|
||||
const TrendIcon = ({ type }) => (
|
||||
<svg className="h-3 w-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d={type === 'increase'
|
||||
? "M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"
|
||||
: "M13 17h8m0 0V9m0 8l-8-8-4 4-6-6"
|
||||
}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
const deltaColor = changeType === 'increase' ? 'text-green-400' : 'text-red-400';
|
||||
const arrow = changeType === 'increase' ? '↑' : '↓';
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`bg-white dark:bg-neutral-900/40 border border-neutral-200 dark:border-neutral-800/50 rounded-md px-5 py-4 transition-all duration-[120ms] ease-out ${className}`}
|
||||
<div
|
||||
className={`bg-white dark:bg-neutral-900/40 border border-neutral-200 dark:border-neutral-800/50 rounded-xl px-5 py-4 flex justify-between items-start transition-all duration-[120ms] ease-out ${className}`}
|
||||
{...props}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-[11px] font-medium text-neutral-500 dark:text-neutral-400 uppercase tracking-[0.04em] mb-2 truncate">
|
||||
{title}
|
||||
</p>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-[11px] font-medium text-neutral-500 dark:text-neutral-400 uppercase tracking-[0.04em] truncate">
|
||||
{title}
|
||||
</p>
|
||||
|
||||
<div className="text-[22px] font-semibold tracking-tight text-neutral-900 dark:text-white mb-1 truncate">
|
||||
{loading ? (
|
||||
<Skeleton height="h-6" width="60%" />
|
||||
) : (
|
||||
value
|
||||
)}
|
||||
</div>
|
||||
|
||||
{change && !loading && (
|
||||
<div className="flex items-center space-x-1">
|
||||
<div className={`flex items-center space-x-1 ${
|
||||
changeType === 'increase'
|
||||
? 'text-green-400'
|
||||
: 'text-red-400'
|
||||
}`}>
|
||||
<TrendIcon type={changeType} />
|
||||
<span className="text-xs font-medium">{change}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading && change && (
|
||||
<Skeleton height="h-3" width="40%" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={`${bgColor} ${color} w-8 h-8 p-2 rounded flex-shrink-0 ml-3 flex items-center justify-center`}>
|
||||
<div className="text-[22px] font-semibold tracking-tight tabular-nums text-neutral-900 dark:text-white mt-[6px] truncate">
|
||||
{loading ? (
|
||||
<Skeleton height="h-4" width="w-4" />
|
||||
<Skeleton height="h-6" width="60%" />
|
||||
) : (
|
||||
Icon && <Icon className="h-4 w-4" />
|
||||
value
|
||||
)}
|
||||
</div>
|
||||
|
||||
{change && !loading && (
|
||||
<div className={`text-[11px] font-medium mt-[5px] ${deltaColor}`}>
|
||||
{arrow} {change}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading && change && (
|
||||
<Skeleton height="h-3" width="40%" className="mt-[5px]" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={`${bgColor} ${color} w-8 h-8 rounded-sm flex-shrink-0 ml-3 mt-[2px] flex items-center justify-center`}>
|
||||
{loading ? (
|
||||
<Skeleton height="h-4" width="w-4" />
|
||||
) : (
|
||||
Icon && <Icon className="h-4 w-4" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user