feat(ui): automation settings start with everyday tabs and confirm risky actions

- Tabs ordered from everyday (suggestions, recurring tasks, labels) to
  technical (calendar sync, API keys, webhooks); the page opens on
  "Vorschläge" instead of Webhooks, and says in one sentence what it is.
- Resetting a number counter, deactivating a label template and ending a
  recurring task now ask first and say plainly what happens.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-01 07:36:28 +02:00
1 parent 78325af1fe
commit dff6c364c8
4 files changed
+38 -32

No files matched your search

@@ -12,6 +12,7 @@ import { AutomationRule, AutomationTriggerType } from "@/lib/automation/types";
import { formatGeneratedNumber } from "@/lib/automation/number-format";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { ConfirmDialog } from "@/components/confirm-dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
@@ -207,15 +208,16 @@ function RuleCard({ rule }: { rule: AutomationRule }) {
</Button>
</div>
{numberFormatRule ? (
<Button
type="button"
variant="ghost"
size="sm"
disabled={resetMutation.isPending}
onClick={() => resetMutation.mutate()}
>
{resetMutation.isPending ? "Wird zurückgesetzt…" : "Zähler zurücksetzen"}
</Button>
<ConfirmDialog
triggerLabel="Zähler zurücksetzen"
triggerVariant="ghost"
triggerDisabled={resetMutation.isPending}
title="Zähler zurücksetzen?"
description="Die nächste Nummer beginnt wieder bei 1. Gibt es im selben Zeitraum schon Nummern, können doppelte Los-/Chargennummern entstehen. Nur zurücksetzen, wenn ein neuer Zeitraum beginnt."
confirmLabel="Zurücksetzen"
isPending={resetMutation.isPending}
onConfirm={() => resetMutation.mutate()}
/>
) : null}
</CardContent>
</Card>
@@ -7,6 +7,7 @@ import { toast } from "sonner";
import { deactivateLabelTemplate, fetchLabelTemplates } from "@/lib/label-templates/api";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { ConfirmDialog } from "@/components/confirm-dialog";
import { EmptyState } from "@/components/empty-state";
import { EntityCard } from "@/components/entity-card";
@@ -74,15 +75,16 @@ export function LabelTemplatesTab() {
<Pencil className="size-3.5" />
Bearbeiten
</Button>
<Button
type="button"
variant="ghost"
size="sm"
disabled={deactivateMutation.isPending}
onClick={() => deactivateMutation.mutate(template.id)}
>
Deaktivieren
</Button>
<ConfirmDialog
triggerLabel="Deaktivieren"
triggerVariant="ghost"
triggerDisabled={deactivateMutation.isPending}
title="Vorlage deaktivieren?"
description={`„${template.name}“ steht danach beim Etikettendruck nicht mehr zur Auswahl. Bereits gedruckte Etiketten bleiben unverändert.`}
confirmLabel="Deaktivieren"
isPending={deactivateMutation.isPending}
onConfirm={() => deactivateMutation.mutate(template.id)}
/>
</>
}
/>
@@ -22,14 +22,15 @@ type Tab =
| "calendar-sync"
| "api-keys";
// Everyday settings first, connections to other systems last.
const TABS: { value: Tab; label: string }[] = [
{ value: "webhooks", label: "Webhooks" },
{ value: "rules", label: "Vorschläge" },
{ value: "task-templates", label: "Wiederkehrende Aufgaben" },
{ value: "label-templates", label: "Etikettenvorlagen" },
{ value: "social-media", label: "Stammdaten & Web" },
{ value: "rules", label: "Regeln" },
{ value: "calendar-sync", label: "Kalender-Sync" },
{ value: "api-keys", label: "API-Schlüssel" },
{ value: "webhooks", label: "Webhooks" },
];
function isTab(value: string | null): value is Tab {
@@ -39,7 +40,7 @@ function isTab(value: string | null): value is Tab {
function AutomationPageContent() {
const router = useRouter();
const searchParams = useSearchParams();
const tab: Tab = isTab(searchParams.get("tab")) ? (searchParams.get("tab") as Tab) : "webhooks";
const tab: Tab = isTab(searchParams.get("tab")) ? (searchParams.get("tab") as Tab) : "rules";
function setTab(next: Tab) {
router.replace(`/settings/automation?tab=${next}`);
@@ -50,7 +51,7 @@ function AutomationPageContent() {
<PageHeader
icon={Zap}
title="Automatisierung"
description="Webhooks, wiederkehrende Aufgaben, Etikettenvorlagen, Social Media, Regeln, Kalender-Sync und API-Schlüssel"
description="Was ApiCore dir abnimmt – und wie es mit anderen Systemen verbunden ist."
gradient="var(--gradient-sky)"
/>
@@ -7,7 +7,7 @@ import { toast } from "sonner";
import { deactivateTaskTemplate, fetchTaskTemplates } from "@/lib/task-templates/api";
import { TaskTemplate, TaskTemplateRecurrenceType } from "@/lib/task-templates/types";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { ConfirmDialog } from "@/components/confirm-dialog";
import { EmptyState } from "@/components/empty-state";
import { EntityCard } from "@/components/entity-card";
import { ActiveHistoryTabs, type EntityLifecycleTab } from "@/components/active-history-tabs";
@@ -106,15 +106,16 @@ export function TaskTemplatesTab() {
actions={
<>
<EditTaskTemplateDialog template={template} />
<Button
type="button"
variant="ghost"
size="sm"
disabled={!template.active || deactivateMutation.isPending}
onClick={() => deactivateMutation.mutate(template.id)}
>
Deaktivieren
</Button>
<ConfirmDialog
triggerLabel="Deaktivieren"
triggerVariant="ghost"
triggerDisabled={!template.active || deactivateMutation.isPending}
title="Wiederkehrende Aufgabe beenden?"
description={`Für „${template.title}“ werden keine neuen Aufgaben mehr angelegt. Bereits angelegte Aufgaben bleiben in der Liste.`}
confirmLabel="Beenden"
isPending={deactivateMutation.isPending}
onConfirm={() => deactivateMutation.mutate(template.id)}
/>
</>
}
/>