--- # quotesdb-250z title: 'quotesdb/ui: /admin page component' status: completed type: feature priority: normal created_at: 2026-03-10T23:32:10Z updated_at: 2026-03-10T23:32:18Z blocked_by: - quotesdb-d09v --- ## /admin page component (UI) Create the /admin route and page component. The page provides a persistent admin auth code input, an auth code reset section, and a submissions lock/unlock section. Depends on ticket 161f32 (admin API client functions). Complete that ticket first. --- ## Files to create / modify - `src/bin/ui/pages/admin.rs` — **create** the new page component - `src/bin/ui/pages/mod.rs` — add `pub mod admin;` - `src/bin/ui/main.rs` — add the `/admin` route to the Yew Router switch and add an "Admin" link to the top nav (or wherever the nav links are defined) --- ## Component: AdminPage The component holds the following local state: | State field | Type | Purpose | |---|---|---| | `admin_code` | `String` | The persistent admin auth code input | | `new_passphrase` | `String` | Optional input for reset section | | `reset_result` | `Option` | Newly returned auth code after reset | | `reset_error` | `Option` | Error message for the reset section | | `submissions_locked` | `Option` | Current lock state, fetched on mount | | `lock_error` | `Option` | Error message for lock/unlock section | | `loading` | `bool` | Disables buttons during in-flight requests | ### On mount Call `api::get_status()` and set `submissions_locked` from the response. ### Layout ``` [ Admin ] (page heading) Admin auth code: [__________________] (persistent text input) --- Reset auth code --- New passphrase (optional): [__________] [ Reset ] > (success) New code: ocean-table-purple-storm > (error) Wrong auth code. --- Submissions --- Status: Open | Closed [ Lock submissions ] / [ Unlock submissions ] > (error) Wrong auth code. ``` ### Behaviour - **Reset button:** calls `api::admin_reset_auth_code(&admin_code, new_passphrase_opt, &admin_code)`. On success, shows the new code in `reset_result` and clears `reset_error`. On `ApiError::Forbidden`, sets `reset_error = "Wrong auth code."`. On other errors, sets a generic message. - **Lock button** (shown when `submissions_locked == Some(false)`): calls `api::admin_lock(&admin_code)`. On success, sets `submissions_locked = Some(true)`. On `ApiError::Forbidden`, sets `lock_error`. - **Unlock button** (shown when `submissions_locked == Some(true)`): calls `api::admin_unlock(&admin_code)`. On success, sets `submissions_locked = Some(false)`. On `ApiError::Forbidden`, sets `lock_error`. - While `loading = true`, disable all buttons. --- ## Route registration (src/bin/ui/main.rs) Add to the router switch: ```rust Route { path: "/admin".to_string(), render: ... } // or whichever router pattern is already in use ``` --- ## Tests No runtime unit tests (wasm-only). Verify the build: ```sh cargo check --target wasm32-unknown-unknown --bin ui ``` --- ## Validation ```sh cargo fmt && cargo check --target wasm32-unknown-unknown --bin ui ``` --- ## Commit ``` feat(quotesdb): /admin page component ```