feat: admin tag management, maintenance mode, TFE visibility states

Tags admin:
- Database: getAllTagsWithCount(), renameTag(), mergeTag(), deleteTag()
- public/admin/tags.php: table with inline rename/merge/delete forms, CSRF-guarded
- public/admin/actions/tag.php: routes on action=rename|merge|delete
- templates/admin/head.php: 'Mots-clés' nav link
- admin.css: admin-inline-form, admin-btn--sm/warning/danger variants

Maintenance mode:
- config/bootstrap.php: gate on MAINTENANCE_FLAG file; admin/ and maintenance.php exempt
- public/maintenance.php: 503 dark minimal page
- public/admin/actions/maintenance.php: enable/disable toggle
- public/admin/index.php: status bar with toggle button
- admin.css: admin-maintenance-bar styles

TFE Visibility (Libre/Interne/Interdit via existing access_type_id):
- migration 002_add_visibility.sql: seeds access_types if missing
- Database: setVisibility(), bulkSetVisibility(), getAccessTypes()
- public/media.php: blocks thesis files for access_type_id=3
- public/tfe.php: shows access_type, context_note; hides file panel for Interdit
- public/admin/edit.php: access_type_id select + context_note textarea; saves both
- public/admin/index.php: three-state badge (Libre/Interne/Interdit) per row
- public/admin/actions/visibility.php: single + bulk visibility action handler
- admin.css: status-access badge variants
This commit is contained in:
Pontoporeia
2026-03-24 15:35:52 +01:00
parent 0933137540
commit 92e344b757
17 changed files with 661 additions and 35 deletions

0
storage/.gitkeep Normal file
View File

View File

@@ -0,0 +1,9 @@
-- Migration 002: Wire visibility states to existing access_type_id column.
-- The access_types table already has Libre (1), Interne (2), Interdit (3).
-- No structural changes needed — this migration is a no-op for the schema.
-- It documents the intent and ensures access_types seed rows exist.
INSERT OR IGNORE INTO access_types (id, name, description) VALUES
(1, 'Libre', 'TFE en libre accès à tout le monde sur la plateforme et en bibliothèque'),
(2, 'Interne', 'TFE accessible uniquement sur place en physique. Une note descriptive est disponible sur le site'),
(3, 'Interdit', 'TFE non disponible en physique ni sur le site. Une note descriptive est disponible sur le site');

Binary file not shown.