From 934f646efa0824489bf38decd01d02f5702dd5a8 Mon Sep 17 00:00:00 2001 From: marcantoinem <marc-antoine.m@outlook.com> Date: Sat, 27 Jul 2024 13:54:05 -0400 Subject: [PATCH] Improve number input --- aep-schedule-website/src/backend/state.rs | 24 +++++--- .../components/common/number_input.rs | 61 ++++++++++++++++--- .../src/frontend/components/options/form.rs | 2 +- .../components/options/optimizations.rs | 6 +- 4 files changed, 70 insertions(+), 23 deletions(-) diff --git a/aep-schedule-website/src/backend/state.rs b/aep-schedule-website/src/backend/state.rs index a9b37e0..391be8e 100644 --- a/aep-schedule-website/src/backend/state.rs +++ b/aep-schedule-website/src/backend/state.rs @@ -36,16 +36,20 @@ pub struct AppState { impl AppState { pub async fn new(leptos_options: LeptosOptions, routes: Vec<RouteListing>) -> Self { - let client = reqwest::Client::builder() - .user_agent("NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)") - .build() - .unwrap(); - let horsage = client.get(HORSAGE_URL).send().await.unwrap(); - let horsage = horsage.text().await.unwrap(); - let fermes = client.get(FERME_URL).send().await.unwrap(); - let fermes = fermes.text().await.unwrap(); - fs::write("horsage.csv", horsage).expect("Unable to write file"); - fs::write("fermes.csv", fermes).expect("Unable to write file"); + #[cfg(not(debug_assertions))] + { + // Don't spam Poly when reloading the website in debug mode + let client = reqwest::Client::builder() + .user_agent("NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)") + .build() + .unwrap(); + let horsage = client.get(HORSAGE_URL).send().await.unwrap(); + let horsage = horsage.text().await.unwrap(); + let fermes = client.get(FERME_URL).send().await.unwrap(); + let fermes = fermes.text().await.unwrap(); + fs::write("horsage.csv", horsage).expect("Unable to write file"); + fs::write("fermes.csv", fermes).expect("Unable to write file"); + } let horsage = BufReader::new(File::open("horsage.csv").unwrap()); let fermes = BufReader::new(File::open("fermes.csv").unwrap()); let courses = Arc::new(RwLock::new(Courses::from_csv(horsage, fermes))); diff --git a/aep-schedule-website/src/frontend/components/common/number_input.rs b/aep-schedule-website/src/frontend/components/common/number_input.rs index ad2ba1d..718ad19 100644 --- a/aep-schedule-website/src/frontend/components/common/number_input.rs +++ b/aep-schedule-website/src/frontend/components/common/number_input.rs @@ -1,19 +1,62 @@ use leptos::*; #[component] -pub fn NumberInput(#[prop(optional, into)] value: RwSignal<u8>, max: u8) -> impl IntoView { +pub fn NumberInput<F>( + #[prop(optional, into)] value: RwSignal<u8>, + max: u8, + label: &'static str, + submit: F, +) -> impl IntoView +where + F: Fn() + Copy + 'static, +{ let on_input = move |ev| { value.set(event_target_value(&ev).parse::<u8>().unwrap()); + submit(); + }; + + let minus = move |_| { + let v = value.get(); + if v > 0 { + value.set(v - 1); + submit(); + } + }; + + let plus = move |_| { + let v = value.get(); + if v != u8::MAX { + value.set(v + 1); + submit(); + } + submit(); }; view! { - <input - on:input=on_input - type="number" - min="0" - max=max - prop:value=value - class="number-input" - /> + <div class="flex flex-row gap-8 items-center"> + <p class="text-white font-sans">{label}</p> + <div class="relative flex items-center max-w-20"> + <button on:click=minus type="button" class="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-s-lg p-1 h-7 focus:ring-gray-100 focus:ring-2 focus:outline-none"> + <svg class="w-3 h-3 text-gray-900" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 2"> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h16"/> + </svg> + </button> + <input + type="numeric" + class="bg-gray-50 border-x-0 border-gray-300 h-7 text-center text-gray-900 text-sm focus:ring-amber-500 focus:border-amber-500 block w-full py-2.5" + placeholder="0" + on:input=on_input + type="number" + min="0" + max=max + prop:value=value + required /> + <button on:click=plus type="button" class="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-e-lg p-1 h-7 focus:ring-gray-100 focus:ring-2 focus:outline-none"> + <svg class="w-3 h-3 text-gray-900" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 18"> + <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 1v16M1 9h16"/> + </svg> + </button> + </div> + </div> } } diff --git a/aep-schedule-website/src/frontend/components/options/form.rs b/aep-schedule-website/src/frontend/components/options/form.rs index 01cf4fc..7b63932 100644 --- a/aep-schedule-website/src/frontend/components/options/form.rs +++ b/aep-schedule-website/src/frontend/components/options/form.rs @@ -28,7 +28,7 @@ pub fn OptionsForms(action: Action<SchedulesOptions, Vec<Schedule>>) -> impl Int view! { <CoursesSelector state=state submit/> <span class="grow"></span> - <div class="row-container input-item auto-bottom"><p>"Nombre de conflits maximum"</p><NumberInput value=state.max_nb_conflicts max=127/></div> + <NumberInput value=state.max_nb_conflicts max=127 label="Nombre de période de cours en conflits maximum: " submit/> <SelectOptimizations state=state submit/> <button on:click=submit_mobile class="lg:hidden select-none rounded-lg bg-amber-500 py-2 text-xl px-4 w-64 self-center text-center align-middle text-black shadow-md shadow-amber-500/20 transition-all hover:shadow-lg hover:shadow-amber-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none">"Générer les horaires"</button> } diff --git a/aep-schedule-website/src/frontend/components/options/optimizations.rs b/aep-schedule-website/src/frontend/components/options/optimizations.rs index 52d500f..e945853 100644 --- a/aep-schedule-website/src/frontend/components/options/optimizations.rs +++ b/aep-schedule-website/src/frontend/components/options/optimizations.rs @@ -30,7 +30,7 @@ where <div class="col-container"> <House weight=weight_house size="10vh"/> <p>"Plus de congés"</p> - <input type="range" min="0" max="4" class="opti-slider" prop:value=state.day_off on:input=move |ev| { + <input type="range" min="0" max="4" class="opti-slider accent-amber-500" prop:value=state.day_off on:input=move |ev| { state.day_off.set(event_target_value(&ev).parse::<u8>().unwrap()); submit(); }/> @@ -41,7 +41,7 @@ where <Sun weight=weight_morning size="10vh"/> </div> <p>"Cours plus tôt ou plus tard"</p> - <input type="range" min="-4" max="4" class="opti-slider" prop:value=state.morning on:input=move |ev| { + <input type="range" min="-4" max="4" class="opti-slider accent-amber-500" prop:value=state.morning on:input=move |ev| { state.morning.set(event_target_value(&ev).parse::<i8>().unwrap()); submit(); }/> @@ -49,7 +49,7 @@ where <div class="col-container"> <CalendarCheck weight=weight_finish size="10vh"/> <p>"Finir plus tôt"</p> - <input type="range" min="0" max="4" class="opti-slider" prop:value=state.finish_early on:input=move |ev| { + <input type="range" min="0" max="4" class="opti-slider accent-amber-500" prop:value=state.finish_early on:input=move |ev| { state.finish_early.set(event_target_value(&ev).parse::<u8>().unwrap()); submit(); }/> -- GitLab