diff --git a/web/app/master/page.tsx b/web/app/master/page.tsx index 36c616f..e6748a6 100644 --- a/web/app/master/page.tsx +++ b/web/app/master/page.tsx @@ -2,7 +2,7 @@ import Link from "next/link"; import { useCallback, useEffect, useState } from "react"; -import PlayerBoard from "../loto-player-board"; +import PlayerBoard from "@/components/player-board"; const STORAGE_KEY = "loto_master"; diff --git a/web/app/page.tsx b/web/app/page.tsx index 45ab44b..1ecff61 100644 --- a/web/app/page.tsx +++ b/web/app/page.tsx @@ -2,7 +2,7 @@ import Link from "next/link"; import { useState } from "react"; -import PlayerBoard from "./loto-player-board"; +import PlayerBoard from "@/components/player-board"; export default function Home() { const [showInstructions, setShowInstructions] = useState(false); diff --git a/web/app/loto-player-board.tsx b/web/components/player-board.tsx similarity index 99% rename from web/app/loto-player-board.tsx rename to web/components/player-board.tsx index ba83148..3cfaca7 100644 --- a/web/app/loto-player-board.tsx +++ b/web/components/player-board.tsx @@ -9,7 +9,7 @@ import { loadGrid, saveCrossedState, saveGrid, -} from "./loto-game-logic"; +} from "@/lib/game-logic"; interface PlayerBoardProps { /** localStorage key prefix; allows multiple independent boards (e.g. user vs master) */ diff --git a/web/docs/code-standards.md b/web/docs/code-standards.md index ab7c11c..02b307d 100644 --- a/web/docs/code-standards.md +++ b/web/docs/code-standards.md @@ -2,7 +2,7 @@ ## File Naming & Structure -- **Kebab-case** for all files: `loto-player-board.tsx`, `loto-game-logic.ts`. +- **Kebab-case** for all files: `player-board.tsx`, `game-logic.ts`. - **Descriptive names**: Long names are preferred for self-documentation. Avoid ambiguity. - **Single responsibility**: Each file has one primary export (component or utilities). - **Max 200 lines per file**: Split larger components into smaller focused ones. @@ -81,13 +81,13 @@ function loadGrid(prefix = "loto"): number[][] | null { | camelCase | `handleCellClick`, `storagePrefix` | variables, functions, props | | PascalCase | `PlayerBoard`, `MasterPage` | components, types | | UPPER_SNAKE | `STORAGE_KEY`, `NUM_ROWS` | constants | -| kebab-case | `loto-player-board.tsx` | file names | +| kebab-case | `player-board.tsx` | file names | ## Comment Style - Document **why**, not **what**. The code shows what it does. - Use `/** JSDoc */` for exported functions. -- Inline comments for complex logic (e.g., weighted random selection in `loto-game-logic.ts:19–28`). +- Inline comments for complex logic (e.g., weighted random selection in `lib/game-logic.ts:19–28`). ### Example ```typescript @@ -111,8 +111,8 @@ function randomANumberInRow(weights: number[]): number { ```typescript import { useCallback, useState } from "react"; import Link from "next/link"; -import PlayerBoard from "./loto-player-board"; -import { generateGrid } from "./loto-game-logic"; +import PlayerBoard from "@/components/player-board"; +import { generateGrid } from "@/lib/game-logic"; ``` ## Testing (Not Currently Implemented) diff --git a/web/docs/codebase-summary.md b/web/docs/codebase-summary.md index 9cd4a2e..ccd2a7b 100644 --- a/web/docs/codebase-summary.md +++ b/web/docs/codebase-summary.md @@ -12,12 +12,12 @@ ### Shared Components | File | Purpose | |------|---------| -| `app/loto-player-board.tsx` | Reusable player card (9×9 grid). Handles crossed state, bingo popup, "Chờ X" toast. Accepts `storagePrefix` prop for multi-card isolation. | +| `components/player-board.tsx` | Reusable player card (9×9 grid). Handles crossed state, bingo popup, "Chờ X" toast. Accepts `storagePrefix` prop for multi-card isolation. | ### Game Logic | File | Purpose | |------|---------| -| `app/loto-game-logic.ts` | Stateless utilities: generateGrid (weighted column selection), saveGrid, loadGrid, saveCrossedState, loadCrossedState, isRowComplete, getWaitingNumber. | +| `lib/game-logic.ts` | Stateless utilities: generateGrid (weighted column selection), saveGrid, loadGrid, saveCrossedState, loadCrossedState, isRowComplete, getWaitingNumber. | ### Styling | File | Purpose | @@ -66,10 +66,10 @@ RootLayout | Function | Location | Effect | |----------|----------|--------| -| `generateGrid()` | loto-game-logic.ts:52 | Creates 9×9 with weighted column selection (5 nums/row). | -| `isRowComplete()` | loto-game-logic.ts:108 | Boolean: all non-zero cells in row crossed? | -| `getWaitingNumber()` | loto-game-logic.ts:120 | Returns the single uncrossed number in row, or null. | -| `handleCellClick()` | loto-player-board.tsx:112 | Toggle crossed[row][col]. | +| `generateGrid()` | game-logic.ts:52 | Creates 9×9 with weighted column selection (5 nums/row). | +| `isRowComplete()` | game-logic.ts:108 | Boolean: all non-zero cells in row crossed? | +| `getWaitingNumber()` | game-logic.ts:120 | Returns the single uncrossed number in row, or null. | +| `handleCellClick()` | player-board.tsx:112 | Toggle crossed[row][col]. | | `handleDrawNext()` | master/page.tsx:88 | Pop first number from remaining, add to called. | Last reviewed: 2026-04-26 diff --git a/web/docs/system-architecture.md b/web/docs/system-architecture.md index be8e960..06996f0 100644 --- a/web/docs/system-architecture.md +++ b/web/docs/system-architecture.md @@ -88,7 +88,7 @@ All pages use `"use client"` because: Files with `"use client"`: - `app/page.tsx` - `app/master/page.tsx` -- `app/loto-player-board.tsx` +- `components/player-board.tsx` ## Data Flow: Mark a Cell diff --git a/web/app/loto-game-logic.ts b/web/lib/game-logic.ts similarity index 100% rename from web/app/loto-game-logic.ts rename to web/lib/game-logic.ts diff --git a/web/package.json b/web/package.json index 65e8ec7..adb4a7f 100644 --- a/web/package.json +++ b/web/package.json @@ -1,5 +1,5 @@ { - "name": "nextjs-temp", + "name": "loto", "version": "0.1.0", "private": true, "scripts": {