feat(frontend): RenameDialog and DeleteConfirmDialog
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "../components/ui/dialog";
|
||||||
|
import { Button } from "../components/ui/button";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
open: boolean;
|
||||||
|
label: string;
|
||||||
|
onOpenChange: (open: boolean) => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DeleteConfirmDialog({ open, label, onOpenChange, onConfirm }: Props) {
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader><DialogTitle>Elimina definitivamente</DialogTitle></DialogHeader>
|
||||||
|
<DialogDescription>
|
||||||
|
"{label}" verrà eliminata definitivamente, inclusi tutti i suoi documenti. L'operazione non è reversibile.
|
||||||
|
</DialogDescription>
|
||||||
|
<DialogFooter>
|
||||||
|
<Button type="button" variant="outline" size="sm" onClick={() => onOpenChange(false)}>Cancel</Button>
|
||||||
|
<Button type="button" variant="destructive" size="sm" onClick={() => { onConfirm(); onOpenChange(false); }}>Delete</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "../components/ui/dialog";
|
||||||
|
import { Button } from "../components/ui/button";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
open: boolean;
|
||||||
|
initial: string;
|
||||||
|
onOpenChange: (open: boolean) => void;
|
||||||
|
onSubmit: (name: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RenameDialog({ open, initial, onOpenChange, onSubmit }: Props) {
|
||||||
|
const [name, setName] = useState(initial);
|
||||||
|
useEffect(() => { if (open) setName(initial); }, [open, initial]);
|
||||||
|
|
||||||
|
function submit(e: React.FormEvent) {
|
||||||
|
e.preventDefault();
|
||||||
|
onSubmit(name.trim());
|
||||||
|
onOpenChange(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader><DialogTitle>Rinomina sessione</DialogTitle></DialogHeader>
|
||||||
|
<form onSubmit={submit} className="flex flex-col gap-3">
|
||||||
|
<div>
|
||||||
|
<label className="mb-1.5 block text-xs font-medium text-muted-foreground" htmlFor="rename-name">Name</label>
|
||||||
|
<input
|
||||||
|
id="rename-name"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
className="w-full rounded-lg border border-input bg-card px-3 py-2 text-sm outline-none focus:border-primary/50 focus:ring-3 focus:ring-ring/15"
|
||||||
|
placeholder="Session name…"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<DialogFooter>
|
||||||
|
<Button type="button" variant="outline" size="sm" onClick={() => onOpenChange(false)}>Cancel</Button>
|
||||||
|
<Button type="submit" size="sm">Save</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import userEvent from "@testing-library/user-event";
|
||||||
|
import { vi } from "vitest";
|
||||||
|
import { RenameDialog } from "./RenameDialog";
|
||||||
|
import { DeleteConfirmDialog } from "./DeleteConfirmDialog";
|
||||||
|
|
||||||
|
test("RenameDialog submits the edited name", async () => {
|
||||||
|
const onSubmit = vi.fn();
|
||||||
|
render(<RenameDialog open initial="Vecchio" onOpenChange={vi.fn()} onSubmit={onSubmit} />);
|
||||||
|
const input = screen.getByLabelText(/name/i);
|
||||||
|
await userEvent.clear(input);
|
||||||
|
await userEvent.type(input, "Nuovo");
|
||||||
|
await userEvent.click(screen.getByRole("button", { name: /save/i }));
|
||||||
|
expect(onSubmit).toHaveBeenCalledWith("Nuovo");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("DeleteConfirmDialog confirms only on the destructive button", async () => {
|
||||||
|
const onConfirm = vi.fn();
|
||||||
|
render(<DeleteConfirmDialog open label="Sessione X" onOpenChange={vi.fn()} onConfirm={onConfirm} />);
|
||||||
|
expect(screen.getByText(/Sessione X/)).toBeInTheDocument();
|
||||||
|
await userEvent.click(screen.getByRole("button", { name: /delete/i }));
|
||||||
|
expect(onConfirm).toHaveBeenCalled();
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user