From a5e0c8335f1ffd2c4a370a1e7f06b7c2e6c8c556 Mon Sep 17 00:00:00 2001 From: Albert Dong Date: Wed, 29 Jul 2026 16:35:35 -0700 Subject: [PATCH] Add combined mid/end-of-quarter UID Excel export Each course row now has a "Download Both" button that writes a single workbook containing the mid-quarter UIDs, the mid-quarter course-change responses, and the end-of-quarter UIDs, instead of requiring two separate downloads. Extract the sheet-building from downloadExcel into appendSheets so the single-type and combined exports share one code path; the combined export calls it twice into the same workbook with distinct sheet-name prefixes. Co-Authored-By: Claude Opus 5 --- laprogram/app/admin/components/ReportTab.tsx | 61 +++++++++++++++----- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/laprogram/app/admin/components/ReportTab.tsx b/laprogram/app/admin/components/ReportTab.tsx index e4a3dd5..b1f3311 100644 --- a/laprogram/app/admin/components/ReportTab.tsx +++ b/laprogram/app/admin/components/ReportTab.tsx @@ -44,18 +44,25 @@ function CopyButton({ text, disabled }: { text: string; disabled?: boolean }) { ); } -function downloadExcel( - course: string, +type FeedbackType = "mid_quarter" | "end_of_quarter"; + +/** Adds a UID sheet — plus, for mid-quarter, a course-change sheet — to `wb`. */ +function appendSheets( + wb: XLSX.WorkBook, uids: UidInformation[], - type: "mid_quarter" | "end_of_quarter", + type: FeedbackType, + prefix = "", ) { - const wb = XLSX.utils.book_new(); const uidRows = uids.map((u) => ({ uid: u.uid, name: u.name, email: u.email, })); - XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet(uidRows), "UIDs"); + XLSX.utils.book_append_sheet( + wb, + XLSX.utils.json_to_sheet(uidRows), + `${prefix}UIDs`, + ); if (type === "mid_quarter") { const feedbackRows = uids @@ -66,13 +73,31 @@ function downloadExcel( XLSX.utils.book_append_sheet( wb, XLSX.utils.json_to_sheet(feedbackRows), - "Course Change", + `${prefix}Course Change`, ); } +} +function downloadExcel( + course: string, + uids: UidInformation[], + type: FeedbackType, +) { + const wb = XLSX.utils.book_new(); + appendSheets(wb, uids, type); XLSX.writeFile(wb, `${course} UIDs - ${type}.xlsx`); } +function downloadCombinedExcel( + course: string, + entry: Record, +) { + const wb = XLSX.utils.book_new(); + appendSheets(wb, entry.mid_quarter, "mid_quarter", "Mid-Quarter "); + appendSheets(wb, entry.end_of_quarter, "end_of_quarter", "End-of-Quarter "); + XLSX.writeFile(wb, `${course} UIDs.xlsx`); +} + function UidLists() { const { data: rows } = useSWR( "/api/admin/audit/feedback-uids", @@ -84,13 +109,7 @@ function UidLists() { return

Loading…

; } - const byCourse = new Map< - string, - { - mid_quarter: UidInformation[]; - end_of_quarter: UidInformation[]; - } - >(); + const byCourse = new Map>(); for (const row of rows) { const course = row.course ?? "(no course)"; let entry = byCourse.get(course); @@ -137,6 +156,19 @@ function UidLists() { end + {isExpanded && (
@@ -197,7 +229,8 @@ export function ReportTab() {

Mid-quarter Excel exports include a second sheet with each student's “What would you change about this course?” - response. + response. “Download Both” puts the mid- and + end-of-quarter sheets in a single file.