feat(ecommerce): migrate Ari Shopping to Next.js 15 headless storefront v4
Build and Push Frontend / build (push) Failing after 9m42s

This commit is contained in:
2026-07-19 21:36:35 -05:00
parent 2e7abc7e72
commit fe7b2019c2
79 changed files with 7686 additions and 187 deletions
+11 -2
View File
@@ -13,8 +13,10 @@ export interface CartItem {
interface CartState {
items: CartItem[];
isOpen: boolean;
hasHydrated: boolean;
openCart: () => void;
closeCart: () => void;
setHasHydrated: (value: boolean) => void;
addItem: (product: Product, variantId?: string) => void;
removeItem: (productId: string) => void;
updateQuantity: (productId: string, quantity: number) => void;
@@ -26,16 +28,22 @@ export const useCartStore = create<CartState>()(
(set) => ({
items: [],
isOpen: false,
hasHydrated: false,
openCart: () => set({ isOpen: true }),
closeCart: () => set({ isOpen: false }),
setHasHydrated: (value) => set({ hasHydrated: value }),
addItem: (product, variantId) => set((state) => {
const existing = state.items.find((item) => item.product.id === product.id && item.variantId === variantId);
const existing = state.items.find(
(item) => item.product.id === product.id && item.variantId === variantId,
);
const items = existing
? state.items.map((item) => item === existing ? { ...item, quantity: item.quantity + 1 } : item)
: [...state.items, { product, quantity: 1, variantId }];
return { items, isOpen: true };
}),
removeItem: (productId) => set((state) => ({ items: state.items.filter((item) => item.product.id !== productId) })),
removeItem: (productId) => set((state) => ({
items: state.items.filter((item) => item.product.id !== productId),
})),
updateQuantity: (productId, quantity) => set((state) => ({
items: quantity <= 0
? state.items.filter((item) => item.product.id !== productId)
@@ -47,6 +55,7 @@ export const useCartStore = create<CartState>()(
name: "ari-shopping-cart-v4",
storage: createJSONStorage(() => localStorage),
partialize: (state) => ({ items: state.items }),
onRehydrateStorage: () => (state) => state?.setHasHydrated(true),
},
),
);
@@ -0,0 +1,45 @@
"use client";
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
import type { Product } from "@/lib/headless/types";
interface WishlistState {
products: Product[];
isOpen: boolean;
hasHydrated: boolean;
openWishlist: () => void;
closeWishlist: () => void;
setHasHydrated: (value: boolean) => void;
toggleProduct: (product: Product) => void;
removeProduct: (productId: string) => void;
contains: (productId: string) => boolean;
}
export const useWishlistStore = create<WishlistState>()(
persist(
(set, get) => ({
products: [],
isOpen: false,
hasHydrated: false,
openWishlist: () => set({ isOpen: true }),
closeWishlist: () => set({ isOpen: false }),
setHasHydrated: (value) => set({ hasHydrated: value }),
toggleProduct: (product) => set((state) => ({
products: state.products.some((item) => item.id === product.id)
? state.products.filter((item) => item.id !== product.id)
: [...state.products, product],
})),
removeProduct: (productId) => set((state) => ({
products: state.products.filter((item) => item.id !== productId),
})),
contains: (productId) => get().products.some((item) => item.id === productId),
}),
{
name: "ari-shopping-wishlist-v4-1",
storage: createJSONStorage(() => localStorage),
partialize: (state) => ({ products: state.products }),
onRehydrateStorage: () => (state) => state?.setHasHydrated(true),
},
),
);