A multi-step product configurator for building a Wyze security system bundle. Users pick cameras, a subscription plan, sensors, and accessories, then review pricing and simulate checkout.
- Node.js 18 or newer (tested with Node 22)
- npm 9+
From a clean clone:
npm ci
npm run devOpen http://localhost:5173 in your browser.
| Command | Description |
|---|---|
npm ci |
Install dependencies from package-lock.json (recommended for a clean clone) |
npm install |
Install dependencies (alternative to npm ci) |
npm run dev |
Start the Vite dev server |
npm run build |
Type-check and build for production (dist/) |
npm run preview |
Serve the production build locally |
npm run lint |
Run ESLint |
npm ci
npm run build
npm run previewThen open the URL printed in the terminal (default: http://localhost:4173).
src/
components/ # UI (stepper, product cards, review panel, checkout modal)
data/ # Product catalog and step config (config.json)
store/ # Zustand store for cart + config loading
types/ # TypeScript types for config and cart
utils/ # Pricing, cart helpers, asset resolution
assets/ # Product and swatch images
- React + Vite + TypeScript + Tailwind CSS v4 — fast local dev, typed config, utility-first styling.
- Zustand for global state instead of Redux or Context — small surface area for cart/config reads and writes.
- JSON-driven catalog (
src/data/config.json) — steps, products, pricing, and promotions live in one file so the UI stays generic. - Cart shape —
productId → variantId → quantityin memory, serialized to a flatselectionsarray inlocalStoragefor persistence. - Linear step unlock — a step stays disabled until the previous step has at least one product selected.
- Mutually exclusive plans — selecting Cam Plus / Cam Unlimited / Cam Unlimited Pro clears the other plan options.
- Color-only variants — swatches map to a
coloroption; products without color options use adefaultvariant key. - Display vs cart pricing — cards show
unitPrice/compareAtPrice; the review panel and checkout usecartUnitPrice/cartCompareAtPricewhere bundle discounts apply. - Simulated checkout — the checkout modal confirms the cart locally; there is no backend or payment integration.
minSelectionsis not enforced — the field exists on each step in config, but checkout only requires at least one item in the cart overall.- Financing badge is hardcoded — the review panel shows a static “as low as $19.19/mo” label rather than computing it from cart totals.
- No server-side validation — cart state is client-only (
localStorage); a real deployment would need API validation. - Fonts CDN — Gilroy is loaded in
index.html, so the font requires network access on first load.