feat(mall): claim and redeem shop coupons from the storefront
The product page loads a shop's claimable coupons through the shared client and claims them in place; the buyer coupon list reads owned snapshots with their claimed/redeemed/expired state. Checkout offers each shop order at most one owned coupon and submits only the choice; the pay page and order detail render the server-persisted discount and reduced total, never a client figure. Coupon fixtures leave the pages; the fixed-data adapter still serves the coupon domain as the rollback path. The demo seed creates two deterministic templates and claims them for the demo customer.
This commit is contained in:
@@ -107,6 +107,12 @@ onMounted(() => void loadOrders());
|
||||
</strong>
|
||||
</div>
|
||||
<footer class="order-total">
|
||||
<template v-if="order.discount_minor > 0">
|
||||
<span>{{ t("checkout.couponDiscount") }}</span>
|
||||
<span class="discount-value">
|
||||
−<PriceText :amount-minor="order.discount_minor" :currency="order.currency" />
|
||||
</span>
|
||||
</template>
|
||||
<span>{{ t("checkout.total") }}</span>
|
||||
<strong><PriceText :amount-minor="order.total_minor" :currency="order.currency" /></strong>
|
||||
</footer>
|
||||
@@ -224,6 +230,9 @@ onMounted(() => void loadOrders());
|
||||
color: var(--mall-red);
|
||||
font-size: 16px;
|
||||
}
|
||||
.discount-value {
|
||||
color: var(--mall-red);
|
||||
}
|
||||
.payment-panel {
|
||||
margin-top: 16px;
|
||||
padding: 0 18px 16px;
|
||||
|
||||
Reference in New Issue
Block a user