use crate::{admin::Admin, notifications::total_for_profile, profiles::Profile, State}; use actix_web::{ dev::Payload, web::{Data, Query}, FromRequest, HttpRequest, }; use futures::future::LocalBoxFuture; use hyaenidae_accounts::LogoutState; use hyaenidae_toolkit::Button; impl FromRequest for NavState { type Config = (); type Error = actix_web::Error; type Future = LocalBoxFuture<'static, Result>; fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { let profile = Option::::extract(req); let logout = Option::::extract(req); let query = Option::>>::extract(req); let admin = Option::::extract(req); let path = req.uri().path().to_owned(); let state = Data::::extract(req); Box::pin(async move { let profile = profile.await?; let logout = logout.await?; let query = query.await?; let admin = admin.await?; let state = state.await?; let dark = true; let mut nav = vec![]; if let Some(logout_state) = logout { let submission = Button::primary("New Submission"); let account = Button::secondary("Account"); let logout = Button::primary_outline("Logout"); logout_state.button(&logout); submission.href("/submissions/create").dark(dark); account.href("/session/account").dark(dark); logout.dark(dark); let profile_btn = if let Some(profile) = profile.as_ref() { let btn = Button::secondary("Profile"); btn.href(&profile.view_path()).dark(dark); btn } else { let btn = Button::secondary("Switch Profile"); btn.href("/profiles/change").dark(dark); btn }; nav.push(submission); nav.push(profile_btn); if let Some(profile) = profile.as_ref() { if let Ok(count) = total_for_profile(profile.id(), &state).await { if count > 0 { let btn = Button::secondary("Notifications"); btn.href("/notifications").dark(dark); nav.push(btn); } } } nav.push(account); if admin.is_some() { let admin = Button::secondary("Admin"); admin.href("/admin").dark(dark); nav.push(admin); } nav.push(logout); } else { let login = Button::primary_outline("Login"); let register = Button::primary_outline("Register"); login.href("/session/auth/login").dark(dark); register.href("/session/auth/register").dark(dark); nav.push(login); nav.push(register); } if let Some(query) = query { let mut is_open = false; let query = query .into_inner() .into_iter() .filter_map(|(key, value)| { if key == "show_nav" { is_open = true; None } else { Some(format!("{}={}", key, value)) } }) .collect::>() .join("&"); let query = if is_open { query } else { format!("{}&show_nav=true", query) }; Ok(NavState { buttons: nav, href: format!("{}?{}", path, query), is_open, dark, }) } else { Ok(NavState { buttons: nav, href: format!("{}?show_nav=true", path), is_open: false, dark, }) } }) } } pub struct NavState { buttons: Vec