shell.rs
⎇
Raw
1use leptos::prelude::*;
2use wasm_bindgen_futures::spawn_local;
3
4use crate::api::{self, Me};
5use crate::components::toast::{provide_toast, ToastView};
6use crate::router::Location;
7use crate::views::admin::AdminView;
8use crate::views::browser::Browser;
9use crate::views::shares::SharesPanel;
10
11#[component]
12pub fn ShellView(
13 me: ReadSignal<Option<Me>>,
14 set_me: WriteSignal<Option<Me>>,
15 set_phase: WriteSignal<crate::app::AuthPhase>,
16 loc: ReadSignal<Location>,
17) -> impl IntoView {
18 let toast = provide_toast();
19 let (show_shares, set_show_shares) = signal(false);
20 let (show_admin, set_show_admin) = signal(false);
21
22 let on_logout = move |_| {
23 spawn_local(async move {
24 let _ = api::logout().await;
25 set_me.set(None);
26 set_phase.set(crate::app::AuthPhase::Login);
27 });
28 };
29
30 view! {
31 <div class="layout">
32 <header class="topbar">
33 <div class="brand">"📂 filebrowser-ng"</div>
34 <div class="topbar-right">
35 {move || {
36 let Some(m) = me.get() else {
37 return None;
38 };
39 let u = m.user?;
40 let is_admin = u.is_admin;
41 Some(
42 view! {
43 <span class="user-badge">
44 {u.name}
45 <Show when=move || is_admin>
46 <span class="badge">"admin"</span>
47 </Show>
48 </span>
49 }
50 .into_view()
51 .into_any(),
52 )
53 }}
54 <Show when=move || me.get().and_then(|m| m.user).map(|u| u.is_admin).unwrap_or(false)>
55 <button
56 class="btn"
57 class:active=move || show_admin.get()
58 on:click=move |_| set_show_admin.update(|v| *v = !*v)
59 >
60 "Admin"
61 </button>
62 </Show>
63 <button class="btn" on:click=move |_| set_show_shares.set(true)>"Shares"</button>
64 <button class="btn" on:click=on_logout>"Log out"</button>
65 </div>
66 </header>
67 <main class="content">
68 {move || {
69 let is_admin = me
70 .get()
71 .and_then(|m| m.user)
72 .map(|u| u.is_admin)
73 .unwrap_or(false);
74 if show_admin.get() && is_admin {
75 view! { <AdminView me=me/> }
76 .into_view()
77 .into_any()
78 } else {
79 view! { <Browser me=me loc=loc/> }
80 .into_view()
81 .into_any()
82 }
83 }}
84 </main>
85 {move || if show_shares.get() {
86 view! {
87 <SharesPanel close=Callback::new(move |_| set_show_shares.set(false))/>
88 }
89 .into_view()
90 .into_any()
91 } else {
92 view! {}.into_any()
93 }}
94 <ToastView toast=toast/>
95 </div>
96 }
97}
98