Files
pomodoro/src/components/Statistics.tsx
T
Puechberty Arthur b933c6040c feat: implement TodoList component with filtering and priority management
feat: add useAmbientSound hook for ambient sound management

feat: create useLocalStorage hook for persistent state management

feat: develop useTheme hook for theme switching functionality

feat: implement useTimer hook for Pomodoro timer logic

feat: create useTodos hook for managing todo list functionality

style: add global styles and custom scrollbar for better UI experience

chore: set up main entry point for the application

feat: define types for Timer, Todo, and Statistics

feat: create utility function for class name merging

chore: configure Tailwind CSS for styling

chore: set up TypeScript configuration for the project

chore: configure Vite for development and build process
2026-03-30 19:27:27 +02:00

97 lines
3.3 KiB
TypeScript

import { TrendingUp, Flame, Target, Award } from 'lucide-react';
import { Statistics as StatsType } from '../types';
interface StatisticsProps {
statistics: StatsType;
dailyGoal: number;
}
export function Statistics({ statistics, dailyGoal }: StatisticsProps) {
const goalProgress = Math.min((statistics.completedToday / dailyGoal) * 100, 100);
const goalReached = statistics.completedToday >= dailyGoal;
const stats = [
{
label: 'Aujourd\'hui',
value: statistics.completedToday,
icon: Target,
color: 'text-rose-500',
bgColor: 'bg-rose-50 dark:bg-rose-900/30',
},
{
label: 'Total',
value: statistics.completedTotal,
icon: TrendingUp,
color: 'text-indigo-500',
bgColor: 'bg-indigo-50 dark:bg-indigo-900/30',
},
{
label: 'Série actuelle',
value: `${statistics.currentStreak} jour${statistics.currentStreak > 1 ? 's' : ''}`,
icon: Flame,
color: 'text-orange-500',
bgColor: 'bg-orange-50 dark:bg-orange-900/30',
},
{
label: 'Meilleure série',
value: `${statistics.bestStreak} jour${statistics.bestStreak > 1 ? 's' : ''}`,
icon: Award,
color: 'text-amber-500',
bgColor: 'bg-amber-50 dark:bg-amber-900/30',
},
];
return (
<div className="bg-white dark:bg-gray-800 rounded-2xl p-6 shadow-sm border border-gray-100 dark:border-gray-700">
<div className="flex items-center justify-between mb-4">
<h3 className="font-semibold text-gray-800 dark:text-white flex items-center gap-2">
<TrendingUp className="w-5 h-5 text-indigo-500" />
Statistiques
</h3>
{goalReached && (
<span className="text-xs px-2 py-1 bg-emerald-100 dark:bg-emerald-900/50 text-emerald-600 dark:text-emerald-400 rounded-full flex items-center gap-1">
<Award className="w-3 h-3" />
Objectif atteint !
</span>
)}
</div>
{/* Goal progress */}
<div className="mb-6">
<div className="flex justify-between text-sm mb-2">
<span className="text-gray-600 dark:text-gray-400">Progression quotidienne</span>
<span className="font-medium text-gray-800 dark:text-white">
{statistics.completedToday}/{dailyGoal} 🍅
</span>
</div>
<div className="h-3 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden">
<div
className={`h-full rounded-full transition-all duration-500 ${
goalReached
? 'bg-gradient-to-r from-emerald-400 to-emerald-500'
: 'bg-gradient-to-r from-rose-400 to-rose-500'
}`}
style={{ width: `${goalProgress}%` }}
/>
</div>
</div>
{/* Stats grid */}
<div className="grid grid-cols-2 gap-3">
{stats.map(({ label, value, icon: Icon, color, bgColor }) => (
<div
key={label}
className={`${bgColor} rounded-xl p-4 transition-transform hover:scale-105`}
>
<Icon className={`w-5 h-5 ${color} mb-2`} />
<div className="text-2xl font-bold text-gray-800 dark:text-white">
{value}
</div>
<div className="text-xs text-gray-500 dark:text-gray-400">{label}</div>
</div>
))}
</div>
</div>
);
}