Commit Graph

14 Commits

Author SHA1 Message Date
Pontoporeia
dfde88eaa5 Migrate all <img>-based icons to inline SVG via PHP helper
Replace every <img src="/assets/icons/..."> with <?= icon('name') ?>
across 26 template files. The PHP helper inlines the SVG markup into the
DOM so CSS color cascades naturally through fill="currentColor".

- Add src/icon.php helper: reads SVG file, sets width/height to 1em,
  injects aria-hidden, supports optional CSS class
- Fix 12 icon SVGs that had hardcoded fill="#000000" or missing fill attr
- Replace search.svg with Phosphor fill-based magnifying glass
- Add explicit SVG sizes for admin header nav icons (16px/20px)
- Scope public search icon CSS to form[role=search]:not(.header-search-form)
  to avoid breaking admin header layout; change stroke to fill
- Remove <img> filter: brightness(0) invert(1) hacks from admin.css
2026-06-21 17:52:27 +02:00
Pontoporeia
b1774e6e97 Replace all inline SVGs with icon files, ensure currentColor fill for proper color inheritance on buttons 2026-06-21 17:11:45 +02:00
Pontoporeia
19bf9f101a Refactor apropos/charte/licence pages: shared layout, TOC anchors, and UI polish
Unify the three public pages (à propos, charte, licence) onto a single
grid layout (.page-content) with sticky TOC sidebar, replacing the old
separate  /  /  markup.

- Merge about.php, charte.php, licence.php templates into shared
  .page-content / .content-section structure
- Add CommonMark HeadingPermalinkExtension for stable heading anchors
- Use SlugNormalizer for TOC links so they match rendered heading IDs
- Standardize link styling across content blocks: bold black, accent on
  hover (consistent with global link style)
- Fix code block wrapping: use pre-wrap instead of pre, constrain grid
  columns with min-width:0, auto scrollbar
- Fix apropos page grid placement: force content-section into column 2
  so contacts and credits stay in the content area, not the sidebar

Also includes accumulated WIP changes:
- Header gradient: hardcoded purple-to-green (replaces CSS variables)
- Search placeholder font
- Duration field: replace minutes/sec/heures with h:m:s time inputs
- TFE file optional for formats 1,4,6 with client-side JS toggle
- Licence form: em-dash to hyphen, details/summary classes
- Pill search: block Enter key form submission when no results
- Draft autosave: remove CSRF rotation (broke concurrent FilePond uploads)
- Language pill: clear hints for excluded main languages
- Search results: gradient placeholder cards for items without covers
- TFE display: format durée values as XhYm instead of decimal
2026-06-19 19:40:05 +02:00
Pontoporeia
3df1456781 fix: author name casing not updating — use ID lookup priority
Root cause: SQLite uses BINARY collation, so WHERE name = ? is
case-sensitive. When changing 'john doe' to 'John Doe', the name
lookup failed and fell through to the email path which didn't update
the name. The previous fix only added UPDATE in the name-match branch.

Fixes in findOrCreateAuthor:
1. Accept optional $idHint parameter — when known (edit flow), update
   directly by ID (fastest, zero ambiguity)
2. Add COLLATE NOCASE to the name lookup (fallback path)
3. Add UPDATE in the email fallback path too

setThesisAuthors now fetches existing author_ids before deletion and
passes them as position-based hints, so identity is always preserved.
2026-06-10 00:17:00 +02:00
Pontoporeia
da153fc604 Refactor HTMX fragment architecture: DRY split into auth endpoints + shared templates
- Created templates/partials/form/_licence.php (shared HTML, no auth logic)
- Created templates/partials/form/_format-website.php (shared HTML, no auth logic)
- Created src/FragmentRenderer.php helper for clean fragment rendering
- Created public/{admin,partage}/fragments/ subdirectories
- Created thin fragment endpoint files: auth guard + data fetch + render template
- Updated all hx-post references in templates to new fragments/ paths
- Updated partage/index.php routing for new fragments subdirectory
- Kept old fragment files as thin delegates for backward compat
- Updated nginx config: added PHP handler in /partage/ location block
2026-05-19 00:08:06 +02:00
Pontoporeia
2f4ac22bcb Fix Interdit Info text 2026-05-19 00:08:06 +02:00
Pontoporeia
8bf95f4e14 feat: refactor licence fragment — Libre→CC2r+licence, Interne→opt-in want_license, Interdit→none, add details/summary to license UI 2026-05-19 00:08:06 +02:00
Pontoporeia
8a4b2541fb Fix: email clearing in findOrCreateAuthor, htmlspecialchars(null) crash in old(), dead contact_interne field, access_type_id radio clearing
- findOrCreateAuthor: always update email column (pass null when empty/falsy) so clearing an email actually persists
- admin/add.php & admin/edit.php old(): add null guard before htmlspecialchars, cast to string
- jury-fieldset.php: guard against old() returning array for scalar-checked jury_lecteur keys
- formulaire.php: only suppress display_errors in production (not cli-server dev mode)
- Removed dead contact_interne field from backoffice form (no DB column, never saved)
- Removed dead contactInterne validation from ThesisCreateController
- Added "— Non défini" radio option for access_type_id in admin mode for clearing
- Fixed strict int-vs-string comparison breaking radio button checked detection
2026-05-19 00:08:05 +02:00
Pontoporeia
21c2b55bfb style: normalize headers, overtype editor rounded corners, remove duplicate cover preview, thesis-add-header grid layout, subtitle below header with top gradient 2026-05-19 00:08:05 +02:00
Pontoporeia
95fcbc919a Remove required from all admin add/edit form inputs
- Skip required-field validation for orientation/ap/finality/licence/jury in admin add+edit
2026-05-13 17:59:13 +02:00
Pontoporeia
696259afae Fix form field required states & missing fields per spec
- Admin add: add contact_public checkbox (matching edit form)
- All forms: formats checkbox-list now required
- All forms: jury promoteur·ice interne required, lecteur·ice interne/externe required
- All forms: licence select now required
- Admin edit: add E-mail de confirmation fieldset
- Partage: contact always visible when provided (no contact_public field)
- Partage: filter PACS from AP programs dropdown
- Server-side validation: formats, jury, licence required (create + edit controllers)
- Autofocus mappings for new validation errors
- No duplicate asterisks — verified across all rendered fields
- fix: add missing old() function in admin edit controller
- refactor: move admin email field to Backoffice as Contact interne, never send email
- Untrack admin.log (covered by .gitignore)
2026-05-07 23:39:41 +02:00
Pontoporeia
24d68dda59 refactor form structure per new spec + fix
- split jury into interne/externe/ULB,
- remove president from student form,
- add language_autre,
- split duration into pages+minutes+annexes,
- move licence to degrés d'ouverture with CC2r,
- add license_custom,
- filter PACS from student AP list,
- editable généralités help block,
- Libre toggle per settings

Fix:
- missing comma after cc4r column in schema.sql
- remove duplicate form footer from partage template
- remove couverture from student files fieldset; add promoteur ULB conditional disable via JS on Approfondi
- promoteur ULB: remove 'si applicable', make required when visible
2026-05-07 19:43:43 +02:00
Pontoporeia
80b7fddea4 fix: partials must not unset caller-owned $formData
fieldset-academic.php, fieldset-metadata.php and fieldset-licence-explanation.php
were each calling unset($formData) (or wrong variable) in their cleanup block,
destroying the variable in the parent renderShareLinkForm() scope.  This caused
an Undefined variable / TypeError on old($formData, ...) for any field rendered
after those partials (e.g. confirmation_email at line 328).

Fix: remove $formData from the unset() calls; fieldset-licence-explanation.php
was also unsetting the wrong name — corrected to unset($n) which is the variable
it actually declares.
2026-04-29 21:56:42 +02:00
Pontoporeia
d665cb502d centralise form fieldsets into shared partials; add TODO stubs in partage form 2026-04-29 20:59:35 +02:00