shell.rs
⎇
Raw
1use leptos::prelude::*;
2use wasm_bindgen_futures::spawn_local;
3
4use crate::api::{self, Me};
5use crate::components::toast::{ToastView, provide_toast};
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 m = me.get()?;
37 let u = m.user?;
38 let is_admin = u.is_admin;
39 Some(
40 view! {
41 <span class="user-badge">
42 {u.name}
43 <Show when=move || is_admin>
44 <span class="badge">"admin"</span>
45 </Show>
46 </span>
47 }
48 .into_view()
49 .into_any(),
50 )
51 }}
52 <Show when=move || me.get().and_then(|m| m.user).map(|u| u.is_admin).unwrap_or(false)>
53 <button
54 class="btn"
55 class:active=move || show_admin.get()
56 on:click=move |_| set_show_admin.update(|v| *v = !*v)
57 >
58 "Admin"
59 </button>
60 </Show>
61 <button class="btn" on:click=move |_| set_show_shares.set(true)>"Shares"</button>
62 <button class="btn" on:click=on_logout>"Log out"</button>
63 </div>
64 </header>
65 <main class="content">
66 {move || {
67 let is_admin = me
68 .get()
69 .and_then(|m| m.user)
70 .map(|u| u.is_admin)
71 .unwrap_or(false);
72 if show_admin.get() && is_admin {
73 view! { <AdminView me=me/> }
74 .into_view()
75 .into_any()
76 } else {
77 view! { <Browser me=me loc=loc/> }
78 .into_view()
79 .into_any()
80 }
81 }}
82 </main>
83 {move || if show_shares.get() {
84 view! {
85 <SharesPanel close=Callback::new(move |_| set_show_shares.set(false))/>
86 }
87 .into_view()
88 .into_any()
89 } else {
90 view! {}.into_any()
91 }}
92 <ToastView toast=toast/>
93 </div>
94 }
95}
96