Skip to main content

flams_router_login/
components.rs

1#![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
34//#[component]
35pub 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}