annoucement banners, calendar pdf export, vehicle booking quck-add, even quick-add

This commit is contained in:
Matthias Hochmeister
2026-03-12 11:47:08 +01:00
parent 71a04aee89
commit cd68bd3795
15 changed files with 997 additions and 0 deletions

View File

@@ -693,6 +693,70 @@ async function generatePdf(
doc.save(filename);
}
// ──────────────────────────────────────────────────────────────────────────────
// PDF Export — Fahrzeugbuchungen
// ──────────────────────────────────────────────────────────────────────────────
async function generateBookingsPdf(
weekStart: Date,
weekEnd: Date,
bookings: FahrzeugBuchungListItem[],
) {
const { jsPDF } = await import('jspdf');
const autoTable = (await import('jspdf-autotable')).default;
const doc = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' });
const startLabel = fnsFormat(weekStart, 'dd.MM.yyyy');
const endLabel = fnsFormat(weekEnd, 'dd.MM.yyyy');
const kwLabel = `KW ${fnsFormat(weekStart, 'w')}`;
// Header bar
doc.setFillColor(183, 28, 28); // fire-red
doc.rect(0, 0, 297, 18, 'F');
doc.setTextColor(255, 255, 255);
doc.setFontSize(14);
doc.setFont('helvetica', 'bold');
doc.text(`Fahrzeugbuchungen — ${kwLabel} · ${startLabel} ${endLabel}`, 10, 12);
doc.setFontSize(9);
doc.setFont('helvetica', 'normal');
doc.text('Feuerwehr Rems', 250, 12);
const formatDt = (iso: string) => {
const d = new Date(iso);
return fnsFormat(d, 'dd.MM.yyyy HH:mm');
};
const active = bookings.filter((b) => !b.abgesagt);
const rows = active.map((b) => [
b.fahrzeug_name + (b.fahrzeug_kennzeichen ? `\n${b.fahrzeug_kennzeichen}` : ''),
b.titel,
formatDt(b.beginn),
formatDt(b.ende),
BUCHUNGS_ART_LABELS[b.buchungs_art],
]);
autoTable(doc, {
head: [['Fahrzeug', 'Titel', 'Beginn', 'Ende', 'Art']],
body: rows,
startY: 22,
headStyles: { fillColor: [183, 28, 28], textColor: 255, fontStyle: 'bold' },
alternateRowStyles: { fillColor: [250, 235, 235] },
margin: { left: 10, right: 10 },
styles: { fontSize: 9, cellPadding: 2 },
columnStyles: {
0: { cellWidth: 45 },
1: { cellWidth: 90 },
2: { cellWidth: 38 },
3: { cellWidth: 38 },
4: { cellWidth: 35 },
},
});
const filename = `fahrzeugbuchungen_${fnsFormat(weekStart, 'yyyy-MM-dd')}.pdf`;
doc.save(filename);
}
// ──────────────────────────────────────────────────────────────────────────────
// CSV Import Dialog
// ──────────────────────────────────────────────────────────────────────────────
@@ -2303,6 +2367,16 @@ export default function Kalender() {
>
Kalender
</Button>
{/* PDF Export */}
<Tooltip title="PDF exportieren">
<IconButton
size="small"
onClick={() => generateBookingsPdf(currentWeekStart, weekEnd, bookings)}
>
<FileDownloadIcon />
</IconButton>
</Tooltip>
</Box>
{bookingsLoading && (