mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
Mirrors the mots-clé tag-search system: dropdown suggestions from existing languages via HTMX, pill display with bin-icon remove buttons, 'Créer' option for new languages. Replaces the plain text input. - New partial: templates/partials/form/language-search.php - New fragment: public/partage/language-search-fragment.php - Admin wrapper: public/admin/language-search-fragment.php - Updated language-autre-fragment to return just the required asterisk indicator - Updated both controllers to handle language_autre as array (pill-based) with backward-compatible string path - Updated edit form to compute selectedOtherLanguages from DB - Registered new route in partage/index.php - Fix CSV importer: split comma-separated language column into individual entries - Add htmx active search to admin index, title line-clamp, predefined languages only in checkboxes - Admin index: filter form now uses htmx triggers (input delay:300ms on search, change on selects) to actively search without page reload - Sort links include hx-push-url for back-button support - Added loading indicator bar (.admin-search-indicator) - Title column: line-clamp at 2 lines with overflow hidden, native title attr tooltip for full text - Language checkboxes now show only 3 predefined languages (Français, Anglais, Néerlandais); all others go via the Autre langue search component - Added Database::getPredefinedLanguages() and excluded predefined from language-search-fragment suggestions - Included hidden sort/dir inputs in table-wrap so sort state preserved across filter changes - Fix language-search: block 'Créer' for predefined languages in dropdown The 'Créer' option in the language-search dropdown now also checks against the predefined set (français, anglais, néerlandais) to avoid offering creation of languages that already exist as checkboxes.
586 lines
28 KiB
PHP
586 lines
28 KiB
PHP
<?php
|
|
/**
|
|
* Shared TFE form partial — single source of truth for add, edit, and partage forms.
|
|
*
|
|
* Required variables (set by the including page):
|
|
* string $mode — 'add' | 'edit' | 'partage'
|
|
* string $formAction — form action URL
|
|
* string $hiddenFields — raw HTML for hidden inputs (csrf, thesis_id, etc.)
|
|
*
|
|
* old/value callables:
|
|
* callable $oldFn — fn(string $key, string $default=''): string (with escaping)
|
|
* callable $withAutofocusFn — fn(string $field, array $attrs=[]): array
|
|
*
|
|
* Data shared across fieldsets:
|
|
* array $formData — raw form repopulation data (not pre-escaped)
|
|
* array $orientations, $apPrograms, $finalityTypes, $languages, $formatTypes, $licenseTypes
|
|
*
|
|
* Jury data:
|
|
* ?string $juryPromoteur, $juryPromoteurUlb
|
|
* array $juryPromoteurs, $juryPromoteursUlb
|
|
* array $lecteursInternes, $lecteursExternes
|
|
* bool $showPromoteurUlb, $promoteurUlbConditional
|
|
*
|
|
* Licence / access:
|
|
* bool $libreEnabled, $interneEnabled, $interditEnabled
|
|
* string $generalitiesHtml
|
|
* int $defaultAccessTypeId
|
|
*
|
|
* Optional flags (all default to false):
|
|
* bool $showIntroHelp — render partage intro help block
|
|
* bool $showFlash — render flash banners (error/warning/success)
|
|
* bool $showContact — Contact checkbox fieldset
|
|
* bool $showCoverPreview — cover image preview + remove checkbox
|
|
* bool $showExistingFiles — existing thesis files list (sortable, deletable)
|
|
* bool $showBackoffice — Backoffice fieldset (context_note, jury_points, remarks, baiu_link, exemplaires, contact_interne, is_published)
|
|
* bool $showEmailConfirmation — E-mail de confirmation fieldset
|
|
|
|
* string $helpFn — fn(string $key): string (for help blocks)
|
|
* string $helpContent — current help block content (for help-block renders)
|
|
* array $helpBlocks — all help blocks (for intro)
|
|
*
|
|
* Files mode variables:
|
|
* string $filesMode — 'add' | 'edit' (determines which file inputs to show)
|
|
* ?string $currentCover — existing cover file info for edit mode
|
|
* array $currentFiles — existing thesis files for edit mode
|
|
* ?string $currentContextNote — existing context note for edit mode
|
|
* array $currentRaw — raw thesis row for edit mode
|
|
* ?string $contactPublic — contact visibility flag for edit mode
|
|
* ?string $contactInterne — contact email for edit mode
|
|
*
|
|
* Website:
|
|
* string $existingWebsiteUrl
|
|
* string $existingWebsiteLabel
|
|
* array $checkedFormatsForSiteWeb
|
|
*/
|
|
|
|
// ── Defaults ──────────────────────────────────────────────────────────────────
|
|
$mode = $mode ?? 'add';
|
|
// In admin add/edit, no field is required (admins can save partial records)
|
|
$adminMode = ($mode === 'add' || $mode === 'edit');
|
|
$formAction = $formAction ?? '';
|
|
$hiddenFields = $hiddenFields ?? '';
|
|
$formData = $formData ?? [];
|
|
$synopsisExtra = $synopsisExtra ?? "";
|
|
|
|
$juryPromoteur = $juryPromoteur ?? null;
|
|
$juryPromoteurs = $juryPromoteurs ?? [];
|
|
$juryPromoteurUlb = $juryPromoteurUlb ?? null;
|
|
$juryPromoteursUlb = $juryPromoteursUlb ?? [];
|
|
$lecteursInternes = $lecteursInternes ?? [];
|
|
$lecteursExternes = $lecteursExternes ?? [];
|
|
$juryPresident = $juryPresident ?? null;
|
|
$showPromoteurUlb = $showPromoteurUlb ?? true;
|
|
$promoteurUlbConditional = $promoteurUlbConditional ?? false;
|
|
|
|
$libreEnabled = $libreEnabled ?? true;
|
|
$interneEnabled = $interneEnabled ?? true;
|
|
$interditEnabled = $interditEnabled ?? true;
|
|
$generalitiesHtml = $generalitiesHtml ?? "";
|
|
$defaultAccessTypeId = $defaultAccessTypeId ?? 2;
|
|
|
|
// Optional flags
|
|
$showIntroHelp = $showIntroHelp ?? false;
|
|
$showFlash = $showFlash ?? false;
|
|
$showContact = $showContact ?? false;
|
|
$showCoverPreview = $showCoverPreview ?? false;
|
|
$showExistingFiles = $showExistingFiles ?? false;
|
|
$showBannerPreview = false; // Banners merged into covers — field removed
|
|
$showBackoffice = $showBackoffice ?? false;
|
|
$showEmailConfirmation = $showEmailConfirmation ?? false;
|
|
|
|
$oldFn = $oldFn ?? (function_exists('old') ? 'old' : fn($k, $d = '') => $d);
|
|
$withAutofocusFn = $withAutofocusFn ?? fn($field, $attrs = []) => $attrs;
|
|
$filesMode = $filesMode ?? 'add';
|
|
$existingWebsiteUrl = $existingWebsiteUrl ?? '';
|
|
$existingWebsiteLabel = $existingWebsiteLabel ?? '';
|
|
$checkedFormatsForSiteWeb = $checkedFormatsForSiteWeb ?? [];
|
|
?>
|
|
|
|
<?php if ($showIntroHelp && isset($helpFn)): ?>
|
|
<?php
|
|
$helpContent = $helpFn("partage_intro");
|
|
$helpKey = 'partage_intro';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
?>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($showFlash): ?>
|
|
<?php
|
|
$flashError = $_SESSION["_flash_error"] ?? null;
|
|
$flashWarning = $_SESSION["_flash_warning"] ?? null;
|
|
$flashSuccess = $_SESSION["_flash_success"] ?? null;
|
|
unset(
|
|
$_SESSION["_flash_error"],
|
|
$_SESSION["_flash_warning"],
|
|
$_SESSION["_flash_success"],
|
|
);
|
|
?>
|
|
<?php if ($flashError): ?>
|
|
<div class="flash-error" role="alert"><?= htmlspecialchars(
|
|
$flashError,
|
|
) ?></div>
|
|
<?php endif; ?>
|
|
<?php if ($flashWarning): ?>
|
|
<div class="flash-warning" id="flash-warning" role="alert" tabindex="-1"><?= htmlspecialchars(
|
|
$flashWarning,
|
|
) ?></div>
|
|
<script>document.addEventListener('DOMContentLoaded',function(){var el=document.getElementById('flash-warning');if(el){el.scrollIntoView({behavior:'smooth',block:'center'});el.focus();}});</script>
|
|
<?php endif; ?>
|
|
<?php if ($flashSuccess): ?>
|
|
<div class="flash-success" role="alert"><?= htmlspecialchars(
|
|
$flashSuccess,
|
|
) ?></div>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
|
|
<form action="<?= $formAction ?>" method="post" enctype="multipart/form-data" class="admin-form" data-beforeunload-guard>
|
|
<?= $hiddenFields ?>
|
|
|
|
<?php if (!$adminMode): ?>
|
|
<p class="required-note"><span class="asterisk">*</span> Champs obligatoires</p>
|
|
<?php endif; ?>
|
|
|
|
<!-- ═══════════════════ Informations du TFE ═══════════════════ -->
|
|
<?php
|
|
if ($mode === "partage" && isset($helpFn)) {
|
|
$helpContent = $helpFn("fieldset_tfe_info");
|
|
$helpKey = 'fieldset_tfe_info';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
}
|
|
include APP_ROOT . "/templates/partials/form/fieldset-tfe-info.php";
|
|
?>
|
|
|
|
<?php if ($showContact): ?>
|
|
<!-- ═══════════════════ Contact ═══════════════════ -->
|
|
<fieldset>
|
|
<legend>Contact</legend>
|
|
<div class="admin-form-group">
|
|
<label class="admin-checkbox-label">
|
|
<input type="checkbox" name="contact_public" value="1"
|
|
<?= !empty($formData["contact_public"]) ||
|
|
($contactPublic ?? false)
|
|
? "checked"
|
|
: "" ?>>
|
|
Rendre le contact visible publiquement sur la fiche du TFE
|
|
</label>
|
|
<small>L'adresse est toujours conservée en interne comme contact de référence.</small>
|
|
</div>
|
|
</fieldset>
|
|
<?php endif; ?>
|
|
|
|
<!-- ═══════════════════ Langue(s) ═══════════════════ -->
|
|
<?php
|
|
if ($mode === "partage" && isset($helpFn)) {
|
|
$helpContent = $helpFn("fieldset_languages");
|
|
$helpKey = 'fieldset_languages';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
}
|
|
?>
|
|
<fieldset id="languages-fieldset">
|
|
<legend>Langue(s)</legend>
|
|
<?php
|
|
$name = "languages";
|
|
$label = "Langue(s) du TFE :";
|
|
$options = $languages;
|
|
$checked = $formData["languages"] ?? [];
|
|
$required = !$adminMode;
|
|
$hxPost = $mode === 'partage' ? "/partage/language-autre-fragment" : "/admin/language-autre-fragment.php";
|
|
$hxTarget = "#language-autre-required";
|
|
$hxSwap = "outerHTML";
|
|
include APP_ROOT . "/templates/partials/form/checkbox-list.php";
|
|
unset($hxSwap);
|
|
?>
|
|
<?php
|
|
$_langAutreRequired = empty($formData["languages"]);
|
|
// Build selectedLanguages array from form data or current other languages
|
|
$_selectedOtherLangs = [];
|
|
if (!empty($formData['language_autre']) && is_array($formData['language_autre'])) {
|
|
foreach ($formData['language_autre'] as $_l) {
|
|
if (is_string($_l) && trim($_l) !== '') {
|
|
$_selectedOtherLangs[] = ['name' => trim($_l)];
|
|
}
|
|
}
|
|
} elseif (!empty($selectedOtherLanguages) && is_array($selectedOtherLanguages)) {
|
|
$_selectedOtherLangs = array_map(fn($n) => ['name' => $n], $selectedOtherLanguages);
|
|
} else {
|
|
$_langRaw = $formData["language_autre"] ?? '';
|
|
if (is_string($_langRaw) && $_langRaw !== '') {
|
|
foreach (array_map('trim', explode(',', $_langRaw)) as $_l) {
|
|
if ($_l !== '') {
|
|
$_selectedOtherLangs[] = ['name' => $_l];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
?>
|
|
<?php
|
|
$name = "language_autre";
|
|
$label = "Autre(s) langue(s) :";
|
|
$placeholder = "Rechercher une langue…";
|
|
$hint = "Si votre TFE contient une langue absente de la liste, précisez-la ici.";
|
|
$selectedLanguages = $_selectedOtherLangs;
|
|
$required = $_langAutreRequired && !$adminMode;
|
|
$hxPost = ($mode === 'partage') ? "/partage/language-search-fragment" : "/admin/language-search-fragment.php";
|
|
include APP_ROOT . "/templates/partials/form/language-search.php";
|
|
unset($_langAutreRequired, $_selectedOtherLangs, $_langRaw, $_l, $name, $label, $placeholder, $hint, $selectedLanguages, $required, $hxPost);
|
|
?>
|
|
</fieldset>
|
|
|
|
<!-- ═══════════════════ Mots-clés ═══════════════════ -->
|
|
<?php
|
|
if ($mode === "partage" && isset($helpFn)) {
|
|
$helpContent = $helpFn("fieldset_keywords");
|
|
$helpKey = 'fieldset_keywords';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
}
|
|
?>
|
|
<fieldset>
|
|
<legend>Mots-clés</legend>
|
|
<?php
|
|
// Build selectedTags array from form data or thesis keywords
|
|
$_selectedTags = [];
|
|
// If formData has tag as an array (pill-based repopulation), prefer that
|
|
if (!empty($formData['tag']) && is_array($formData['tag'])) {
|
|
foreach ($formData['tag'] as $_t) {
|
|
if (is_string($_t) && trim($_t) !== '') {
|
|
$_selectedTags[] = ['name' => trim($_t)];
|
|
}
|
|
}
|
|
} elseif (!empty($currentTags) && is_array($currentTags)) {
|
|
$_selectedTags = array_map(fn($n) => ['name' => $n], $currentTags);
|
|
} else {
|
|
$_tagsRaw = $formData["tag"] ?? '';
|
|
if (is_string($_tagsRaw) && $_tagsRaw !== '') {
|
|
foreach (array_map('trim', explode(',', $_tagsRaw)) as $_t) {
|
|
if ($_t !== '') {
|
|
$_selectedTags[] = ['name' => $_t];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$name = "tag";
|
|
$label = "Mots-clés :";
|
|
$placeholder = "Rechercher un mot-clé…";
|
|
$hint = "Tapez pour rechercher ou créer des mots-clés.";
|
|
$selectedTags = $_selectedTags;
|
|
$hxPost = ($mode === 'partage') ? "/partage/tag-search-fragment" : "/admin/tag-search-fragment.php";
|
|
include APP_ROOT . "/templates/partials/form/tag-search.php";
|
|
unset($_tagsRaw, $_selectedTags, $_t, $name, $label, $placeholder, $hint, $selectedTags, $hxPost);
|
|
?>
|
|
</fieldset>
|
|
|
|
<!-- ═══════════════════ Cadre académique ═══════════════════ -->
|
|
<?php
|
|
if ($mode === "partage" && isset($helpFn)) {
|
|
$helpContent = $helpFn("fieldset_academic");
|
|
$helpKey = 'fieldset_academic';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
}
|
|
include APP_ROOT .
|
|
"/templates/partials/form/fieldset-academic.php"; ?>
|
|
|
|
<!-- ═══════════════════ Composition du jury ═══════════════════ -->
|
|
<?php
|
|
if ($mode === "partage" && isset($helpFn)) {
|
|
$helpContent = $helpFn("fieldset_jury");
|
|
$helpKey = 'fieldset_jury';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
}
|
|
require APP_ROOT . "/templates/partials/form/jury-fieldset.php";
|
|
?>
|
|
|
|
<!-- ═══════════════════ Format(s) + Fichiers ═══════════════════ -->
|
|
<?php if ($filesMode === 'add'): ?>
|
|
<?php
|
|
// Add / partage mode: Format + Fichiers rendered as one HTMX-swappable block.
|
|
// Synthesise POST-like data so fichiers-fragment.php can render the initial state.
|
|
if ($mode === "partage" && isset($helpFn)) {
|
|
$helpContent = $helpFn("fieldset_files");
|
|
$helpKey = 'fieldset_files';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
}
|
|
// Temporarily populate $_POST so the fragment can read formats/website/annexes values.
|
|
$_savedPost = $_POST;
|
|
$_POST['formats'] = $checkedFormatsForSiteWeb;
|
|
$_POST['website_url'] = $existingWebsiteUrl;
|
|
$_POST['website_label'] = $existingWebsiteLabel;
|
|
$_POST['admin_mode'] = $adminMode ? '1' : '0';
|
|
$_POST['has_annexes'] = $formData['has_annexes'] ?? null;
|
|
include APP_ROOT . '/public/partage/fichiers-fragment.php';
|
|
$_POST = $_savedPost;
|
|
unset($_savedPost);
|
|
?>
|
|
<?php else: ?>
|
|
<!-- Edit mode: reuse the same Format + Fichiers HTMX fragment as add/partage -->
|
|
<?php
|
|
// Synthesise POST-like data so fichiers-fragment.php renders the initial state.
|
|
$_savedPost = $_POST;
|
|
$_POST['formats'] = $checkedFormatsForSiteWeb;
|
|
$_POST['website_url'] = $existingWebsiteUrl;
|
|
$_POST['website_label'] = $existingWebsiteLabel;
|
|
$_POST['admin_mode'] = $adminMode ? '1' : '0';
|
|
$_POST['edit_mode'] = '1';
|
|
$_POST['_cover'] = $currentCover['file_path'] ?? null;
|
|
$_POST['has_annexes'] = $formData['has_annexes'] ?? null;
|
|
include APP_ROOT . '/public/partage/fichiers-fragment.php';
|
|
$_POST = $_savedPost;
|
|
unset($_savedPost);
|
|
?>
|
|
|
|
<!-- Edit-only: existing files management -->
|
|
<div id="edit-existing-files-block">
|
|
<!-- Existing thesis files — sortable, with labels -->
|
|
<?php $thesisFilesList = array_values(
|
|
array_filter(
|
|
$currentFiles,
|
|
fn($f) => $f["file_type"] !== "cover",
|
|
),
|
|
); ?>
|
|
<?php if (!empty($thesisFilesList)): ?>
|
|
<div class="admin-form-group">
|
|
<label>Fichiers du TFE existants :</label>
|
|
<small style="display:block;margin-bottom:var(--space-2xs);color:var(--text-tertiary)">
|
|
Glissez-déposez les lignes pour réordonner les fichiers sur la page publique.
|
|
</small>
|
|
<ul id="existing-files-sortable" class="admin-file-list sortable-list">
|
|
<?php foreach ($thesisFilesList as $f):
|
|
|
|
$fExt = strtolower(
|
|
pathinfo($f["file_path"] ?? "", PATHINFO_EXTENSION),
|
|
);
|
|
$fType = $f["file_type"] ?? "other";
|
|
$fIcon = match (true) {
|
|
$fType === "main" || $fExt === "pdf" => "📄",
|
|
in_array($fExt, [
|
|
"jpg",
|
|
"jpeg",
|
|
"png",
|
|
"gif",
|
|
"webp",
|
|
])
|
|
=> "🖼️",
|
|
$fType === "video" ||
|
|
in_array($fExt, ["mp4", "webm", "mov", "ogv"])
|
|
=> "🎬",
|
|
$fType === "audio" ||
|
|
in_array($fExt, [
|
|
"mp3",
|
|
"ogg",
|
|
"wav",
|
|
"flac",
|
|
"aac",
|
|
"m4a",
|
|
])
|
|
=> "🔊",
|
|
$fType === "caption" || $fExt === "vtt" => "💬",
|
|
$fType === "website" => "🌐",
|
|
default => "📎",
|
|
};
|
|
$isExternalUrl =
|
|
str_starts_with($f["file_path"] ?? "", "http://") ||
|
|
str_starts_with($f["file_path"] ?? "", "https://");
|
|
$fLinkHref = $isExternalUrl
|
|
? htmlspecialchars($f["file_path"])
|
|
: "/media?path=" . urlencode($f["file_path"]);
|
|
?>
|
|
<li class="admin-file-list-item" data-file-id="<?= (int) $f[
|
|
"id"
|
|
] ?>">
|
|
<input type="hidden" name="file_sort_order[]" value="<?= (int) $f[
|
|
"id"
|
|
] ?>">
|
|
<span class="admin-file-drag-handle" title="Réordonner">⠿</span>
|
|
<span class="admin-file-icon-col"><?= $fIcon ?></span>
|
|
<span class="admin-file-info">
|
|
<a href="<?= $fLinkHref ?>" target="_blank" rel="noopener" class="admin-file-name">
|
|
<?= htmlspecialchars(
|
|
$f["file_name"] ??
|
|
basename($f["file_path"]),
|
|
) ?>
|
|
</a>
|
|
<span class="admin-file-meta-row">
|
|
<span class="admin-file-type-badge"><?= htmlspecialchars(
|
|
$fType,
|
|
) ?></span>
|
|
<?php if (
|
|
!empty($f["file_size"]) &&
|
|
$f["file_size"] > 0
|
|
): ?>
|
|
<span class="admin-file-size"><?= number_format(
|
|
$f["file_size"] / 1024 / 1024,
|
|
2,
|
|
) ?> MB</span>
|
|
<?php endif; ?>
|
|
</span>
|
|
<input type="text" name="file_label[<?= (int) $f[
|
|
"id"
|
|
] ?>]"
|
|
value="<?= htmlspecialchars(
|
|
$f["display_label"] ?? "",
|
|
) ?>"
|
|
placeholder="Légende / description (optionnel)"
|
|
class="admin-file-label-input">
|
|
</span>
|
|
<label class="admin-checkbox-label admin-file-delete">
|
|
<input type="checkbox" name="delete_files[]" value="<?= (int) $f[
|
|
"id"
|
|
] ?>"> Supprimer
|
|
</label>
|
|
</li>
|
|
<?php
|
|
endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div><!-- #edit-existing-files-block -->
|
|
<?php endif; ?>
|
|
|
|
<!-- ═══════════════════ Métadonnées complémentaires ═══════════════════
|
|
(Durée/Nombre de pages supprimés — redondants avec les fichiers attachés) -->
|
|
|
|
<!-- ═══════════════════ Degrés d'ouverture et licences ═══════════════════ -->
|
|
<?php
|
|
if ($mode === "partage" && isset($helpFn)) {
|
|
$helpContent = $helpFn("fieldset_access");
|
|
$helpKey = 'fieldset_access';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
}
|
|
include APP_ROOT .
|
|
"/templates/partials/form/fieldset-licence-explanation.php";
|
|
?>
|
|
|
|
<?php if ($showBackoffice): ?>
|
|
<!-- ═══════════════════ Backoffice ═══════════════════ -->
|
|
<fieldset>
|
|
<legend>Backoffice</legend>
|
|
|
|
<!-- 1. Note contextuelle -->
|
|
<div class="admin-form-group">
|
|
<label for="context_note">Note contextuelle :</label>
|
|
<div>
|
|
<textarea id="context_note" name="context_note"
|
|
rows="4" maxlength="1500"><?= htmlspecialchars(
|
|
$currentContextNote ??
|
|
($formData["context_note"] ?? ""),
|
|
) ?></textarea>
|
|
<small>Visible publiquement pour les TFE Interne ou Interdit. Max 1 500 caractères.</small>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 2. Points du jury -->
|
|
<div class="admin-form-group">
|
|
<label for="jury_points">Points du jury :</label>
|
|
<input type="number" id="jury_points" name="jury_points"
|
|
value="<?= htmlspecialchars(
|
|
$currentRaw["jury_points"] ??
|
|
($formData["jury_points"] ?? ""),
|
|
) ?>"
|
|
step="0.01" min="0" max="20" placeholder="sur 20">
|
|
<small>Note du jury (interne, non visible publiquement).</small>
|
|
</div>
|
|
|
|
<!-- 3. Remarques -->
|
|
<div class="admin-form-group">
|
|
<label for="remarks">Remarques :</label>
|
|
<textarea id="remarks" name="remarks" rows="4"><?= htmlspecialchars(
|
|
$currentRaw["remarks"] ?? ($formData["remarks"] ?? ""),
|
|
) ?></textarea>
|
|
<small>Notes internes (non visibles publiquement).</small>
|
|
</div>
|
|
|
|
<!-- 4. Lien BAIU -->
|
|
<?php
|
|
$name = 'lien'; $label = 'Lien BAIU :'; $value = $oldFn('lien');
|
|
$type = 'url'; $placeholder = 'https://...'; $hint = '';
|
|
include APP_ROOT . '/templates/partials/form/text-field.php';
|
|
?>
|
|
|
|
<!-- 5. Exemplaire BAIU -->
|
|
<div class="admin-form-group">
|
|
<label class="admin-checkbox-label">
|
|
<input type="checkbox" name="exemplaire_baiu" value="1"
|
|
<?= !empty(
|
|
$currentRaw["exemplaire_baiu"] ??
|
|
($formData["exemplaire_baiu"] ?? false)
|
|
)
|
|
? "checked"
|
|
: "" ?>>
|
|
Exemplaire physique BAIU
|
|
</label>
|
|
<small>Case logistique : cocher si un exemplaire physique est disponible à la BAIU.</small>
|
|
</div>
|
|
|
|
<!-- 6. Exemplaire ERG -->
|
|
<div class="admin-form-group">
|
|
<label class="admin-checkbox-label">
|
|
<input type="checkbox" name="exemplaire_erg" value="1"
|
|
<?= !empty(
|
|
$currentRaw["exemplaire_erg"] ??
|
|
($formData["exemplaire_erg"] ?? false)
|
|
)
|
|
? "checked"
|
|
: "" ?>>
|
|
Exemplaire physique ERG
|
|
</label>
|
|
<small>Case logistique : cocher si un exemplaire physique est disponible à l'ERG.</small>
|
|
</div>
|
|
|
|
<!-- 7. Contact interne -->
|
|
<div class="admin-form-group">
|
|
<label for="contact_interne">Contact interne :</label>
|
|
<input type="email" id="contact_interne" name="contact_interne"
|
|
value="<?= htmlspecialchars($contactInterne ?? $formData['contact_interne'] ?? '') ?>"
|
|
placeholder="ton.email@exemple.be">
|
|
<small>Adresse de contact interne (non visible publiquement). Peut être laissé vide.</small>
|
|
</div>
|
|
|
|
<!-- 8. Publication -->
|
|
<div class="admin-form-group">
|
|
<label class="admin-checkbox-label">
|
|
<input type="checkbox" name="is_published" value="1"
|
|
<?= !empty($currentRaw["is_published"] ?? false)
|
|
? "checked"
|
|
: "" ?>>
|
|
Publier ce TFE sur le site public
|
|
</label>
|
|
<small>Si coché, la fiche apparaîtra dans les résultats de recherche du site public.</small>
|
|
</div>
|
|
</fieldset>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($showEmailConfirmation): ?>
|
|
<!-- ═══════════════════ E-mail de confirmation ═══════════ -->
|
|
<fieldset>
|
|
<legend>E-mail de confirmation</legend>
|
|
<?php if ($mode === "partage" && isset($helpFn)): ?>
|
|
<?php
|
|
$helpContent = $helpFn("fieldset_email");
|
|
$helpKey = 'fieldset_email';
|
|
include APP_ROOT . "/templates/partials/form/form-help-block.php";
|
|
?>
|
|
<?php endif; ?>
|
|
<?php
|
|
$name = "confirmation_email";
|
|
$label = "Adresse e-mail :";
|
|
$value = $oldFn("confirmation_email");
|
|
$type = "email";
|
|
$required = !$adminMode;
|
|
$placeholder = "ton.email@exemple.be";
|
|
$hint =
|
|
"Nécessaire pour recevoir le récapitulatif de ta soumission.";
|
|
include APP_ROOT . "/templates/partials/form/text-field.php";
|
|
?>
|
|
</fieldset>
|
|
<?php endif; ?>
|
|
|
|
<div class="form-footer admin-form-footer">
|
|
<button type="submit" name="go" class="btn btn--primary"><?= $mode === 'edit' ? 'Enregistrer' : 'Soumettre' ?></button>
|
|
<?php if ($mode === 'add' || $mode === 'edit'): ?>
|
|
<a href="/admin/" class="btn btn--secondary">Annuler</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
</form>
|