From 4492f8d6e63513c9bbc86b1e5380cfd83a31b539 Mon Sep 17 00:00:00 2001 From: Jonathan Bourdon Date: Wed, 7 May 2025 13:47:51 -0400 Subject: [PATCH] feat(creator): add validation when editing the presentation infos --- frontend/src/views/creators/AboutCreator.vue | 42 +++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/frontend/src/views/creators/AboutCreator.vue b/frontend/src/views/creators/AboutCreator.vue index 75b07c1..f84f317 100644 --- a/frontend/src/views/creators/AboutCreator.vue +++ b/frontend/src/views/creators/AboutCreator.vue @@ -23,7 +23,7 @@ class="w-12 h-12 bg-hutopyPrimary rounded-full flex items-center justify-center shadow-lg" @click="saveChanges()" :title="t('save')" - :disabled="editableDescription.length > 2000" + :disabled="!canSave" > mdi-check @@ -60,7 +60,10 @@ :label="t('creator.sections.about.description')" :error-messages="descriptionError" :counter="2000" - :rules="[v => v.length <= 2000 || t('creator.validation.descriptionTooLong')]" + :rules="[ + v => !!v || t('creator.validation.descriptionRequired'), + v => v.length <= 2000 || t('creator.validation.descriptionTooLong') + ]" auto-grow rows="5" variant="outlined"> @@ -158,6 +161,26 @@ const editableVideoUrl = ref(""); const videoUrlError = ref(""); const descriptionError = ref(""); +// Computed property to check if we can save +const canSave = computed(() => { + // Check if description is empty or only whitespace + if (!editableDescription.value || editableDescription.value.trim() === '') { + return false; + } + + // Check if description is too long + if (editableDescription.value.length > 2000) { + return false; + } + + // Check if video URL is invalid (if one is provided) + if (editableVideoUrl.value && !validateVideoUrl(editableVideoUrl.value)) { + return false; + } + + return true; +}); + // Computed property to check if there are images const hasImages = computed(() => { // Only consider it has images if there are actual image URLs (not empty strings) @@ -255,6 +278,12 @@ async function saveChanges() { return; } + // Validate description is not empty + if (!editableDescription.value || editableDescription.value.trim() === '') { + descriptionError.value = t('creator.validation.descriptionRequired'); + return; + } + // Validate description length if (editableDescription.value.length > 2000) { descriptionError.value = t('creator.validation.descriptionTooLong'); @@ -447,7 +476,8 @@ function cancelEdit() { }, "validation": { "invalidYoutubeUrl": "Please enter a valid YouTube URL or video ID", - "descriptionTooLong": "Description cannot exceed 2000 characters" + "descriptionTooLong": "Description cannot exceed 2000 characters", + "descriptionRequired": "Description is required" } } }, @@ -476,7 +506,8 @@ function cancelEdit() { }, "validation": { "invalidYoutubeUrl": "Veuillez entrer une URL YouTube ou un ID de vidéo valide", - "descriptionTooLong": "La description ne peut pas dépasser 2000 caractères" + "descriptionTooLong": "La description ne peut pas dépasser 2000 caractères", + "descriptionRequired": "La description est obligatoire" } } }, @@ -505,7 +536,8 @@ function cancelEdit() { }, "validation": { "invalidYoutubeUrl": "Por favor, introduce una URL de YouTube o un ID de video válido", - "descriptionTooLong": "La descripción no puede exceder los 2000 caracteres" + "descriptionTooLong": "La descripción no puede exceder los 2000 caracteres", + "descriptionRequired": "La descripción es obligatoria" } } }