mirror of
https://github.com/arthur-pbty/pomodoro.git
synced 2026-06-16 08:12:40 +02:00
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
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user