mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 15:51:15 +00:00
feat(export): CSV export for bookings and customers
GET /v1/export/bookings.csv (optional from/to bounds) and /v1/export/customers.csv — UTF-8 with BOM for Excel, labels resolved at export time, buffered responses so auth failures stay JSON. Export buttons on the bookings and customers pages. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
d86cba61e3
commit
4674203502
12 files changed
+583
-5
No files matched your search
@@ -0,0 +1,38 @@
|
||||
import { createSignal, Accessor } from "solid-js";
|
||||
import { apiBaseUrl } from "../../lib/api-client";
|
||||
import { useI18n } from "../../providers/i18n-provider";
|
||||
import { DownloadIcon } from "./icons";
|
||||
|
||||
// Downloads an authenticated CSV endpoint — fetch + blob because the
|
||||
// generated api-client is typed for JSON, not file responses.
|
||||
export function ExportCsvButton(props: { path: string; filename: string; token: Accessor<string | null | undefined> }) {
|
||||
const i18n = useI18n();
|
||||
const [busy, setBusy] = createSignal(false);
|
||||
|
||||
const handleClick = async () => {
|
||||
const bearer = props.token?.();
|
||||
if (!bearer || busy()) return;
|
||||
setBusy(true);
|
||||
try {
|
||||
const response = await fetch(`${apiBaseUrl}${props.path}`, {
|
||||
headers: { Authorization: `Bearer ${bearer}` },
|
||||
});
|
||||
if (!response.ok) return;
|
||||
const blob = await response.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchor = document.createElement("a");
|
||||
anchor.href = url;
|
||||
anchor.download = props.filename;
|
||||
anchor.click();
|
||||
URL.revokeObjectURL(url);
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button onClick={handleClick} disabled={busy()} class="btn-secondary text-sm shrink-0">
|
||||
<DownloadIcon /> {i18n.t("dashboard.exportCsv")}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user