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 [startTime, setStartTime] = useState(null); 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); setStartTime(state.startTime || null); // 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, DEFAULT_TIME - elapsed); setTimeLeft(newTimeLeft); if (newTimeLeft > 0) { setIsRunning(true); } else { setIsRunning(false); setShowCompletionMessage(true); } } else { // Timer was paused, use the saved timeLeft setTimeLeft(state.timeLeft); setIsRunning(state.isRunning); } } } 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: startTime || undefined, }; localStorage.setItem(POMODORO_STORAGE_KEY, JSON.stringify(state)); }, [isActive, timeLeft, isRunning, startTime]); 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); setStartTime(null); }; const handlePlayPause = () => { if (!isRunning) { // Starting the timer - set start time based on current progress const elapsedTime = DEFAULT_TIME - timeLeft; setStartTime(Date.now() - elapsedTime * 1000); } setIsRunning(!isRunning); }; const handleReset = () => { setIsRunning(false); setTimeLeft(DEFAULT_TIME); setStartTime(null); setShowCompletionMessage(false); }; const handleClose = () => { setIsActive(false); setIsRunning(false); setTimeLeft(DEFAULT_TIME); setStartTime(null); 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;