//! Login redirect and return-to-page handling. use gloo_timers::callback::Timeout; use sycamore_router::navigate_replace; const RETURN_TO_KEY: &str = "kca.login.return_to"; fn storage() -> Option { web_sys::window()?.session_storage().ok().flatten() } fn current_path() -> String { match web_sys::window() { Some(window) => { let location = window.location(); let path = location.pathname().unwrap_or_default(); let search = location.search().unwrap_or_default(); format!("{path}{search}") } None => "/".to_string(), } } fn is_restorable(path: &str) -> bool { !path.is_empty() && path.starts_with('/') && !path.starts_with("/api/") && !path.starts_with("/auth/") && path != "/login" } pub fn redirect_to_login() { let path = current_path(); if is_restorable(&path) { if let Some(storage) = storage() { let _ = storage.set_item(RETURN_TO_KEY, &path); } } Timeout::new(0, move || { if current_path() != "/login" { navigate_replace("/login"); } }) .forget(); } pub fn saved_return_to() -> Option { storage()?.get_item(RETURN_TO_KEY).ok().flatten() } pub fn clear_return_to() { if let Some(storage) = storage() { let _ = storage.remove_item(RETURN_TO_KEY); } } pub const LOGOUT_URL: &str = "/auth/logout";