diff --git a/src/routes/auftrag/lieferarten.jsx b/src/routes/auftrag/lieferarten.jsx
deleted file mode 100644
index a47c726..0000000
--- a/src/routes/auftrag/lieferarten.jsx
+++ /dev/null
@@ -1,270 +0,0 @@
-import { PureComponent, createRef } from 'react';
-import Box from '@mui/material/Box';
-import Button from '@mui/material/Button';
-import CircularProgress from '@mui/material/CircularProgress';
-import List from '@mui/material/List';
-import Typography from '@mui/material/Typography';
-import Sortable from 'sortablejs';
-import { enqueueSnackbar } from 'notistack';
-import BackendError from '../../components/BackendError';
-import SingleLineTextEdit from 'dashgui/SingleLineTextEdit';
-import { PanelTile, PanelTileGrid } from 'dashgui/panels';
-import withNavigate from '../../components/withNavigate';
-import { backendErrorFrom } from '../../utils/backendError';
-import { notifyError } from '../../utils/notify';
-import carrierAutomat from '../../automats/carrierAutomat';
-import { CarrierItem } from '../../components/carrier';
-import { GREEN_PANEL } from '../../colors';
-
-class LieferartenSearchField extends PureComponent {
- constructor(props) {
- super(props);
- const initial = carrierAutomat.state.filter || '';
- this.state = {
- input: initial,
- submitting: false,
- };
- this.handleSubmit = this.handleSubmit.bind(this);
- }
-
- componentDidMount() {
- this.unsub = carrierAutomat.subscribe(this, (state) => ({
- input: state.filter,
- }));
- }
-
- componentWillUnmount() {
- this.unsub?.();
- }
-
- onInputChange(input) {
- this.setState({ input });
- carrierAutomat.actions.filter(input);
- }
-
- async handleSubmit() {
- const name = this.state.input.trim();
- if (!name || this.state.submitting) return;
-
- this.setState({ submitting: true });
- try {
- const row = await carrierAutomat.actions.create({
- name,
- hasPackages: true,
- isReverse: false,
- });
- enqueueSnackbar(`Lieferart „${row.name || name}“ angelegt.`, { variant: 'success' });
- this.setState({ input: '', submitting: false });
- carrierAutomat.actions.filter('');
- } catch (err) {
- this.setState({ submitting: false });
- notifyError(err);
- }
- }
-
- render() {
- const { inputRef } = this.props;
- const { input, submitting } = this.state;
- const canSubmit = Boolean(input.trim()) && !submitting;
-
- return (
-
-
-
- this.onInputChange(next)}
- onKeyDown={(event) => {
- if (event.key === 'Enter') {
- event.preventDefault();
- void this.handleSubmit();
- }
- }}
- />
-
-
-
-
- );
- }
-}
-
-class AuftragLieferartenPage extends PureComponent {
- constructor(props) {
- super(props);
- const initialCarriers =
- carrierAutomat.state.filteredCarriers ?? carrierAutomat.state.carriers ?? [];
- this.state = {
- status: carrierAutomat.state.status === 'ready' ? 'ready' : 'loading',
- error: carrierAutomat.state.error ? backendErrorFrom(carrierAutomat.state.error) : null,
- carriers: initialCarriers,
- filter: carrierAutomat.state.filter ?? '',
- };
- this.searchRef = createRef();
- this.listRef = createRef();
- this._sortable = null;
- this._cancelled = false;
- this.handleRetry = this.handleRetry.bind(this);
- this._initSortable = this._initSortable.bind(this);
- this._destroySortable = this._destroySortable.bind(this);
- }
-
- componentDidMount() {
- this._cancelled = false;
-
- this.unsub = carrierAutomat.subscribe(this, (state) => ({
- carriers: state.filteredCarriers ?? state.carriers,
- filter: state.filter ?? '',
- status: state.status,
- error: state.error ? backendErrorFrom(state.error) : null,
- }));
-
- if (carrierAutomat.state.status !== 'ready') {
- void carrierAutomat.actions.load().catch((err) => notifyError(err));
- } else {
- this._initSortable();
- }
- }
-
- componentDidUpdate(prevProps, prevState) {
- if (
- prevState.status !== this.state.status ||
- prevState.carriers !== this.state.carriers ||
- prevState.filter !== this.state.filter
- ) {
- if (this.state.status === 'ready') {
- this._initSortable();
- }
- }
- }
-
- componentWillUnmount() {
- this._cancelled = true;
- this.unsub?.();
- this._destroySortable();
- }
-
- _initSortable() {
- this._destroySortable();
- const el = this.listRef.current;
- if (!el) return;
-
- const isFiltered = Boolean(this.state.filter?.trim());
-
- this._sortable = Sortable.create(el, {
- handle: '.drag-handle',
- animation: 150,
- ghostClass: 'sortable-ghost',
- chosenClass: 'sortable-chosen',
- disabled: isFiltered,
- onEnd: (evt) => {
- const { oldIndex, newIndex } = evt;
- if (oldIndex === newIndex) return;
-
- this.setState(
- (prev) => {
- const next = [...prev.carriers];
- const [moved] = next.splice(oldIndex, 1);
- next.splice(newIndex, 0, moved);
- return { carriers: next };
- },
- () => {
- const ids = this.state.carriers.map((c) => c.id);
- void this._persistOrder(ids);
- }
- );
- },
- });
- }
-
- _destroySortable() {
- this._sortable?.destroy();
- this._sortable = null;
- }
-
- async _persistOrder(carrierIds) {
- try {
- await carrierAutomat.actions.reorder(carrierIds);
- } catch (err) {
- if (this._cancelled) return;
- notifyError(err);
- void carrierAutomat.actions.reload();
- }
- }
-
- handleRetry() {
- void carrierAutomat.actions.load().catch((err) => notifyError(err));
- }
-
- render() {
- const { status, error, carriers, filter } = this.state;
-
- if (status === 'loading' || status === 'idle') {
- return (
-
-
-
- );
- }
-
- if (status === 'failed') {
- return ;
- }
-
- const trimmedFilter = filter?.trim() ?? '';
-
- return (
- <>
-
-
-
-
- {carriers.length === 0 ? (
-
- {trimmedFilter
- ? `Keine Treffer für „${trimmedFilter}“.`
- : 'Noch keine Lieferarten angelegt.'}
-
- ) : (
- carriers.map((c) => (
-
- ))
- )}
-
-
-
- >
- );
- }
-}
-
-export { CarrierItem, LieferartenSearchField };
-export default withNavigate(AuftragLieferartenPage);