From 68fa303a38d78ed5b68bad1431028052e8bc1eea Mon Sep 17 00:00:00 2001 From: traxys Date: Mon, 29 May 2023 17:24:34 +0200 Subject: [PATCH] app: Implement disconnection & leaving an household --- app/src/bootstrap.rs | 46 ++++++++++++++++++++++++++ app/src/main.rs | 6 ++-- app/src/sidebar.rs | 78 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 127 insertions(+), 3 deletions(-) diff --git a/app/src/bootstrap.rs b/app/src/bootstrap.rs index ada8be4..db35e43 100644 --- a/app/src/bootstrap.rs +++ b/app/src/bootstrap.rs @@ -58,6 +58,52 @@ pub fn Modal(props: &ModalProps) -> Html { } } +#[derive(Properties, PartialEq)] +pub struct ConfirmDangerModalProps { + pub id: AttrValue, + #[prop_or(true)] + pub fade: bool, + #[prop_or_default] + pub centered: bool, + pub title: AttrValue, + pub on_confirm: Callback<()>, + pub children: Children, +} + +#[function_component] +pub fn ConfirmDangerModal( + ConfirmDangerModalProps { + id, + fade, + centered, + title, + children, + on_confirm, + }: &ConfirmDangerModalProps, +) -> Html { + let on_confirm = on_confirm.clone(); + html! { + + + { for children.iter() } + + + + + + + } +} + #[derive(Properties, PartialEq)] pub struct TitledModalProps { pub id: AttrValue, diff --git a/app/src/main.rs b/app/src/main.rs index 9b1afaa..4706ad4 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -25,10 +25,12 @@ const API_ROUTE: &str = match option_env!("REGALADE_API_SERVER_BASE") { Some(v) => v, }; +#[macro_export] macro_rules! api { - ($($arg:tt)*) => { + ($($arg:tt)*) => {{ + use $crate::API_ROUTE; &format!("{API_ROUTE}/api/{}", format_args!($($arg)*)) - }; + }}; } #[derive(Routable, Debug, Clone, Copy, PartialEq, Eq)] diff --git a/app/src/sidebar.rs b/app/src/sidebar.rs index 6ba9b87..bcc0be3 100644 --- a/app/src/sidebar.rs +++ b/app/src/sidebar.rs @@ -1,7 +1,10 @@ -use crate::{RegaladeGlobalState, Route}; +use gloo_storage::{LocalStorage, Storage}; +use uuid::Uuid; use yew::prelude::*; use yew_router::prelude::*; +use crate::{api, bootstrap::ConfirmDangerModal, RegaladeGlobalState, Route}; + #[derive(PartialEq)] struct MenuEntry { icon: &'static str, @@ -16,9 +19,54 @@ struct SidebarProps { children: Children, } +async fn do_leave(token: String, household: Uuid) -> anyhow::Result<()> { + let rsp = gloo_net::http::Request::delete(api!("household/{household}")) + .header("Authorization", &format!("Bearer {token}")) + .send() + .await?; + + if !rsp.ok() { + let body = rsp.body(); + match body { + None => anyhow::bail!("Could not leave: {rsp:?}"), + Some(s) => anyhow::bail!("Could not leave: {}", s.to_string()), + } + } + + LocalStorage::delete("household"); + + Ok(()) +} + #[function_component] fn Sidebar(props: &SidebarProps) -> Html { let global_state = use_state(RegaladeGlobalState::get); + let navigator = use_navigator().unwrap(); + + let token = global_state.token.token.clone(); + let household = global_state.household.id; + let nav = navigator.clone(); + let leave_household = Callback::from(move |()| { + let token = token.clone(); + let nav = nav.clone(); + wasm_bindgen_futures::spawn_local(async move { + match do_leave(token, household).await { + Err(e) => { + log::error!("Could not leave household: {e:?}"); + } + Ok(_) => { + nav.push(&Route::HouseholdSelect); + } + } + }) + }); + + let logout = Callback::from(move |_| { + LocalStorage::delete("token"); + LocalStorage::delete("household"); + + navigator.push(&Route::HouseholdSelect); + }); html! {
@@ -105,7 +153,35 @@ fn Sidebar(props: &SidebarProps) -> Html { {format!("{} ({})", global_state.household.name, global_state.token.name)} + + {format!("Are you sure you want to leave the household '{}' ?", global_state.household.name)} +