Frontend Application
The frontend is the web application that serves employers, job seekers, and platform administrators. It communicates with both the backend and background-tasks services through GraphQL.
Technology
| Component | Detail |
|---|---|
| Framework | Next.js 16 with App Router and Turbopack |
| GraphQL Client | Apollo Client with a multi-link chain |
| UI Library | Custom TW* components (TWButton, TWModal, TWInput, etc.) built on Tailwind CSS |
| Styling | Tailwind CSS 4 (CSS-first config via @theme directive in globals.css) |
| State Management | Zustand for local state; Apollo cache for server state |
| Port | 4000 (production: https://www.aiqlick.com) |
Application Structure
The app uses Next.js App Router with route groups organized by user role:
app/
(visitor)/ -- Public pages (about, contacts, jobs)
(shared)/ -- Authenticated shared pages (profile, CV builder)
company/ -- Employer pages (role-based access)
jobseeker/ -- Job seeker pages
admin/ -- Admin panel (17+ sections)
auth/ -- Authentication flows
onboarding/ -- User onboarding
| Route Group | Audience | Key Pages |
|---|---|---|
app/company/ | Employers | Dashboard, job management, pipelines, talent pools, candidates, meetings, billing |
app/jobseeker/ | Job seekers | Profile, job search, applications, CV management |
app/admin/ | Super administrators | Platform analytics, user management, RBAC, payments, audit logs, system logs, media manager |
app/auth/ | All users | Sign in, sign up, password reset, email verification |
Dual Mode: Employer and Job Seeker
The frontend supports two operating modes determined by the user's selectedCompanyId:
- Employer mode (
selectedCompanyIdis set): The UI displays company resources -- jobs, pipelines, talent pools, candidates, and team management. AI operation costs are charged to the company's credit balance. - Job seeker mode (
selectedCompanyIdis null): The UI displays personal resources -- profile, CV management, job search, and applications. AI costs are charged to the user's personal credit balance.
Users can switch between modes without logging out.
Key Features
CV Upload and Extraction
Users upload CV documents which are sent to background-tasks via a dedicated upload flow. The cvExtraction subscription streams real-time progress as the AI parses the document into structured fields (skills, experience, education, contact information).
Pipeline Kanban
A drag-and-drop Kanban board for managing candidates through recruitment stages. Candidates can be moved between columns representing pipeline stages (NEW -> IN_REVIEW -> INTERVIEW -> APPROVED / REJECTED).
AI Agent Chat
An interactive chat interface connected to background-tasks via the agentChat subscription. Responses stream as typed events: ChatProcessing, ChatContextLoaded, ChatChunk, ChatToolCall, ChatToolResult, and ChatComplete or ChatError.
Video Meetings
Integration with the custom Jitsi Meet instance at book.aiqlick.com. Meetings can be scheduled with calendar invitations and joined directly from the application.
Notifications
Notifications use a polling strategy rather than WebSocket subscriptions for reliability. The unread count is polled every 30 seconds, and individual notifications are fetched on demand.
Development
npm install
npm run dev # Start dev server with Turbopack at http://localhost:4000
npm run build # Production build
npm run lint # ESLint
FFmpeg is required for client-side video compression. Run ./scripts/download-ffmpeg.sh once to download the binary (~31MB).
There is no test framework configured for the frontend. Build verification (npm run build) is used as the pre-commit check via scripts/verify-build.sh.
Further Reading
- Frontend Architecture -- Apollo Client configuration, authentication flow, provider hierarchy, state management, environment variables, and deployment details.
- Frontend Patterns -- Component patterns (PageContainer, TWResponsiveCard, ChatModal) and conventions.
- Theme System -- Tailwind CSS v4 semantic tokens, dark/light mode, HeroUI integration.
- Structured CV Migration -- Migrating from legacy
schemaDataJSON to typed GraphQL fields.