cart and buy page
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use crate::{controllers::i18n::current_lang, shared::money::format_price, models::products};
|
||||
use axum::{http::HeaderMap, response::Redirect};
|
||||
use axum_extra::extract::cookie::{Cookie, CookieJar, SameSite};
|
||||
use loco_rs::prelude::*;
|
||||
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
||||
@@ -96,6 +97,8 @@ async fn add(
|
||||
async fn update(
|
||||
jar: CookieJar,
|
||||
State(ctx): State<AppContext>,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
headers: HeaderMap,
|
||||
Form(form): Form<UpdateForm>,
|
||||
) -> Result<Response> {
|
||||
let stock = published_product(&ctx, form.product_id)
|
||||
@@ -110,19 +113,57 @@ async fn update(
|
||||
}
|
||||
items.retain(|(_, qty)| *qty > 0);
|
||||
|
||||
format::render()
|
||||
.cookies(&[cart_cookie(serialize_cart(&items))])?
|
||||
.redirect("/cart")
|
||||
let jar = jar.add(cart_cookie(serialize_cart(&items)));
|
||||
cart_response(&ctx, &v, jar, &headers).await
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn remove(jar: CookieJar, Form(form): Form<RemoveForm>) -> Result<Response> {
|
||||
async fn remove(
|
||||
jar: CookieJar,
|
||||
State(ctx): State<AppContext>,
|
||||
ViewEngine(v): ViewEngine<TeraView>,
|
||||
headers: HeaderMap,
|
||||
Form(form): Form<RemoveForm>,
|
||||
) -> Result<Response> {
|
||||
let mut items = parse_cart(&jar);
|
||||
items.retain(|(id, _)| *id != form.product_id);
|
||||
|
||||
format::render()
|
||||
.cookies(&[cart_cookie(serialize_cart(&items))])?
|
||||
.redirect("/cart")
|
||||
let jar = jar.add(cart_cookie(serialize_cart(&items)));
|
||||
cart_response(&ctx, &v, jar, &headers).await
|
||||
}
|
||||
|
||||
/// Response after a cart mutation: for an htmx request, just the `#cart-body`
|
||||
/// fragment (so the page never fully reloads); otherwise a redirect back to
|
||||
/// `/cart` for no-JS fallback. `jar` must already hold the updated cart cookie.
|
||||
async fn cart_response(
|
||||
ctx: &AppContext,
|
||||
v: &TeraView,
|
||||
jar: CookieJar,
|
||||
headers: &HeaderMap,
|
||||
) -> Result<Response> {
|
||||
if !headers.contains_key("HX-Request") {
|
||||
return Ok((jar, Redirect::to("/cart")).into_response());
|
||||
}
|
||||
|
||||
let (lines, valid, total) = resolve_cart(ctx, &jar).await?;
|
||||
let currency = lines
|
||||
.first()
|
||||
.and_then(|line| line["currency"].as_str())
|
||||
.unwrap_or("EUR")
|
||||
.to_string();
|
||||
// Persist the re-validated cookie (drops now-invalid lines).
|
||||
let jar = jar.add(cart_cookie(serialize_cart(&valid)));
|
||||
let response = format::view(
|
||||
v,
|
||||
"shop/_cart_body.html",
|
||||
json!({
|
||||
"items": lines,
|
||||
"total": format_price(total),
|
||||
"currency": currency,
|
||||
"lang": current_lang(&jar),
|
||||
}),
|
||||
)?;
|
||||
Ok((jar, response).into_response())
|
||||
}
|
||||
|
||||
/// Resolve the cart cookie into priced line items, dropping anything that is no
|
||||
|
||||
Reference in New Issue
Block a user