feat/frontend-thymeleaf-templates - #85
Merged
Merged
Conversation
Copy the mockup stylesheets into the served static resources: base.css (structural tokens and BEM components), theme-catppuccin.css (default theme, Catppuccin Latte light and Mocha dark via prefers-color-scheme), and theme-soft-paper.css (dormant alternate defining the same token names). The mockups under docs/design/ remain the design source of truth.
Serve Atkinson Hyperlegible (400, 700), Sora (600, 700), and JetBrains Mono (400) as woff2 files from the application itself, declared in fonts.css with font-display swap, and allow anonymous access to /fonts/**. Loading these from Google Fonts would transmit every visitor's IP address to Google before any consent, which LG Muenchen I (20 Jan 2022, 3 O 17493/20) held to violate the GDPR. All three families are SIL OFL licensed, which permits self-hosting; the license texts ship next to the font files as the OFL requires. Fixes #78
Add templates/fragments/layout.html with three plain Thymeleaf fragments (no layout dialect dependency): head(title) with the stylesheet links, header(current) with the skip link and an authentication-aware navigation (sec:authorize switches between the anonymous links and the Dashboard plus logout POST form; the current parameter drives aria-current=page), and the site footer carrying the privacy policy and source links. The chrome is marked lang=en so it stays correctly identified on the French privacy page.
Convert the five templates to the mockup markup, keeping the live Thymeleaf wiring: - home: hero with accent heading, decorative aria-hidden code card, feature cards; CTA buttons link to register and login. - login: narrow form card with labelled, autocompleted fields; the flash states become semantic alerts (registered and logout as role=status, error as role=alert), replacing the inline color style. - register: full server-driven error state: a role=alert summary when the form has errors, and per field a conditional form__input--invalid class, aria-invalid=true, and aria-describedby pointing at the hint and the th:errors span. Hints mirror the real Bean Validation constraints (username 3 to 50, password 8 to 100). Autocomplete uses new-password. - dashboard: authenticated header from the fragment (logout POST moved there), welcome heading with sec:authentication, honest empty state for courses until the course domain exists. - privacy: wrapped with the shared head, header, and footer fragments, content unchanged and still lang=fr. The per-page privacy links added earlier are superseded by the footer fragment, which carries the policy link on every page.
Add docs/rgaa.md: what the RGAA is (the French application of WCAG 2.1 AA, 106 criteria in 13 themes), what the DWWM certification expects, how accessibility is built into learn-dev by construction (WCAG-checked tokens, mockups encoding the wiring, shared layout fragments), a criteria map giving for each implemented criterion the requirement, the how, and the where (clickable file links), and the verification method with the manual passes still to run. Tracked by the RGAA epic issue #84. Linked from the README documentation list and from the CONTRIBUTING design expectations.
The happy-path flow test never rendered the register template: a template exception on GET /auth/register surfaced as a redirect to the login page (the error page sits behind authentication), not as a visible failure. Add a test that renders the empty form and the invalid-submission re-render, asserting the alert, aria-invalid, and the field error id are present in the response body.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #85 +/- ##
============================================
+ Coverage 76.13% 80.68% +4.54%
- Complexity 24 26 +2
============================================
Files 9 9
Lines 88 88
Branches 5 5
============================================
+ Hits 67 71 +4
+ Misses 16 13 -3
+ Partials 5 4 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR applies the mockup design to the application.
The five Thymeleaf pages now render the Catppuccin theme with the accessibility wiring designed in
docs/design/.fragments/layout.html, plainth:fragment): skip link, landmarks, and an auth-aware navigation (sec:authorizeswitches anonymous links vs Dashboard + logout POST;aria-current="page"driven per page). The chrome is markedlang="en"so it stays correctly identified on the French privacy page.static/css/:@font-face, OFL notices included; zero requests to Google (GDPR: LG Muenchen I, 3 O 17493/20).role="alert"summary, per-fieldaria-invalid+aria-describedbywired to theth:errorsspans; hints mirror the real Bean Validation bounds.Bug caught during browser verification: calling
#fields.hasAnyErrors()outside theth:objectscope madeGET /auth/register500 disguised as a redirect to login (the error page sits behind authentication).Fixed by moving
th:objectto<main>, and add a new test that renders the form and its invalid-submission re-render (the gap: the flow test only POSTed valid data).Verified:
- All tests passed, and all pages rendered light and dark,
- Fonts 200 from
/fonts/**with nofonts.googleapis.comtraffic,- Live error state shows computed
aria-describedby="username-hint username-error"(and none on valid fields),- Landmarks present,
- Mobile 375px reflows cleanly.
Closes #78