import { useState } from "react"; import { useClient } from "urql"; import { graphql, type ResultOf, type VariablesOf } from "@/graphql"; import { useToast } from "@/hooks/use-toast"; import { fetchAllPages } from "@/lib/fetch-all-pages"; import { toDateInputValue } from "@/lib/format-date"; import { csvTimestamp, downloadCsv, toCsv, type CsvColumn } from "@/lib/to-csv"; /** CSV export for the Sites dashboard (issue #605). */ const SitesCsvQuery = graphql(` query SitesCsv($first: Int, $after: String, $order: [SiteOrderInput], $query: SiteQueryInput) { sites(first: $first, after: $after, order: $order, query: $query) { pageInfo { hasNextPage endCursor } edges { node { name type city country status createdAt company { legalName } } } } } `); type CsvVariables = VariablesOf; type CsvResult = ResultOf; type SiteCsvRow = NonNullable["edges"]>[number]["node"]; const columns: CsvColumn[] = [ { header: "Name", value: (r) => r.name }, { header: "Type", value: (r) => r.type }, { header: "Company", value: (r) => r.company?.legalName }, { header: "City", value: (r) => r.city }, { header: "Country", value: (r) => r.country }, { header: "Status", value: (r) => r.status }, { header: "Created Date", value: (r) => toDateInputValue(r.createdAt) }, ]; export function useExportSitesCsv() { const client = useClient(); const toast = useToast(); const [isExporting, setIsExporting] = useState(false); async function exportCsv(order: CsvVariables["order"], query: CsvVariables["query"]) { if (isExporting) return; setIsExporting(true); try { const rows = await fetchAllPages(client, SitesCsvQuery, { order, query }, (d) => d.sites); if (rows.length === 0) { toast.error("No sites to export"); return; } downloadCsv(toCsv(rows, columns), `sites-${csvTimestamp()}.csv`); toast.success(`${rows.length.toLocaleString()} rows exported`); } catch (err) { console.error("CSV export failed:", err); toast.error("Failed to export CSV"); } finally { setIsExporting(false); } } return { exportCsv, isExporting }; }