diff --git a/src/components/dashboard/CompanyApplicationsPage.tsx b/src/components/dashboard/CompanyApplicationsPage.tsx index a47169b..cdf2a96 100644 --- a/src/components/dashboard/CompanyApplicationsPage.tsx +++ b/src/components/dashboard/CompanyApplicationsPage.tsx @@ -1,7 +1,15 @@ -import { For, Show, createSignal, onMount } from 'solid-js'; -import { BTN_GHOST, BTN_ORANGE, CARD, INPUT, LABEL } from '~/components/DashboardShell'; +/** + * Company Applications Page - Wired to real backend APIs + * Endpoints: + * GET /api/companies/jobs - List company's jobs + * GET /api/companies/jobs/:id/applications - Get applications for a job + * POST /api/companies/applications/:id/contact - Unlock contact info + * PATCH /api/companies/applications/:id/status - Update application status + */ +import { For, Show, createSignal, onMount } from "solid-js"; +import { BTN_GHOST, BTN_ORANGE, CARD, INPUT, LABEL } from "~/components/DashboardShell"; -const API = '/api/gateway'; +const API = "/api/gateway"; interface JobItem { id: string; @@ -32,26 +40,26 @@ interface ContactInfo { async function apiFetch(path: string, opts?: RequestInit) { return fetch(`${API}${path}`, { ...opts, - credentials: 'include', - headers: { 'Content-Type': 'application/json', ...(opts?.headers ?? {}) }, + credentials: "include", + headers: { "Content-Type": "application/json", ...(opts?.headers ?? {}) }, }); } export default function CompanyApplicationsPage() { const [jobs, setJobs] = createSignal([]); - const [selectedJobId, setSelectedJobId] = createSignal(''); + const [selectedJobId, setSelectedJobId] = createSignal(""); const [applications, setApplications] = createSignal([]); const [loading, setLoading] = createSignal(true); const [loadingApps, setLoadingApps] = createSignal(false); - const [statusFilter, setStatusFilter] = createSignal(''); - const [actionMsg, setActionMsg] = createSignal(''); + const [statusFilter, setStatusFilter] = createSignal(""); + const [actionMsg, setActionMsg] = createSignal(""); const [busyAppId, setBusyAppId] = createSignal(null); const [contactByApp, setContactByApp] = createSignal>({}); const loadJobs = async () => { setLoading(true); try { - const res = await apiFetch('/api/companies/jobs?page=1&limit=100'); + const res = await apiFetch("/api/companies/jobs?page=1&limit=100"); if (!res.ok) { setJobs([]); return; @@ -64,7 +72,7 @@ export default function CompanyApplicationsPage() { setSelectedJobId(nextJobId); await loadApplications(nextJobId, statusFilter()); } else { - setSelectedJobId(''); + setSelectedJobId(""); setApplications([]); } } finally { @@ -80,9 +88,9 @@ export default function CompanyApplicationsPage() { setLoadingApps(true); try { const query = new URLSearchParams(); - query.set('page', '1'); - query.set('limit', '50'); - if (status) query.set('status', status); + query.set("page", "1"); + query.set("limit", "50"); + if (status) query.set("status", status); const res = await apiFetch(`/api/companies/jobs/${jobId}/applications?${query.toString()}`); if (!res.ok) { setApplications([]); @@ -105,18 +113,18 @@ export default function CompanyApplicationsPage() { const updateApplicationStatus = async (id: string, status: string) => { setBusyAppId(id); - setActionMsg(''); + setActionMsg(""); try { const res = await apiFetch(`/api/companies/applications/${id}/status`, { - method: 'PATCH', + method: "PATCH", body: JSON.stringify({ status }), }); if (res.ok) { - setActionMsg(`Application marked as ${status.replace(/_/g, ' ')}.`); + setActionMsg(`Application marked as ${status.replace(/_/g, " ")}.`); await refreshCurrent(); } else { const data = await res.json().catch(() => ({})); - setActionMsg(data.error ?? data.message ?? 'Failed to update application status.'); + setActionMsg(data.error ?? data.message ?? "Failed to update application status."); } } finally { setBusyAppId(null); @@ -125,14 +133,14 @@ export default function CompanyApplicationsPage() { const loadContact = async (id: string) => { setBusyAppId(id); - setActionMsg(''); + setActionMsg(""); try { const res = await apiFetch(`/api/companies/applications/${id}/contact`); const data = await res.json().catch(() => ({})); if (res.ok) { setContactByApp((prev) => ({ ...prev, [id]: data })); } else { - setActionMsg(data.error ?? data.message ?? 'Failed to load contact details.'); + setActionMsg(data.error ?? data.message ?? "Failed to load contact details."); } } finally { setBusyAppId(null); @@ -140,35 +148,64 @@ export default function CompanyApplicationsPage() { }; const prettyDate = (value?: string) => { - if (!value) return '—'; + if (!value) return "—"; const d = new Date(value); - return Number.isNaN(d.getTime()) ? value : d.toLocaleString('en-IN'); + return Number.isNaN(d.getTime()) ? value : d.toLocaleString("en-IN"); }; return ( -
-
+
+
-

Applications

-

+

+ Applications +

+

Review applicants and update their hiring stage.

- +
-
+
{actionMsg()}
-
Loading jobs…
+
Loading jobs…
-
+
setField('title', e.currentTarget.value)} style={INPUT} placeholder="Frontend Developer" /> + setField("title", e.currentTarget.value)} + style={INPUT} + placeholder="Frontend Developer" + />
- setField('category', e.currentTarget.value)} style={INPUT} placeholder="Engineering" /> + setField("category", e.currentTarget.value)} + style={INPUT} + placeholder="Engineering" + />
- setField("job_type", e.currentTarget.value)} + style={INPUT} + >
-
+
- setField('location', e.currentTarget.value)} style={INPUT} placeholder="Bengaluru (Hybrid)" /> + setField("location", e.currentTarget.value)} + style={INPUT} + placeholder="Bengaluru (Hybrid)" + />
-
+