feat(storefront): dedicated Sweet Corn Box product page with 2-3 click order flow
- New route /tuxedo/products/sweet-corn-box with editorial Fraunces/JetBrains Mono typography, paper-grain hero, tilted 'Peak Season 2026' stamp, and sticky buy-box (desktop) + sticky mobile bottom bar with 48px+ tap targets - QuickCartSheet slide-up drawer: mobile bottom sheet (spring + drag-to-close) vs desktop right drawer, with Apple Pay / Google Pay / Shop Pay express row and one-page 'Checkout' CTA — enables the user's specified 2-3 click flow - CartContext.buyNow() — single-item cart replace + clear stop for 1-tap 'Quick Buy' that pushes directly to /checkout - 4-feature check list, 100% Sweetness Guarantee, FAQ accordion, dark final CTA strip, and proper SEO/Open Graph meta
This commit is contained in:
@@ -30,6 +30,12 @@ type CartContextType = {
|
||||
cartRestored: boolean; // true when server cart was loaded (for toast)
|
||||
setSelectedStop: (stop: StopInfo | null) => void;
|
||||
addToCart: (item: Omit<CartItem, "quantity">, fulfillment?: "pickup" | "ship") => void;
|
||||
/**
|
||||
* Replaces the cart with a single item (clears other items + selected stop)
|
||||
* and returns the resulting item so the caller can navigate to /checkout
|
||||
* for a true 1-tap "Buy Now" flow.
|
||||
*/
|
||||
buyNow: (item: Omit<CartItem, "quantity">, fulfillment?: "pickup" | "ship") => CartItem;
|
||||
increaseQuantity: (id: string) => void;
|
||||
decreaseQuantity: (id: string) => void;
|
||||
removeFromCart: (id: string) => void;
|
||||
@@ -201,6 +207,27 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the entire cart with this single item. Use for "Buy Now" /
|
||||
* "Quick Buy" flows where the buyer wants to skip the cart step and go
|
||||
* straight to checkout. The returned CartItem reflects the final state
|
||||
* (existing items of the same product are merged by quantity).
|
||||
*/
|
||||
function buyNow(item: Omit<CartItem, "quantity">, fulfillment?: "pickup" | "ship"): CartItem {
|
||||
// Always clear selected stop on a buy-now — the buyer is bypassing the
|
||||
// standard stop-picker flow and will pick a stop at checkout.
|
||||
setSelectedStop(null);
|
||||
|
||||
const finalItem: CartItem = {
|
||||
...item,
|
||||
quantity: 1,
|
||||
fulfillment: fulfillment ?? "pickup",
|
||||
};
|
||||
setCart([finalItem]);
|
||||
setJustAdded(finalItem);
|
||||
return finalItem;
|
||||
}
|
||||
|
||||
function increaseQuantity(id: string) {
|
||||
setCart((prev) =>
|
||||
prev.map((item) => (item.id === id ? { ...item, quantity: item.quantity + 1 } : item))
|
||||
@@ -291,6 +318,7 @@ export function CartProvider({ children }: { children: ReactNode }) {
|
||||
cartRestored: showRestoredToast,
|
||||
setSelectedStop: setSelectedStop,
|
||||
addToCart,
|
||||
buyNow,
|
||||
increaseQuantity,
|
||||
decreaseQuantity,
|
||||
removeFromCart,
|
||||
|
||||
Reference in New Issue
Block a user