- Header, Sidebar, Toast, Dropdown, EmptyState component refinements - Auth flow: LoginPage, RegisterPage, AuthInput, AuthLayout improvements - Player bar: glass effect, progress, track info, controls enhancements - Dashboard, Discover, Search pages updates - PlaylistCard, TrackCard component improvements - Auth store and API interceptors hardening - i18n: updated en/es/fr locale files - CSS additions in index.css - Package.json and vite config updates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
65 lines
2.3 KiB
TypeScript
65 lines
2.3 KiB
TypeScript
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { AnimatedNumber } from '@/components/ui/AnimatedNumber';
|
|
import { cn } from '@/lib/utils';
|
|
import { useTranslation } from '@/hooks/useTranslation';
|
|
import { Music, MessageSquare, Heart, Users } from 'lucide-react';
|
|
|
|
const STATS = [
|
|
{
|
|
titleKey: 'dashboard.stats.tracksListened',
|
|
value: 1234,
|
|
change: '+12%',
|
|
icon: Music,
|
|
color: 'text-primary',
|
|
shadow: 'drop-shadow-stat-icon',
|
|
},
|
|
{
|
|
titleKey: 'dashboard.stats.messagesSent',
|
|
value: 567,
|
|
change: '+8%',
|
|
icon: MessageSquare,
|
|
color: 'text-success',
|
|
shadow: 'drop-shadow-stat-icon',
|
|
},
|
|
{
|
|
titleKey: 'dashboard.stats.favorites',
|
|
value: 89,
|
|
change: '+23%',
|
|
icon: Heart,
|
|
color: 'text-destructive',
|
|
shadow: 'drop-shadow-stat-icon',
|
|
},
|
|
{
|
|
titleKey: 'dashboard.stats.activeFriends',
|
|
value: 45,
|
|
change: '+5%',
|
|
icon: Users,
|
|
color: 'text-destructive',
|
|
shadow: 'drop-shadow-stat-icon',
|
|
},
|
|
] as const;
|
|
|
|
export function StatsSection() {
|
|
const { t } = useTranslation();
|
|
|
|
return (
|
|
<section aria-label="Performance statistics" className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
|
{STATS.map((stat, i) => (
|
|
<Card key={stat.titleKey} variant="glass" className="group hover:border-primary/50 hover-lift transition-all duration-[var(--sumi-duration-normal)] animate-content-reveal" style={{ animationDelay: `${i * 80}ms` }}>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium text-muted-foreground group-hover:text-foreground transition-colors duration-[var(--duration-fast)]">
|
|
{t(stat.titleKey)}
|
|
</CardTitle>
|
|
<stat.icon className={cn("h-4 w-4 transition-all duration-[var(--sumi-duration-normal)]", stat.color, stat.shadow, "group-hover:scale-110")} />
|
|
</CardHeader>
|
|
<CardContent>
|
|
<AnimatedNumber value={stat.value} className="text-2xl font-bold text-foreground tracking-tight" />
|
|
<p className="text-xs text-muted-foreground mt-1">
|
|
<span className="text-success font-medium">{stat.change}</span> {t('dashboard.fromLastMonth')}
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</section>
|
|
);
|
|
}
|