93 lines
3.0 KiB
TypeScript
93 lines
3.0 KiB
TypeScript
/**
|
||
* Task CAD-9 – Stuecklisten-Dialog fuer Traversen-Systeme.
|
||
*
|
||
* Zeigt die gruppierte Stueckliste (Traversen + Eck-Traversen)
|
||
* als Tabelle mit Summenzeile; CSV-Download als Datei.
|
||
*/
|
||
import React, { useMemo } from 'react';
|
||
import { buildBOM, exportBOMCsv } from '../services/bomService';
|
||
|
||
interface BOMDialogProps {
|
||
elements: import('../types/cad.types').CADElement[];
|
||
onClose: () => void;
|
||
}
|
||
|
||
const BOMDialog: React.FC<BOMDialogProps> = ({ elements, onClose }) => {
|
||
const bom = useMemo(() => buildBOM(elements), [elements]);
|
||
|
||
const handleDownload = () => {
|
||
const csv = exportBOMCsv(bom);
|
||
const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' });
|
||
const url = URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = `stueckliste-traversen-${new Date().toISOString().slice(0, 10)}.csv`;
|
||
a.click();
|
||
URL.revokeObjectURL(url);
|
||
};
|
||
|
||
return (
|
||
<div className="bom-dialog-overlay" onClick={onClose}>
|
||
<div className="bom-dialog" onClick={(e) => e.stopPropagation()}>
|
||
<div className="bom-dialog-header">
|
||
<h3>Stückliste – Traversen</h3>
|
||
<button className="bom-close" onClick={onClose} title="Schließen">✕
|
||
</button>
|
||
</div>
|
||
{bom.rows.length === 0 ? (
|
||
<div className="bom-empty">
|
||
Keine Traversen oder Eck-Traversen in der Zeichnung gefunden.
|
||
<br />
|
||
Platziere zuerst Traversen mit dem Traverse- oder Eck-Traverse-Werkzeug.
|
||
</div>
|
||
) : (
|
||
<>
|
||
<table className="bom-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Pos</th>
|
||
<th>Typ</th>
|
||
<th>Länge (cm)</th>
|
||
<th>Breite (cm)</th>
|
||
<th>Anzahl</th>
|
||
<th>Gesamt</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{bom.rows.map((r) => (
|
||
<tr key={`${r.pos}-${r.label}`}>
|
||
<td>{r.pos}</td>
|
||
<td>{r.type}</td>
|
||
<td>{r.length}</td>
|
||
<td>{r.width}</td>
|
||
<td>{r.count}</td>
|
||
<td>{(r.totalCm / 100).toFixed(2)} m</td>
|
||
</tr>
|
||
))}
|
||
<tr className="bom-sum-row">
|
||
<td colSpan={5}>
|
||
<strong>SUMME</strong>
|
||
</td>
|
||
<td>
|
||
<strong>{bom.totalLengthM.toFixed(2)} m</strong>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div className="bom-dialog-actions">
|
||
<button className="bom-btn-primary" onClick={handleDownload}>
|
||
CSV herunterladen
|
||
</button>
|
||
<button className="bom-btn-secondary" onClick={onClose}>
|
||
Schließen
|
||
</button>
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default BOMDialog;
|