Export CSV based on currently visible columns instead of hardcoded list

- CSV export now respects column visibility settings, exporting only the
  columns the user has toggled on
- Boolean fields export as "Yes"/"No", arrays as comma-separated values
- Toast message shows row and column counts for confirmation

Made-with: Cursor
This commit is contained in:
Randall Stillwell 2026-04-09 10:35:58 -05:00
parent ec51c049c3
commit 05a40cca51

View file

@ -6,7 +6,7 @@ import { toast } from "sonner";
import { StatCards, type StatFilter } from "./stat-cards";
import { Filters } from "./filters";
import { DataTable, getDefaultColumnVisibility } from "./data-table";
import { DataTable, getDefaultColumnVisibility, ALL_TOGGLEABLE_COLUMNS } from "./data-table";
import { SelectionToolbar } from "./selection-toolbar";
import { UploadModal, type UploadingFile } from "./upload-modal";
import { createColumns, COPYABLE_FIELDS, type ResponseCard } from "./columns";
@ -173,17 +173,25 @@ export function DashboardContent() {
return;
}
const headers = [
"Name", "Email", "Phone", "City", "State", "Gender",
"Visit Type", "Attendance", "Service", "OCR Status", "Review Status",
"Confidence",
];
const rows = data.map((c) => [
c.name || "", c.email || "", c.cellPhone || "", c.city || "",
c.state || "", c.gender || "", c.visitType || "",
c.attendanceDuration || "", c.serviceAttended || "", c.ocrStatus,
c.reviewStatus, c.ocrConfidence?.toString() || "",
]);
const visibleCols = ALL_TOGGLEABLE_COLUMNS.filter(
(col) => columnVisibility[col.id] !== false
);
if (visibleCols.length === 0) {
toast.error("No columns visible to export");
return;
}
const headers = visibleCols.map((c) => c.label);
const rows = data.map((card) =>
visibleCols.map((col) => {
const val = (card as Record<string, unknown>)[col.id];
if (val == null) return "";
if (typeof val === "boolean") return val ? "Yes" : "No";
if (Array.isArray(val)) return val.filter(Boolean).join(", ");
return String(val);
})
);
const csv = [headers, ...rows]
.map((r) => r.map((v) => `"${v.replace(/"/g, '""')}"`).join(","))
@ -196,7 +204,7 @@ export function DashboardContent() {
a.download = `response-cards-${new Date().toISOString().split("T")[0]}.csv`;
a.click();
URL.revokeObjectURL(url);
toast.success("CSV exported");
toast.success(`Exported ${data.length} rows × ${visibleCols.length} columns`);
};
const columns = React.useMemo(