use super::error::error_provider::ErrorContext; use crate::services::rest::RestService; use crate::services::rest::RestServiceError; use common::CreateMilestone; use wasm_bindgen::JsCast; use wasm_bindgen_futures::spawn_local; use web_sys::HtmlInputElement; use yew::html; use yew::Callback; use yew::Component; use yew::Html; use yew::NodeRef; use yew_router::scope_ext::RouterScopeExt; #[derive(Debug)] pub enum Msg { Submit, SubmitResult(Result<(), RestServiceError>), UpdateInput(String), } #[derive(Default)] pub struct CreateMilestoneComponent { input_value: String, submitted: bool, input_ref: NodeRef, } impl Component for CreateMilestoneComponent { type Message = Msg; type Properties = (); fn create(_ctx: &yew::Context) -> Self { Self::default() } fn rendered(&mut self, _ctx: &yew::Context, first_render: bool) { if first_render { if let Some(input_element) = self.input_ref.get() { let input_element = input_element .dyn_into::() .expect("Failed to cast input element"); input_element.focus().expect("Failed to focus input"); } } } fn update(&mut self, ctx: &yew::Context, msg: Self::Message) -> bool { match msg { Msg::Submit => { log::info!("Creating achievement"); let Ok(goal) = self.input_value.parse::() else { return false; }; let goal = goal as usize; let payload = CreateMilestone { goal }; let link = ctx.link().clone(); spawn_local(async move { let res = RestService::create_milestone(payload).await; link.send_message(Msg::SubmitResult(res)); }); self.submitted = true; true } Msg::SubmitResult(result) => { match result { Ok(_response) => { let nav = ctx.link().navigator().unwrap(); nav.push(&crate::Route::Root); } Err(err) => { let (error_context, _context_listener) = ctx .link() .context(Callback::from(|_: ErrorContext| ())) .expect("No Error Context Provided"); log::info!("dispatching error"); error_context.dispatch(err.to_string()); } }; true } Msg::UpdateInput(value) => { self.input_value = value; true } } } fn view(&self, ctx: &yew::Context) -> Html { let link = ctx.link().clone(); let nav = ctx.link().navigator().unwrap(); if self.submitted { let onclick_go_back = Callback::from(move |_: web_sys::MouseEvent| { nav.push(&crate::Route::Root); }); html! { <>

{"Submitted!"}

} } else { let onclick_go_back = Callback::from(move |_: web_sys::MouseEvent| { nav.push(&crate::Route::Root); }); let onsubmit = link.callback(|e: web_sys::SubmitEvent| { e.prevent_default(); Msg::Submit }); let oninput = link.callback(|e: web_sys::InputEvent| { let Some(input) = e .target() .and_then(|t| t.dyn_into::().ok()) else { unreachable!() }; Msg::UpdateInput(input.value()) }); html! { <>

} } } }