feat : refacto de la partie calendrier + ajout de validation sur les formulaires + ajout des jours fériés

This commit is contained in:
2026-02-09 14:25:18 +01:00
parent 03f5552dd4
commit c1025d6066
18 changed files with 1303 additions and 427 deletions

View File

@@ -64,16 +64,23 @@
<AppDrawer v-model="isDrawerOpen" :title="drawerTitle">
<form class="space-y-4" @submit.prevent="handleSubmit">
<div>
<label class="text-md font-semibold text-neutral-700" for="name">Nom</label>
<label class="text-md font-semibold text-neutral-700" for="name">
Nom <span class="text-red-600">*</span>
</label>
<input
id="name"
v-model="form.name"
type="text"
class="mt-2 w-full rounded-md border border-neutral-300 px-3 py-2 text-base text-neutral-900 focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-200"
:class="nameFieldClass"
/>
<p v-if="showNameError" class="mt-1 text-sm text-red-600">
Le nom du site est obligatoire.
</p>
</div>
<div>
<label class="text-md font-semibold text-neutral-700" for="color">Couleur</label>
<label class="text-md font-semibold text-neutral-700" for="color">
Couleur <span class="text-red-600">*</span>
</label>
<div class="mt-2 flex items-center gap-3">
<input
id="color"
@@ -95,7 +102,7 @@
<button
type="submit"
class="rounded-lg bg-primary-500 px-4 py-2 text-md font-semibold text-white hover:bg-secondary-500"
:disabled="isSubmitting"
:class="submitButtonClass"
>
Enregistrer
</button>
@@ -125,6 +132,31 @@ const form = reactive({
color: '#222783'
})
const validationTouched = reactive({
name: false
})
const isNameValid = computed(() => form.name.trim() !== '')
const isFormValid = computed(() => isNameValid.value)
const showNameError = computed(() => validationTouched.name && !isNameValid.value)
const baseInputClass =
'mt-2 w-full rounded-md border px-3 py-2 text-base text-neutral-900 focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-200'
const nameFieldClass = computed(() => {
if (showNameError.value) {
return `${baseInputClass} border-red-500`
}
return `${baseInputClass} border-neutral-300`
})
const submitButtonClass = computed(() => {
if (isSubmitting.value || !isFormValid.value) {
return 'opacity-50 cursor-not-allowed'
}
return ''
})
const loadSites = async () => {
isLoading.value = true
try {
@@ -162,6 +194,8 @@ const closeDrawer = () => {
const handleSubmit = async () => {
if (isSubmitting.value) return
validationTouched.name = true
if (!isFormValid.value) return
isSubmitting.value = true
try {
@@ -184,6 +218,12 @@ const handleSubmit = async () => {
}
}
watch(isDrawerOpen, (isOpen) => {
if (!isOpen) {
validationTouched.name = false
}
})
const confirmDelete = async (site: Site) => {
const ok = window.confirm(`Supprimer le site ${site.name} ?`)
if (!ok) return