Job Seeker Pages
The app/jobseeker/ route group contains all job seeker-facing pages. These are accessible when selectedCompanyId is null (job seeker mode).
Route Sections
Dashboard (/jobseeker/dashboard)
The main job seeker dashboard with 13 cards:
| Card | Data |
|---|---|
| KPICards | Key performance indicators |
| MonthlyStats | Monthly activity statistics |
| TrendCharts | Application trend visualization |
| ProfileCompletion | Profile completion % tracker |
| ProfileProgressCard | Progress toward profile goals |
| QualityMetrics | Profile quality score |
| RecommendedJobs / RecommendedGrid | AI-recommended jobs |
| UpcomingDeadlines | Application deadline tracker |
| JobseekerSummary | Profile summary card |
| Snapshot | Profile overview snapshot |
| GroupsSection | Groups/communities |
Compact variant: JobSeekerDashboardSlim.
Applications (/jobseeker/application)
Track submitted job applications, their status, and responses.
Connections (/jobseeker/connections/)
| Route | Purpose |
|---|---|
collaboratingpartner/ | Collaborating partner management |
contacts/ | Personal contact directory |
Credits (/jobseeker/credits)
Personal credit balance and purchase history.
Interviews (/jobseeker/interviews)
Interview schedule and details. Dynamic route [interviewId] for individual interview details with meeting link.
Jobs (/jobseeker/jobs)
Browse job listings. Dynamic route [jobId] for job details and application submission.
Messages (/jobseeker/messages)
Messaging inbox. Dynamic route [conversationId] for conversation threads.
Pricing (/jobseeker/pricing)
Subscription plan selection and comparison.
Resume (/jobseeker/resume/)
CV/resume management:
| Route | Purpose |
|---|---|
create/ | Build a new resume from scratch or upload |
edit/[cvId]/ | Edit an existing resume |
See CV Processing for the underlying extraction and builder features.
Search Job (/jobseeker/searchjob)
Advanced job search with filters (location, skills, salary, job type, work site).
Welcome (/jobseeker/welcome)
Onboarding welcome page for new job seeker accounts.
Onboarding Flow (/onboarding/jobseeker)
The job-seeker onboarding flow lives under app/onboarding/jobseeker/ and is a multi-step form that populates the user's profile, CV, and CvJobPreference row before landing them on the dashboard. The final SummaryStep calls updateUser({ isOnboarding: true }) and seeds a default AI agent via createDefaultAgent — this is where the "Job Search Assistant" (type: JOB_MATCHING) gets created for the user. See AI Agent — default-agent auto-create.
Preferences Step — salary sanity check
app/onboarding/jobseeker/steps/PreferencesStep.tsx collects the user's job preferences including expectedSalary, salaryCurrency (default SEK), and salaryFrequency (default MONTHLY). The default-MONTHLY is a footgun for users in EUR/USD/GBP/CHF markets who routinely enter a yearly figure without thinking to change the frequency — a user typing 150000 and leaving the defaults would silently persist €150,000 per month (€1.8M/year) into CvJobPreference.
The step guards against this with a three-part sanity check. The guard fires when all of these hold:
rateType === "MONTHLY"salaryCurrencyis one ofEUR,USD,GBP,CHF(high-value currencies where 50k/month is implausible — SEK/NOK/DKK are excluded because 50k/month is a plausible Scandinavian senior salary)expectedSalary >= 50,000
When triggered:
- Inline warning panel appears below the
SalaryFrequencyFieldwith the computed yearly amount ("${currency} X per month is ${currency} X×12 per year") and a "Switch to Yearly" button that flipsrateTypetoYEARLYin one click. - First Continue press is blocked by a warning
TWToastreminding the user of the implied yearly amount and pointing them at the Switch to Yearly button. An acknowledgement flag is set on the component state. - Second Continue press proceeds — the user has been warned and has chosen to save the monthly figure as-is.
- Editing any salary / currency / frequency field resets the acknowledgement flag so a fresh bad value re-triggers the guard instead of sliding through on the existing ack.
This is the guard for the expectedSalary: 150000, salaryFrequency: MONTHLY data-quality bug seen on real onboarding records. The CV LLM extractor never touches salary fields — they're populated only here, by this form. Without the guard, any high-value-currency user who left the MONTHLY default would silently ship a bogus yearly-as-monthly figure into their CvJobPreference.