import { Component } from 'react'; import AddIcon from '@mui/icons-material/Add'; import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import AppDialog from '../AppDialog'; import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogTitle from '@mui/material/DialogTitle'; import IconButton from '@mui/material/IconButton'; import InputAdornment from '@mui/material/InputAdornment'; import TextInput from '../TextInput'; import Typography from '@mui/material/Typography'; import { formatPriceAmount, parsePriceInput } from '../../utils/price'; function emptyTier() { return { minmultiplier: '', gross: '' }; } function parseMultiplier(value) { if (value === '' || value == null) return null; const n = Number(String(value).trim()); return Number.isInteger(n) && n >= 2 ? n : null; } function tiersValid(tiers) { const seen = new Set(); for (const tier of tiers) { const mult = parseMultiplier(tier.minmultiplier); const gross = parsePriceInput(tier.gross); if (mult == null || gross == null) return false; if (seen.has(mult)) return false; seen.add(mult); } return true; } class ArticlePriceTiersDialog extends Component { constructor(props) { super(props); this.state = { tiers: [] }; } componentDidUpdate(prevProps) { if (this.props.open && !prevProps.open) { const tiers = this.props.tiers?.length ? this.props.tiers.map((row) => ({ minmultiplier: String(row.minmultiplier), gross: row.gross, })) : []; this.setState({ tiers }); } } handleChange = (index, field, value) => { this.setState((state) => { const tiers = state.tiers.map((row, i) => i === index ? { ...row, [field]: value } : row, ); return { tiers }; }); }; handleAdd = () => { this.setState((state) => ({ tiers: [...state.tiers, emptyTier()] })); }; handleRemove = (index) => { this.setState((state) => ({ tiers: state.tiers.filter((_, i) => i !== index), })); }; handleApply = () => { const { tiers } = this.state; if (!tiersValid(tiers)) return; this.props.onApply( tiers.map((row) => ({ minmultiplier: parseMultiplier(row.minmultiplier), gross: formatPriceAmount(parsePriceInput(row.gross)), })), ); this.props.onClose(); }; render() { const { open, onClose } = this.props; const { tiers } = this.state; const canApply = tiersValid(tiers); return ( Staffelpreise {tiers.length === 0 ? ( Keine Staffeln. Basispreis bleibt der Einzelpreis (×1). ) : null} {tiers.map((tier, index) => { const mult = parseMultiplier(tier.minmultiplier); const gross = parsePriceInput(tier.gross); return ( this.handleChange(index, 'minmultiplier', event.target.value) } error={tier.minmultiplier !== '' && mult == null} slotProps={{ htmlInput: { inputMode: 'numeric' }, }} sx={{ width: 120 }} /> this.handleChange(index, 'gross', event.target.value) } fullWidth error={tier.gross !== '' && gross == null} slotProps={{ input: { startAdornment: ( € ), }, htmlInput: { inputMode: 'decimal' }, }} /> this.handleRemove(index)} sx={{ mt: 0.5 }} > ); })} ); } } export default ArticlePriceTiersDialog;