Merge pull request #143 from R0m1k3/claude/statistics-modal-popup-01P7c6z7G5KXo9Tk6BwEa4ew

fix: persister l'état du Pomodoro Timer avec localStorage
This commit is contained in:
LogiFlow authored and GitHub committed 2025-11-28 22:39:56 +01:00
commit cf8428291c
3 files changed
+44 -11

No files matched your search

+4 -4
View File
@@ -1,18 +1,18 @@
import { ReactNode } from "react";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { PomodoroTimer } from "./PomodoroTimer";
interface PomodoroModalProps { interface PomodoroModalProps {
open: boolean; open: boolean;
onOpenChange: (open: boolean) => void; onOpenChange: (open: boolean) => void;
onTimerStateChange?: (isRunning: boolean, timeLeft: number, mode: string) => void; children: ReactNode;
} }
export function PomodoroModal({ open, onOpenChange, onTimerStateChange }: PomodoroModalProps) { export function PomodoroModal({ open, onOpenChange, children }: PomodoroModalProps) {
return ( return (
<Dialog open={open} onOpenChange={onOpenChange}> <Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-md"> <DialogContent className="max-w-md">
@@ -20,7 +20,7 @@ export function PomodoroModal({ open, onOpenChange, onTimerStateChange }: Pomodo
<DialogTitle className="text-2xl">Pomodoro Timer</DialogTitle> <DialogTitle className="text-2xl">Pomodoro Timer</DialogTitle>
</DialogHeader> </DialogHeader>
<div className="mt-4"> <div className="mt-4">
<PomodoroTimer onStateChange={onTimerStateChange} /> {children}
</div> </div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
+34 -4
View File
@@ -20,12 +20,42 @@ interface PomodoroTimerProps {
} }
export function PomodoroTimer({ onStateChange }: PomodoroTimerProps = {}) { export function PomodoroTimer({ onStateChange }: PomodoroTimerProps = {}) {
const [mode, setMode] = useState<TimerMode>('work'); // Load initial state from localStorage
const [timeLeft, setTimeLeft] = useState(TIMER_DURATIONS.work); const [mode, setMode] = useState<TimerMode>(() => {
const [isRunning, setIsRunning] = useState(false); const saved = localStorage.getItem('pomodoroMode');
const [sessionsCompleted, setSessionsCompleted] = useState(0); return (saved as TimerMode) || 'work';
});
const [timeLeft, setTimeLeft] = useState(() => {
const saved = localStorage.getItem('pomodoroTimeLeft');
return saved ? parseInt(saved) : TIMER_DURATIONS.work;
});
const [isRunning, setIsRunning] = useState(() => {
const saved = localStorage.getItem('pomodoroIsRunning');
return saved === 'true';
});
const [sessionsCompleted, setSessionsCompleted] = useState(() => {
const saved = localStorage.getItem('pomodoroSessionsCompleted');
return saved ? parseInt(saved) : 0;
});
const intervalRef = useRef<NodeJS.Timeout | null>(null); const intervalRef = useRef<NodeJS.Timeout | null>(null);
// Save state to localStorage whenever it changes
useEffect(() => {
localStorage.setItem('pomodoroMode', mode);
}, [mode]);
useEffect(() => {
localStorage.setItem('pomodoroTimeLeft', timeLeft.toString());
}, [timeLeft]);
useEffect(() => {
localStorage.setItem('pomodoroIsRunning', isRunning.toString());
}, [isRunning]);
useEffect(() => {
localStorage.setItem('pomodoroSessionsCompleted', sessionsCompleted.toString());
}, [sessionsCompleted]);
// Function to play notification sound using Web Audio API // Function to play notification sound using Web Audio API
const playNotificationSound = () => { const playNotificationSound = () => {
try { try {
+6 -3
View File
@@ -1,4 +1,5 @@
import { useEffect, useState, useRef, useCallback } from "react"; import { useEffect, useState, useRef, useCallback, useId } from "react";
import { createPortal } from "react-dom";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
@@ -38,6 +39,7 @@ import { TemplateSelector } from "@/components/TemplateSelector";
import type { NoteTemplate } from "@/utils/noteTemplates"; import type { NoteTemplate } from "@/utils/noteTemplates";
import { AdvancedSearch, type SearchFilters, type TagOption } from "@/components/AdvancedSearch"; import { AdvancedSearch, type SearchFilters, type TagOption } from "@/components/AdvancedSearch";
import { PomodoroModal } from "@/components/PomodoroModal"; import { PomodoroModal } from "@/components/PomodoroModal";
import { PomodoroTimer } from "@/components/PomodoroTimer";
import { KanbanBoard } from "@/components/KanbanBoard"; import { KanbanBoard } from "@/components/KanbanBoard";
import { getSmartTagSuggestions } from "@/utils/smartTags"; import { getSmartTagSuggestions } from "@/utils/smartTags";
import { QuickCaptureWidget } from "@/components/QuickCaptureWidget"; import { QuickCaptureWidget } from "@/components/QuickCaptureWidget";
@@ -3217,8 +3219,9 @@ const Index = () => {
<PomodoroModal <PomodoroModal
open={showPomodoroModal} open={showPomodoroModal}
onOpenChange={setShowPomodoroModal} onOpenChange={setShowPomodoroModal}
onTimerStateChange={handlePomodoroStateChange} >
/> <PomodoroTimer onStateChange={handlePomodoroStateChange} />
</PomodoroModal>
{/* Quick Capture Widget */} {/* Quick Capture Widget */}
<QuickCaptureWidget onNoteCaptured={loadNotes} /> <QuickCaptureWidget onNoteCaptured={loadNotes} />