new features

This commit is contained in:
Matthias Hochmeister
2026-03-23 14:01:39 +01:00
parent d2dc64d54a
commit 3326156b15
35 changed files with 1341 additions and 257 deletions

View File

@@ -89,6 +89,8 @@ export default function Bestellungen() {
const [statusFilter, setStatusFilter] = useState<string>('');
const [orderDialogOpen, setOrderDialogOpen] = useState(false);
const [orderForm, setOrderForm] = useState<BestellungFormData>({ ...emptyOrderForm });
const [inlineVendorOpen, setInlineVendorOpen] = useState(false);
const [inlineVendorForm, setInlineVendorForm] = useState<LieferantFormData>({ ...emptyVendorForm });
const [vendorDialogOpen, setVendorDialogOpen] = useState(false);
const [vendorForm, setVendorForm] = useState<LieferantFormData>({ ...emptyVendorForm });
@@ -122,10 +124,17 @@ export default function Bestellungen() {
const createVendor = useMutation({
mutationFn: (data: LieferantFormData) => bestellungApi.createVendor(data),
onSuccess: () => {
onSuccess: (newVendor) => {
queryClient.invalidateQueries({ queryKey: ['lieferanten'] });
showSuccess('Lieferant erstellt');
closeVendorDialog();
// If inline vendor creation during order creation, auto-select the new vendor
if (inlineVendorOpen) {
setOrderForm((f) => ({ ...f, lieferant_id: newVendor.id }));
setInlineVendorOpen(false);
setInlineVendorForm({ ...emptyVendorForm });
} else {
closeVendorDialog();
}
},
onError: () => showError('Fehler beim Erstellen des Lieferanten'),
});
@@ -264,14 +273,6 @@ export default function Bestellungen() {
{/* ── Tab 1: Vendors ── */}
<TabPanel value={tab} index={1}>
<Box sx={{ mb: 2, display: 'flex', justifyContent: 'flex-end' }}>
{hasPermission('bestellungen:create') && (
<Button variant="contained" startIcon={<AddIcon />} onClick={() => setVendorDialogOpen(true)}>
Lieferant hinzufügen
</Button>
)}
</Box>
<TableContainer component={Paper}>
<Table size="small">
<TableHead>
@@ -315,6 +316,12 @@ export default function Bestellungen() {
</TableBody>
</Table>
</TableContainer>
{hasPermission('bestellungen:manage_vendors') && (
<ChatAwareFab onClick={() => setVendorDialogOpen(true)} aria-label="Lieferant hinzufügen">
<AddIcon />
</ChatAwareFab>
)}
</TabPanel>
{/* ── Create Order Dialog ── */}
@@ -327,13 +334,38 @@ export default function Bestellungen() {
value={orderForm.bezeichnung}
onChange={(e) => setOrderForm((f) => ({ ...f, bezeichnung: e.target.value }))}
/>
<Autocomplete
options={vendors}
getOptionLabel={(o) => o.name}
value={vendors.find((v) => v.id === orderForm.lieferant_id) || null}
onChange={(_e, v) => setOrderForm((f) => ({ ...f, lieferant_id: v?.id }))}
renderInput={(params) => <TextField {...params} label="Lieferant" />}
/>
<Box sx={{ display: 'flex', gap: 1, alignItems: 'flex-start' }}>
<Autocomplete
options={vendors}
getOptionLabel={(o) => o.name}
value={vendors.find((v) => v.id === orderForm.lieferant_id) || null}
onChange={(_e, v) => setOrderForm((f) => ({ ...f, lieferant_id: v?.id }))}
renderInput={(params) => <TextField {...params} label="Lieferant" />}
sx={{ flexGrow: 1 }}
/>
<Tooltip title="Neuen Lieferant anlegen">
<IconButton
onClick={() => setInlineVendorOpen(!inlineVendorOpen)}
color={inlineVendorOpen ? 'primary' : 'default'}
sx={{ mt: 1 }}
>
<AddIcon />
</IconButton>
</Tooltip>
</Box>
{inlineVendorOpen && (
<Paper variant="outlined" sx={{ p: 2, display: 'flex', flexDirection: 'column', gap: 1.5 }}>
<Typography variant="subtitle2">Neuer Lieferant</Typography>
<TextField size="small" label="Name *" value={inlineVendorForm.name} onChange={(e) => setInlineVendorForm(f => ({ ...f, name: e.target.value }))} />
<TextField size="small" label="Kontakt-Name" value={inlineVendorForm.kontakt_name || ''} onChange={(e) => setInlineVendorForm(f => ({ ...f, kontakt_name: e.target.value }))} />
<TextField size="small" label="E-Mail" value={inlineVendorForm.email || ''} onChange={(e) => setInlineVendorForm(f => ({ ...f, email: e.target.value }))} />
<TextField size="small" label="Telefon" value={inlineVendorForm.telefon || ''} onChange={(e) => setInlineVendorForm(f => ({ ...f, telefon: e.target.value }))} />
<Box sx={{ display: 'flex', gap: 1, justifyContent: 'flex-end' }}>
<Button size="small" onClick={() => { setInlineVendorOpen(false); setInlineVendorForm({ ...emptyVendorForm }); }}>Abbrechen</Button>
<Button size="small" variant="contained" onClick={() => createVendor.mutate(inlineVendorForm)} disabled={!inlineVendorForm.name.trim() || createVendor.isPending}>Anlegen</Button>
</Box>
</Paper>
)}
<TextField
label="Besteller"
value={orderForm.besteller_id || ''}