mirror of
https://github.com/tiennm99/loto.git
synced 2026-09-02 12:20:22 +00:00
feat(ui): big bundle — settings (theme/master/auto), purple default, mobile fit, master extraction
Settings expansion: 4 new keys (theme auto/light/dark, masterMode, autoCallEnabled, autoCallSpeed 1-10) with per-key validators that preserve old saved data. Default empty-cell color flipped from Tân Tân blue to Excel Standard Purple #7030A0; preset palette swapped to Office's 10 standard colors (5x2 grid). 15 new tests, 53 total. Theme system: Tailwind v4 @variant dark (.dark *); applyTheme() toggles <html class="dark"> based on settings.theme; auto mode mirrors prefers-color-scheme via matchMedia listener (cleanly torn down when switching modes). Existing dark-mode CSS converted from @media to :where(.dark) selectors. Mobile fit: PlayerBoard cells aspect-square on mobile, sm:aspect-[3/5] desktop. Number text scales text-base sm:text-2xl md:text-3xl. Page padding tightened (px-2 py-4 sm:px-3 sm:py-12). Container bumped max-w-lg to max-w-2xl. Header / footer: removed instructions toggle and "Trang quản trò" link from player page. New PageFooter.svelte (tagline + Made by miti99 with [SVG heart] link); also duplicated in PlayerBoard's closing section-label band per request. Heart is inline SVG (red), not emoji. Master mode: extracted everything from /master route into reusable MasterPanel.svelte. /master route slimmed to header + MasterPanel + footer. / mounts MasterPanel conditionally when settings.masterMode. Storage prefixes unchanged. Master tracking grid removed: per request, the 11x9 ones-digit master board is gone. Host still gets controls, "Số vừa xổ" hero, draw history list, and their own player card. Player card is enough. Auto-call: single $effect lifecycle keyed on (autoRunning, settings.autoCallSpeed, settings.autoCallEnabled). Setup / clear setInterval cleanly across speed changes, master-mode toggle off, component unmount, and "user disabled auto" mid-run. Button toggles "Xổ số" -> "Bắt đầu / Dừng". Speed slider in Settings (only visible when master mode is on). aria-label / aria-valuetext on slider. Code-review nice-to-fixes applied: folded the two MasterPanel $effects into one, removed muddled onkeydown on the SettingsButton modal backdrop, added slider a11y attrs. Docs: PDR / codebase-summary / system-architecture / development-roadmap / code-standards all synced to the new state.
This commit is contained in:
@@ -41,8 +41,8 @@ Use the `.svelte.js` extension for modules that export rune-based reactive state
|
||||
### Utilities
|
||||
- Utility-first: `className="px-4 py-2 rounded-lg text-white"`.
|
||||
- Responsive: `sm:`, `md:`, `lg:` prefixes for breakpoints.
|
||||
- Dark mode: `dark:bg-slate-800`, `dark:text-white`.
|
||||
- Animations: Custom keyframes in `globals.css`, apply via `animate-fade-in`.
|
||||
- Dark mode: Explicit `@variant dark (.dark *)` in `app.css` declares dark-mode selector; use `dark:bg-slate-800 dark:text-white`. Settings store toggles `<html class="dark">` rather than relying on `@media (prefers-color-scheme: dark)`.
|
||||
- Animations: Custom keyframes in `app.css`, apply via `animate-fade-in`.
|
||||
|
||||
### Layout
|
||||
- Flexbox for alignment: `flex flex-col items-center justify-center`.
|
||||
@@ -167,8 +167,8 @@ Use inline event handlers (`onclick`, `onkeydown`). Svelte 5 handles click deleg
|
||||
|
||||
### Unit Tests (Implemented)
|
||||
- **Framework**: Vitest 4.1.5 with happy-dom
|
||||
- **Test Files**: `src/lib/game-logic.test.js` (26 tests), `src/lib/settings-store.test.js` (12 tests) — 38 total passing
|
||||
- **Coverage**: Game logic (generateGrid shape/constraints, isRowComplete, getWaitingNumber, persistence with validators), settings (load/save/reset with error handling)
|
||||
- **Test Files**: `src/lib/game-logic.test.js` (26 tests), `src/lib/settings-store.test.js` (27 tests) — 53 total passing
|
||||
- **Coverage**: Game logic (generateGrid shape/constraints, isRowComplete, getWaitingNumber, persistence with validators), settings (load/save/reset with error handling, theme detection, master mode toggle, auto-call speed, color validation)
|
||||
- **Scripts**: `npm test` (run once), `npm run test:watch` (continuous)
|
||||
- **Pattern**: Use vitest's `describe` / `it` blocks, `expect()` assertions. Test both happy path and error cases (corrupt JSON, missing localStorage).
|
||||
|
||||
@@ -192,3 +192,4 @@ Set in `.env.local` (not committed).
|
||||
- **basePath**: Dual-mode: `""` (Cloudflare, dev) or `/loto` (GitHub Pages via `BUILD_PROFILE=gh`).
|
||||
|
||||
Last reviewed: 2026-04-27
|
||||
Last synced: 2026-04-27 (6-phase refactor)
|
||||
|
||||
Reference in New Issue
Block a user