workspace-ui-kit/components/workspace/SettingsDialog.tsx
snc777 f6a781c47e initial commit
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-09 14:24:17 +09:00

149 lines
4.6 KiB
TypeScript

"use client";
import { useState } from "react";
import { Plus, Trash2 } from "lucide-react";
import { type Department } from "@/lib/schema";
import { DeleteConfirmDialog } from "@/components/workspace/DeleteConfirmDialog";
import { Button } from "@/components/ui/button";
import {
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogClose,
} from "@/components/ui/dialog";
import { FieldGroup, Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import {
InputGroup,
InputGroupInput,
InputGroupAddon,
} from "@/components/ui/input-group";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
type SettingsDialogContentProps = {
departments: Department[];
onAddDepartment: (name: string) => void;
onDeleteDepartment: (deptId: string) => void;
};
export function SettingsDialogContent({
departments,
onAddDepartment,
onDeleteDepartment,
}: SettingsDialogContentProps) {
const [newDeptName, setNewDeptName] = useState("");
const [deleteDeptTarget, setDeleteDeptTarget] = useState<{
id: string;
name: string;
} | null>(null);
const handleAddDept = () => {
const trimmed = newDeptName.trim();
if (!trimmed) return;
onAddDepartment(trimmed);
setNewDeptName("");
};
return (
<>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
</DialogDescription>
</DialogHeader>
<FieldGroup>
<Field>
<FieldLabel htmlFor="settings-new-dept"></FieldLabel>
<ScrollArea className="max-h-48">
<div className="divide-y divide-border rounded-lg border border-border">
{departments.map((dept) => (
<div
key={dept.id}
className="flex items-center justify-between px-3 py-2"
>
<span className="text-sm">{dept.name}</span>
<Button
type="button"
variant="ghost"
size="icon-xs"
onClick={() =>
setDeleteDeptTarget({ id: dept.id, name: dept.name })
}
aria-label={`${dept.name} を削除`}
className="text-muted-foreground hover:text-destructive"
>
<Trash2 />
</Button>
</div>
))}
{departments.length === 0 && (
<div className="px-3 py-4 text-center text-sm text-muted-foreground">
</div>
)}
</div>
</ScrollArea>
<InputGroup>
<InputGroupInput
id="settings-new-dept"
placeholder="新しい事業部名"
value={newDeptName}
onChange={(e) => setNewDeptName(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") handleAddDept();
}}
/>
<InputGroupAddon align="inline-end">
<Button
variant="outline"
size="sm"
onClick={handleAddDept}
disabled={!newDeptName.trim()}
>
<Plus data-icon="inline-start" />
</Button>
</InputGroupAddon>
</InputGroup>
</Field>
<Separator />
<Field>
<FieldLabel htmlFor="settings-workspace-name">
</FieldLabel>
<Input id="settings-workspace-name" defaultValue="採用管理" />
</Field>
</FieldGroup>
<DialogFooter>
<DialogClose render={<Button variant="outline"></Button>} />
</DialogFooter>
</DialogContent>
<DeleteConfirmDialog
open={deleteDeptTarget !== null}
onOpenChange={(open) => {
if (!open) setDeleteDeptTarget(null);
}}
title="事業部を削除しますか?"
itemName={deleteDeptTarget?.name ?? ""}
onConfirm={() => {
if (deleteDeptTarget) {
onDeleteDepartment(deleteDeptTarget.id);
setDeleteDeptTarget(null);
}
}}
/>
</>
);
}