Untitled

 avatar
unknown
plain_text
3 months ago
3.5 kB
4
Indexable
'use client';

import { useRouter } from 'next/navigation';
import { useMetrics } from '@/hooks/useMetrics';
import { Card, CardContent } from '@/components/ui/card';
import { Trophy, Package, Calendar, Flame } from 'lucide-react';
import { useTranslation, type SupportedLanguages } from "@/utils/translations";
import { useSettings } from "@/hooks/useSettings";

function MetricCard({ 
  icon: Icon, 
  label, 
  value, 
  onClick, 
  clickable = false 
}: {
  icon: React.ElementType;
  label: string;
  value: string | number;
  onClick?: () => void;
  clickable?: boolean;
}) {
  const baseClasses = "relative rounded-lg border bg-card text-card-foreground shadow p-6";
  const clickableClasses = clickable 
    ? "cursor-pointer transition-all hover:scale-105 active:scale-95 hover:shadow-lg" 
    : "";

  return (
    <Card 
      className={`${baseClasses} ${clickableClasses}`}
      onClick={onClick}
    >
      <CardContent className="p-0">
        <div className="flex items-center space-x-4">
          <Icon className="h-6 w-6 text-muted-foreground" />
          <div className="space-y-1">
            <p className="text-sm font-medium text-muted-foreground leading-none">
              {label}
            </p>
            <p className="text-2xl font-bold">
              {value}
            </p>
          </div>
        </div>
      </CardContent>
    </Card>
  );
}

export function MetricsOverview() {
  const router = useRouter();
  const { metrics, loading } = useMetrics();
  const { settings } = useSettings();
  const { t } = useTranslation(settings?.language as SupportedLanguages || 'EN');

  if (loading) {
    return (
      <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
        {[...Array(4)].map((_, i) => (
          <Card key={i} className="animate-pulse h-32" />
        ))}
      </div>
    );
  }

  if (!metrics) return null;

  const today = new Date().toISOString().split('T')[0];
  const todayItems = metrics.time_metrics.daily_usage_counts[today] || 0;

  const recentAchievements = Object.entries(metrics.achievements)
    .filter(([_, achievement]) => achievement.status === 'completed')
    .sort((a, b) => {
      const dateA = a[1].unlock_date ? new Date(a[1].unlock_date).getTime() : 0;
      const dateB = b[1].unlock_date ? new Date(b[1].unlock_date).getTime() : 0;
      return dateB - dateA;
    })[0];

  let achievementName = t('metrics.none');
  if (recentAchievements) {
    const key = recentAchievements[0].replace(/-/g, '_');
    achievementName = t(`achievements.${key}.name`);
  }

  const streakCount = metrics.time_metrics.daily_weekly_monthly_streaks.daily;
  const dayString = streakCount === 1 ? t('metrics.day') : t('metrics.days');

  return (
    <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
      <MetricCard
        icon={Package}
        label={t('metrics.today')}
        value={todayItems}
      />
      <MetricCard
        icon={Calendar}
        label={t('metrics.streak')}
        value={`${streakCount} ${dayString}`}
      />
      <MetricCard
        icon={Flame}
        label={t('metrics.best_streak')}
        value={metrics.time_metrics.daily_weekly_monthly_streaks.daily_best}
      />
      <MetricCard
        icon={Trophy}
        label={t('metrics.latest_achievement')}
        value={achievementName}
        clickable={true}
        onClick={() => router.push('/achievements')}
      />
    </div>
  );
}
Editor is loading...
Leave a Comment