since3-portal/modules/shared/ui/components/folder-dialogs.tsx
2026-09-29 16:15:28 +02:00

124 lines
4.4 KiB
TypeScript

"use client";
import { useActionState, useState } from "react";
import { useRouter } from "next/navigation";
import { FolderPlusIcon, Trash2Icon } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { createFolder, deleteFolder, type DocumentActionState } from "@/modules/shared/actions/documents";
function CreateFolderForm({ profileId, onDone }: { profileId: string; onDone: () => void }) {
async function run(prev: DocumentActionState, formData: FormData) {
const result = await createFolder(prev, formData);
if (result && "success" in result) onDone();
return result;
}
const [state, formAction, pending] = useActionState(run, undefined);
return (
<form action={formAction} className="flex flex-col gap-4">
<input type="hidden" name="profileId" value={profileId} />
<Field>
<FieldLabel htmlFor="folder-name">Name</FieldLabel>
<Input id="folder-name" name="name" placeholder="z. B. Verträge" autoFocus required />
</Field>
{state && "error" in state && <p className="text-sm text-destructive">{state.error}</p>}
<DialogFooter>
<Button type="submit" disabled={pending}>
{pending ? "Wird erstellt..." : "Erstellen"}
</Button>
</DialogFooter>
</form>
);
}
export function CreateFolderDialog({ profileId }: { profileId: string }) {
const [open, setOpen] = useState(false);
const [instanceKey, setInstanceKey] = useState(0);
function handleOpenChange(nextOpen: boolean) {
setOpen(nextOpen);
if (!nextOpen) setInstanceKey((key) => key + 1);
}
return (
<Dialog open={open} onOpenChange={handleOpenChange}>
<DialogTrigger render={<Button />}>
<FolderPlusIcon className="size-4" /> Neuer Ordner
</DialogTrigger>
<DialogContent>
<DialogHeader className="mb-2">
<DialogTitle>Neuer Ordner</DialogTitle>
</DialogHeader>
<CreateFolderForm key={instanceKey} profileId={profileId} onDone={() => handleOpenChange(false)} />
</DialogContent>
</Dialog>
);
}
export function DeleteFolderDialog({
profileId,
folderId,
folderName,
redirectTo,
}: {
profileId: string;
folderId: string;
folderName: string;
redirectTo: string;
}) {
const router = useRouter();
const [open, setOpen] = useState(false);
const [pending, setPending] = useState(false);
const [error, setError] = useState<string | null>(null);
async function handleDelete() {
setPending(true);
setError(null);
const result = await deleteFolder(profileId, folderId);
setPending(false);
if (result && "error" in result) {
setError(result.error);
return;
}
setOpen(false);
router.push(redirectTo);
}
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger render={<Button variant="outline" />}>
<Trash2Icon className="size-4" /> Ordner löschen
</DialogTrigger>
<DialogContent>
<DialogHeader className="mb-4">
<DialogTitle>Ordner löschen</DialogTitle>
<DialogDescription>
Möchtest du den Ordner <span className="font-medium text-foreground">{folderName}</span> löschen?
Das geht nur, wenn er leer ist.
</DialogDescription>
</DialogHeader>
{error && <p className="text-sm text-destructive">{error}</p>}
<DialogFooter>
<Button type="button" variant="outline" onClick={() => setOpen(false)} disabled={pending}>
Abbrechen
</Button>
<Button type="button" variant="destructive" onClick={handleDelete} disabled={pending}>
{pending ? "Wird gelöscht..." : "Löschen"}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}