Added auth

This commit is contained in:
Connor Johnstone
2026-03-19 14:02:33 -04:00
parent 93392db27c
commit 421ec3199b
21 changed files with 719 additions and 26 deletions

View File

@@ -8,18 +8,86 @@ use yew_router::prelude::*;
use components::navbar::Navbar;
use pages::{switch, Route};
use types::UserInfo;
#[derive(Clone, PartialEq)]
enum AuthState {
Loading,
NeedsSetup,
NeedsLogin,
Authenticated(UserInfo),
}
#[function_component(App)]
fn app() -> Html {
html! {
<BrowserRouter>
<div class="app">
<Navbar />
<div class="main-content">
<Switch<Route> render={switch} />
</div>
let auth = use_state(|| AuthState::Loading);
// Check auth state on mount
{
let auth = auth.clone();
use_effect_with((), move |_| {
wasm_bindgen_futures::spawn_local(async move {
match api::get_me().await {
Ok(user) => auth.set(AuthState::Authenticated(user)),
Err(_) => {
// Not logged in — check if setup is needed
match api::check_setup_required().await {
Ok(sr) if sr.required => auth.set(AuthState::NeedsSetup),
_ => auth.set(AuthState::NeedsLogin),
}
}
}
});
});
}
let on_auth_success = {
let auth = auth.clone();
Callback::from(move |_: ()| {
let auth = auth.clone();
wasm_bindgen_futures::spawn_local(async move {
if let Ok(user) = api::get_me().await {
auth.set(AuthState::Authenticated(user));
}
});
})
};
match &*auth {
AuthState::Loading => html! {
<div class="auth-page">
<p class="loading">{ "Loading..." }</p>
</div>
</BrowserRouter>
},
AuthState::NeedsSetup => html! {
<pages::setup::SetupPage on_setup={on_auth_success.clone()} />
},
AuthState::NeedsLogin => html! {
<pages::login::LoginPage on_login={on_auth_success.clone()} />
},
AuthState::Authenticated(user) => {
let user = user.clone();
let on_logout = {
let auth = auth.clone();
Callback::from(move |_: ()| {
let auth = auth.clone();
wasm_bindgen_futures::spawn_local(async move {
let _ = api::logout().await;
auth.set(AuthState::NeedsLogin);
});
})
};
html! {
<BrowserRouter>
<div class="app">
<Navbar username={user.username.clone()} role={user.role.clone()} on_logout={on_logout} />
<div class="main-content">
<Switch<Route> render={switch} />
</div>
</div>
</BrowserRouter>
}
}
}
}