feat: tablet-first UX overhaul with wizard improvements
- Tablet-first responsive scoreboard: whole player card is tap target - Per-step wizard backgrounds and live summary panel - Larger touch targets, safe-area handling, reduced-motion support - German UI error strings in App.tsx - Updated SOUL.md and README.md for current architecture - Cleanup: removed legacy components, .cursor/, UI_IMPROVEMENTS.md - Renamed package to bscscore, fixed TOTAL_WIZARD_STEPS
This commit is contained in:
@@ -1,88 +1,87 @@
|
||||
# BSC Score - Pool Scoring Application
|
||||
|
||||
A modern, responsive pool/billiards scoring application built with **Astro** and **Preact**, following best practices for maintainability, performance, and reusability.
|
||||
A tablet-first PWA for live pool/billiards scoring at the table. Built with **Astro 5** (islands) and **Preact**, with reusable logic under `src/lib`.
|
||||
|
||||
## ✨ Features
|
||||
## Features
|
||||
|
||||
- **Multi-game Support**: 8-Ball, 9-Ball, 10-Ball, and 14/1 Endlos
|
||||
- **Real-time Scoring**: Live score tracking with undo functionality
|
||||
- **Player Management**: Automatic player name history and suggestions
|
||||
- **Game Management**: Create, track, and manage multiple games
|
||||
- **Responsive Design**: Optimized for mobile and desktop
|
||||
- **Progressive Web App**: Offline support and app-like experience
|
||||
- **TypeScript**: Full type safety for better development experience
|
||||
- **Game types**: 8-Ball, 9-Ball, 10-Ball; Race-to or 14/1 Endlos
|
||||
- **Live scoring**: Tap a player's score card for +1; undo for the last point
|
||||
- **New-game wizard**: 7 steps with running summary (`WizardSummary`) and per-step colored backgrounds
|
||||
- **Break tracking**: Winnerbreak / Wechselbreak, break-order selection, live break indicator on scoreboard
|
||||
- **Player history**: Quick-pick from previously used names
|
||||
- **Game list**: Filter (Alle / Aktiv / Abgeschlossen), tap card to open, delete with confirmation
|
||||
- **Rematch**: Start a new game with the same players after completion
|
||||
- **PWA**: Offline via service worker + IndexedDB (`BSCScoreDB`), fullscreen manifest, German UI
|
||||
- **TypeScript**: Strict mode throughout
|
||||
|
||||
## 🏗️ Architecture
|
||||
**Device priority:** landscape tablet at the table, then mobile portrait, then desktop. Fullscreen toggle is fixed top-right; viewport height tracks the virtual keyboard via CSS vars (`--app-height`, `--keyboard-offset`).
|
||||
|
||||
Everything reusable now lives under `src/lib`, allowing you to embed the core experience inside another React/Preact host without the Astro shell.
|
||||
## Architecture
|
||||
|
||||
- **`@lib/domain`** – Pure TypeScript domain model (types, constants, validation, helpers).
|
||||
- **`@lib/data`** – Persistence adapters and repositories (IndexedDB, migrations).
|
||||
- **`@lib/state`** – Composable hooks that orchestrate domain + data.
|
||||
- **`@lib/ui`** – Stateless UI primitives with co-located CSS modules.
|
||||
- **`@lib/features/*`** – Feature bundles composing UI + state (game list, detail, lifecycle modals, new-game wizard).
|
||||
Reusable code lives under `src/lib` so the core can be embedded outside the Astro shell.
|
||||
|
||||
The Astro `src/components` folder is now a thin host layer (screens + island bootstrap) that consumes the library.
|
||||
- **`@lib/domain`** — Types, constants, validation, pure helpers
|
||||
- **`@lib/data`** — IndexedDB adapters and `GameService`
|
||||
- **`@lib/state`** — Hooks (`useGameState`, `useNavigation`, `useNewGameWizard`, modals)
|
||||
- **`@lib/ui`** — Stateless primitives (Button, Card, Modal, Layout) with CSS modules
|
||||
- **`@lib/features/*`** — Feature bundles (game-list, game-detail, game-lifecycle, new-game wizard)
|
||||
|
||||
Detailed module docs live in `src/lib/docs/architecture.md` and the individual `README.md` files under each package.
|
||||
`src/components` is a thin Astro host: `App.tsx` orchestrates screens and islands.
|
||||
|
||||
## 🚀 Getting Started
|
||||
Module docs: `src/lib/docs/architecture.md` and per-package READMEs.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
- Node.js 18+
|
||||
- npm or yarn
|
||||
|
||||
- Node.js 18+
|
||||
- npm
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <repository-url>
|
||||
cd bscscore
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start development server
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Available Scripts
|
||||
Dev server: `http://localhost:3000`
|
||||
|
||||
### Scripts
|
||||
|
||||
```bash
|
||||
npm run dev # Start development server
|
||||
npm run build # Build for production
|
||||
npm run preview # Preview production build
|
||||
npm run test:record # Record browser interactions with Playwright
|
||||
npm run test:e2e # Run all recorded browser automation scripts
|
||||
npm run dev # Dev server (--host)
|
||||
npm run build # Production build → dist/
|
||||
npm run preview # Preview production build
|
||||
npm run test:record # Playwright codegen (record flows)
|
||||
npm run test:e2e # Run Playwright recordings
|
||||
```
|
||||
|
||||
### Building with Docker
|
||||
### Docker build
|
||||
|
||||
```bash
|
||||
# Build for production using Docker
|
||||
docker run -it -v $(pwd):/app -w /app --rm node:latest npx astro build
|
||||
```
|
||||
|
||||
## 🧪 Testing
|
||||
## Testing
|
||||
|
||||
The project uses **Playwright** for browser automation and recording. This allows you to record interactions once and replay them anytime, making it easy to test repetitive workflows.
|
||||
Playwright recordings under `tests/recordings/` cover core game flows. See `tests/recordings/README.md`.
|
||||
|
||||
### Quick Start
|
||||
|
||||
**Recording interactions:**
|
||||
```bash
|
||||
# Terminal 1: Start dev server
|
||||
# Terminal 1
|
||||
npm run dev
|
||||
|
||||
# Terminal 2: Start recording
|
||||
# Terminal 2 — record
|
||||
npm run test:record
|
||||
```
|
||||
|
||||
**Running recordings:**
|
||||
```bash
|
||||
# Replay all
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
### Seed test matches via browser console
|
||||
### Seed test matches (browser console)
|
||||
|
||||
Copy/paste this snippet in your browser devtools console while the app is open. It inserts 10 sample matches (mix of 2/3 players, 8/9/10-ball, completed + active) into IndexedDB and reloads the page.
|
||||
Paste while the app is open. Inserts 10 sample matches into IndexedDB and reloads.
|
||||
|
||||
```js
|
||||
await (async () => {
|
||||
@@ -185,152 +184,40 @@ await (async () => {
|
||||
})();
|
||||
```
|
||||
|
||||
### Features
|
||||
## Project structure
|
||||
|
||||
- **Record interactions**: Use Playwright codegen to capture clicks, form fills, and navigation
|
||||
- **Replay scripts**: Run recorded scripts automatically
|
||||
- **Duplicate & modify**: Copy any script and modify it (e.g., change the last step from clicking 'z' to clicking 'a')
|
||||
- **Full scripting power**: Edit generated TypeScript files directly for custom automation
|
||||
```
|
||||
src/
|
||||
├── components/ # Astro shell (App.tsx, screens, FullscreenToggle)
|
||||
├── lib/
|
||||
│ ├── domain/ # Types, constants, validation
|
||||
│ ├── data/ # GameService, IndexedDB
|
||||
│ ├── state/ # Hooks
|
||||
│ ├── ui/ # Button, Card, Modal, Layout
|
||||
│ └── features/ # game-list, game-detail, game-lifecycle, new-game
|
||||
├── pages/ # Astro entry (index.astro)
|
||||
└── styles/ # Global tokens (index.css)
|
||||
```
|
||||
|
||||
### Documentation
|
||||
## Design system
|
||||
|
||||
For detailed instructions on recording, modifying, and running scripts, see:
|
||||
- **[tests/recordings/README.md](tests/recordings/README.md)** - Complete workflow documentation
|
||||
Tokens in `src/styles/index.css`:
|
||||
|
||||
## 📁 Project Structure
|
||||
- **Theme**: Dark only — background `#1a1a1a`, surfaces `#222`, accent `#ff9800`
|
||||
- **Typography**: System font stack (no webfonts)
|
||||
- **Touch targets**: 48px min, 56px comfortable, 64px large
|
||||
- **Breakpoints**: 480px / 768px / 1024px / 1200px (`@lib/domain/constants`)
|
||||
- **Scoreboard cards**: Per-player gradient colors (`--color-player-1` … `3`); entire card is the tap target
|
||||
- **Components**: Button variants `primary` | `secondary` | `danger`; Card `default` | `elevated` | `outlined`
|
||||
|
||||
### **Core Components**
|
||||
- `src/components/App.tsx` - Astro-bound shell orchestrating library modules
|
||||
- `src/components/screens/` - Screen containers consuming `@lib/features`
|
||||
- `src/lib/` - Reusable application spine (domain/data/state/ui/features)
|
||||
UI copy and validation messages: `@lib/domain/constants` (`VALIDATION_MESSAGES`, `ARIA_LABELS`). Product tone: `SOUL.md`.
|
||||
|
||||
### **State Management**
|
||||
- `@lib/state/useGameState` - Game CRUD operations and persistence
|
||||
- `@lib/state/useNavigation` - Application routing and screen state
|
||||
- `@lib/state/useModal` - Modal state management helpers
|
||||
## Stack
|
||||
|
||||
### **Business Logic**
|
||||
- `@lib/data/gameService` - Game creation, updates, and persistence orchestration
|
||||
- `@lib/domain/gameUtils` - Game-related utility functions
|
||||
- `@lib/domain/validation` - Input validation and sanitisation
|
||||
- [Astro](https://astro.build/) 5 + [Preact](https://preactjs.com/)
|
||||
- TypeScript strict, CSS Modules, Vite
|
||||
- Playwright for recorded E2E flows
|
||||
|
||||
### **Type Definitions**
|
||||
- `@lib/domain/types` - Game domain types
|
||||
- `@lib/ui/types` - UI component types
|
||||
- `types/css-modules.d.ts` - CSS modules type support
|
||||
## Deploy
|
||||
|
||||
## 🎯 Key Improvements
|
||||
|
||||
### **From Monolithic to Modular**
|
||||
- **Before**: 360-line App component handling everything
|
||||
- **After**: Separated concerns with focused, single-responsibility components
|
||||
|
||||
### **Type Safety**
|
||||
- **Before**: JavaScript with PropTypes comments
|
||||
- **After**: Full TypeScript with comprehensive type definitions
|
||||
|
||||
### **State Management**
|
||||
- **Before**: All state in one component with prop drilling
|
||||
- **After**: Custom hooks with proper encapsulation and reusability
|
||||
|
||||
### **Reusability**
|
||||
- **Before**: Tightly coupled, single-use components
|
||||
- **After**: Reusable UI components with variant support
|
||||
|
||||
### **Performance**
|
||||
- **Before**: Client-side only rendering
|
||||
- **After**: Astro's islands architecture with optimal hydration
|
||||
|
||||
### **Developer Experience**
|
||||
- **Before**: No structure, mixed concerns
|
||||
- **After**: Clear architecture, proper tooling, and documentation
|
||||
|
||||
## 🛠️ Technology Stack
|
||||
|
||||
- **Framework**: [Astro](https://astro.build/) - Islands architecture for optimal performance
|
||||
- **UI Library**: [Preact](https://preactjs.com/) - Lightweight React alternative
|
||||
- **Language**: [TypeScript](https://www.typescriptlang.org/) - Type safety and better DX
|
||||
- **Styling**: CSS Modules with design tokens
|
||||
- **Build Tool**: Vite (integrated with Astro)
|
||||
|
||||
## 📱 Progressive Web App
|
||||
|
||||
The application includes PWA features:
|
||||
- Offline support with service worker
|
||||
- App manifest for "Add to Home Screen"
|
||||
- Optimized for mobile devices
|
||||
- Fast loading with proper caching strategies
|
||||
|
||||
## 🎨 Design System
|
||||
|
||||
### **Design Tokens**
|
||||
- Consistent color palette
|
||||
- Standardized spacing and sizing
|
||||
- Responsive breakpoints
|
||||
- Accessibility-compliant contrast ratios
|
||||
|
||||
### **Component Variants**
|
||||
- Button: `primary`, `secondary`, `danger`
|
||||
- Card: `default`, `elevated`, `outlined`
|
||||
- Sizes: `small`, `medium`, `large`
|
||||
|
||||
## 🧪 Best Practices Implemented
|
||||
|
||||
### **Code Quality**
|
||||
- ✅ SOLID principles
|
||||
- ✅ DRY (Don't Repeat Yourself)
|
||||
- ✅ Single Responsibility Principle
|
||||
- ✅ Proper separation of concerns
|
||||
- ✅ TypeScript strict mode
|
||||
|
||||
### **Performance**
|
||||
- ✅ Code splitting with Astro islands
|
||||
- ✅ Optimized bundle size
|
||||
- ✅ Efficient re-rendering with proper hooks
|
||||
- ✅ CSS Modules for optimized styling
|
||||
|
||||
### **Accessibility**
|
||||
- ✅ ARIA labels and roles
|
||||
- ✅ Keyboard navigation support
|
||||
- ✅ Screen reader compatibility
|
||||
- ✅ High contrast support
|
||||
|
||||
### **Maintainability**
|
||||
- ✅ Clear file structure
|
||||
- ✅ Comprehensive documentation
|
||||
- ✅ Type safety throughout
|
||||
- ✅ Modular, testable components
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
### **Astro Configuration**
|
||||
- Preact integration with React compatibility
|
||||
- TypeScript strict mode
|
||||
- Optimized build settings
|
||||
- Development server configuration
|
||||
|
||||
### **TypeScript Configuration**
|
||||
- Strict type checking
|
||||
- Modern ES2020+ features
|
||||
- CSS Modules support
|
||||
- Astro-specific types
|
||||
|
||||
## 📈 Future Improvements
|
||||
|
||||
- Unit and integration testing (if needed)
|
||||
- Internationalization (i18n) support
|
||||
- Advanced game statistics and analytics
|
||||
- Real-time multiplayer support
|
||||
- Game export/import functionality
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
This codebase follows strict development principles:
|
||||
1. Every feature must be type-safe
|
||||
2. Components must be reusable and well-documented
|
||||
3. Business logic must be separated from UI logic
|
||||
4. All changes must follow the established architecture patterns
|
||||
|
||||
## 📄 License
|
||||
|
||||
[Include your license information here]
|
||||
`npm run build` → `dist/` → nginx via `compose.yml` on `score.bsc-gp.de`.
|
||||
|
||||
Reference in New Issue
Block a user