use crate::util::surrealdb::{client::sort_participants, client::Time, schemas}; use leptos::{ev::keydown, *}; use leptos_toaster::{Toast, ToastId, ToastVariant, Toasts}; use leptos_use::*; use web_sys::ScrollIntoViewOptions; cfg_if::cfg_if! { if #[cfg(feature = "ssr")] { use crate::util::surrealdb::{DB, schemas::Participant}; use crate::util::websocket::{server, ParticipantsAction}; use surrealdb::opt::PatchOp; use leptos::logging; } } #[server(AddTime)] async fn add_time( mut participant: schemas::Participant, event: String, time: u32, ) -> Result<(), ServerFnError> { let websocket_state = &server::WEBSOCKET_STATE; let updated: Option = DB .update(("participant", &participant.id)) .patch(PatchOp::replace(&("/events/".to_owned() + &event), time)) .await?; match updated { Some(participant_updated) => { logging::log!( "Updated participant: {} ({})", participant_updated.name, participant_updated.group ); let action = ParticipantsAction::Replace { participant: Participant { name: participant_updated.name.clone(), group: participant_updated.group.clone(), id: participant.id, events: participant_updated.events.clone(), }, }; match websocket_state.apply(action) { Ok(_) => Ok(()), Err(_) => Err(ServerFnError::new("Error sending websocket action")), } } None => Err(ServerFnError::ServerError(String::from( "Could not update participant", ))), } } /// Renders the home page of your application. #[component] pub fn AddTime() -> impl IntoView { let participants = use_context::().unwrap(); let toasts_context = expect_context::(); let container_ref: NodeRef = create_node_ref(); let name_input_ref: NodeRef = create_node_ref(); let event = create_rw_signal("lifesaver".to_string()); let name = create_rw_signal("".to_string()); let time = create_rw_signal(Time { minutes: 0, seconds: 0, milliseconds: 0, }); let selected_index = create_rw_signal::(0); let participants_sorted = create_memo(move |_| sort_participants(participants.get(), name.get())); let add_time_action = create_action(|input: &(schemas::Participant, String, u32)| { let input = input.to_owned(); async move { add_time(input.0, input.1, input.2).await } }); let form_submit = move |ev: ev::SubmitEvent| { ev.prevent_default(); let participant = &participants_sorted.get()[selected_index.get()]; add_time_action.dispatch(( participant.value.get(), event.get(), time.get().as_milliseconds(), )); let toast_id = ToastId::new(); toasts_context.toast( view! { }, Some(toast_id), None, ); name.set("".to_string()); time.set(Time { minutes: 0, seconds: 0, milliseconds: 0, }); let _ = name_input_ref.get().unwrap().focus(); }; let _ = use_event_listener(name_input_ref, keydown, move |evt| { match evt.key().as_str() { "ArrowDown" => selected_index.update(|x| { let len = participants.get_untracked().len(); if *x != len { *x += 1; } }), "ArrowUp" => selected_index.update(|x| { if *x != 0 { *x -= 1; } }), "Enter" => evt.prevent_default(), _ => (), } let el: web_sys::Element = container_ref .get_untracked() .unwrap() .children() .item(selected_index.get_untracked().try_into().unwrap()) .unwrap(); el.scroll_into_view_with_scroll_into_view_options( &ScrollIntoViewOptions::new().block(web_sys::ScrollLogicalPosition::Center), ); }); view! {

"Tijd toevoegen"

    {move || participants_sorted.get().into_iter().enumerate().map(|(i, participant)| view! {
  • {participant.value.get().name + " " + "(" + &participant.value.get().group + ")" }
  • }).collect_view()}
() { Ok(x) => x, Err(_) => 0, }); } prop:value=move || time.get().minutes /> () { Ok(x) => x, Err(_) => 0, }); } prop:value=move || time.get().seconds /> () { Ok(x) => x, Err(_) => 0, }); } prop:value=move || time.get().milliseconds />
} } #[component] pub fn SelectOption(is: &'static str, value: ReadSignal) -> impl IntoView { view! { } }