feat(frontend): confirmation dialogs and undo for destructive-feeling actions
Volk aufloesen, Bienenstand deaktivieren, Benutzer deaktivieren und Webhook loeschen liefen bisher ohne jede Rueckfrage direkt auf Klick. Neue wiederverwendbare ConfirmDialog-Komponente erzwingt jetzt eine bewusste Bestaetigung. Zusaetzlich zeigen Volk/Bienenstand/Benutzer nach dem Aufloesen/Deaktivieren einen Reaktivieren-Button (nutzt die neuen Backend-Endpunkte), da diese Aktionen nie ein echtes Loeschen sind und ein versehentlicher Klick bisher nicht rueckgaengig zu machen war.
This commit is contained in:
1 parent
57979f0371
commit
6ab028d1be
9 files changed
+231
-36
No files matched your search
@@ -2,13 +2,15 @@
|
||||
|
||||
import { FormEvent, useState } from "react";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { deactivateApiary, updateApiary } from "@/lib/apiaries/api";
|
||||
import { toast } from "sonner";
|
||||
import { deactivateApiary, reactivateApiary, updateApiary } from "@/lib/apiaries/api";
|
||||
import { Apiary } from "@/lib/apiaries/types";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { ConfirmDialog } from "@/components/confirm-dialog";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
@@ -40,7 +42,20 @@ export function ApiaryEditCard({ apiary }: { apiary: Apiary }) {
|
||||
mutationFn: () => deactivateApiary(apiary.id),
|
||||
onSuccess: () => {
|
||||
void queryClient.invalidateQueries({ queryKey: ["apiaries"] });
|
||||
toast.success("Bienenstand deaktiviert", {
|
||||
description: "Er kann jederzeit über „Reaktivieren“ wiederhergestellt werden.",
|
||||
});
|
||||
},
|
||||
onError: () => toast.error("Bienenstand konnte nicht deaktiviert werden"),
|
||||
});
|
||||
|
||||
const reactivateMutation = useMutation({
|
||||
mutationFn: () => reactivateApiary(apiary.id),
|
||||
onSuccess: () => {
|
||||
void queryClient.invalidateQueries({ queryKey: ["apiaries"] });
|
||||
toast.success("Bienenstand reaktiviert");
|
||||
},
|
||||
onError: () => toast.error("Bienenstand konnte nicht reaktiviert werden"),
|
||||
});
|
||||
|
||||
function handleSubmit(event: FormEvent<HTMLFormElement>) {
|
||||
@@ -95,14 +110,25 @@ export function ApiaryEditCard({ apiary }: { apiary: Apiary }) {
|
||||
<Button type="submit" disabled={updateMutation.isPending}>
|
||||
{updateMutation.isPending ? "Speichert…" : "Speichern"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
disabled={apiary.status !== "ACTIVE" || deactivateMutation.isPending}
|
||||
onClick={() => deactivateMutation.mutate()}
|
||||
>
|
||||
Deaktivieren
|
||||
</Button>
|
||||
{apiary.status === "ACTIVE" ? (
|
||||
<ConfirmDialog
|
||||
triggerLabel="Deaktivieren"
|
||||
triggerDisabled={deactivateMutation.isPending}
|
||||
title="Bienenstand deaktivieren?"
|
||||
description={`„${apiary.name}“ wird deaktiviert. Die Historie bleibt erhalten und der Bienenstand kann jederzeit wieder reaktiviert werden.`}
|
||||
confirmLabel="Deaktivieren"
|
||||
isPending={deactivateMutation.isPending}
|
||||
onConfirm={() => deactivateMutation.mutate()}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
type="button"
|
||||
disabled={reactivateMutation.isPending}
|
||||
onClick={() => reactivateMutation.mutate()}
|
||||
>
|
||||
{reactivateMutation.isPending ? "Wird reaktiviert…" : "Reaktivieren"}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
</CardContent>
|
||||
|
||||
Reference in new issue
Block a user