4.1 KiB
4.1 KiB
Frontend Architecture
Framework
Next.js 15 App Router with TypeScript and CSS Modules. All pages under src/app/(dashboard)/ are protected by AuthGuard and wrapped in the dashboard layout (sidebar + header).
Route Map
| Route | Page |
|---|---|
/ |
Redirects to /overview |
/overview |
Dashboard overview |
/videos |
Video list — paginated, sortable, filterable, with tabs |
/videos/[id] |
Video editor — metadata + description config |
/blocks |
Description block management |
/templates |
Template management |
/variables |
Team global variables |
/collaborators |
Collaborator management |
/settings |
Team members + connected channels |
/saved-views |
Saved filter preset management |
/linting |
Lint results browser — filter by severity/rule |
/bulk-jobs |
Bulk operation history + rollback |
/calendar |
Scheduled video calendar (month/week/agenda) |
/audit |
Change history / audit log |
/quota-history |
YouTube API quota usage history |
/io |
CSV / JSON import and export |
/login |
Google OAuth login |
/auth/callback |
OAuth callback handler |
Key Files
| File | Role |
|---|---|
src/lib/api.ts |
All API call functions + TypeScript interfaces for every API response |
src/lib/api-client.ts |
Axios instance — sets baseURL, attaches JWT, handles 401 refresh |
src/store/useAuthStore.ts |
Zustand — user, teamId, token, clearAuth |
src/store/useUIStore.ts |
Zustand (persisted) — sidebarCollapsed, toggleSidebar |
src/middleware.ts |
Route protection — redirects unauthenticated users to /login |
src/styles/globals.css |
Design tokens (CSS variables), global utility classes |
src/hooks/useTheme.ts |
Dark/light theme toggle with localStorage persistence |
State Management
| Concern | Tool |
|---|---|
| Server data (videos, blocks, etc.) | TanStack Query v5 useQuery / useMutation |
| Auth state | Zustand useAuthStore |
| UI state (sidebar) | Zustand useUIStore (localStorage-persisted) |
| Page-level UI state | useState / useReducer |
TanStack Query Patterns
useQueryClient()must be called at component level, never inside callbacks- After mutations, invalidate related queries in
onSuccess:- After saving a video: invalidate
['video', id]and['videos'] - After changing blocks: invalidate
['blocks']and affected video queries
- After saving a video: invalidate
- Use
placeholderData: (prev) => prevto keep stale data visible during page transitions - Query keys are arrays:
['videos'],['video', id],['preferences']
API Layer
All API calls are in src/lib/api.ts. The file exports:
- TypeScript interfaces for all API response shapes
- Named functions for each endpoint (
fetchVideos,updateVideo,lintVideo, etc.)
The Axios client (api-client.ts) handles:
- Base URL from
NEXT_PUBLIC_API_URL - JWT
Authorization: Bearerheader injection - 401 → automatic token refresh → retry
Component Structure
src/components/
video-table/
VideoTable.tsx TanStack Table — video list with sorting, pagination
VideoTable.module.css
video-config/
VideoConfigEditor.tsx forwardRef component — exposes save() and isDirty()
VideoConfigEditor.module.css
shared/
Sidebar.tsx Collapsible navigation sidebar
Header.tsx Top bar — search, sync status, bulk change, theme, user
Modal.tsx Generic modal wrapper
FormField.module.css Shared form field utility classes
Providers.tsx TanStack Query provider wrapper
AuthGuard.tsx Redirects unauthenticated users
SortableSection.tsx DnD-kit sortable wrapper for video editor sections
Video Editor Layout
The video editor (/videos/[id]) uses a combined horizontal header card (thumbnail + meta + actions) above a two-column sortable editing area. Sections (Basic Info, Language, Audience, Playlists, Description) can be dragged between the two columns. Column layout is persisted to User.preferences via PATCH /users/me/preferences.
Related
- 01 - System Overview
- 01 - Visual Design (design guidelines)
- 02 - CSS Conventions (design guidelines)