From bd7d6b381dca4b3579f5ddf1dd7014bf87087e49 Mon Sep 17 00:00:00 2001 From: marcantoinem <marc-antoine.m@outlook.com> Date: Sun, 28 Jul 2024 00:18:50 -0400 Subject: [PATCH] (feat) error message with problematic course --- .../src/frontend/components/options/todo.rs | 12 +++++++-- .../src/frontend/components/schedules.rs | 4 ++- .../src/frontend/pages/generator.rs | 27 ++++++++++++++++--- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/aep-schedule-website/src/frontend/components/options/todo.rs b/aep-schedule-website/src/frontend/components/options/todo.rs index 526f973..6ba9845 100644 --- a/aep-schedule-website/src/frontend/components/options/todo.rs +++ b/aep-schedule-website/src/frontend/components/options/todo.rs @@ -13,6 +13,7 @@ pub fn Step( step: ReadSignal<u8>, title: &'static str, description: &'static str, + #[prop(optional)] children: Option<Children>, ) -> impl IntoView { let bg_color = move || { match n.cmp(&step.get()) { @@ -40,6 +41,7 @@ pub fn Step( <p class="text-gray-700"> {description} </p> + {children.map(|c| c())} </div> </div> } @@ -49,6 +51,8 @@ pub fn Step( pub fn Todo( action: Action<SchedulesOptions, Vec<Schedule>>, step: ReadSignal<u8>, + section_error: RwSignal<String>, + personal_error: RwSignal<String>, ) -> impl IntoView { let state: OptionState = use_context().unwrap(); let first_generation_done: FirstGenerationDone = use_context().unwrap(); @@ -71,8 +75,12 @@ pub fn Todo( <div class="grid gap-6 row-gap-10"> <div class="lg:py-6 lg:pr-16"> <Step n=1 step title="Ajoutez vos cours" description="Utilisez la barre de recherche à gauche pour trouver et sélectionner vos cours. Une fois les cours sélectionnés, ils apparaîtront comme un onglet."/> - <Step n=2 step title="Ouvrez des sections" description="Assurez d'avoir au moins une section d'ouverte pour la théorie et la pratique. En sélectionnant l'onglet du cours et en appuyant sur les sections."/> - <Step n=3 step title="Forcer des heures libres" description="Sélectionnez une plage de temps à avoir absolument libre en pressant et relâchant sur votre horaire personnel."/> + <Step n=2 step title="Ouvrez des sections" description="Assurez d'avoir au moins une section d'ouverte pour la théorie et la pratique. En sélectionnant l'onglet du cours et en appuyant sur les sections."> + <span class="text-red-800">{section_error}</span> + </Step> + <Step n=3 step title="Forcer des heures libres" description="Sélectionnez une plage de temps à avoir absolument libre en pressant et relâchant sur votre horaire personnel."> + <span class="text-red-800">{personal_error}</span> + </Step> <Step n=4 step title="Ajustez les paramètres" description="Bougez les curseurs en bas pour ajuster vos préférences. Vous pouvez choisir d'avoir plus de congés, de commencer en moyenne les cours plus tôt ou plus tard, ou de finir en moyenne plus tôt."/> <div class="flex items-center"> <div class="flex flex-col items-center mr-4"> diff --git a/aep-schedule-website/src/frontend/components/schedules.rs b/aep-schedule-website/src/frontend/components/schedules.rs index 2ec6422..a03e5aa 100644 --- a/aep-schedule-website/src/frontend/components/schedules.rs +++ b/aep-schedule-website/src/frontend/components/schedules.rs @@ -8,6 +8,8 @@ use leptos::*; pub fn SchedulesComponent( read_signal: RwSignal<Option<Vec<Schedule>>>, action: Action<SchedulesOptions, Vec<Schedule>>, + section_error: RwSignal<String>, + personal_error: RwSignal<String>, step: ReadSignal<u8>, ) -> impl IntoView { view! { @@ -23,7 +25,7 @@ pub fn SchedulesComponent( } }).collect_view(), _ => view ! { - <Todo action step/> + <Todo action step section_error personal_error/> } } } diff --git a/aep-schedule-website/src/frontend/pages/generator.rs b/aep-schedule-website/src/frontend/pages/generator.rs index 783631e..a9b6757 100644 --- a/aep-schedule-website/src/frontend/pages/generator.rs +++ b/aep-schedule-website/src/frontend/pages/generator.rs @@ -31,18 +31,37 @@ pub fn GeneratorPage() -> impl IntoView { let state = OptionState::default(); + let section_error = create_rw_signal("".to_string()); + let personal_error = create_rw_signal("".to_string()); + let validate = move |state: OptionState| { let mut options: SchedulesOptions = (&state).into(); if options.courses_to_take.is_empty() { set_step.set(1); return; } - if !options.get_impossible_course().is_empty() { + let mut impossible_courses = options.get_impossible_course().into_iter(); + if let Some(first_impossible_course) = impossible_courses.next() { + let mut error = format!("Les sections des/du cours {}", first_impossible_course); + for impossible_course in impossible_courses { + error.push_str(", "); + error.push_str(&impossible_course); + } + error.push_str(" sont toutes fermées."); + section_error.set(error); set_step.set(2); return; } options.apply_personal_schedule(); - if !options.get_impossible_course().is_empty() { + let mut impossible_courses = options.get_impossible_course().into_iter(); + if let Some(first_impossible_course) = impossible_courses.next() { + let mut error = format!("Les sections des/du cours {}", first_impossible_course); + for impossible_course in impossible_courses { + error.push_str(", "); + error.push_str(&impossible_course); + } + error.push_str(" sont en conflits avec les heures libres sélectionnées."); + personal_error.set(error); set_step.set(3); return; } @@ -55,10 +74,10 @@ pub fn GeneratorPage() -> impl IntoView { view! { <aside class="left-panel" class=("hide-left-panel", hide)> - <OptionsForms action=action validate step/> + <OptionsForms action validate step/> </aside> <section class="right-panel"> - <SchedulesComponent action=action read_signal=action.value() step/> + <SchedulesComponent section_error personal_error action=action read_signal=action.value() step/> </section> <Notifications modal set_modal/> <button on:click=move |_| {set_hide(false)} id="go-back"><CaretDoubleRight weight=IconWeight::Regular size="3vh"/></button> -- GitLab