1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useEffect, useRef } from "https://esm.sh/react@18.2.0";
3import type { TimerState } from "../../shared/types.ts";
4import { TIMER_DURATIONS, POMODOROS_BEFORE_LONG_BREAK } from "../../shared/types.ts";
6interface TimerProps {
7 timerState: TimerState;
8 setTimerState: React.Dispatch<React.SetStateAction<TimerState>>;
9 onStartSession: (type: 'work' | 'short_break' | 'long_break') => void;
10 onCompleteSession: () => void;
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState, useEffect } from "https://esm.sh/react@18.2.0";
3import Timer from "./Timer.tsx";
4import Stats from "./Stats.tsx";
58## Technology Stack
59
60- **Frontend**: React 18.2.0 with TypeScript
61- **Backend**: Hono framework
62- **Database**: SQLite
165- **Imports:** Use `https://esm.sh` for npm and Deno dependencies to ensure compatibility on server and browser
166- **Storage Strategy:** Only use backend storage if explicitly required; prefer simple static client-side sites
167- **React Configuration:** When using React libraries, pin versions with `?deps=react@18.2.0,react-dom@18.2.0` and start the file with `/** @jsxImportSource https://esm.sh/react@18.2.0 */`
168- Ensure all React dependencies and sub-dependencies are pinned to the same version
169- **Styling:** Default to using TailwindCSS via `<script src="https://cdn.twind.style" crossorigin></script>` unless otherwise specified
170
252 - Always run table creation before querying
253
2543. **React Configuration:**
255 - All React dependencies must be pinned to 18.2.0
256 - Always include `@jsxImportSource https://esm.sh/react@18.2.0` at the top of React files
257 - Rendering issues often come from mismatched React versions
258
2594. **File Handling:**
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState } from "https://esm.sh/react@18.2.0?deps=react@18.2.0";
3import type { Site, Game, CreateGameRequest } from "../../shared/types.ts";
4
402 const availableCourts = selectedSite?.courts.filter(court => court.isActive) || [];
403
404 const handleSubmit = async (e: React.FormEvent) => {
405 e.preventDefault();
406
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState, useEffect } from "https://esm.sh/react@18.2.0?deps=react@18.2.0";
3import type { Game, Court } from "../../shared/types.ts";
4
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React from "https://esm.sh/react@18.2.0?deps=react@18.2.0";
3import type { Game, PointLog } from "../../shared/types.ts";
4
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState } from "https://esm.sh/react@18.2.0?deps=react@18.2.0";
3import type { Game, PointLog } from "../../shared/types.ts";
4import PointLogModal from "./PointLogModal.tsx";
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState } from "https://esm.sh/react@18.2.0?deps=react@18.2.0";
3import type { Site, Game, Court, CreateGameRequest } from "../../shared/types.ts";
4
233 const availableCourts = selectedSite?.courts.filter(court => court.isActive) || [];
234
235 const handleSubmit = async (e: React.FormEvent) => {
236 e.preventDefault();
237
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState, useEffect } from "https://esm.sh/react@18.2.0?deps=react@18.2.0";
3import type { Site, Game, Court } from "../../shared/types.ts";
4import GameBoard from "./GameBoard.tsx";