Marijn 404c0dcc26 Summer cleanup: XLSX export, WIDM-style quiz UI, CSS fixes (#162)
* Add CLAUDE.md, replace Makefile with Justfile, remove .junie

- Add CLAUDE.md with project overview, commands, architecture, and domain entity docs
- Remove Makefile in favour of the existing Justfile
- Remove .junie/AGENTS.md (knowledge transferred to CLAUDE.md)
- Update .gitignore: drop .junie/ entries, add .claude/settings.local.json
- Minor doc fixes in config/reference.php (typo, type correction)

* Clean up templates and CSS

- season.html.twig: remove dead empty column, drop redundant flex-row
- tab_overview.html.twig: extract Twig macro for confirm modals, fix duplicate aria-labelledby IDs
- tab_result.html.twig: remove dead comment, replace inline widths with CSS classes, simplify nested row/col forms to d-flex gap-1
- backoffice.scss: add col-result-xs/sm/md column width classes
- quiz.scss: replace broken display:grid + justify-self:center with flexbox centering

* Implement quizToXlsx() export and add export button

- QuizSpreadsheetService: implement quizToXlsx() as the inverse of
  fillQuizFromArray() — writes quiz questions and answers to XLSX using
  the same column layout as the import template
- BackofficeController: add exportQuiz() action at GET /backoffice/quiz/{quiz}/export
- tab_overview.html.twig: add Export to XLSX button in Quick actions

* Add unit tests for QuizSpreadsheetService

7 tests covering generateTemplate(), quizToXlsx(), and xlsxToQuiz():
- valid XLSX output and MIME type
- template without example reimports as empty
- template example data survives a reimport
- round-trip (export → reimport) preserves questions, answers, and correct flags
- empty quiz exports and reimports cleanly
- invalid MIME type throws InvalidArgumentException
- question with no answers throws SpreadsheetDataException with error list

* Fix quiz page vertical centering regression

The CSS cleanup broke vertical centering: flex on body causes main to
stretch full-width; place-items:center on a grid body only centers
items within their auto-sized track (not the track within body).

Fix: move background/color to html (full-viewport grid that centers
body), give body height:100% + display:grid + align-content:center
(centers the content track within full-height body) + justify-self:center
(shrink-wraps body width). Matches production behavior exactly.

* Improve quiz page layouts: WIDM-style answers and responsive centering

- Add green square answer buttons styled after the TV show
- Two-column answer grid for 6+ answers, single column on mobile
- fit-content centering for question pages so block matches question width
- Narrow fixed-width centering for form pages (enter name, select season)

* Use HeaderUtils::makeDisposition() for safe Content-Disposition filename

* Fix quizToXlsx to support unlimited answers and add header count tests

- Replace hardcoded 6-column arrays with dynamic Coordinate arithmetic
- Write data rows first to determine max answer count, write headers last
- Replace try/catch ErrorException in fillQuizFromArray with array_key_exists
- Add data-provider test covering 2, 6, 7, and 10 answers
- Add cross-question max-header and 7-answer round-trip tests

* Fix Sass healthcheck

* Improve quiz layout: add fixed topbar, include navigation, and clean up unused elements

- Add `.quiz-topbar` with fixed positioning and spacing in `quiz.scss`
- Update `base.html.twig` to include `quiz/nav.html.twig` in a new `nav` block
- Remove unused "Manage Quiz" button from `select_season.html.twig`

* Refactor generateTemplate to reuse quizToXlsx and add second example question

- generateTemplate now builds an in-memory Quiz entity and delegates to
  quizToXlsx, eliminating duplicate spreadsheet-building logic
- Adds a second example question "Wie is de mol?" with 10 Dutch names
  (5 male, 5 female) to better illustrate the import format
- Updates tests to assert both example questions and adds a test for the
  blank-row halt behaviour in fillQuizFromArray (achieving 100% coverage)

* Move PHPUnit cache to /tmp to avoid writing into the mounted volume

* Update src/Service/QuizSpreadsheetService.php

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-07-02 20:25:02 +00:00
2026-05-25 14:19:14 +02:00
2025-09-28 18:14:58 +02:00
2025-09-28 18:14:58 +02:00
2026-03-22 22:40:25 +01:00
2024-12-29 14:58:03 +01:00
2026-01-25 19:58:39 +01:00
2026-02-18 16:20:14 +01:00
WIP
2025-06-01 15:40:47 +02:00
2026-02-18 16:20:14 +01:00
2026-03-22 22:40:25 +01:00
2026-03-22 22:40:25 +01:00
2026-03-22 22:40:25 +01:00
2026-02-18 16:50:04 +01:00
2026-03-22 22:40:25 +01:00
2026-05-27 12:36:07 +02:00
2026-05-25 13:56:46 +00:00
2026-03-22 22:40:25 +01:00
2026-02-18 16:20:14 +01:00

Tijd voor de test

Requirements

Maken van de test

  • WIDM-tests met een variabel aantal vragen.
  • Vragen in een vaste volgorde zijn samen één test (een vraag kan niet bij meerdere tests horen).
  • Vragen hebben 2 of meer antwoordmogelijkheden. Slechts één antwoord is correct.
  • Meerdere test samen vormen een seizoen.
  • Een seizoen heeft één of geen actieve tests, als er een test actief is kan uitsluitend die test gemaakt worden.
  • Kandidaten kunnen een test maximaal 1 keer invullen.
  • Vanaf het moment dat de kandidaat op start klikt na het intypen van hun naam gaat de tijd lopen. Deze stopt na het aanklikken van een antwoord op de laatste vraag van de test.
  • Achtergrondmuziek

Schermen kijken

  • Nadat een speler een test heeft gemaakt (of vooraf als de namen vooraf ingevoerd zijn) kunnen jokers toegekend worden aan de test van kandidaat. Een positief getal om antwoorden goed te rekenen, een negatief getal om antwoorden fout te rekenen.
  • Vooraf kan gekozen worden hoe veel afvallers er zijn.
  • Bij het kijken naam rode en groene schermen wordt een naam ingevoerd. Er wordt een rood of groen scherm getoond.
  • Spelers kunnen geforceerd op groen of rood gezet worden, deze worden dan niet meegenomen in de berekening van de slechtste speler.

Statistieken

TBD

Nice to haves

  • Optie voor antwoord geven in twee klikken (selecteren en volgende).
S
Description
No description provided
Readme AGPL-3.0 19 MiB
Languages
PHP 79%
Twig 13.3%
Shell 3.2%
JavaScript 1.8%
Dockerfile 1.1%
Other 1.6%