#![allow(clippy::must_use_candidate)]
use crate::{Auth, AuthSignal};
use leptos::prelude::*;
use leptos_router::hooks::use_navigate;
use leptos_router::NavigateOptions;
#[must_use]
#[component(transparent)]
pub fn Authenticated(
children: ChildrenFn,
#[prop(optional, into)] unauthenticated: ViewFn,
) -> impl IntoView {
let auth =
use_context::<AuthSignal>().expect("AuthSignal not initialized in Authenticated component");
let unauthenticated = move || unauthenticated.run();
let authenticated = move || auth.get().is_authenticated();
let children = StoredValue::new(children);
view! {
<Show
when=authenticated
fallback=unauthenticated
>
{ children.read_value()() }
</Show>
}
}
#[must_use]
#[component(transparent)]
pub fn AuthLoaded(children: ChildrenFn, #[prop(optional, into)] fallback: ViewFn) -> impl IntoView {
let auth =
use_context::<AuthSignal>().expect("AuthSignal not initialized in AuthLoaded component");
let children = StoredValue::new(children);
let loaded = move || auth.get().is_loaded();
view! {
<Show when=loaded fallback>
{ children.read_value()() }
</Show>
}
}
#[must_use]
#[component(transparent)]
pub fn LoginLink(
children: Children,
#[prop(optional, into)] class: Option<String>,
) -> impl IntoView {
let auth = use_context::<AuthSignal>().expect("AuthSignal not present in LoginLink");
let login_url = move || {
auth.with(|auth| {
auth.unauthenticated()
.map(|unauthenticated| unauthenticated.login_url())
})
};
view! {
<a href=login_url class=class>
{children()}
</a>
}
}
#[must_use]
#[component(transparent)]
pub fn LogoutLink(
children: Children,
#[prop(optional, into)] class: Option<String>,
) -> impl IntoView {
let auth = use_context::<AuthSignal>().expect("AuthSignal not present in LogoutLink");
let logout_url = move || {
auth.get()
.authenticated()
.map(|authenticated| authenticated.logout_url())
};
view! {
<a href=logout_url class=class>
{children()}
</a>
}
}
#[must_use]
#[component(transparent)]
pub fn AuthLoading(children: ChildrenFn) -> impl IntoView {
let auth =
use_context::<AuthSignal>().expect("AuthSignal not initialized in AuthLoading component");
let children = StoredValue::new(children);
let loading = move || auth.get().is_loading();
view! {
<Show when=loading fallback=|| ()>
{ children.read_value()() }
</Show>
}
}
#[must_use]
#[component(transparent)]
pub fn AuthErrorContext(
children: ChildrenFn,
#[prop(optional, into)] fallback: ViewFn,
) -> impl IntoView {
let auth =
use_context::<AuthSignal>().expect("AuthErrorContext: RwSignal<AuthSignal> not present");
let is_error = move || auth.get().error().is_some();
view! {
<Show when=is_error fallback=fallback >
{ children() }
</Show>
}
}
#[must_use]
#[component]
pub fn ReloadButton(#[prop(optional, into)] path: Option<String>) -> impl IntoView {
let auth = use_context::<AuthSignal>().expect("AuthSignal not initialized in ReloadButton");
let navigate = use_navigate();
let path = path.unwrap_or("/".to_string());
view! {
<button
on:click=move |_| {
auth.set(Auth::Loading);
navigate(&path, NavigateOptions::default());
}
>
"Reload"
</button>
}
}