From ed131acab4fd6255855992cf5d3238272f7fa894 Mon Sep 17 00:00:00 2001 From: Syasya Date: Fri, 29 Aug 2025 15:29:59 +0800 Subject: [PATCH] download excel --- app/(admin)/adminDashboard/page.tsx | 190 ++++++++++++++++++++++++++-- 1 file changed, 180 insertions(+), 10 deletions(-) diff --git a/app/(admin)/adminDashboard/page.tsx b/app/(admin)/adminDashboard/page.tsx index 4aebff4..9a26ff7 100644 --- a/app/(admin)/adminDashboard/page.tsx +++ b/app/(admin)/adminDashboard/page.tsx @@ -336,6 +336,47 @@ useEffect(() => { } }; + // helpers +// helpers +const ymd = (d: Date) => d.toISOString().slice(0, 10); +const excelUrl = (site: string, device: string, fn: 'grid' | 'solar', dateYMD: string) => + `${API}/excel-fs/${encodeURIComponent(site)}/${encodeURIComponent(device)}/${fn}/${dateYMD}.xlsx`; + +// popup state +const [isDownloadOpen, setIsDownloadOpen] = useState(false); +const [meter, setMeter] = useState('01'); // ADW300 device id +const [fn, setFn] = useState<'grid' | 'solar'>('grid'); // which function +const [downloadDate, setDownloadDate] = useState(ymd(new Date())); // YYYY-MM-DD +const [downloading, setDownloading] = useState(false); + +// action +const downloadExcel = async () => { + if (!selectedProject) return; + try { + setDownloading(true); + const url = excelUrl(selectedProject.name, meter.trim(), fn, downloadDate); + const resp = await fetch(url, { credentials: 'include' }); + if (!resp.ok) { + const text = await resp.text().catch(() => ''); + throw new Error(text || `HTTP ${resp.status}`); + } + const blob = await resp.blob(); + const a = document.createElement('a'); + a.href = URL.createObjectURL(blob); + a.download = `${meter}_${fn}_${downloadDate}.xlsx`; + document.body.appendChild(a); + a.click(); + a.remove(); + URL.revokeObjectURL(a.href); + setIsDownloadOpen(false); + } catch (e: any) { + alert(`Download failed: ${e?.message ?? e}`); + } finally { + setDownloading(false); + } +}; + + // ---------- RENDER ---------- if (!authChecked) { return
Checking authentication…
; @@ -459,25 +500,154 @@ useEffect(() => { />
- - setIsDownloadOpen(true)} className="text-sm lg:text-lg btn-primary" > - View Excel Logs - + Download Excel Log +
+ )} + {isDownloadOpen && ( +
e.key === 'Escape' && setIsDownloadOpen(false)} + > + {/* Backdrop */} +
setIsDownloadOpen(false)} + /> + + {/* Modal */} +
+
+

+ Download Excel Log +

+

+ Choose device, function, and date to export the .xlsx generated by the logger. +

+
+ +
+ {/* Site (read-only preview) */} +
+ +
+ {selectedProject?.project_name || selectedProject?.name} +
+
+ + {/* Device + Function */} +
+
+ + setMeter(e.target.value)} + placeholder="01" + className="input input-bordered w-full pl-2 rounded-lg" + /> +

+ Matches topic: ADW300/<site>/{meter || '01'}/… +

+
+ +
+ +
+ + +
+
+
+ + {/* Date + quick picks */} +
+ +
+ setDownloadDate(e.target.value)} + className="input input-bordered w-48 pl-2 rounded-lg" + /> +
+ + +
+
+
+
+ + {/* Footer */} +
+ + +
+
+
+)}