mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-08-10 15:21:22 +02:00
refactor: combined duration (pages + minutes), has_annexes checkbox, remove Mo
- Remove Mo option from duration, keep only pages and minutes - Redesign duration fieldset: separate Pages input + Durée h:m inputs, both can be set together - Fix minutes input visibility: wider inputs (6ch), proper CSS layout - Add has_annexes checkbox to fichiers fragment + DB column + controllers - Display duration on admin backoffice recap page - Display duration on public partage recap page - Update public TFE page for new combined duration format - Migration 041: add duration_pages, duration_minutes, has_annexes columns; migrate data; recreate views
This commit is contained in:
@@ -131,6 +131,25 @@
|
||||
<dt>Mots-clés</dt><dd><?= htmlspecialchars($thesis['keywords']) ?></dd>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$_hasPages = isset($thesis['duration_pages']) && $thesis['duration_pages'] !== null;
|
||||
$_hasMins = isset($thesis['duration_minutes']) && $thesis['duration_minutes'] !== null;
|
||||
if ($_hasPages || $_hasMins):
|
||||
$_parts = [];
|
||||
if ($_hasPages) $_parts[] = $thesis['duration_pages'] . ' pages';
|
||||
if ($_hasMins) {
|
||||
$_h = (int)floor($thesis['duration_minutes'] / 60);
|
||||
$_m = $thesis['duration_minutes'] % 60;
|
||||
$_parts[] = $_h . 'h' . str_pad((string)$_m, 2, '0', STR_PAD_LEFT);
|
||||
}
|
||||
?>
|
||||
<dt>Durée</dt><dd><?= htmlspecialchars(implode(', ', $_parts)) ?></dd>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($thesis['has_annexes'])): ?>
|
||||
<dt>Annexes</dt><dd>Oui</dd>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($thesis['baiu_link']): ?>
|
||||
<dt>Lien BAIU</dt><dd><a href="<?= htmlspecialchars($thesis['baiu_link']) ?>" target="_blank" rel="noopener"><?= htmlspecialchars($thesis['baiu_link']) ?></a></dd>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -185,9 +185,15 @@ $websiteLabel = htmlspecialchars($_POST['website_label'] ?? '');
|
||||
|
||||
<!-- ── 4. Annexes ── -->
|
||||
<div id="annexes-input-block">
|
||||
<input type="hidden" name="has_annexes" value="0">
|
||||
<div class="admin-form-group">
|
||||
<label class="admin-checkbox-label">
|
||||
<input type="checkbox" name="has_annexes" value="1"
|
||||
<?= !empty($_POST['has_annexes']) ? 'checked' : '' ?>>
|
||||
Ce TFE contient des annexes
|
||||
</label>
|
||||
</div>
|
||||
<div class="admin-form-group admin-files-fieldgroup">
|
||||
<label for="annexe-files-input">Annexes (optionnel)</label>
|
||||
<label for="annexe-files-input">Fichiers annexes (optionnel)</label>
|
||||
<div class="admin-file-input">
|
||||
<input type="file" id="annexe-files-input"
|
||||
name="queue_file[annexe][]"
|
||||
|
||||
@@ -103,8 +103,7 @@ $existingWebsiteLabel = $existingWebsiteLabel ?? '';
|
||||
$checkedFormatsForSiteWeb = $checkedFormatsForSiteWeb ?? [];
|
||||
|
||||
// Duration (value + unit)
|
||||
$durationValue = $durationValue ?? null;
|
||||
$durationUnit = $durationUnit ?? 'pages';
|
||||
|
||||
|
||||
// WCAG 3.3.1: which field has a validation error (set by caller from App::consumeAutofocus())
|
||||
$errorFieldName = $errorFieldName ?? null;
|
||||
@@ -419,70 +418,46 @@ if ($filesMode === 'add'): ?>
|
||||
|
||||
<!-- ═══════════════════ Durée ═══════════════════ -->
|
||||
<?php
|
||||
$_durRaw = $durationValue ?? ($formData['duration_value'] ?? null);
|
||||
$_durUnit = $durationUnit ?? ($formData['duration_unit'] ?? 'pages');
|
||||
$_durFloat = $_durRaw !== null && $_durRaw !== '' ? (float)$_durRaw : null;
|
||||
// Pre-split stored hours into h/m/s for the time-input fields
|
||||
// Combined duration: pages (integer) + minutes (integer, stored as total minutes)
|
||||
$_pagesRaw = $formData['duration_pages'] ?? $currentRaw['duration_pages'] ?? null;
|
||||
$_minsRaw = $formData['duration_minutes'] ?? $currentRaw['duration_minutes'] ?? null;
|
||||
$_pages = $_pagesRaw !== null && $_pagesRaw !== '' ? (int)$_pagesRaw : null;
|
||||
$_totalMins = $_minsRaw !== null && $_minsRaw !== '' ? (int)$_minsRaw : null;
|
||||
// Pre-split total minutes into h/m for the time inputs
|
||||
$_durH = '';
|
||||
$_durM = '';
|
||||
$_durS = '';
|
||||
if ($_durFloat !== null && $_durUnit === 'durée') {
|
||||
$_durH = (int)floor($_durFloat);
|
||||
$_remaining = round(($_durFloat - $_durH) * 3600);
|
||||
$_durM = (int)floor($_remaining / 60);
|
||||
$_durS = $_remaining % 60;
|
||||
$_durH = (string)$_durH;
|
||||
$_durM = (string)$_durM;
|
||||
$_durS = (string)$_durS;
|
||||
if ($_totalMins !== null) {
|
||||
$_durH = (string)(int)floor($_totalMins / 60);
|
||||
$_durM = (string)($_totalMins % 60);
|
||||
}
|
||||
?>
|
||||
<fieldset id="duration-fieldset">
|
||||
<legend>Durée</legend>
|
||||
<div class="admin-form-group">
|
||||
<div>
|
||||
<label for="duration_unit">Unité :</label>
|
||||
<select id="duration_unit" name="duration_unit">
|
||||
<?php
|
||||
$_units = [
|
||||
'pages' => 'pages',
|
||||
'mo' => 'Mo',
|
||||
'durée' => 'durée (h:m:s)',
|
||||
];
|
||||
foreach ($_units as $_val => $_label): ?>
|
||||
<option value="<?= $_val ?>" <?= $_durUnit === $_val ? 'selected' : '' ?>><?= htmlspecialchars($_label) ?></option>
|
||||
<?php endforeach; unset($_units, $_val, $_label); ?>
|
||||
</select>
|
||||
</div>
|
||||
<!-- Integer input for pages / Mo -->
|
||||
<div id="duration-value-integer"<?= $_durUnit === 'durée' ? ' style="display:none"' : '' ?>>
|
||||
<label for="duration_value_int" id="duration-value-label">Valeur :</label>
|
||||
<input type="number" id="duration_value_int"
|
||||
value="<?= htmlspecialchars($_durUnit !== 'durée' ? (string)($_durFloat ?? '') : '') ?>"
|
||||
step="1" min="0" placeholder="0"
|
||||
<!-- Pages -->
|
||||
<div class="duration-field">
|
||||
<label for="duration_pages">Pages :</label>
|
||||
<input type="number" id="duration_pages" name="duration_pages"
|
||||
value="<?= htmlspecialchars($_pages !== null ? (string)$_pages : '') ?>"
|
||||
step="1" min="0" placeholder="Ex: 88"
|
||||
style="width: 8ch;">
|
||||
</div>
|
||||
<!-- Time inputs for durée -->
|
||||
<div id="duration-value-time" class="duration-time-inputs"<?= $_durUnit !== 'durée' ? ' style="display:none"' : '' ?>>
|
||||
<!-- Time duration (h:m) -->
|
||||
<div class="duration-field duration-time-field">
|
||||
<label>Durée :</label>
|
||||
<span class="duration-time-fields">
|
||||
<input type="number" id="duration_h" value="<?= htmlspecialchars($_durH) ?>"
|
||||
<input type="number" id="duration_h" name="duration_h" value="<?= htmlspecialchars($_durH) ?>"
|
||||
step="1" min="0" placeholder="0" style="width: 5ch;" aria-label="Heures">
|
||||
<span>h</span>
|
||||
<input type="number" id="duration_m" value="<?= htmlspecialchars($_durM) ?>"
|
||||
<input type="number" id="duration_m" name="duration_m" value="<?= htmlspecialchars($_durM) ?>"
|
||||
step="1" min="0" max="59" placeholder="0" style="width: 5ch;" aria-label="Minutes">
|
||||
<span>m</span>
|
||||
<input type="number" id="duration_s" value="<?= htmlspecialchars($_durS) ?>"
|
||||
step="1" min="0" max="59" placeholder="0" style="width: 5ch;" aria-label="Secondes">
|
||||
<span>s</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Hidden field: always submitted, populated by JS on unit change / submit -->
|
||||
<input type="hidden" id="duration_value" name="duration_value"
|
||||
value="<?= htmlspecialchars((string)($_durFloat ?? '')) ?>">
|
||||
<small>Optionnel. Exemples : 88 pages, 120 Mo, 1h30.</small>
|
||||
<small>Optionnel. Vous pouvez indiquer des pages, une durée, ou les deux.</small>
|
||||
</fieldset>
|
||||
<?php unset($_durRaw, $_durUnit, $_durFloat, $_durH, $_durM, $_durS, $_remaining); ?>
|
||||
<?php unset($_pagesRaw, $_minsRaw, $_pages, $_totalMins, $_durH, $_durM); ?>
|
||||
|
||||
<!-- ═══════════════════ Degrés d'ouverture et licences ═══════════════════ -->
|
||||
<?php
|
||||
|
||||
@@ -46,29 +46,23 @@
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($data["duration_value"]) && !empty($data["duration_unit"])): ?>
|
||||
<?php
|
||||
$_dVal = (float)$data["duration_value"];
|
||||
$_dUnit = $data["duration_unit"];
|
||||
$_label = match($_dUnit) {
|
||||
'pages' => 'pages',
|
||||
'mo' => 'Mo',
|
||||
'durée' => '',
|
||||
default => $_dUnit,
|
||||
};
|
||||
if ($_dUnit === 'durée') {
|
||||
$_hours = (int)floor($_dVal);
|
||||
$_mins = (int)round(($_dVal - $_hours) * 60);
|
||||
$_display = ($_mins > 0) ? "{$_hours}h{$_mins}" : "{$_hours}h";
|
||||
} else {
|
||||
$_display = ($_dVal == (int)$_dVal) ? (int)$_dVal : $_dVal;
|
||||
}
|
||||
$_hasPages = isset($data["duration_pages"]) && $data["duration_pages"] !== null;
|
||||
$_hasMins = isset($data["duration_minutes"]) && $data["duration_minutes"] !== null;
|
||||
if ($_hasPages || $_hasMins):
|
||||
$_parts = [];
|
||||
if ($_hasPages) $_parts[] = $data['duration_pages'] . ' pages';
|
||||
if ($_hasMins) {
|
||||
$_h = (int)floor($data['duration_minutes'] / 60);
|
||||
$_m = $data['duration_minutes'] % 60;
|
||||
$_parts[] = $_h . 'h' . str_pad((string)$_m, 2, '0', STR_PAD_LEFT);
|
||||
}
|
||||
?>
|
||||
<p class="tfe-meta-item">
|
||||
<span class="tfe-meta-label">Durée :</span>
|
||||
<?= $_display ?><?= $_label ? ' ' . htmlspecialchars($_label) : '' ?>
|
||||
<?= htmlspecialchars(implode(', ', $_parts)) ?>
|
||||
</p>
|
||||
<?php unset($_dVal, $_dUnit, $_label, $_display, $_hours, $_mins); endif; ?>
|
||||
<?php unset($_hasPages, $_hasMins, $_parts, $_h, $_m); endif; ?>
|
||||
|
||||
<?php if (!empty($data["languages"])): ?>
|
||||
<p class="tfe-meta-item">
|
||||
|
||||
Reference in New Issue
Block a user