Admin Overview
App path: apps/admin/
Router: React Router v7
Auth: Supabase Auth (email/password)
Page Structure
The admin is a single-page dashboard that switches between views via local state (no URL-based routing beyond the root).
| View | Component | Trigger |
|---|---|---|
| Login | LoginPage | Unauthenticated state |
| Job List | JobList | Default authenticated view |
| Job Detail | JobDetailPage | Click a job in the list |
| Job Form (create) | JobForm | ”New Job” button |
| Job Form (edit) | JobForm | ”Edit” button on job detail |
| Candidate Info | CandidateInfoPage | Click a candidate in the table |
| Applicant List | ApplicantList | Click “Applicants” tab in job detail |
LoginPage
File: apps/admin/src/app/components/LoginPage.tsx
A centered login card over a blurred ShaderGradientBackground.
Shared UI Used
| Component | Import Source |
|---|---|
Card, CardHeader, CardContent, CardFooter | @prosper/shared/components/ui/card |
Input | @prosper/shared/components/ui/input |
Label | @prosper/shared/components/ui/label |
Button | @prosper/shared/components/ui/button |
ShaderGradientBackground | Local (./ShaderGradientBackground) |
Validation
Uses Zod for email/password validation with manual useState error handling (not react-hook-form’s Form component).
Auth Flow
- Validates with Zod schema
- Calls
supabase.auth.signInWithPassword() - On success, parent component detects auth state change and shows dashboard
ProsperChatPanel
File: apps/admin/src/app/components/ProsperChatPanel.tsx
An AI-powered chat sidebar that can:
- Answer questions about a job posting
- Suggest edits to job fields (via
~~~actionblocks) - Generate LinkedIn search queries
- Stream responses from a Supabase Edge Function (
prosper-chat)
UI Features
- Resizable panel (drag handle on left edge)
- Collapsible to a floating button
- Message bubbles with markdown rendering
- Copy-to-clipboard for messages
- Action buttons for applying AI suggestions
Not using shared UI — Custom implementations
The chat panel uses entirely custom styling with Tailwind. It does not use any shared components (Button, Card, Input, etc.), relying on inline-styled elements.