You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.7 KiB
Rust

//! UI binary entrypoint for quotesdb.
//!
//! Compiled to WebAssembly via Trunk targeting `wasm32-unknown-unknown`.
//! Runs the Yew single-page application with client-side routing.
//!
//! All functional code is gated on `wasm32` — yew, web-sys, and wasm-bindgen
//! are wasm32-only crates unavailable on native targets.
#[cfg(target_arch = "wasm32")]
mod api;
#[cfg(target_arch = "wasm32")]
mod components;
#[cfg(target_arch = "wasm32")]
mod pages;
#[cfg(target_arch = "wasm32")]
mod storage;
#[cfg(target_arch = "wasm32")]
use yew::prelude::*;
#[cfg(target_arch = "wasm32")]
use yew_router::prelude::*;
/// Application routes matching the frontend route definitions in the design spec.
///
/// Routes map to page components. The `NotFound` variant catches all unmatched paths.
#[cfg(target_arch = "wasm32")]
#[derive(Clone, Routable, PartialEq)]
pub enum Route {
/// Home page — displays a random quote.
#[at("/")]
Home,
/// Browse page — paginated list of quotes with filters.
#[at("/browse")]
Browse,
/// Single quote view/edit/delete page.
#[at("/quotes/:id")]
QuoteDetail { id: String },
/// All quotes by a specific author.
#[at("/author/:name")]
Author { name: String },
/// New quote submission form.
#[at("/submit")]
Submit,
/// Admin panel for managing submissions lock and auth codes.
#[at("/admin")]
Admin,
/// Catch-all 404 page.
#[not_found]
#[at("/404")]
NotFound,
}
/// Route switch function — maps each `Route` variant to its page component.
#[cfg(target_arch = "wasm32")]
fn switch(routes: Route) -> Html {
match routes {
Route::Home => html! { <pages::home::HomePage /> },
Route::Browse => html! { <pages::browse::BrowsePage /> },
Route::QuoteDetail { id } => html! { <pages::quote::QuotePage id={id} /> },
Route::Author { name } => html! { <pages::author::AuthorPage name={name} /> },
Route::Submit => html! { <pages::submit::SubmitPage /> },
Route::Admin => html! { <pages::admin::AdminPage /> },
Route::NotFound => html! {
<div class="page-not-found">
<h1>{ "404 — Page Not Found" }</h1>
<p>{ "The page you are looking for does not exist." }</p>
<a href="/">{ "Go home" }</a>
</div>
},
}
}
/// Root application component.
///
/// Wraps the entire application in a `BrowserRouter` and renders the
/// route-switched page components via `Switch`.
#[cfg(target_arch = "wasm32")]
#[function_component(App)]
fn app() -> Html {
html! {
<BrowserRouter>
<nav class="nav">
<Link<Route> to={Route::Home} classes="nav__brand">{ "QuotesDB" }</Link<Route>>
<div class="nav__links">
<Link<Route> to={Route::Browse} classes="nav__link">{ "Browse" }</Link<Route>>
<Link<Route> to={Route::Submit} classes="nav__link">{ "Submit" }</Link<Route>>
</div>
</nav>
<main class="main-content">
<Switch<Route> render={switch} />
</main>
<footer class="site-footer">
<p>{ "Contact: " }<a href="mailto:quotes@elijah.run">{ "quotes@elijah.run" }</a></p>
</footer>
</BrowserRouter>
}
}
/// WASM entry point — called by the Trunk-generated JS bootstrap.
#[cfg(target_arch = "wasm32")]
fn main() {
yew::Renderer::<App>::new().render();
}
/// Stub entry point for native targets.
///
/// The UI binary is only meaningful when compiled for wasm32 via Trunk.
/// This stub satisfies the Rust binary requirement on other targets.
#[cfg(not(target_arch = "wasm32"))]
fn main() {}