Eine Domain zu registrieren genuegt nicht — DNS, Reverse Proxy und Zertifikat muessen dazu passen. Bislang stand das nur im README, also genau dort nicht, wo man es braucht. Auf der Domain-Seite oeffnet ein Knopf die Erklaerung in sechs Schritten, mit den drei noetigen Kopfzeilen und einem Pruefbefehl. Der Knopf selbst ist als HelpButton allgemein gehalten, damit andere Verwaltungsseiten spaeter dieselbe Form bekommen koennen. Refs #4
95 lines
2.3 KiB
TypeScript
95 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
import { useState, type ReactNode } from "react";
|
|
|
|
import { Icon } from "@/components/icons";
|
|
import { Modal } from "@/components/modal";
|
|
import { Button } from "@/components/ui";
|
|
|
|
/**
|
|
* Kurzhilfe: ein Fragezeichen neben einer Überschrift, das eine Erklärung
|
|
* aufklappt.
|
|
*
|
|
* Bewusst ein Dialog und kein Dauertext auf der Seite — die Erklärung braucht
|
|
* man einmal beim Einrichten und danach nie wieder. Sie ständig zu zeigen
|
|
* würde die Seite für alle anderen Aufrufe zumüllen.
|
|
*/
|
|
export function HelpButton({
|
|
title,
|
|
label = "Hilfe",
|
|
children,
|
|
}: {
|
|
/** Überschrift des Dialogs. */
|
|
title: string;
|
|
/** Beschriftung des Knopfes. */
|
|
label?: string;
|
|
children: ReactNode;
|
|
}) {
|
|
const [open, setOpen] = useState(false);
|
|
|
|
return (
|
|
<>
|
|
<Button
|
|
type="button"
|
|
variant="secondary"
|
|
size="sm"
|
|
onClick={() => setOpen(true)}
|
|
aria-haspopup="dialog"
|
|
>
|
|
<Icon name="help" className="size-4" />
|
|
{label}
|
|
</Button>
|
|
|
|
<Modal
|
|
open={open}
|
|
size="lg"
|
|
title={title}
|
|
onClose={() => setOpen(false)}
|
|
footer={
|
|
<Button type="button" onClick={() => setOpen(false)}>
|
|
Verstanden
|
|
</Button>
|
|
}
|
|
>
|
|
<div className="max-h-[65vh] overflow-y-auto pr-1 text-sm text-slate-700">
|
|
{children}
|
|
</div>
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|
|
|
|
/* ------------------------------------------------- Bausteine für den Inhalt */
|
|
|
|
/** Ein nummerierter Schritt mit Überschrift. */
|
|
export function HelpStep({
|
|
n,
|
|
title,
|
|
children,
|
|
}: {
|
|
n: number;
|
|
title: string;
|
|
children: ReactNode;
|
|
}) {
|
|
return (
|
|
<li className="flex gap-3">
|
|
<span className="mt-0.5 flex size-6 shrink-0 items-center justify-center rounded-full bg-accent-soft text-xs font-semibold text-accent-soft-fg">
|
|
{n}
|
|
</span>
|
|
<div className="min-w-0 flex-1">
|
|
<h3 className="font-semibold text-slate-900">{title}</h3>
|
|
<div className="mt-1 space-y-2 text-slate-600">{children}</div>
|
|
</div>
|
|
</li>
|
|
);
|
|
}
|
|
|
|
/** Ein Befehl oder Wert zum Abtippen — auf schmalen Schirmen scrollbar. */
|
|
export function HelpCode({ children }: { children: ReactNode }) {
|
|
return (
|
|
<pre className="overflow-x-auto rounded-lg bg-slate-100 px-3 py-2 font-mono text-xs text-slate-800">
|
|
{children}
|
|
</pre>
|
|
);
|
|
}
|