flams_router_login/
components.rs1#![allow(clippy::must_use_candidate)]
2
3use flams_database::UserData;
4use flams_router_base::{LoginState, maybe_lazy};
5use flams_web_utils::components::display_error;
6use ftml_component_utils::Spinner;
7use leptos::{either::EitherOf4, prelude::*};
8
9#[component(transparent)]
10pub fn LoginProvider<Ch: IntoView + 'static>(children: TypedChildren<Ch>) -> impl IntoView {
11 let children = children.into_inner();
12 let res = Resource::new_blocking(
13 || (),
14 |()| async {
15 super::server_fns::login_state().await.unwrap_or_else(|e| {
16 leptos::logging::error!("Error getting login state: {e}");
17 LoginState::None
18 })
19 },
20 );
21 let sig = RwSignal::new(LoginState::Loading);
22 let _ = view! {<Suspense>{move || {res.get();}}</Suspense>};
23 let _ = Effect::new(move |_| {
24 if let Some(r) = res.get() {
25 sig.set(r);
26 }
27 });
28 provide_context(sig);
29 children()
30}
31
32maybe_lazy!(Users = users());
33
34pub fn users() -> AnyView {
36 let r = Resource::new(|| (), |()| super::server_fns::get_users());
37 view! {<Suspense fallback = || view!(<Spinner/>)>{move ||
38 match r.get() {
39 Some(Ok(users)) if users.is_empty() => EitherOf4::A("(No users)"),
40 Some(Err(e)) => EitherOf4::B(
41 display_error(e.to_string().into())
42 ),
43 None => EitherOf4::C(view!(<Spinner/>)),
44 Some(Ok(users)) => EitherOf4::D(user_table(users))
45 }
46 }</Suspense>}
47 .into_any()
48}
49
50fn user_table(v: Vec<UserData>) -> impl IntoView {
51 use ftml_component_utils::{Button, ButtonSize, Table, TableCell, TableHeader, TableRow};
52 view! {<Table>
53 <TableHeader slot>
54 <TableCell>""</TableCell>
55 <TableCell>"Id"</TableCell>
56 <TableCell>"Username"</TableCell>
57 <TableCell>"Name"</TableCell>
58 <TableCell>"Email"</TableCell>
59 <TableCell>"Admin Access"</TableCell>
60 </TableHeader>
61 {v.into_iter().map(|UserData {id,name,username,email,avatar_url,is_admin}| {
62 let is_admin = RwSignal::new(is_admin);
63 let a = ArcAction::new(move |()| async move {
64 let nv = !is_admin.get_untracked();
65 if super::server_fns::set_admin(id,nv).await.is_ok() {
66 is_admin.set(nv);
67 }
68 });
69 let f = move || {
70 let on_click = a.clone();
71 if is_admin.get() {
72 leptos::either::Either::Left(
73 view!{
74 "Yes "
75 <Button size=ButtonSize::Small on_click=move |_| {on_click.dispatch(());}>"Demote"</Button>
76 }
77 )
78 } else {
79 leptos::either::Either::Right(
80 view!{
81 "No "
82 <Button size=ButtonSize::Small on_click=move |_| {on_click.dispatch(());}>"Promote"</Button>
83 }
84 )
85 }
86 };
87 view! {<TableRow>
88 <TableCell><ftml_component_utils::Avatar src=avatar_url /></TableCell>
89 <TableCell>{id}</TableCell>
90 <TableCell>{username}</TableCell>
91 <TableCell>{name}</TableCell>
92 <TableCell>{email}</TableCell>
93 <TableCell>{f}</TableCell>
94 </TableRow>}
95 }).collect_view()}
96 </Table>}
97}