import { PureComponent } from 'react'; import Autocomplete from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import { enqueueSnackbar } from 'notistack'; import BackendError from '../../components/BackendError'; import SingleLineTextEdit from '../../components/SingleLineTextEdit'; import { PanelTile, PanelTileGrid } from '../../components/panels'; import { StorageManagerContext } from '../../api/storageManagerContext'; import { router } from '../../appRouter'; import { requireDefined, requireObject } from '../../utils/apiShape'; import { backendErrorFrom } from '../../utils/backendError'; import { notifyError } from '../../utils/notify'; function sortGroups(groups) { return [...groups].sort((a, b) => { const bySort = a.sort - b.sort; if (bySort !== 0) return bySort; const byName = String(a.name).localeCompare(String(b.name), 'de'); if (byName !== 0) return byName; return a.id - b.id; }); } class KundeNeuPage extends PureComponent { static contextType = StorageManagerContext; constructor(props) { super(props); this.state = { status: 'loading', error: null, groups: [], customergroupId: null, name: '', firstName: '', saving: false, }; this._cancelled = false; this.handleRetry = this.handleRetry.bind(this); this.handleGroupChange = this.handleGroupChange.bind(this); this.handleSave = this.handleSave.bind(this); } componentDidMount() { this._cancelled = false; void this.loadGroups(); } componentWillUnmount() { this._cancelled = true; } async loadGroups() { this.setState({ status: 'loading', error: null }); try { const list = this.context.customergroups ?? (await this.context.customergroupPromise); if (this._cancelled) return; this.setState({ status: 'ready', groups: sortGroups(list), }); } catch (err) { if (this._cancelled) return; this.setState({ status: 'failed', error: backendErrorFrom(err), }); } } handleRetry() { void this.loadGroups(); } handleGroupChange(_event, option) { this.setState({ customergroupId: option?.id ?? null }); } async handleSave() { if (this.state.saving) return; const { customergroupId, name, firstName } = this.state; const trimmedName = name.trim(); const trimmedFirst = firstName.trim(); if (customergroupId == null) { notifyError(new Error('Kundengruppe fehlt.')); return; } if (!trimmedName) { notifyError(new Error('Name fehlt.')); return; } const body = { customergroupId, name: trimmedName, }; if (trimmedFirst) body.firstName = trimmedFirst; this.setState({ saving: true }); try { const data = await this.context.entity.create(body); requireObject(data, 'POST /api/entity'); requireObject(data.entity, 'entity'); requireDefined(data.entity.id, 'entity.id'); await this.context.updateEntity(); if (this._cancelled) return; enqueueSnackbar('Kunde angelegt.', { variant: 'success' }); void router.navigate(`/kunde/${data.entity.id}`); } catch (err) { if (this._cancelled) return; notifyError(err); this.setState({ saving: false }); } } render() { const { status, error, groups, customergroupId, name, firstName, saving, } = this.state; if (status === 'failed') { return ; } const selected = groups.find((row) => row.id === customergroupId) ?? null; const canSave = customergroupId != null && name.trim() !== '' && !saving; return ( String(option.name ?? '')} isOptionEqualToValue={(option, value) => option.id === value.id} onChange={this.handleGroupChange} renderInput={(params) => ( )} /> this.setState({ name: next })} /> this.setState({ firstName: next })} /> ); } } export default KundeNeuPage;