Skip to content

Commit 1524567

Browse files
committed
feat: added leave group button
1 parent b8da7f7 commit 1524567

6 files changed

Lines changed: 125 additions & 50 deletions

File tree

packages/api/src/routes/groups.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ pub async fn remove_user_from_group(
154154
}
155155
}
156156

157+
#[post("/api/groups/{group_id}/leave-group", auth: Extension<server::AuthenticationState>)]
158+
pub async fn leave_group(group_id: i32) -> Result<NoContent, ServerFnError> {
159+
let user = auth.user.as_ref().or_unauthorized("Not authenticated")?;
160+
remove_user_from_group(group_id, user.id).await
161+
}
162+
157163
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
158164
pub struct GroupDetailData {
159165
pub name: String,

packages/frontend/src/components/ui/events/eventlist.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
use crate::components::ui::events::eventlistentry::{EventListEntry, SharedEventRow};
2-
use crate::components::ui::list::List;
3-
use crate::components::ui::toaster::{ToastOptions, use_toaster};
4-
use api::routes::events::invitations::list_shared_friend_events;
5-
use api::routes::events::{delete_event, leave_event, list_events, remove_event_from_group};
1+
use crate::components::ui::{
2+
events::eventlistentry::{EventListEntry, SharedEventRow},
3+
list::List,
4+
toaster::{ToastOptions, use_toaster},
5+
};
6+
use api::routes::events::{
7+
invitations::list_shared_friend_events,
8+
{delete_event, leave_event, list_events, remove_event_from_group},
9+
};
610
use api::routes::groups::retrieve_group;
711
use dioxus::prelude::*;
812
use roommates::message_from_captured_error;

packages/frontend/src/components/ui/events/eventlistentry.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
use crate::Route;
22
use crate::components::tooltip::Tooltip;
3-
use crate::components::ui::form::submit_button::SubmitButton;
43
use crate::components::ui::{
54
button::{Button, ButtonVariant},
65
dialog::{Dialog, DialogAction, DialogContent, DialogTrigger, use_dialog},
6+
form::submit_button::SubmitButton,
77
form::vectorselect::VectorSelect,
88
list::{ComplexListDetails, List, ListRow},
99
toaster::{ToastOptions, use_toaster},
1010
};
1111
use api::routes::events::{add_event_to_group, list_event_groups, list_event_members};
1212
use api::routes::groups::list_groups;
1313
use dioxus::prelude::*;
14-
use dioxus_free_icons::Icon;
15-
use dioxus_free_icons::icons::ld_icons::{
16-
LdEye, LdEyeOff, LdLogOut, LdMapPin, LdRefreshCcw, LdTrash, LdUserPlus, LdUsers,
14+
use dioxus_free_icons::{
15+
Icon,
16+
icons::ld_icons::{
17+
LdEye, LdEyeOff, LdLogOut, LdMapPin, LdRefreshCcw, LdTrash, LdUserPlus, LdUsers,
18+
},
19+
};
20+
use form_hooks::{
21+
use_form::{use_form, use_on_submit},
22+
use_form_field::use_form_field,
23+
validators,
1724
};
18-
use form_hooks::use_form::{use_form, use_on_submit};
19-
use form_hooks::use_form_field::use_form_field;
20-
use form_hooks::validators;
2125
use roommates::message_from_captured_error;
2226
use time::macros::format_description;
2327

packages/frontend/src/components/ui/groupcard.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use crate::Route;
22
use crate::components::ui::card::{Card, CardBody, CardTitle};
33
use api::routes::groups::retrieve_group;
44
use dioxus::prelude::*;
5-
use dioxus_free_icons::Icon;
6-
use dioxus_free_icons::icons::ld_icons::LdSquarePen;
5+
use dioxus_free_icons::{Icon, icons::ld_icons::LdSquarePen};
76

87
#[component]
98
pub fn GroupCard(group_id: i32) -> Element {

packages/frontend/src/views/groups/group_detailed.rs

Lines changed: 82 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
use crate::Route;
2-
use crate::components::ui::button::{Button, ButtonShape, ButtonVariant};
3-
use crate::components::ui::card::{Card, CardActions, CardBody, CardTitle};
4-
use crate::components::ui::dialog::{
5-
Dialog, DialogAction, DialogContent, DialogTrigger, use_dialog,
2+
use crate::components::ui::{
3+
button::{Button, ButtonShape, ButtonVariant},
4+
card::{Card, CardActions, CardBody, CardTitle},
5+
dialog::{Dialog, DialogAction, DialogContent, DialogTrigger, use_dialog},
6+
events::eventlist::EventListGroups,
7+
form::input::Input,
8+
form::submit_button::SubmitButton,
9+
list::{ComplexList, ListDetails, ListRow},
10+
toaster::{ToastOptions, use_toaster},
611
};
7-
use crate::components::ui::events::eventlist::EventListGroups;
8-
use crate::components::ui::form::input::Input;
9-
use crate::components::ui::form::submit_button::SubmitButton;
10-
use crate::components::ui::list::{ComplexList, ListDetails, ListRow};
11-
use crate::components::ui::toaster::{ToastOptions, use_toaster};
12-
use api::routes::groups::retrieve_group;
13-
use api::routes::groups::{
14-
add_user_to_group, change_group_name, delete_group, remove_user_from_group,
12+
use api::routes::{
13+
groups::{
14+
add_user_to_group, change_group_name, delete_group, leave_group, remove_user_from_group,
15+
retrieve_group,
16+
},
17+
users::{EMAIL_REGEX, UserInfo},
1518
};
16-
use api::routes::users::{EMAIL_REGEX, UserInfo};
1719
use dioxus::prelude::*;
18-
use dioxus_free_icons::Icon;
19-
use dioxus_free_icons::icons::ld_icons::{LdMail, LdMinus, LdPlus, LdUsers};
20-
use form_hooks::use_form::{use_form, use_on_submit};
21-
use form_hooks::use_form_field::use_form_field;
22-
use form_hooks::validators;
20+
use dioxus_free_icons::{
21+
Icon,
22+
icons::ld_icons::{LdLogOut, LdMail, LdMinus, LdPlus, LdTrash, LdUsers},
23+
};
24+
use form_hooks::{
25+
use_form::{use_form, use_on_submit},
26+
use_form_field::use_form_field,
27+
validators,
28+
};
2329
use regex::Regex;
2430
use roommates::message_from_captured_error;
2531

@@ -133,7 +139,7 @@ pub fn EditGroup(group_id: i32) -> Element {
133139
}
134140
}
135141
}
136-
div { class: "relative flex flex-col md:w-1/6 overflow-y-auto w-full",
142+
div { class: "relative flex flex-col md:w-1/6 overflow-y-auto w-full pb-32",
137143
ComplexList {
138144
header: rsx! {
139145
div { class: "flex justify-between items-center w-full",
@@ -171,19 +177,31 @@ pub fn EditGroup(group_id: i32) -> Element {
171177
}
172178
}
173179
}
174-
div {
180+
div { class: "fixed bottom-16 lg:bottom-4 right-4 flex gap-3",
175181
Dialog {
176182
DialogTrigger {
177-
variant: ButtonVariant::Primary,
183+
variant: ButtonVariant::Error,
178184
shape: ButtonShape::Default,
179185
ghost: false,
180-
class: "fixed bottom-16 lg:bottom-4 right-4 btn btn-primary lg:btn-lg",
181-
"Delete group"
186+
class: "btn lg:btn-lg",
187+
Icon { icon: LdTrash }
182188
}
183189
DialogContent { title: "Do you want to delete this group?",
184190
DeleteGroup { group_id }
185191
}
186192
}
193+
Dialog {
194+
DialogTrigger {
195+
variant: ButtonVariant::Error,
196+
shape: ButtonShape::Default,
197+
ghost: false,
198+
class: "btn lg:btn-lg",
199+
Icon { icon: LdLogOut }
200+
}
201+
DialogContent { title: "Do you want to leave this group?",
202+
LeaveGroup { group_id }
203+
}
204+
}
187205
}
188206
}
189207
}
@@ -361,3 +379,44 @@ pub fn DeleteGroup(group_id: i32) -> Element {
361379
}
362380
}
363381
}
382+
383+
#[component]
384+
pub fn LeaveGroup(group_id: i32) -> Element {
385+
let mut toaster = use_toaster();
386+
let dialog = use_dialog();
387+
let mut leave_group = use_action(leave_group);
388+
let nav = navigator();
389+
390+
rsx! {
391+
DialogAction {
392+
Button {
393+
onclick: move |_| {
394+
dialog.close();
395+
},
396+
r#type: "button",
397+
variant: ButtonVariant::Secondary,
398+
"Cancel"
399+
}
400+
Button {
401+
onclick: move |_| async move {
402+
leave_group.call(group_id).await;
403+
if let Some(Err(error)) = leave_group.value() {
404+
toaster
405+
.error(
406+
"Leaving group failed!",
407+
ToastOptions::new().description(rsx! {
408+
span { {message_from_captured_error(&error)} }
409+
}),
410+
);
411+
} else {
412+
toaster.success("Left group successfully!", ToastOptions::new());
413+
nav.push(Route::GroupView {});
414+
}
415+
},
416+
r#type: "submit",
417+
variant: ButtonVariant::Primary,
418+
"Leave"
419+
}
420+
}
421+
}
422+
}

packages/frontend/src/views/groups/group_view.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
use crate::Route;
2-
use crate::components::ui::button::{Button, ButtonShape, ButtonVariant};
3-
use crate::components::ui::dialog::{
4-
Dialog, DialogAction, DialogContent, DialogTrigger, use_dialog,
2+
use crate::components::ui::{
3+
button::{Button, ButtonShape, ButtonVariant},
4+
dialog::{Dialog, DialogAction, DialogContent, DialogTrigger, use_dialog},
5+
form::input::Input,
6+
groupcard::GroupCard,
7+
toaster::{ToastOptions, use_toaster},
58
};
6-
use crate::components::ui::form::input::Input;
7-
use crate::components::ui::groupcard::GroupCard;
8-
use crate::components::ui::toaster::{ToastOptions, use_toaster};
9-
use api::routes::groups::create_group;
10-
use api::routes::groups::list_groups;
9+
use api::routes::groups::{create_group, list_groups};
1110
use dioxus::prelude::*;
12-
use dioxus_free_icons::Icon;
13-
use dioxus_free_icons::icons::ld_icons::{LdPlus, LdUsers};
14-
use form_hooks::use_form::{use_form, use_on_submit};
15-
use form_hooks::use_form_field::use_form_field;
16-
use form_hooks::validators;
11+
use dioxus_free_icons::{
12+
Icon,
13+
icons::ld_icons::{LdPlus, LdUsers},
14+
};
15+
use form_hooks::{
16+
use_form::{use_form, use_on_submit},
17+
use_form_field::use_form_field,
18+
validators,
19+
};
1720
use roommates::message_from_captured_error;
1821

1922
#[derive(serde::Deserialize)]

0 commit comments

Comments
 (0)