- Create /bags/:id detail page with coffee, roaster, map, and bag info cards - Extract shared template macros into detail_cards.html (coffee_card, roaster_card, map_with_legend, share_button) - Extract build_coffee_info() and build_roaster_info() view model helpers - Refactor brew.html and cup.html to use shared macros - Make bag cards on homepage clickable, linking to detail page - Add Close Bag and Delete actions on bag detail page - Unify homepage card styling (bg-surface, hover:border-accent/40) - Update CLAUDE.md with detail page patterns
50 lines
1.4 KiB
Rust
50 lines
1.4 KiB
Rust
use axum::extract::{Path, State};
|
|
use axum::http::StatusCode;
|
|
use axum::response::{IntoResponse, Response};
|
|
use tower_cookies::Cookies;
|
|
|
|
use crate::application::errors::map_app_error;
|
|
use crate::application::routes::render_html;
|
|
use crate::application::state::AppState;
|
|
use crate::domain::ids::BagId;
|
|
use crate::presentation::web::templates::BagDetailTemplate;
|
|
use crate::presentation::web::views::BagDetailView;
|
|
|
|
#[tracing::instrument(skip(state, cookies))]
|
|
pub(crate) async fn bag_detail_page(
|
|
State(state): State<AppState>,
|
|
cookies: Cookies,
|
|
Path(id): Path<BagId>,
|
|
) -> Result<Response, StatusCode> {
|
|
let is_authenticated = crate::application::routes::is_authenticated(&state, &cookies).await;
|
|
|
|
let bag = state
|
|
.bag_repo
|
|
.get_with_roast(id)
|
|
.await
|
|
.map_err(|e| map_app_error(e.into()))?;
|
|
|
|
let roast = state
|
|
.roast_repo
|
|
.get(bag.bag.roast_id)
|
|
.await
|
|
.map_err(|e| map_app_error(e.into()))?;
|
|
|
|
let roaster = state
|
|
.roaster_repo
|
|
.get(roast.roaster_id)
|
|
.await
|
|
.map_err(|e| map_app_error(e.into()))?;
|
|
|
|
let view = BagDetailView::from_parts(bag, &roast, &roaster);
|
|
|
|
let template = BagDetailTemplate {
|
|
nav_active: "",
|
|
is_authenticated,
|
|
version_info: &crate::VERSION_INFO,
|
|
base_url: crate::base_url(),
|
|
bag: view,
|
|
};
|
|
|
|
render_html(template).map(IntoResponse::into_response)
|
|
}
|