//! The team page at `/team`, described. //! //! The first described document this server serves to a reader who may or may //! not hold a session, which is the question `b5cbb646` left open and //! [`super::Audience`] answers. It replaces `templates/pages/team.html`, //! `TeamTemplate` and `landing::team_page`. //! //! # Why this is the screen that answers the signed-out question //! //! The gated documents (`/feed`, `/dashboard/export`) resolve a session and //! refuse without one. `/pricing` resolves nothing and takes a state built once //! at startup, which is why it carries no site header: with no per-request //! session there is nobody for a header to greet. //! //! Every remaining `pages/` template is neither. They are public, they carry //! the header, and the header reads differently once a reader signs in -- //! `crate::shell::site_header` puts Library, Dashboard and the cart behind //! `Some(user)`. A screen like that needs a per-request viewer whose user is //! optional, and `/team` is the smallest of them: static content, no writes, no //! reads, so the only thing being proved is the mount. //! //! # One behaviour this changes, and it is a fix //! //! `team_page` resolved its user through `MaybeUserUnverified`, which reads the //! session and short-circuits a legacy one but never validates the tracking row. //! [`super::viewer_factory`] calls `crate::auth::authenticate`, which does: //! a revoked or suspended session renders as signed out here where it would have //! kept rendering as signed in. That is the posture `auth`'s own doc recommends //! ("prefer this anywhere the identity actually gates"), and the cost is one //! cached session touch on a page that made no database call at all before. //! //! # The card is a row, and the bio is a disclosure //! //! `
` is the exact disclosure shape the wiki note //! records (`mnw-server-conversion-plan`, 2026-08-26): a selective region //! showing at most one, holding exactly one labelled sub-region. The near miss //! -- label on the outer slot -- renders as a carousel with Prev/Next buttons //! and compiles fine, so [`the_bio_is_a_disclosure_and_not_a_stepper`] asserts //! the rendering rather than the text. //! //! [`the_bio_is_a_disclosure_and_not_a_stepper`]: tests::the_bio_is_a_disclosure_and_not_a_stepper use makeover_layout as layout; use quasi_router::screen::{Act, Row}; use quasi_router::{ Action, Document, Node, RegionKind, Request, Response, RouteError, Screen as Described, Slot, }; use quasi_webview::Webview; /// The address, registered whole. See [`super::public_document_mount`]. pub const PATH: &str = "/team"; /// The page's own region, and what the skip link points at. pub const PAGE_REGION: &str = "team"; /// The disclosure that holds the founder's bio. const BIO: &str = "founder-bio"; /// The one labelled frame inside it, which is what makes it a disclosure rather /// than a one-slide carousel. const BIO_BODY: &str = "founder-bio-body"; const MEASURE: layout::Measure = layout::Measure::Wide; /// The page, which reads nothing and so takes no round trip. pub fn screen(_viewer: &super::Viewer, _request: Request) -> Result { Ok(page_screen().into()) } /// The whole document: the title, the measure, the body. fn page_screen() -> Described { Described::single("Team - Makenotwork") .measured(MEASURE) .documented(Document::default().classed(crate::shell::body_class(MEASURE, &["team-page"]))) .summarised("Small by design: who builds Makenotwork, and what they did before.") .with( Slot::new(PAGE_REGION, RegionKind::Pane) .with(Node::page("Team")) .with(Node::text( "Small by design. The base platform was designed by the founder, who intends \ to stay as the technical lead through the project's growth.", )) .with(Node::section("Founder")) .with(Node::list([founder()])) .with(bio()), ) } /// The one card on the page. /// /// A row rather than a grid of one: `use-case-grid-2col` held a single article, /// so the grid was describing an intention rather than a layout. When there is a /// second person the list grows a second row and the design system decides how /// two rows sit, which is the arrangement question answered once for every /// screen instead of in this page's own CSS. fn founder() -> Row { Row::new("Max") .secondary("CEO & Tech Lead") .meta("Designed and built the platform.") .act(Act::new("@max", Action::get("/u/max").navigating())) } /// The bio, closed until asked for. /// /// `showing_at_most_one(None)` is closed; `Some(0)` would be `
`. fn bio() -> Node { Node::Region( Slot::new(BIO, RegionKind::Group) .with(Node::Region( Slot::new(BIO_BODY, RegionKind::Pane) .label("Bio") .with(Node::text(BIO_TEXT)), )) .showing_at_most_one(None), ) } /// Carried over verbatim from the template. Prose the founder wrote, so it is /// content rather than copy and nothing here rewrites it. const BIO_TEXT: &str = "I started in the creator space as a young kid making backgrounds and \ montages for CoD MW2 players. I picked up programming around the same time, helping Minecraft \ server owners with whatever they needed. I spent the years after that focused on my \ education: a BA in mathematics at the University of Chicago, then a PhD in mathematics at UC \ San Diego. Afterward I decided to start my own business, and here we are."; /// The document this screen is drawn in. /// /// The head, the tail and the token meta come off /// [`super::Viewer::document_shell`]. What is added is what every public page on /// this site opens with: the skip link, and the site header, which reads the /// viewer's user through an `Option` because on this mount there may not be one. #[must_use] pub fn renderer(viewer: &super::Viewer) -> Webview { Webview::new().with_shell(viewer.document_shell().with_body_first(format!( "{}{}", crate::shell::skip_link(PAGE_REGION), crate::shell::site_header(viewer.user.as_ref()), ))) } #[cfg(test)] mod tests { use super::*; fn html() -> String { use quasi_axum::Serves as _; Webview::new().screen(&page_screen()) } /// `2790e5c4` for this screen. The template wrote the measure on the body /// and `team-page` on a container div inside it; a described document has no /// container, so both land on the body and the CSS measure moved onto /// `.team-page main` the way `/feed`'s did. Same two classes, one element. #[test] fn the_document_carries_the_classes_the_template_carried() { let screen = page_screen(); assert_eq!( screen.document.body_class.as_deref(), Some("padded-page team-page") ); assert!(html().contains("padded-page team-page"), "{}", html()); } /// The disclosure shape, asserted by what it renders rather than by what it /// says: a label on the outer slot instead of the inner one is a legal /// carousel, so the text is identical and the markup is not. #[test] fn the_bio_is_a_disclosure_and_not_a_stepper() { let html = html(); assert!(html.contains(r#"aria-expanded="false""#), "{html}"); assert!(!html.contains(r#"data-shows="next""#), "{html}"); assert!(html.contains("University of Chicago"), "{html}"); } /// The founder's row says who, what, and where to read more. #[test] fn the_founder_row_links_to_the_profile() { let html = html(); assert!(html.contains("CEO & Tech Lead"), "{html}"); assert!(html.contains(r#"href="/u/max""#), "{html}"); } /// `736f45a5`: this screen's markup carries none of the four spellings. #[test] fn the_page_spells_no_spinner() { let html = html(); for spelling in ["htmx-indicator", "spinner", "loading-text", "loading-state"] { assert!(!html.contains(spelling), "{spelling} survives in {html}"); } } }