import { Component } from 'react'; import Alert from '@mui/material/Alert'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import CircularProgress from '@mui/material/CircularProgress'; import Dialog from '@mui/material/Dialog'; import DialogContent from '@mui/material/DialogContent'; import DialogTitle from '@mui/material/DialogTitle'; import Divider from '@mui/material/Divider'; import FormControl from '@mui/material/FormControl'; import FormLabel from '@mui/material/FormLabel'; import InputAdornment from '@mui/material/InputAdornment'; import List from '@mui/material/List'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Typography from '@mui/material/Typography'; import BusinessIcon from '@mui/icons-material/Business'; import BackendError from './BackendError'; import { company } from '../api'; import { StorageManagerContext } from '../api/storageManagerContext'; import authAutomat from '../automats/authAutomat'; import { defaultIso639, ISO639_OPTIONS, parseTaxRate, } from '../utils/companyForm'; import { backendErrorFrom, isBackendFailure } from '../utils/backendError'; class CompanySetupDialog extends Component { static contextType = StorageManagerContext; constructor(props) { super(props); this.state = { companies: [], loading: true, busy: false, error: null, name: '', iso639: defaultIso639(), taxrate: '19', reducedtaxrate: '7', }; this.handleSelect = this.handleSelect.bind(this); this.handleCreate = this.handleCreate.bind(this); this.handleLogout = this.handleLogout.bind(this); this.handleClose = this.handleClose.bind(this); } componentDidMount() { void this.loadCompanies(); } async loadCompanies() { this.setState({ loading: true }); try { const data = await company.list(); this.setState({ companies: data.companies ?? [] }); } catch { this.setState({ companies: [] }); } finally { this.setState({ loading: false }); } } async handleSelect(companyId) { this.setState({ busy: true, error: null }); try { await authAutomat.actions.selectCompany(companyId); await this.context.updateAuthMe(); } catch (err) { this.setState({ error: backendErrorFrom(err) }); } finally { this.setState({ busy: false }); } } async handleCreate(event) { event.preventDefault(); const { name, iso639, taxrate, reducedtaxrate } = this.state; const parsedTaxrate = parseTaxRate(taxrate); const parsedReducedtaxrate = parseTaxRate(reducedtaxrate); const canCreate = name.trim() !== '' && ISO639_OPTIONS.includes(iso639) && parsedTaxrate != null && parsedReducedtaxrate != null; if (!canCreate) { this.setState({ error: 'Bitte alle Pflichtfelder ausfüllen.' }); return; } this.setState({ busy: true, error: null }); try { await authAutomat.actions.createCompany({ name: name.trim(), iso639, taxrate: parsedTaxrate, reducedtaxrate: parsedReducedtaxrate, }); await this.context.updateAuthMe(); await this.context.updateCompany(); } catch (err) { this.setState({ error: backendErrorFrom(err) }); } finally { this.setState({ busy: false }); } } async handleLogout() { try { await authAutomat.actions.logout(); await this.context.updateAuthMe(); } catch (err) { this.setState({ error: backendErrorFrom(err) }); } } handleClose(_event, reason) { if (reason === 'backdropClick' || reason === 'escapeKeyDown') return; } render() { const { companies, loading, busy, error, name, iso639, taxrate, reducedtaxrate } = this.state; const hasCompanies = companies.length > 0; const parsedTaxrate = parseTaxRate(taxrate); const parsedReducedtaxrate = parseTaxRate(reducedtaxrate); const canCreate = name.trim() !== '' && ISO639_OPTIONS.includes(iso639) && parsedTaxrate != null && parsedReducedtaxrate != null; return ( {loading ? 'Unternehmen' : hasCompanies ? 'Unternehmen auswählen' : 'Unternehmen anlegen'} {!loading ? ( {hasCompanies ? 'Wählen Sie ein bestehendes Unternehmen oder legen Sie ein neues an.' : 'Legen Sie Ihr Unternehmen an, um fortzufahren.'} ) : null} {error ? ( isBackendFailure(error) ? ( ) : ( {typeof error === 'string' ? error : error.message} ) ) : null} {loading ? ( ) : ( {hasCompanies ? ( {companies.map((item) => ( this.handleSelect(item.id)} > ))} ) : null} {hasCompanies ? oder : null} {hasCompanies ? ( Neues Unternehmen anlegen ) : null} this.setState({ name: e.target.value })} autoComplete="organization" autoFocus={!hasCompanies} /> Sprache { if (value) this.setState({ iso639: value }); }} > Deutsch English this.setState({ taxrate: e.target.value })} error={taxrate !== '' && parsedTaxrate == null} slotProps={{ input: { endAdornment: %, }, htmlInput: { min: 0, max: 100, step: 0.01, required: true }, }} /> this.setState({ reducedtaxrate: e.target.value })} error={reducedtaxrate !== '' && parsedReducedtaxrate == null} slotProps={{ input: { endAdornment: %, }, htmlInput: { min: 0, max: 100, step: 0.01, required: true }, }} /> )} ); } } export default CompanySetupDialog;