DocsSection 6
6Section 6 of 10

Frontend Architecture

Frontend Architecture

6.1 Component Hierarchy

Root Layout (app/layout.tsx)
    ↓
Page Layout (app/(admin)/admin/layout.tsx)
    ↓
Page (app/(admin)/admin/dashboard/page.tsx)
    ↓
Components (StatCard, ActivityFeed, etc.)
        ↓
UI Primitives (Button, Card, Input from app/components/ui/)

6.2 UI Component Library

Location: app/components/ui/

Philosophy: Headless-style with Tailwind

// app/components/ui/Button.tsx
interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  loading?: boolean;
  children: React.ReactNode;
  onClick?: () => void;
}

export function Button({ variant = 'primary', size = 'md', ...props }: ButtonProps) {
  const baseClasses = 'rounded-lg font-medium transition-colors';
  const variantClasses = {
    primary: 'bg-indigo-600 hover:bg-indigo-700 text-white',
    secondary: 'bg-slate-200 hover:bg-slate-300 text-slate-900',
    danger: 'bg-red-600 hover:bg-red-700 text-white',
  };
  const sizeClasses = {
    sm: 'px-3 py-1.5 text-sm',
    md: 'px-4 py-2 text-base',
    lg: 'px-6 py-3 text-lg',
  };
  
  return (
    <button 
      className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]}`}
      {...props}
    />
  );
}

Usage:

<Button variant="primary" size="lg" onClick={handleSave}>
  Save Changes
</Button>

6.3 State Management

No Redux! We use:

  1. React useState: Local component state
  2. React useContext: Shared state (auth, theme)
  3. Server state: Database is source of truth
  4. SWR/React Query: (Future) Data fetching/caching

Example: Auth context

// app/components/AuthProvider.tsx
const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  
  useEffect(() => {
    fetch('/api/me').then(r => r.json()).then(setUser);
  }, []);
  
  return (
    <AuthContext.Provider value={{ user, setUser }}>
      {children}
    </AuthContext.Provider>
  );
}

// Usage in component
const { user } = useContext(AuthContext);

6.4 Styling with Tailwind

Color scheme (Dark mode default):

Background: slate-950 (very dark)
Cards: slate-900
Borders: slate-800
Text: slate-100 (headings), slate-300 (body)
Primary: indigo-600
Success: emerald-500
Warning: amber-500
Error: red-500

Common pattern:

<div className="min-h-screen bg-slate-950 text-slate-100">
  <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <div className="bg-slate-900 rounded-xl border border-slate-800 p-6">
      <h1 className="text-2xl font-bold text-white">Dashboard</h1>
      <p className="mt-2 text-slate-400">
        Welcome back!
      </p>
    </div>
  </div>
</div>