import { For, Show, createMemo, createSignal, onMount } from 'solid-js'; import { BTN_GHOST, CARD } from '~/components/DashboardShell'; import { PROFESSIONAL_ROLE_SET, ROLE_PREFIXES, type RoleKey } from './RoleDashboardShared'; import { readJobSeekerProfile } from '~/lib/job-seeker-custom-data'; const API = '/api/gateway'; type Props = { roleKey: RoleKey; userName?: string; }; type Metric = { title: string; value: string; hint: string; }; async function apiFetch(path: string, opts?: RequestInit) { return fetch(`${API}${path}`, { ...opts, credentials: 'include', headers: { 'Content-Type': 'application/json', ...(opts?.headers ?? {}) }, }); } export default function MyDashboardPage(props: Props) { const [metrics, setMetrics] = createSignal([]); const [loading, setLoading] = createSignal(true); const [err, setErr] = createSignal(''); const roleLabel = createMemo(() => String(props.roleKey || '').replace(/_/g, ' ')); const loadData = async () => { setLoading(true); setErr(''); const next: Metric[] = []; try { if (props.roleKey === 'COMPANY') { const [jobsRes, appsRes] = await Promise.all([ apiFetch('/api/companies/jobs?page=1&limit=100'), apiFetch('/api/companies/jobs?page=1&limit=1'), ]); const jobsJson = await jobsRes.json().catch(() => ({})); const appsJson = await appsRes.json().catch(() => ({})); const jobs = Array.isArray(jobsJson?.data) ? jobsJson.data : []; next.push( { title: 'Total Jobs', value: String(jobs.length), hint: 'All job posts created' }, { title: 'Active Jobs', value: String(jobs.filter((j: any) => String(j.status || '').toUpperCase() === 'OPEN').length), hint: 'Open to applications' }, { title: 'Jobs In Verification', value: String(jobs.filter((j: any) => String(j.status || '').toUpperCase().includes('PENDING')).length), hint: 'Pending verification/approval' }, { title: 'Latest Sync', value: appsRes.ok ? 'Live' : 'Partial', hint: 'Dashboard data status' }, ); if (!jobsRes.ok && !appsRes.ok) setErr('Some company metrics could not be loaded.'); } else if (props.roleKey === 'CUSTOMER') { const reqRes = await apiFetch('/api/customers/requirements?page=1&limit=100'); const reqJson = await reqRes.json().catch(() => ({})); const reqs = Array.isArray(reqJson?.data) ? reqJson.data : []; next.push( { title: 'My Requirements', value: String(reqs.length), hint: 'Total posted requirements' }, { title: 'Open Requirements', value: String(reqs.filter((r: any) => String(r.status || '').toUpperCase() === 'OPEN').length), hint: 'Visible to professionals' }, { title: 'In Verification', value: String(reqs.filter((r: any) => String(r.status || '').toUpperCase().includes('PENDING')).length), hint: 'Verification/approval stage' }, { title: 'Drafts', value: String(reqs.filter((r: any) => String(r.status || '').toUpperCase() === 'DRAFT').length), hint: 'Not yet submitted' }, ); if (!reqRes.ok) setErr('Some customer metrics could not be loaded.'); } else if (props.roleKey === 'JOB_SEEKER') { const [jobsRes, appsRes, profile] = await Promise.all([ apiFetch('/api/jobseeker/jobs?page=1&limit=100'), apiFetch('/api/jobseeker/applications?page=1&limit=100'), readJobSeekerProfile(), ]); const jobsJson = await jobsRes.json().catch(() => ({})); const appsJson = await appsRes.json().catch(() => ({})); const jobs = Array.isArray(jobsJson?.data) ? jobsJson.data : []; const apps = Array.isArray(appsJson?.data) ? appsJson.data : []; const customData = (profile?.custom_data && typeof profile.custom_data === 'object') ? (profile.custom_data as Record) : {}; const savedJobs = Array.isArray(customData.saved_jobs) ? customData.saved_jobs : []; const portfolio = (customData.job_seeker_portfolio && typeof customData.job_seeker_portfolio === 'object') ? (customData.job_seeker_portfolio as Record) : {}; const profileStatus = String(profile?.status || 'NOT_SUBMITTED').replace(/_/g, ' '); const portfolioDone = Boolean( String(portfolio.headline || '').trim() && String(portfolio.education || '').trim() && String(portfolio.workExperience || '').trim() && String(portfolio.skills || '').trim(), ); next.push( { title: 'Available Jobs', value: String(jobs.length), hint: 'Open approved jobs' }, { title: 'My Applications', value: String(apps.length), hint: 'Total applications submitted' }, { title: 'Shortlisted', value: String(apps.filter((a: any) => String(a.status || '').toUpperCase() === 'SHORTLISTED').length), hint: 'Moved ahead in process' }, { title: 'Saved Jobs', value: String(savedJobs.length), hint: 'Bookmarked for later' }, { title: 'Profile Status', value: profileStatus, hint: 'Verification state' }, { title: 'Portfolio', value: portfolioDone ? 'Complete' : 'Incomplete', hint: 'Education/work/skills sections' }, ); if (!jobsRes.ok && !appsRes.ok && !profile) setErr('Some job seeker metrics could not be loaded.'); } else if (PROFESSIONAL_ROLE_SET.has(props.roleKey)) { const prefix = ROLE_PREFIXES[props.roleKey]; const [marketRes, reqRes, walletRes] = await Promise.all([ apiFetch(`/api/${prefix}/marketplace?page=1&limit=100`), apiFetch(`/api/${prefix}/leads/requests/me?page=1&limit=100`), apiFetch(`/api/${prefix}/wallet/me`), ]); const marketJson = await marketRes.json().catch(() => ({})); const reqJson = await reqRes.json().catch(() => ({})); const walletJson = await walletRes.json().catch(() => ({})); const market = Array.isArray(marketJson?.data) ? marketJson.data : []; const requests = Array.isArray(reqJson?.data) ? reqJson.data : []; next.push( { title: 'Open Leads', value: String(market.length), hint: 'Available opportunities' }, { title: 'My Requests', value: String(requests.length), hint: 'Lead requests sent' }, { title: 'Accepted Requests', value: String(requests.filter((r: any) => ['APPROVED', 'CONTACT_UNLOCKED'].includes(String(r.status || '').toUpperCase())).length), hint: 'Approved responses' }, { title: 'Tracecoins', value: String(walletJson?.balance ?? 0), hint: 'Current wallet balance' }, ); if (!marketRes.ok && !reqRes.ok && !walletRes.ok) setErr('Some professional metrics could not be loaded.'); } else { next.push( { title: 'Welcome', value: 'Ready', hint: 'Dashboard initialized' }, { title: 'Role', value: roleLabel(), hint: 'Current active role' }, ); } setMetrics(next); } catch { setErr('Network error while loading dashboard metrics.'); setMetrics([ { title: 'Status', value: 'Unavailable', hint: 'Please retry' }, ]); } finally { setLoading(false); } }; onMount(loadData); return (

My Dashboard

Welcome {props.userName || 'User'}. Role: {roleLabel()}.

{err()}

Quick Summary

Loading dashboard...

{(m) => (

{m.title}

{m.value}

{m.hint}

)}
); }