Skip to content

Frontend Architecture

The frontend is built with Next.js 16, React 19, and Tailwind CSS 4.

Project Structure

frontend/
├── app/                    # Next.js App Router
│   ├── layout.tsx          # Root layout with providers
│   ├── page.tsx            # Homepage
│   ├── account/            # User account settings
│   ├── admin/              # Admin dashboard (React)
│   ├── auth/               # Authentication pages
│   ├── cart/               # Shopping cart
│   ├── catalog/            # Product catalog listing
│   ├── checkout/           # Checkout flow
│   ├── contact/            # Contact form
│   ├── designer/           # Product designer (Fabric.js)
│   ├── designs/            # Saved designs
│   ├── login/              # Login page
│   ├── orders/             # Order history
│   ├── products/           # Product detail pages
│   ├── team-order/         # Team/bulk ordering
│   ├── faq/                # FAQ page
│   ├── over-ons/           # About page
│   ├── privacy/            # Privacy policy
│   ├── retouren/           # Return policy
│   └── voorwaarden/        # Terms & conditions
├── components/
│   ├── header/             # Header components
│   ├── homepage/           # Homepage sections
│   ├── products/           # Product listing
│   ├── product-detail/     # Product detail page
│   ├── ProductDesigner/    # Canvas designer
│   └── providers/          # Context providers
├── contexts/               # React contexts
│   ├── AuthContext.tsx
│   ├── CartContext.tsx
│   ├── TeamOrderContext.tsx
│   └── ThemeContext.tsx
├── hooks/                  # Custom hooks
│   ├── api/                # API query hooks
│   └── admin/              # Admin hooks
├── lib/                    # Utilities
│   ├── api/client.ts       # API client (Axios)
│   ├── posthog.ts          # PostHog analytics init
│   └── queryClient.ts      # TanStack Query
├── types/                  # TypeScript types
└── public/                 # Static assets

Component Architecture

Component Organization

Components are organized by feature:

components/
├── [feature]/
│   ├── FeatureComponent.tsx
│   ├── FeatureComponent.stories.tsx  # Storybook
│   └── FeatureComponent.test.tsx     # Jest tests

Component Patterns

Presentational Components

interface ButtonProps {
  variant: 'primary' | 'secondary';
  children: React.ReactNode;
}

export function Button({ variant, children }: ButtonProps) {
  return <button className={styles[variant]}>{children}</button>;
}

Container Components

export function ProductList() {
  const { data: products } = useQuery({
    queryKey: ['products'],
    queryFn: fetchProducts,
  });

  return <ProductGrid products={products} />;
}

State Management

Server State (TanStack Query)

const { data, isLoading, error } = useQuery({
  queryKey: ['products', categoryId],
  queryFn: () => api.products.list({ category: categoryId }),
});

Client State (React Context)

The primary client state is managed via React Context:

  • AuthContext - Authentication state and user session
  • CartContext - Shopping cart items and operations
  • TeamOrderContext - Team order builder state
  • ThemeContext - Light/dark theme preferences
// Example: CartContext usage
const { items, addItem, removeItem, total } = useCart();

Persistent State (Zustand)

Zustand is used for localStorage-persisted state that must survive SSR:

// Admin onboarding checklist progress
const useOnboardingProgress = create(
  persist((set) => ({
    completedSteps: [],
    markComplete: (step) => set((state) => ({
      completedSteps: [...state.completedSteps, step],
    })),
  }), { name: 'admin-onboarding' })
);

Styling

Tailwind CSS 4 with custom design tokens in app/globals.css:

:root {
  --primary: #31a8b6;
  --primary-dark: #2a919d;
}

@theme inline {
  --color-primary: var(--primary);
}

Visual Identity System

The "Freeze" brand visual language uses frost/ice effects:

Color Tokens: - --frost-N - Frost blue shades (100-900) - --ice-N - Ice accent colors - --coral-N - Warm accent for CTAs

Utility Classes: - glass-frost - Glassmorphism with backdrop-blur - frost-overlay - Decorative ice pattern overlay - link-underline - Animated underline on hover/focus

Animation Patterns (Motion):

// Entrance animations with stagger
<motion.div variants={containerVariants} initial="hidden" animate="visible">
  <motion.div variants={itemVariants}>...</motion.div>
</motion.div>

// Tactile feedback
<motion.button whileTap={{ scale: 0.95 }} transition={{ duration: 0.1 }}>

// Frost glow hover
className="hover:shadow-[0_0_15px_rgba(125,211,252,0.25)]"

Product Designer

The Fabric.js canvas editor supports:

  • Text with custom fonts
  • Image uploads
  • Shape tools
  • Multi-view support (front/back/left/right)
  • Undo/redo
  • Print area boundaries