import { authFetch } from "@/lib/api"; import { FilterFormValues } from "@/types/candidate-table"; /** * Fetch all candidates without pagination for export */ export const fetchAllCandidatesForExport = async ( search: string, sortConfig: { key: string | null; direction: "asc" | "desc" }, filters: FilterFormValues, criteriaId: string | null ): Promise => { const params = new URLSearchParams() // Set very high limit to get all results in one request // Adjust based on your backend's maximum limit params.set("page", "1") params.set("limit", "10000") // Fetch up to 10,000 records if (search) params.set("search", search) if (sortConfig.key) { params.set("sortBy", sortConfig.key) params.set("sortOrder", sortConfig.direction) } if (filters.domicile) params.set("domicile", filters.domicile) if (filters.yoe) params.set("yoe", filters.yoe) filters.educations.forEach((edu, i) => { const n = i + 1 if (edu.university) params.set(`univ_edu_${n}`, edu.university) if (edu.major) params.set(`major_edu_${n}`, edu.major) if (edu.gpa) params.set(`gpa_${n}`, edu.gpa) }) if (filters.softskills) params.append("softskills", filters.softskills) if (filters.hardskills) params.append("hardskills", filters.hardskills) if (filters.certifications) params.append("certifications", filters.certifications) if (filters.businessDomain) params.append("business_domain", filters.businessDomain) if (criteriaId) params.append("criteria_id", criteriaId) const res = await authFetch(`/api/cv-profile?${params}`) if (!res.ok) throw new Error("Failed to fetch candidates for export") const data = await res.json() return data.data ?? [] } /** * Convert candidates array to CSV string */ export const generateCSVContent = (candidates: any[]): string => { if (candidates.length === 0) return "" // Define all possible columns const columns = [ "profile_id", "fullname", "domicile", "yoe", "univ_edu_1", "major_edu_1", "gpa_edu_1", "univ_edu_2", "major_edu_2", "gpa_edu_2", "univ_edu_3", "major_edu_3", "gpa_edu_3", "hardskills", "softskills", "certifications", "business_domain", "score", ] // CSV Header const header = columns.join(",") // CSV Rows const rows = candidates.map((candidate) => columns .map((col) => { const value = candidate[col] // Handle arrays (join with semicolon) if (Array.isArray(value)) { return `"${value.join("; ")}"` } // Handle null/undefined if (value === null || value === undefined) { return "" } // Handle strings with commas or quotes (escape them) const stringValue = String(value) if (stringValue.includes(",") || stringValue.includes('"') || stringValue.includes("\n")) { return `"${stringValue.replace(/"/g, '""')}"` // Escape quotes } return stringValue }) .join(",") ) return [header, ...rows].join("\n") } /** * Trigger CSV download in browser */ export const downloadCSV = (content: string, filename: string = "candidates.csv"): void => { const blob = new Blob([content], { type: "text/csv;charset=utf-8;" }) const link = document.createElement("a") const url = URL.createObjectURL(blob) 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) } /** * Main export function - orchestrates fetch, generate, and download */ export const exportCandidatesToCSV = async ( search: string, sortConfig: { key: string | null; direction: "asc" | "desc" }, filters: FilterFormValues, criteriaId: string | null, userId: string ): Promise => { try { const params = new URLSearchParams() if (search) params.set("search", search) if (sortConfig.key) { params.set("sortBy", sortConfig.key) params.set("sortOrder", sortConfig.direction) } if (filters.domicile) params.set("domicile", filters.domicile) if (filters.yoe) params.set("yoe", filters.yoe) filters.educations.forEach((edu, i) => { const n = i + 1 // Handle arrays for university and major edu.university.forEach((univ) => params.append(`univ_edu_${n}`, univ)) edu.major.forEach((maj) => params.append(`major_edu_${n}`, maj)) if (edu.gpa) params.set(`gpa_${n}`, edu.gpa) }) // Updated to handle arrays filters.softskills.forEach((skill) => params.append("softskills", skill)) filters.hardskills.forEach((skill) => params.append("hardskills", skill)) filters.certifications.forEach((cert) => params.append("certifications", cert)) filters.businessDomain.forEach((domain) => params.append("business_domain", domain)) if (criteriaId) params.append("criteria_id", criteriaId) params.append("user_id", userId) // Call backend export endpoint const response = await authFetch(`/api/cv-profile/export?${params}`, { method: "GET", headers: { "Accept": "text/csv", }, }) if (!response.ok) { const error = await response.json() throw new Error(error.error || "Export failed") } // Get blob and trigger download const blob = await response.blob() const url = window.URL.createObjectURL(blob) const link = document.createElement("a") link.href = url // Extract filename from Content-Disposition header const contentDisposition = response.headers.get("Content-Disposition") const filename = contentDisposition ? contentDisposition.split("filename=")[1]?.replace(/"/g, "") : `candidates-${new Date().toISOString().slice(0, 10)}.csv` link.setAttribute("download", filename) document.body.appendChild(link) link.click() // Cleanup document.body.removeChild(link) window.URL.revokeObjectURL(url) } catch (error) { console.error("Export failed:", error) throw error } }