From 05a40cca51ad3020a8e1dd0c4f515382c1f0e8cf Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Thu, 9 Apr 2026 10:35:58 -0500 Subject: [PATCH] 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 --- src/components/cards/dashboard-content.tsx | 34 +++++++++++++--------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/components/cards/dashboard-content.tsx b/src/components/cards/dashboard-content.tsx index e5ed0d4..fa4f9ad 100644 --- a/src/components/cards/dashboard-content.tsx +++ b/src/components/cards/dashboard-content.tsx @@ -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)[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(