Skip to main content

Marketplace

Routes

RoutePurpose
/marketplaceProduct grid
/marketplace/[slug]Product detail — dynamicParams = false
/servicesService cards grid
/services/[slug]Service detail + order form

Product data

Products are defined in data/products.ts (static). Each product has:

  • type: 3d-asset | plugin
  • personalPrice / commercialPrice
  • featured flag
  • previewUrl or previewImages
  • tags, software

Cart (Zustand)

// store/cart.ts
type CartItem = {
productSlug: string;
title: string;
price: number;
licenseType: 'personal' | 'commercial';
quantity: number;
};

addItem increments quantity if the same slug + license already exists. openDrawer() is called after add so the cart slides open.

CartDrawer is rendered once in app/layout.tsx — never scope it to a sub-route.

Checkout

Stripe checkout is stubbed. Handler is in place; wire up when ready.

Stripe product metadata fields

Set these in the Stripe dashboard on each product:

FieldValues
slugURL slug e.g. my-product
type3d-asset | plugin
collectionScene Packs | Templates | Merch
deliveryTypedigital | physical
featuredtrue | false
tagscomma-separated
softwarecomma-separated
downloadPathserver path for digital delivery
printfulProductIdnumeric ID — required for physical products

Services

Six services defined in data/services.ts. Each service detail page includes ServiceOrderForm (react-hook-form), which submits via app/actions/service-orders.ts → submitServiceOrder.

Admin manages service orders at /admin/service-orders.