Files
Momento/memento-note/components/admin-metrics.tsx
Antigravity 45297da333 fix: images, couverture, slash, agents, wizard, Stripe et admin
- Collage/accès images: ownership path userId + meta legacy, 403 non caché
- Couverture note: explicite (choix/aucune), plus d’auto depuis le corps
- Éditeur: suppression image TipTap, sync immédiate, toolbar réordonnée
- Slash: listes par titre (plus d’index), keywords nettoyés
- Agents: nextRun à la réactivation, cron sans stampede null
- Wizard: titres courts + mode Expert plus robuste
- Stripe checkout hosted fiable; admin métriques live; dark mode IA/settings
- Indexation notes courtes + test unit aligné
2026-07-16 16:58:07 +00:00

74 lines
2.1 KiB
TypeScript

'use client'
import { Card } from '@/components/ui/card'
import { cn } from '@/lib/utils'
import { useLanguage } from '@/lib/i18n'
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) {
const { t } = useLanguage()
return (
<div
className={cn(
'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-4',
className
)}
>
{metrics.map((metric, index) => (
<Card
key={index}
className="p-6 bg-card border-border"
>
<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">
{t('admin.metrics.vsLastPeriod')}
</span>
</div>
)}
</div>
{metric.icon && (
<div className="p-2 bg-gray-100 dark:bg-zinc-800 rounded-lg">
{metric.icon}
</div>
)}
</div>
</Card>
))}
</div>
)
}