diff --git a/apps/admin/app/(main)/jobs/[jobId]/ExportButton.tsx b/apps/admin/app/(main)/jobs/[jobId]/ExportButton.tsx new file mode 100644 index 0000000..bded4d7 --- /dev/null +++ b/apps/admin/app/(main)/jobs/[jobId]/ExportButton.tsx @@ -0,0 +1,70 @@ +'use client'; + +import { Button } from '@workspace/ui/components/button'; +import { Download } from 'lucide-react'; + +type Applicant = { + applicationId: number; + status: string; + firstName: string | null; + lastName: string | null; + email: string | null; + studentId: number | null; +}; + +interface ExportButtonProps { + applicants: Applicant[]; + jobId: number; + jobTitle: string; +} + +export default function ExportButton({ applicants, jobId, jobTitle }: ExportButtonProps) { + const exportToCSV = () => { + if (applicants.length === 0) { + alert('No applications to export.'); + return; + } + + const headers = ['Application ID', 'Student Name', 'Email', 'Status']; + const csvData = applicants.map(applicant => [ + applicant.applicationId.toString(), + `${applicant.firstName ?? ''} ${applicant.lastName ?? ''}`.trim() || 'Unknown', + applicant.email || '', + applicant.status + ]); + + const csvContent = [ + headers.join(','), + ...csvData.map(row => row.map(field => `"${field.replace(/"/g, '""')}"`).join(',')) + ].join('\n'); + + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const link = document.createElement('a'); + const url = URL.createObjectURL(blob); + + // Clean job title for filename + const cleanJobTitle = jobTitle.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase(); + const filename = `${cleanJobTitle}-job-${jobId}-applications-${new Date().toISOString().split('T')[0]}.csv`; + + link.setAttribute('href', url); + link.setAttribute('download', filename); + link.style.visibility = 'hidden'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + URL.revokeObjectURL(url); + }; + + return ( + + ); +} \ No newline at end of file diff --git a/apps/admin/app/(main)/jobs/[jobId]/page.tsx b/apps/admin/app/(main)/jobs/[jobId]/page.tsx index e2db91c..9fd0101 100644 --- a/apps/admin/app/(main)/jobs/[jobId]/page.tsx +++ b/apps/admin/app/(main)/jobs/[jobId]/page.tsx @@ -15,11 +15,13 @@ import { ExternalLink, Users, FileText, - Clock + Clock, + Download } from 'lucide-react'; import Link from 'next/link'; import StatusSelect from './StatusSelect'; import ApplicationsTable from './ApplicationsTable'; +import ExportButton from './ExportButton'; export const dynamic = 'force-dynamic'; @@ -303,13 +305,22 @@ export default async function JobDetailPage({ params }: { params: Promise<{ jobI