# Anlegen & Bearbeiten

```tsx
import {
  Action,
  ActionGroup,
  Button,
  CheckboxButton,
  ColumnLayout,
  Content,
  FieldDescription,
  Heading,
  Label,
  Modal,
  NumberField,
  Option,
  PasswordCreationField,
  Section,
  Select,
  TextField,
  useModalController,
} from "@mittwald/flow-react-components";
import {
  Form,
  SubmitButton,
  typedField,
} from "@mittwald/flow-react-components/react-hook-form";
import { useForm } from "react-hook-form";

export default () => {
  const controller = useModalController();

  const form = useForm<{
    localPart: string;
    domain: string;
    password: string;
    storageInGb: number;
    spamProtection: boolean;
  }>({
    defaultValues: {
      localPart: "",
      domain: "mustermann.de",
      password: "",
      storageInGb: 2,
      spamProtection: true,
    },
  });

  const Field = typedField(form);

  const handleSubmit = async () => {
    /** ... anlegen */
    return () => {
      // Erst nach erfolgreichem Anlegen schließen
      controller.close();
    };
  };

  return (
    <>
      <Button onPress={controller.open}>
        E-Mail-Adresse anlegen
      </Button>

      <Modal controller={controller} offCanvas>
        <Form form={form} onSubmit={handleSubmit}>
          <Heading>E-Mail-Adresse anlegen</Heading>

          <Content>
            <Section>
              <ColumnLayout m={[2, 1]}>
                <Field
                  name="localPart"
                  rules={{
                    required:
                      "Bitte gib einen lokalen Teil ein",
                  }}
                >
                  <TextField>
                    <Label>Lokaler Teil</Label>
                    <FieldDescription>
                      Der Teil vor dem @
                    </FieldDescription>
                  </TextField>
                </Field>
                <Field
                  name="domain"
                  rules={{
                    required: "Bitte wähle eine Domain",
                  }}
                >
                  <Select>
                    <Label>Domain</Label>
                    <Option value="mustermann.de">
                      mustermann.de
                    </Option>
                    <Option value="muster-shop.de">
                      muster-shop.de
                    </Option>
                  </Select>
                </Field>
              </ColumnLayout>

              <Field
                name="password"
                rules={{
                  required: "Bitte vergib ein Passwort",
                }}
              >
                <PasswordCreationField>
                  <Label>Passwort</Label>
                </PasswordCreationField>
              </Field>
            </Section>

            <Section>
              <Heading>Speicherplatz</Heading>
              <Field
                name="storageInGb"
                rules={{
                  required:
                    "Bitte gib einen Speicherplatz an",
                }}
              >
                <NumberField
                  minValue={1}
                  formatOptions={{
                    style: "unit",
                    unit: "gigabyte",
                  }}
                >
                  <Label>Speicherplatz</Label>
                </NumberField>
              </Field>
            </Section>

            <Section>
              <Heading>Spamschutz</Heading>
              <Field name="spamProtection">
                <CheckboxButton>
                  Spamschutz aktivieren
                </CheckboxButton>
              </Field>
            </Section>
          </Content>

          <ActionGroup>
            <SubmitButton>Anlegen</SubmitButton>
            <Action closeModal>
              <Button variant="soft" color="secondary">
                Abbrechen
              </Button>
            </Action>
          </ActionGroup>
        </Form>
      </Modal>
    </>
  );
}
```

---

# Verwendung

Verwende dieses Overlay für Eingaben, die zu einem Objekt gehören: anlegen,
bearbeiten oder konfigurieren. Wird nichts eingegeben, sondern nur eine
Entscheidung getroffen, nimm ein Overlay zum
[Bestätigen](https://flow.mittwald.de/templates/overlays/bestaetigen); hängt die Eingabe von einer
vorgelagerten Auswahl ab, eines mit
[mehreren Schritten](https://flow.mittwald.de/templates/overlays/mehrere-schritte).

---

# Aufbau

- **Overlay-Container** – Ein [Modal](https://flow.mittwald.de/components/overlays/modal) legt sich über
  die auslösende Seite; nach dem Speichern kehrt der Nutzer an dieselbe Stelle
  zurück. Je nach Umfang des Formulars wird das mittige Modal gewählt oder – für
  lange, ausführliche Inhalte, die sonst im Modal scrollen müssten – die
  `offCanvas`-Variante.
- **Überschrift** – Eine [Heading](https://flow.mittwald.de/components/content/heading) benennt Aktion
  und Objekt, etwa „E-Mail-Adresse anlegen". Sie ist meist der einzige Hinweis
  auf den Bezug des Formulars, da die auslösende Seite verdeckt ist.
- **Formular** – Ein [Form](https://flow.mittwald.de/components/react-hook-form/form) fasst die Felder
  zusammen. Umfangreiche Formulare lassen sich mit
  [Sections](https://flow.mittwald.de/components/structure/section) in Abschnitte unterteilen.
- **Aktionen** – Das Formular wird über den
  [SubmitButton](https://flow.mittwald.de/components/react-hook-form/submit-button) in der
  [ActionGroup](https://flow.mittwald.de/components/actions/action-group) abgesendet. Sie enthält
  außerdem immer einen „Abbrechen"-Button, der das Overlay wieder schließt.

---

# Varianten und Abwandlung

## Bearbeiten

Anlegen und Bearbeiten teilen sich ein Template. Sie unterscheiden sich in
Überschrift, Button-Beschriftung und der Vorbelegung der Felder.

```tsx
import {
  Action,
  ActionGroup,
  Button,
  CheckboxButton,
  ColumnLayout,
  Content,
  Heading,
  Label,
  Modal,
  NumberField,
  Section,
  TextField,
  useModalController,
} from "@mittwald/flow-react-components";
import {
  Form,
  SubmitButton,
  typedField,
} from "@mittwald/flow-react-components/react-hook-form";
import { useForm } from "react-hook-form";

export default () => {
  const controller = useModalController();

  const form = useForm<{
    description: string;
    storageInGb: number;
    spamProtection: boolean;
  }>({
    defaultValues: {
      description: "Persönliches Postfach",
      storageInGb: 2,
      spamProtection: true,
    },
  });

  const Field = typedField(form);

  const handleSubmit = async () => () => controller.close();

  return (
    <>
      <Button
        variant="soft"
        color="secondary"
        onPress={controller.open}
      >
        Bearbeiten
      </Button>

      <Modal controller={controller} offCanvas>
        <Form form={form} onSubmit={handleSubmit}>
          <Heading>E-Mail-Adresse bearbeiten</Heading>

          <Content>
            <Section>
              <ColumnLayout m={[1, 1]}>
                <Field name="description">
                  <TextField>
                    <Label>Beschreibung</Label>
                  </TextField>
                </Field>
                <Field
                  name="storageInGb"
                  rules={{
                    required:
                      "Bitte gib einen Speicherplatz an",
                  }}
                >
                  <NumberField
                    minValue={1}
                    formatOptions={{
                      style: "unit",
                      unit: "gigabyte",
                    }}
                  >
                    <Label>Speicherplatz</Label>
                  </NumberField>
                </Field>
              </ColumnLayout>
            </Section>

            <Section>
              <Heading>Spamschutz</Heading>
              <Field name="spamProtection">
                <CheckboxButton>
                  Spamschutz aktivieren
                </CheckboxButton>
              </Field>
            </Section>
          </Content>

          <ActionGroup>
            <SubmitButton>Speichern</SubmitButton>
            <Action closeModal>
              <Button variant="soft" color="secondary">
                Abbrechen
              </Button>
            </Action>
          </ActionGroup>
        </Form>
      </Modal>
    </>
  );
}
```

## Kurzes Formular

Bei wenigen Feldern ist das Formular im mittigen
[Modal](https://flow.mittwald.de/components/overlays/modal) gut aufgehoben. Hier kann der Fokus beim
Öffnen direkt in das erste [TextField](https://flow.mittwald.de/components/form-controls/text-field)
springen (`autoFocus`), sodass die Eingabe ohne weiteren Klick beginnt. Setze
`autoFocus` nur, wenn das Overlay ausschließlich diesem Eingabezweck dient –
sonst überspringen Screenreader-Nutzer den einleitenden Kontext aus Überschrift
und Beschreibung.

```tsx
import {
  Action,
  ActionGroup,
  Button,
  Content,
  Heading,
  Label,
  Modal,
  TextField,
  useModalController,
} from "@mittwald/flow-react-components";
import {
  Form,
  SubmitButton,
  typedField,
} from "@mittwald/flow-react-components/react-hook-form";
import { useForm } from "react-hook-form";

export default () => {
  const controller = useModalController();

  const form = useForm<{ description: string }>({
    defaultValues: { description: "Persönliches Postfach" },
  });

  const Field = typedField(form);

  const handleSubmit = async () => () => controller.close();

  return (
    <>
      <Button
        variant="soft"
        color="secondary"
        onPress={controller.open}
      >
        Beschreibung ändern
      </Button>

      <Modal controller={controller} size="s">
        <Form form={form} onSubmit={handleSubmit}>
          <Heading>Beschreibung ändern</Heading>
          <Content>
            <Field
              name="description"
              rules={{
                required: "Bitte gib eine Beschreibung ein",
              }}
            >
              <TextField autoFocus>
                <Label>Beschreibung</Label>
              </TextField>
            </Field>
          </Content>
          <ActionGroup>
            <SubmitButton>Speichern</SubmitButton>
            <Action closeModal>
              <Button variant="soft" color="secondary">
                Abbrechen
              </Button>
            </Action>
          </ActionGroup>
        </Form>
      </Modal>
    </>
  );
}
```

## Fehlende Voraussetzung

Manchmal hängt das Anlegen an einer Voraussetzung, die noch fehlt – etwa ein
Vertragspartner, ohne den eine Extension nicht installiert werden kann. Ein
[Alert](https://flow.mittwald.de/components/status/alert) im Overlay erklärt die fehlende Voraussetzung
und bietet an, den nötigen Teilprozess direkt hier zu starten. So bleibt der
Nutzer im Kontext und kehrt nach dem Anlegen an dieselbe Stelle zurück. Die
abschließende Aktion bleibt deaktiviert, bis die Voraussetzung erfüllt ist.

```tsx
import {
  Action,
  ActionGroup,
  Alert,
  Button,
  Content,
  Heading,
  Label,
  Modal,
  Option,
  Section,
  Select,
  Text,
  useModalController,
} from "@mittwald/flow-react-components";

export default () => {
  const controller = useModalController();

  return (
    <>
      <Button onPress={controller.open}>
        Extension installieren
      </Button>

      <Modal controller={controller} offCanvas>
        <Heading>Extension installieren</Heading>

        <Content>
          <Section>
            <Text>
              Wähle die Organisation, in der die Extension
              bereitgestellt werden soll.
            </Text>

            <Select isRequired defaultSelectedKey="1">
              <Label>Organisation</Label>
              <Option value="1">Meine Organisation</Option>
              <Option value="2">
                Noch eine Organisation
              </Option>
            </Select>

            <Alert status="warning">
              <Heading>
                Kein Vertragspartner hinterlegt
              </Heading>
              <Content>
                <Text>
                  Für diese Organisation ist noch kein
                  Vertragspartner hinterlegt. Lege einen an,
                  um mit der Installation fortzufahren.
                </Text>
                <Button>Vertragspartner anlegen</Button>
              </Content>
            </Alert>
          </Section>
        </Content>

        <ActionGroup>
          <Button isDisabled>Installieren</Button>
          <Action closeModal>
            <Button variant="soft" color="secondary">
              Abbrechen
            </Button>
          </Action>
        </ActionGroup>
      </Modal>
    </>
  );
}
```
