import React, { useState, useEffect, useRef } from 'react'; import { PlayIcon, PauseIcon, ArrowPathIcon, XMarkIcon } from '@heroicons/react/24/outline'; import { useTranslation } from 'react-i18next'; interface PomodoroTimerProps { className?: string; } const POMODORO_STORAGE_KEY = 'tududi_pomodoro_timer'; const DEFAULT_TIME = 25 * 60; // 25 minutes in seconds interface PomodoroState { isActive: boolean; timeLeft: number; isRunning: boolean; startTime?: number; } const PomodoroTimer: React.FC = ({ className = '' }) => { const { t } = useTranslation(); const [isActive, setIsActive] = useState(false); const [timeLeft, setTimeLeft] = useState(DEFAULT_TIME); const [isRunning, setIsRunning] = useState(false); const [showCompletionMessage, setShowCompletionMessage] = useState(false); const intervalRef = useRef(null); // Load state from localStorage on mount useEffect(() => { const savedState = localStorage.getItem(POMODORO_STORAGE_KEY); if (savedState) { try { const state: PomodoroState = JSON.parse(savedState); if (state.isActive) { setIsActive(true); setTimeLeft(state.timeLeft); setIsRunning(state.isRunning); // If timer was running, calculate how much time has passed if (state.isRunning && state.startTime) { const elapsed = Math.floor((Date.now() - state.startTime) / 1000); const newTimeLeft = Math.max(0, state.timeLeft - elapsed); setTimeLeft(newTimeLeft); if (newTimeLeft > 0) { setIsRunning(true); } else { setIsRunning(false); } } } } catch (error) { console.error('Failed to load pomodoro state:', error); } } }, []); // Save state to localStorage whenever it changes useEffect(() => { const state: PomodoroState = { isActive, timeLeft, isRunning, startTime: isRunning ? Date.now() - (DEFAULT_TIME - timeLeft) * 1000 : undefined }; localStorage.setItem(POMODORO_STORAGE_KEY, JSON.stringify(state)); }, [isActive, timeLeft, isRunning]); useEffect(() => { if (isRunning && timeLeft > 0) { intervalRef.current = setInterval(() => { setTimeLeft(prev => { if (prev <= 1) { setIsRunning(false); setShowCompletionMessage(true); return 0; } return prev - 1; }); }, 1000); } else { if (intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = null; } } return () => { if (intervalRef.current) { clearInterval(intervalRef.current); } }; }, [isRunning, timeLeft]); const formatTime = (seconds: number) => { const mins = Math.floor(seconds / 60); const secs = seconds % 60; return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; }; const handleTomatoClick = () => { setIsActive(true); setTimeLeft(DEFAULT_TIME); setIsRunning(false); }; const handlePlayPause = () => { setIsRunning(!isRunning); }; const handleReset = () => { setIsRunning(false); setTimeLeft(DEFAULT_TIME); setShowCompletionMessage(false); }; const handleClose = () => { setIsActive(false); setIsRunning(false); setTimeLeft(DEFAULT_TIME); setShowCompletionMessage(false); localStorage.removeItem(POMODORO_STORAGE_KEY); }; // Tomato SVG Icon const TomatoIcon = () => ( {/* Tomato body */} {/* Tomato stem */} {/* Tomato leaf */} ); if (!isActive) { return (
); } return (
{formatTime(timeLeft)}
{/* Completion Message */} {showCompletionMessage && (
🍅 {t('pomodoro.complete')}

{t('pomodoro.completeMessage')}

)}
); }; export default PomodoroTimer;