# Dashboard

Ein Dashboard präsentiert dem User relevante Informationen übersichtlich in klar
abgegrenzten Bereichen auf einer einzigen Oberfläche. Es unterstützt den User
dabei, wichtige Daten auf einen Blick zu erfassen. Häufig dient ein Dashboard
als Startseite oder zur Darstellung von Analyse-Diagrammen.

---

# Zentrale Merkmale

Ein Dashboard bündelt relevante Informationen auf einer kachelartigen
Oberfläche. Damit es den größtmöglichen Nutzen bietet, sollten folgende
Prinzipien berücksichtigt werden:

- **Übersichtlichkeit:** Klar strukturiert und kompakt.
- **Relevanz:** Daten die einem Mehrwert bieten.
- **Erfassbarkeit:** Kennzahlen und Trends sofort erkennbar (z. B. Diagrammen).
- **Aktualität und Interaktivität:** Aktuelle Daten, oft mit Filtern oder
  Anpassungsmöglichkeiten.

---

# Aufbau

Ein Dashboard besteht aus mehreren
[LayoutCards](/04-components/structure/layout-card/overview), die jeweils ein
Thema abbilden. Mithilfe von
[ColumnLayouts](/04-components/structure/column-layout/overview) entsteht die
kachelartige Struktur. Innerhalb einer LayoutCard sorgen
[Sections](/04-components/structure/section/overview) für die Gliederung in die
drei Bereiche Header, Content und Footer.

---

# Willkommens-Dashboard

Ein Willkommens-Dashboard auf der Startseite bietet einen schnellen Überblick
über zentrale Informationen und Funktionen. Es erleichtert den Einstieg, schafft
Orientierung und dient als klarer Ausgangspunkt für den Zugriff auf weitere
Bereiche.

```tsx
import {
  AlertBadge,
  Avatar,
  Button,
  ColumnLayout,
  Content,
  Flex,
  Header,
  Heading,
  IconCheck,
  IconEmail,
  Image,
  LayoutCard,
  Link,
  Section,
  Text,
  typedList,
} from "@mittwald/flow-react-components";

export default () => {
  const List = typedList<{
    title: string;
    date: string;
    status?: "info" | "warning" | "danger";
    isInvite?: boolean;
  }>();

  return (
    <ColumnLayout l={[1]} m={[1]}>
      <Heading color="dark" level={1}>
        Hey Max!
      </Heading>
      <ColumnLayout m={[1]} l={[3, 2]}>
        <ColumnLayout l={[1]} m={[1]}>
          <LayoutCard>
            <Section>
              <Header>
                <Heading>Benachrichtigungen</Heading>
                <Button
                  onPress={() => alert("not implemented")}
                  variant="soft"
                  color="secondary"
                >
                  Alle anzeigen
                </Button>
              </Header>
              <List.List
                hidePagination
                onAction={() => alert("not implemented")}
              >
                <List.StaticData
                  data={[
                    {
                      title:
                        "Projekteinladung: „Mein Projekt“",
                      date: "10.03.2025, 09:42 Uhr",
                      isInvite: true,
                    },
                    {
                      title:
                        "E-Mail-Empfang wurde deaktiviert",
                      date: "15.05.2025, 10:33 Uhr",
                      status: "danger",
                    },
                    {
                      title:
                        "E-Mail-Versand wurde gesperrt",
                      date: "15.05.2025, 10:33 Uhr",
                      status: "warning",
                    },
                    {
                      title: "Ticket wurde beantwortet",
                      date: "16.05.2025, 16:33 Uhr",
                      status: "info",
                    },
                  ]}
                />
                <List.Item textValue={(i) => i.title}>
                  {(i) => (
                    <List.ItemView>
                      {i.isInvite ? (
                        <Avatar>
                          <IconEmail />
                        </Avatar>
                      ) : (
                        <Avatar status={i.status} />
                      )}
                      <Heading>{i.title}</Heading>
                      <Text>{i.date}</Text>
                      <Content>
                        {i.isInvite ? (
                          <Button
                            onPress={() =>
                              alert("not implemented")
                            }
                            variant="soft"
                            color="secondary"
                          >
                            Öffnen
                          </Button>
                        ) : (
                          <Button
                            onPress={() =>
                              alert("not implemented")
                            }
                            aria-label="Erledigt"
                            variant="plain"
                            color="secondary"
                          >
                            <IconCheck />
                          </Button>
                        )}
                      </Content>
                    </List.ItemView>
                  )}
                </List.Item>
              </List.List>
            </Section>
          </LayoutCard>

          <LayoutCard>
            <ColumnLayout m={[1, 3]} s={[null, 1]}>
              <Flex align="center" grow>
                <Image
                  src="https://flow.mittwald.de/assets/onboarding.png"
                  alt=""
                  aria-hidden
                />
              </Flex>
              <Section>
                <Heading>mStudio entdecken</Heading>
                <Text>
                  Du willst das Beste aus deinen Projekten
                  herausholen? Unsere{" "}
                  <Link href="#">Wissensdatenbank</Link>{" "}
                  hilft dir dabei, das mStudio und seine
                  Möglichkeiten besser kennenzulernen.
                </Text>
              </Section>
            </ColumnLayout>
          </LayoutCard>
        </ColumnLayout>

        <ColumnLayout l={[1]} m={[1]}>
          <LayoutCard>
            <Section>
              <Heading>
                Status
                <AlertBadge status="success">
                  Alle Systeme funktionieren
                </AlertBadge>
              </Heading>
              <Text>
                Das mStudio und alle dazugehörenden Systeme
                laufen einwandfrei.
              </Text>
              <Link target="_blank" href="#">
                Zur Statusseite
              </Link>
            </Section>
          </LayoutCard>

          <LayoutCard>
            <Section>
              <Heading>Neues aus dem Blog</Heading>
              <Image
                src="https://flow.mittwald.de/assets/blog.png"
                alt=""
                aria-hidden
              />

              <Heading level={3}>
                Zukunft pflanzen – mittwald unterstützt 8000
                m² Aufforstung für den Klimaschutz
              </Heading>
              <Text>
                Nachhaltigkeitsmanager Marvin von mittwald
                berichtet über ein regionales
                Aufforstungsprojekt mit 8.000 m² neuem Wald.
              </Text>
              <Link href="#" target="_blank">
                Zum Blogartikel
              </Link>
            </Section>
          </LayoutCard>
        </ColumnLayout>
      </ColumnLayout>
    </ColumnLayout>
  );
}
```

Dashboards sollen nicht nur funktional, sondern auch visuell ansprechend
gestaltet sein. Dies kann durch den Einsatz eines
[Images](/04-components/content/image/overview) oder mithilfe der
[AccentBox](/04-components/structure/accent-box/overview) erfolgen.

---

# Detail-Dashboard

Detail-Dashboards geben Usern einen schnellen Einblick in ein Objekt. Sie können
den aktuellen Status, relevante Kennzahlen und wichtige Zusammenhänge zeigen –
oft anschaulich visualisiert durch Diagramme.

```tsx
import {
  Breadcrumb,
  ColumnLayout,
  DonutChart,
  Flex,
  Header,
  Heading,
  Label,
  LabeledValue,
  LayoutCard,
  Link,
  ProgressBar,
  Section,
  Text,
} from "@mittwald/flow-react-components";

export default () => {
  return (
    <ColumnLayout l={[1]} m={[1]}>
      <Flex direction="column" gap="xs">
        <Breadcrumb color="dark">
          <Link href="#">Projekt</Link>
          <Link href="#">Dashboard</Link>
        </Breadcrumb>
        <Heading color="dark" level={1}>
          Dashboard
        </Heading>
      </Flex>
      <LayoutCard>
        <Section>
          <Heading>Projektdetails</Heading>
          <ColumnLayout>
            <LabeledValue>
              <Label>Short-ID</Label>
              <Text>p12345</Text>
            </LabeledValue>
            <LabeledValue>
              <Label>Server</Label>
              <Link href="#">Mein Server</Link>
            </LabeledValue>
          </ColumnLayout>
        </Section>
      </LayoutCard>
      <ColumnLayout l={[1, 1]} m={[1]}>
        <LayoutCard>
          <Section>
            <Header>
              <Heading>vCPU Auslastung</Heading>
              <Link href="#">Details</Link>
            </Header>
            <Flex
              columnGap="l"
              grow
              justify="center"
              rowGap="m"
              wrap="wrap"
            >
              <DonutChart
                aria-label="vCPU Auslastung"
                status="success"
                value={43}
              >
                <strong>43 %</strong>
              </DonutChart>
              <Flex direction="column" grow rowGap="m">
                <LabeledValue>
                  <Label>Messzeitpunkt</Label>
                  <Text>05.09.2025, 07:30 Uhr</Text>
                </LabeledValue>
                <LabeledValue>
                  <Label>Maximum (Letzte 7 Tage)</Label>
                  <Text>67 %</Text>
                </LabeledValue>
              </Flex>
            </Flex>
          </Section>
        </LayoutCard>
        <LayoutCard>
          <Section>
            <Header>
              <Heading>RAM Auslastung</Heading>
              <Link href="#">Details</Link>
            </Header>
            <Flex
              columnGap="l"
              grow
              justify="center"
              rowGap="m"
              wrap="wrap"
            >
              <DonutChart
                aria-label="RAM Auslastung"
                status="success"
                value={12}
              >
                <strong>12 %</strong>
              </DonutChart>
              <Flex direction="column" grow rowGap="m">
                <LabeledValue>
                  <Label>Messzeitpunkt</Label>
                  <Text>05.09.2025, 07:30 Uhr</Text>
                </LabeledValue>
                <LabeledValue>
                  <Label>Maximum (Letzte 7 Tage)</Label>
                  <Text>24 %</Text>
                </LabeledValue>
              </Flex>
            </Flex>
          </Section>
        </LayoutCard>
      </ColumnLayout>
      <LayoutCard>
        <Section>
          <Header>
            <Heading>Speicherplatz</Heading>
            <Link href="#">Details</Link>
          </Header>
          <ProgressBar
            value={2.3}
            maxValue={5}
            formatOptions={{
              style: "unit",
              unit: "gigabyte",
            }}
            showMaxValue
            size="l"
            status="success"
          >
            <Label>Speicherplatz</Label>
          </ProgressBar>
        </Section>
      </LayoutCard>
    </ColumnLayout>
  );
}
```

Für die Datenvisualisierung in Dashboards eignen sich unter anderem folgende
Components: [ProgressBar](/04-components/status/progress-bar/overview),
[DonutChart](/04-components/data-visualisation/donut-chart/overview),
[BigNumber](/04-components/data-visualisation/big-number/overview),
[CartesianChart](/04-components/data-visualisation/cartesian-chart/overview).

## LayoutCard kombiniert mit AccentBox

[AccentBoxen](/04-components/structure/accent-box/overview) eignen sich, um
gezielt farbliche Akzente zu setzen – insbesondere bei Werbemaßnahmen. Dabei
sollte jedoch sparsam vorgegangen werden, damit das Gesamtbild stimmig bleibt.
In der Regel genügt bereits eine farbige Box.

```tsx
import {
  AccentBox,
  Breadcrumb,
  Button,
  ColumnLayout,
  Flex,
  Header,
  Heading,
  Icon,
  LayoutCard,
  Link,
  Section,
  Text,
} from "@mittwald/flow-react-components";
import { IconHeartHandshake } from "@tabler/icons-react";

export default () => {
  return (
    <ColumnLayout l={[1]} m={[1]}>
      <Flex direction="column" gap="xs">
        <Breadcrumb color="dark">
          <Link href="#">Organisation</Link>
          <Link href="#">Dashboard</Link>
        </Breadcrumb>
        <Heading color="dark" level={1}>
          Dashboard
        </Heading>
      </Flex>
      <ColumnLayout l={[1, 1]} m={[1]}>
        <LayoutCard>
          <Section>
            <Header>
              <Heading>Vertragspartner</Heading>
              <Button
                onPress={() => alert("not implemented")}
                color="secondary"
                variant="soft"
              >
                Bearbeiten
              </Button>
            </Header>
            <Text>
              Mittwald CM Service GmbH & Co.KG
              <br />
              Max Mustermann
              <br />
              Königsberger Straße 4-6, 32339 Espelkamp
              <br />
              mittwald@mittwald.de
              <br />
              +49 1234 5678910
            </Text>
          </Section>
        </LayoutCard>
        <LayoutCard>
          <Section>
            <Header>
              <Heading>Rechnungsempfänger</Heading>
              <Button
                onPress={() => alert("not implemented")}
                color="secondary"
                variant="soft"
              >
                Bearbeiten
              </Button>
            </Header>
            <Text>
              <strong>Rechnung</strong>
            </Text>
            <Text>
              Max Mustermann
              <br />
              Königsberger Straße 4-6, 32339 Espelkamp
              <br />
              mittwald@mittwald.de
              <br />
              +49 1234 5678910
            </Text>
          </Section>
        </LayoutCard>
      </ColumnLayout>
      <LayoutCard>
        <AccentBox color="dark">
          <Icon>
            <IconHeartHandshake />
          </Icon>
          <Section>
            <Heading>
              Entwickle deine eigene Extension
            </Heading>
            <Text>
              Du hast Lust als Organisation deine eigene
              Extension zu bauen und sie der Community
              bereitzustellen? Du hast vorab noch Fragen
              rund um die Contribution? Lass uns drüber
              quatschen.
            </Text>
            <Link href="#" target="_blank">
              Contributor werden
            </Link>
          </Section>
        </AccentBox>
      </LayoutCard>
    </ColumnLayout>
  );
}
```
