Skip to main content
This guide covers the SnackBase React admin UI architecture, development patterns, and how to build and extend the frontend.

Tech Stack

The SnackBase admin UI is built with modern, production-ready technologies:

Project Structure

Architecture Overview

The frontend follows a layered architecture with clear separation of concerns:

State Management

Global State: Zustand

Authentication state is managed in src/stores/auth.store.ts:
Key Features:
  • Token stored in localStorage with key auth-storage
  • Persist middleware for session persistence
  • restoreSession() verifies token validity on app load
  • Automatic logout on 401 responses

Server State: TanStack Query

All data from the API is managed by TanStack Query:

API Service Layer

All services follow a consistent pattern in src/services/:

Axios Configuration

The lib/api.ts file configures the Axios instance:

Authentication Flow

Login Flow

Protected Routes

The ProtectedRoute component wraps routes that require authentication:

Usage in App.tsx

All admin routes are under the /admin prefix:

Components & Patterns

ShadCN Components

ShadCN provides pre-built, accessible components. Never edit ShadCN components directly in src/components/ui/. To add new ShadCN components:

Component Composition Pattern

Build complex components by composing ShadCN primitives:

Dialog-Based CRUD Operations

Most CRUD operations use ShadCN Dialog components:

Routing

All routes are under the /admin prefix:

Styling

SnackBase uses TailwindCSS 4 with the new @tailwindcss/vite plugin.

Theme Configuration

Theme is configured in src/App.css:

Common Patterns

Development Workflow

Environment Setup

Create a .env file in the ui directory:

Running the Dev Server

The Vite dev server starts at http://localhost:5173 with:
  • Hot Module Replacement (HMR)
  • Fast refresh
  • TypeScript checking

Build for Production

Best Practices

1. Component Organization

  • Keep components focused and single-purpose
  • Extract reusable logic into custom hooks
  • Co-locate related components in feature folders

2. Type Safety

  • Always define TypeScript interfaces for API responses
  • Use Zod schemas for runtime validation
  • Avoid any type - use unknown if truly unknown

3. Error Handling

  • Always handle loading and error states from TanStack Query
  • Show user-friendly error messages
  • Use the handleApiError() utility from lib/api.ts

4. Performance

  • Use TanStack Query’s caching to avoid redundant requests
  • Implement pagination for large datasets
  • Lazy load components with React.lazy()