diff --git a/docs/superpowers/specs/2026-04-01-game-config-panel-design.md b/docs/superpowers/specs/2026-04-01-game-config-panel-design.md new file mode 100644 index 0000000..a236655 --- /dev/null +++ b/docs/superpowers/specs/2026-04-01-game-config-panel-design.md @@ -0,0 +1,119 @@ +# Game Configuration Panel + +## Summary + +Add a configuration panel above the "Commencer une partie" button on the homepage, allowing players to customize game generation parameters before starting. + +## Parameters + +### Films vus (toggle on/off) + +- **Visible only** for authenticated users +- Default: off +- When enabled: all actors in the grid (main actor + hint actors) must appear in at least one film marked as watched by the user +- When disabled: no filtering, any actor can appear + +### Paramètres des indices (checkboxes) + +Three checkboxes controlling which hint types can appear in the grid: + +- **Film** (default: checked) — hint shows a film the actor appeared in +- **Rôle** (default: checked) — hint shows a character name the actor played +- **Récompense** (default: checked) — hint shows an award the actor received + +**Constraint:** at least one must remain checked. The UI prevents unchecking the last one. + +### Récompenses (multi-select checkboxes) + +- **Visible only** when "Récompense" is checked +- Lists all `AwardType` entities that have 5+ distinct actors in the database +- A "Toutes les récompenses" option at the top that toggles all +- Default: all checked (= "Toutes" checked) +- Unchecking an individual item unchecks "Toutes"; rechecking all rechecks "Toutes" +- Selected AwardType IDs are sent as `award_types[]` in the form POST + +## UI Layout + +``` +┌─────────────────────────────────┐ +│ Films vus [ toggle ] │ ← auth users only +├─────────────────────────────────┤ +│ Paramètres des indices │ +│ │ +│ ☑ Film ☑ Rôle ☑ Récompense│ +│ │ +│ Récompenses : │ ← visible if Récompense checked +│ ┌───────────────────────┐ │ +│ │ ☑ Toutes les récomp. │ │ +│ │ ☑ Academy Awards │ │ +│ │ ☑ Golden Globes │ │ +│ │ ☑ César │ │ +│ │ ... │ │ +│ └───────────────────────┘ │ +├─────────────────────────────────┤ +│ [ Commencer une partie ] │ +│ │ +│ Connectez-vous pour importer...│ +└─────────────────────────────────┘ +``` + +## Form Fields + +All parameters are fields within the existing start game `
`: + +| Field name | Type | Value | +|---|---|---| +| `watched_only` | hidden + checkbox | `"1"` if checked, absent otherwise | +| `hint_film` | checkbox | `"1"` if checked | +| `hint_character` | checkbox | `"1"` if checked | +| `hint_award` | checkbox | `"1"` if checked | +| `award_types[]` | checkbox (multiple) | Array of AwardType IDs | + +## Backend Changes + +### HomepageController + +- Query `AwardTypeRepository::findWithMinActors(5)` to get eligible AwardType list +- Pass to template for rendering the multi-select + +### GameController (POST /game/start) + +- Extract config parameters from the Request +- Pass config to `GameGridProvider::generate()` + +### GameGridProvider::generate() + +Receives a config array/object with: + +- `watchedOnly` (bool) — filter actors to those in user's watched films +- `hintTypes` (array) — subset of `['film', 'character', 'award']` based on checked boxes +- `awardTypeIds` (array|null) — list of selected AwardType IDs, null = all + +Generation logic changes: + +- **Actor selection:** if `watchedOnly` is true, only pick actors with a MovieRole in a film watched by the authenticated user +- **Hint selection:** only use hint types present in `hintTypes` +- **Award hints:** only pick awards whose AwardType ID is in `awardTypeIds` +- **Retry mechanism:** if generation fails (cannot find a valid hint for every row), retry up to 5 times. After 5 failures, redirect to homepage with a flash error message explaining the grid could not be generated with the chosen parameters. + +### AwardTypeRepository + +New method: `findWithMinActors(int $minActors): array` — returns AwardType entities having at least `$minActors` distinct actors. + +## Frontend Changes + +### Stimulus controller: `game-config` + +Registered on the config panel container. Handles: + +1. **Award section visibility:** show/hide the AwardType checkbox list when "Récompense" is toggled +2. **Minimum one hint type:** prevent unchecking the last remaining hint checkbox +3. **"Toutes les récompenses" toggle:** check/uncheck all AwardType checkboxes; sync state when individual items change + +### CSS (in app.css) + +- **Toggle switch:** CSS-only using `appearance: none` on checkbox, `::before` pseudo-element for the sliding circle, `--orange` when active, `--border` when inactive +- **Hint checkboxes:** `accent-color: var(--orange)` +- **AwardType list:** border `var(--border)`, `border-radius: var(--radius-sm)`, `max-height: 150px`, `overflow-y: auto` +- **Section labels:** `color: var(--text-muted)`, `font-size: 13px`, `text-transform: uppercase` +- No new CSS or JS files — everything in existing `app.css` and a new Stimulus controller file