130 lines
7.9 KiB
HTML
130 lines
7.9 KiB
HTML
<!DOCTYPE html>
|
|
<html xmlns:th="http://www.thymeleaf.org">
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
|
<meta charset="UTF-8">
|
|
<title>Créneau d'Entraînement - AS Talange</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<style> body { font-family: 'Inter', sans-serif; } </style>
|
|
</head>
|
|
<body class="bg-gray-50 text-gray-900 flex h-screen overflow-hidden">
|
|
<!-- Sidebar -->
|
|
<div th:replace="~{fragments/sidebar :: sidebar}"></div>
|
|
|
|
<main class="flex-1 flex flex-col h-screen overflow-hidden">
|
|
<!-- Header -->
|
|
<header class="h-16 bg-white border-b border-gray-200 flex items-center px-6">
|
|
<h2 class="text-lg font-semibold text-gray-800" th:text="${creneau.id == null ? 'Ajouter un Créneau d''Entraînement' : 'Modifier le Créneau d''Entraînement'}">Créneau</h2>
|
|
</header>
|
|
|
|
<!-- Form content -->
|
|
<div class="flex-1 overflow-auto p-6">
|
|
<div class="max-w-xl mx-auto bg-white rounded-xl shadow-sm border border-gray-100 p-8">
|
|
<form th:action="@{/planning}" th:object="${creneau}" method="post" class="space-y-6">
|
|
<input type="hidden" th:field="*{id}" />
|
|
<input type="hidden" th:field="*{saison.id}" th:if="${creneau.saison != null}" />
|
|
|
|
<!-- Catégorie -->
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Catégorie <span class="text-red-500">*</span></label>
|
|
<select th:field="*{categorie.id}" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
|
<option value="">Sélectionnez une catégorie</option>
|
|
<option th:each="cat : ${categories}" th:value="${cat.id}" th:text="${cat.nom}">U15</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Équipe (Optionnelle) -->
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Équipe</label>
|
|
<select id="planningEquipe" name="equipe.id" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
|
<option value="">Aucune équipe</option>
|
|
<option th:each="team : ${equipes}" th:value="${team.id}" th:text="${team.nom}" th:selected="${creneau.equipe != null && creneau.equipe.id == team.id}"></option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Terrain -->
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Terrain <span class="text-red-500">*</span></label>
|
|
<select th:field="*{terrain.id}" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
|
<option value="">Sélectionnez un terrain</option>
|
|
<option th:each="t : ${terrains}" th:value="${t.id}" th:text="${t.nom}">Terrain Vert</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Zone de terrain -->
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Zone de terrain <span class="text-red-500">*</span></label>
|
|
<select th:field="*{zone}" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
|
<option value="">Sélectionnez la zone occupée</option>
|
|
<option th:each="z : ${zones}" th:value="${z.name()}" th:text="${z.libelle}">Terrain Complet</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Jour de la semaine -->
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Jour de la semaine <span class="text-red-500">*</span></label>
|
|
<select th:field="*{jourSemaine}" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
|
<option value="">Sélectionnez le jour</option>
|
|
<option th:each="j : ${jours}" th:value="${j.name()}" th:text="${j.libelle}">Lundi</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Horaires (Début & Fin) -->
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Heure de début <span class="text-red-500">*</span></label>
|
|
<input type="time" th:field="*{heureDebut}" required min="08:00" max="22:00"
|
|
class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Heure de fin <span class="text-red-500">*</span></label>
|
|
<input type="time" th:field="*{heureFin}" required min="08:00" max="22:00"
|
|
class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Custom Validation Error Display -->
|
|
<div th:if="${#fields.hasErrors('heureDebut')}" class="text-red-500 text-xs font-semibold mt-1">
|
|
<p th:errors="*{heureDebut}"></p>
|
|
</div>
|
|
|
|
<!-- Info notice -->
|
|
<div class="bg-gray-50 border border-gray-200 rounded-lg p-4 text-xs text-gray-500">
|
|
<p class="font-semibold text-gray-700 mb-1">Information sur les plages horaires :</p>
|
|
<p>Les entraînements doivent être planifiés entre 08:00 et 22:00.</p>
|
|
<p class="mt-1">Les éventuels conflits de superposition d'horaires et de zones de terrain seront calculés et signalés automatiquement sur le tableau de bord.</p>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="pt-4 flex justify-end space-x-3 border-t border-gray-100">
|
|
<a th:href="@{/planning}" class="px-4 py-2 text-sm font-medium text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-50">Annuler</a>
|
|
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700">Enregistrer</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
const catSelect = document.getElementsByName('categorie.id')[0];
|
|
if (catSelect) {
|
|
catSelect.addEventListener('change', function() {
|
|
const catId = this.value;
|
|
const equipeSelect = document.getElementById('planningEquipe');
|
|
equipeSelect.innerHTML = '<option value="">Aucune équipe</option>';
|
|
if (catId) {
|
|
fetch('/categories/equipes?categorieId=' + catId)
|
|
.then(response => response.text())
|
|
.then(html => {
|
|
equipeSelect.innerHTML = html;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|