A multi-step security system bundle builder with a live review panel. Frontend take-home prototype built with Next.js, React, Redux Toolkit, HeroUI, and Tailwind CSS v4.
npm install
npm run devOpen http://localhost:3000.
Production build:
npm run build
npm startLint:
npm run lint- 4-step builder — Cameras, Plan, Sensors, and Extra Protection (one open step at a time)
- Product cards — badges, variant pills with thumbnails, quantity steppers, and pricing
- Per-variant quantities — each color variant tracks its own count; the card stepper edits the active variant
- Live review panel — grouped line items, shipping, financing, totals, and savings
- Synced steppers — quantities stay in sync between product cards and the review panel
- Persistence — “Save my system for later” writes to
localStorageand restores on reload - Responsive layouts — mobile (390px), tablet (768–1439px), and desktop side-by-side (1440px+)
app/
page.tsx # Entry: BundleHydration + BundleBuilderPage
layout.tsx # Root layout, Gilroy font, Redux StoreProvider
globals.css # Tailwind + HeroUI imports, @theme token mappings
theme.css # your-security-system design tokens (Figma-aligned)
components/ # All bundle builder UI
BundleBuilderPage.tsx # Page shell and responsive grid
BuilderSteps.tsx # Step accordion, product grid, next button
ProductCard.tsx # Product card with variants and stepper
ReviewPanel.tsx # Review sidebar / wide checkout layout
ProductImage.tsx # Unified image helper (next/image for raster, <img> for SVG)
icons.tsx # Step icons, carrot chevrons, inline stepper SVGs
...
lib/
store.ts # Redux store factory
storeProvider.tsx # Client-side Redux provider
hooks.ts # useAppDispatch / useAppSelector
features/
bundleSlice.ts # Selections, active step, variants, save/checkout messages
utils/
catalog.ts # Catalog helpers (imports bundle-catalog.json)
format.ts # Currency and price formatting
selectors.ts # Line items, totals, grouped review sections
persistence.ts # localStorage save/load
index.ts # Public utils exports
types.ts # Shared TypeScript types
bundle-catalog.json # Product catalog, steps, shipping, and seeded initial state
public/
fonts/ # Gilroy font files
icons/ # Step icons, delivery, carrot chevrons
products/ # Product and variant images
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router) |
| UI | React 19, HeroUI v3 (Button, theme tokens) |
| Styling | Tailwind CSS v4, custom tokens in app/theme.css |
| State | Redux Toolkit |
| Font | Gilroy (local, via next/font/local) |
- Data-driven UI — Products, steps, shipping, and initial selections come from
bundle-catalog.json. Components render from catalog data, not hard-coded product markup. - Redux Toolkit — Centralized state keeps card and review steppers in sync and simplifies persistence.
- Custom step UI — Steps use a hand-built expand/collapse pattern (
BuilderSteps) rather than a HeroUI Accordion, to match Figma layout (step icons beside titles, carrot chevrons, 2/5/1-column product grids). - Design tokens — Colors, gaps, border widths, radii, and line heights from Figma live in
app/theme.cssand are exposed to Tailwind viaapp/globals.css(text-muted,gap-step-stack,border-hairline, etc.). - Images — All file-based assets go through
ProductImage, which usesnext/imagefor PNG/JPG and native<img>for SVG. - Desktop layout — Side-by-side builder + review starts at
1440px(768px builder + 31px gap + 399px review), matching Figma Frame 1735. Odd product counts in the 2-column grid center the last card; the step “Next” button is centered on desktop.
- Add 2× White Wyze Cam v4, switch to Black — the stepper resets to 0 while White remains in the review panel.
- Change quantities from either the builder cards or the review panel — totals update immediately.
- Click Save my system for later, reload the page — your configuration is restored.
- Resize across mobile, tablet (1213px content, 5-column product grid), and desktop (1440px+, sticky review sidebar).
Layout and tokens are based on Frontend-Test-Figma frames:
- iPhone 13 & 14 — mobile (
<768px) - Frame 1736 — tablet (
768–1439px) - Frame 1735 — desktop (
≥1440px)