mirror of
https://github.com/arthur-pbty/pomodoro.git
synced 2026-06-05 13:52:22 +02:00
b933c6040c
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
97 lines
3.3 KiB
TypeScript
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>
|
|
);
|
|
}
|