"use client"; import React, { useEffect, useCallback } from "react"; import { useStopwatch } from "../hooks/useStopwatch"; import { formatTime, copyToClipboard } from "../lib/utils"; export default function Stopwatch({ onCopyFeedback, }: { onCopyFeedback: () => void; }) { const { elapsed, isRunning, laps, toggle, reset, lap } = useStopwatch(); const time = formatTime(elapsed); // Keyboard shortcuts const handleKeyDown = useCallback( (e: KeyboardEvent) => { if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return; switch (e.code) { case "Space": e.preventDefault(); toggle(); break; case "KeyR": if (!e.ctrlKey && !e.metaKey) { e.preventDefault(); reset(); } break; case "KeyL": e.preventDefault(); lap(); break; case "KeyC": if (!e.ctrlKey && !e.metaKey) { e.preventDefault(); copyToClipboard(time.full).then((ok) => { if (ok) onCopyFeedback(); }); } break; } }, [toggle, reset, lap, time.full, onCopyFeedback] ); useEffect(() => { window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, [handleKeyDown]); const lapDiffs = laps.map((lapTime, i) => { const prev = i === 0 ? 0 : laps[i - 1]; return lapTime - prev; }); return (
{/* Time display */}
{/* Copy icon hint */}
{/* Controls */}
{isRunning && ( )} {(elapsed > 0 || laps.length > 0) && ( )}
{/* Laps */} {laps.length > 0 && (

Tours ({laps.length})

{[...laps] .map((l, i) => ({ lap: l, diff: lapDiffs[i], index: i })) .reverse() .map(({ lap: l, diff, index }) => { const best = Math.min(...lapDiffs); const worst = Math.max(...lapDiffs); const isBest = lapDiffs.length > 1 && diff === best; const isWorst = lapDiffs.length > 1 && diff === worst; return ( ); })}
# Temps total Delta
{index + 1} {isBest && ( BEST )} {isWorst && ( SLOW )} {formatTime(l).full} +{formatTime(diff).full}
)} {/* Keyboard shortcuts */}
Espace {" "} Start/Pause L {" "} Tour R {" "} Reset C {" "} Copier
); }