- Unified localStorage key to 'theme-preference' across all components
- Fixed header.tsx using wrong localStorage key ('theme' instead of 'theme-preference')
- Added localStorage hybrid persistence for instant theme changes
- Removed router.refresh() which was causing stale data revert
- Replaced Blue theme with Sepia
- Consolidated auth() calls to prevent race conditions
- Updated UserSettingsData types to include all themes
71 lines
2.0 KiB
TypeScript
71 lines
2.0 KiB
TypeScript
'use client'
|
|
|
|
import { Card } from '@/components/ui/card'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
export interface MetricItem {
|
|
title: string
|
|
value: string | number
|
|
trend?: {
|
|
value: number
|
|
isPositive: boolean
|
|
}
|
|
icon?: React.ReactNode
|
|
}
|
|
|
|
export interface AdminMetricsProps {
|
|
metrics: MetricItem[]
|
|
className?: string
|
|
}
|
|
|
|
export function AdminMetrics({ metrics, className }: AdminMetricsProps) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4',
|
|
className
|
|
)}
|
|
>
|
|
{metrics.map((metric, index) => (
|
|
<Card
|
|
key={index}
|
|
className="p-6 bg-white dark:bg-zinc-900 border-gray-200 dark:border-gray-800"
|
|
>
|
|
<div className="flex items-start justify-between">
|
|
<div className="flex-1">
|
|
<p className="text-sm font-medium text-gray-600 dark:text-gray-400 mb-2">
|
|
{metric.title}
|
|
</p>
|
|
<p className="text-2xl font-bold text-gray-900 dark:text-white">
|
|
{metric.value}
|
|
</p>
|
|
{metric.trend && (
|
|
<div className="flex items-center gap-1 mt-2">
|
|
<span
|
|
className={cn(
|
|
'text-xs font-medium',
|
|
metric.trend.isPositive
|
|
? 'text-green-600 dark:text-green-400'
|
|
: 'text-red-600 dark:text-red-400'
|
|
)}
|
|
>
|
|
{metric.trend.isPositive ? '↑' : '↓'} {Math.abs(metric.trend.value)}%
|
|
</span>
|
|
<span className="text-xs text-gray-500 dark:text-gray-400">
|
|
vs last period
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
{metric.icon && (
|
|
<div className="p-2 bg-gray-100 dark:bg-zinc-800 rounded-lg">
|
|
{metric.icon}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|