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