Files
erp-nutzfahrzeuge/frontend/components/vehicles/VehicleActions.tsx
T

112 lines
3.7 KiB
TypeScript
Raw Normal View History

'use client';
import { Button } from '@/components/ui/Button';
import type { VehicleResponse } from '@/lib/vehicles';
interface VehicleActionsProps {
vehicle: VehicleResponse;
}
function escapeCsvValue(value: string | number | undefined | null): string {
if (value === null || value === undefined) return '';
const str = String(value);
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
return `"${str.replace(/"/g, '""')}"`;
}
return str;
}
function downloadCsv(filename: string, csvContent: string): void {
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
function vehicleToCsvRow(v: VehicleResponse): string {
const headers = [
'Make', 'Model', 'FIN', 'Year', 'Price', 'Vehicle Type',
'Condition', 'Availability', 'Mileage (km)', 'Power (kW)',
'Fuel Type', 'Transmission', 'Color', 'Location',
'First Registration', 'Description',
];
return headers.map(h => {
switch (h) {
case 'Make': return escapeCsvValue(v.make);
case 'Model': return escapeCsvValue(v.model);
case 'FIN': return escapeCsvValue(v.fin);
case 'Year': return escapeCsvValue(v.year);
case 'Price': return escapeCsvValue(v.price);
case 'Vehicle Type': return escapeCsvValue(v.vehicle_type);
case 'Condition': return escapeCsvValue(v.condition);
case 'Availability': return escapeCsvValue(v.availability);
case 'Mileage (km)': return escapeCsvValue(v.mileage_km);
case 'Power (kW)': return escapeCsvValue(v.power_kw);
case 'Fuel Type': return escapeCsvValue(v.fuel_type);
case 'Transmission': return escapeCsvValue(v.transmission);
case 'Color': return escapeCsvValue(v.color);
case 'Location': return escapeCsvValue(v.location);
case 'First Registration': return escapeCsvValue(v.first_registration);
case 'Description': return escapeCsvValue(v.description);
default: return '';
}
}).join(',');
}
export function VehicleActions({ vehicle }: VehicleActionsProps) {
const handlePrint = () => {
window.print();
};
const handleExportPdf = () => {
window.print();
};
const handleExportCsv = () => {
const headers = 'Make,Model,FIN,Year,Price,Vehicle Type,Condition,Availability,Mileage (km),Power (kW),Fuel Type,Transmission,Color,Location,First Registration,Description';
const row = vehicleToCsvRow(vehicle);
const csv = `${headers}\n${row}`;
const filename = `vehicle_${vehicle.fin || vehicle.id}.csv`;
downloadCsv(filename, csv);
};
return (
<div data-testid="vehicle-actions" className="flex gap-2 print:hidden">
<Button
variant="secondary"
onClick={handlePrint}
data-testid="print-button"
>
Drucken
</Button>
<Button
variant="secondary"
onClick={handleExportPdf}
data-testid="export-pdf-button"
>
Als PDF exportieren
</Button>
<Button
variant="secondary"
onClick={handleExportCsv}
data-testid="export-csv-button"
>
Als CSV exportieren
</Button>
</div>
);
}
export function exportVehiclesToCsv(vehicles: VehicleResponse[]): void {
const headers = 'Make,Model,FIN,Year,Price,Vehicle Type,Condition,Availability,Mileage (km),Power (kW),Fuel Type,Transmission,Color,Location,First Registration,Description';
const rows = vehicles.map(v => vehicleToCsvRow(v));
const csv = [headers, ...rows].join('\n');
const now = new Date().toISOString().split('T')[0];
downloadCsv(`vehicles_export_${now}.csv`, csv);
}