feat(rental): Sprint D — panier + checkout + intégration carbet
Some checks failed
CI / test (pull_request) Failing after 1m8s
Some checks failed
CI / test (pull_request) Failing after 1m8s
Cart lib + cookie persistence (karbe-rental-cart, 30j) avec context React
useCart(). Provider wrappé dans layout pour hydratation server→client.
Page /panier :
- Récap regroupé par prestataire (sous-totaux, caution)
- Édition lignes (dates, qté), suppression, vider panier
- Bouton « Valider et payer » → POST /api/rentals/checkout
- Badge 🛒 dans SiteHeader avec total items
Composant <AddToCart /> sur /materiel/[itemId] avec date picker + qté.
API POST /api/rentals/checkout :
- Validation auth + items actifs + provider approved + qté/dates
- Transaction Prisma : recheck stock par fenêtre + crée 1 RentalBooking
par prestataire + RentalLines (snapshot prix) + RentalItemAvailability
(blocage des dispos)
- Calcul commissionAmount selon provider.commissionPct
- Si Stripe activé : Checkout Session unique avec 1 line_item par
RentalBooking, metadata {type:"rental-bundle", rentalBookingIds:[]}
- Sinon : crée en PENDING, retourne rentalBookingIds
- Vide le cookie panier après création
- Audit log rental.checkout.created
Webhook Stripe étendu :
- checkout.session.completed type=rental-bundle → CONFIRMED+SUCCEEDED
sur toutes les RentalBookings du bundle
- payment_intent.payment_failed metadata.rentalBookingIds → CANCELLED
+ supprime les RentalItemAvailability (libère le stock)
Intégration carbet :
- /carbets/[slug] : panneau « Compléter votre séjour » avec items des
prestataires de la même rivière + System D (recommandation contextuelle)
- /reservations/[id] : section « Matériel associé » listant les
RentalBookings liées
- /mes-locations : page récap toutes les locations (System D + tiers,
liées carbet ou standalone)
- Lien « Mes locations » dans SiteHeader
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1165f32a63
commit
91b4d918ea
16 changed files with 1309 additions and 7 deletions
|
|
@ -8,6 +8,7 @@ import Link from "next/link";
|
|||
import { auth } from "@/auth";
|
||||
import { UserRole } from "@/generated/prisma/enums";
|
||||
|
||||
import { CartBadge } from "./CartBadge";
|
||||
import { SignOutButton } from "./SignOutButton";
|
||||
|
||||
export async function SiteHeader() {
|
||||
|
|
@ -40,6 +41,7 @@ export async function SiteHeader() {
|
|||
</nav>
|
||||
|
||||
<div className="flex items-center gap-3 text-sm">
|
||||
<CartBadge />
|
||||
{u ? (
|
||||
<>
|
||||
<Link href="/mes-favoris" className="hidden text-zinc-700 hover:text-zinc-900 sm:inline">
|
||||
|
|
@ -48,6 +50,9 @@ export async function SiteHeader() {
|
|||
<Link href="/mes-reservations" className="hidden text-zinc-700 hover:text-zinc-900 sm:inline">
|
||||
Mes réservations
|
||||
</Link>
|
||||
<Link href="/mes-locations" className="hidden text-zinc-700 hover:text-zinc-900 sm:inline">
|
||||
Mes locations
|
||||
</Link>
|
||||
<Link href="/mon-compte" className="hidden text-zinc-700 hover:text-zinc-900 sm:inline">
|
||||
Mon compte
|
||||
</Link>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue