summaryrefslogtreecommitdiff
path: root/components/permissions/permission-crud-manager.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-09-29 13:31:40 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-09-29 13:31:40 +0000
commit4614210aa9878922cfa1e424ce677ef893a1b6b2 (patch)
tree5e7edcce05fbee207230af0a43ed08cd351d7c4f /components/permissions/permission-crud-manager.tsx
parente41e3af4e72870d44a94b03e0f3246d6ccaaca48 (diff)
(대표님) 구매 권한설정, data room 등
Diffstat (limited to 'components/permissions/permission-crud-manager.tsx')
-rw-r--r--components/permissions/permission-crud-manager.tsx92
1 files changed, 84 insertions, 8 deletions
diff --git a/components/permissions/permission-crud-manager.tsx b/components/permissions/permission-crud-manager.tsx
index 01c9959f..a9b2f64e 100644
--- a/components/permissions/permission-crud-manager.tsx
+++ b/components/permissions/permission-crud-manager.tsx
@@ -26,6 +26,16 @@ import {
DialogTrigger,
} from "@/components/ui/dialog";
import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+} from "@/components/ui/alert-dialog";
+import {
Table,
TableBody,
TableCell,
@@ -52,7 +62,8 @@ import {
Key,
Shield,
Copy,
- CheckCircle
+ CheckCircle,
+ AlertTriangle
} from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
@@ -90,6 +101,8 @@ export function PermissionCrudManager() {
const [loading, setLoading] = useState(false);
const [createDialogOpen, setCreateDialogOpen] = useState(false);
const [editingPermission, setEditingPermission] = useState<Permission | null>(null);
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
+ const [deletingPermission, setDeletingPermission] = useState<Permission | null>(null);
useEffect(() => {
loadPermissions();
@@ -139,20 +152,25 @@ export function PermissionCrudManager() {
setFilteredPermissions(filtered);
};
- const handleDelete = async (id: number) => {
- if (!confirm("이 권한을 삭제하시겠습니까? 관련된 모든 할당이 제거됩니다.")) {
- return;
- }
-
+ const handleDelete = async () => {
+ if (!deletingPermission) return;
+
try {
- await deletePermission(id);
+ await deletePermission(deletingPermission.id);
toast.success("권한이 삭제되었습니다.");
loadPermissions();
+ setDeleteDialogOpen(false);
+ setDeletingPermission(null);
} catch (error) {
toast.error("권한 삭제에 실패했습니다.");
}
};
+ const openDeleteDialog = (permission: Permission) => {
+ setDeletingPermission(permission);
+ setDeleteDialogOpen(true);
+ };
+
return (
<div className="space-y-6">
{/* 헤더 및 필터 */}
@@ -280,7 +298,7 @@ export function PermissionCrudManager() {
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
- onClick={() => handleDelete(permission.id)}
+ onClick={() => openDeleteDialog(permission)}
className="text-destructive"
disabled={permission.isSystem}
>
@@ -314,6 +332,64 @@ export function PermissionCrudManager() {
loadPermissions();
}}
/>
+
+ {/* 삭제 확인 다이얼로그 */}
+ <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>
+ <div className="flex items-center gap-2">
+ <AlertTriangle className="h-5 w-5 text-destructive" />
+ 권한 삭제 확인
+ </div>
+ </AlertDialogTitle>
+ <AlertDialogDescription>
+ {deletingPermission && (
+ <div className="space-y-4">
+ <p>
+ <span className="font-semibold">&quot;{deletingPermission.name}&quot;</span> 권한을 삭제하시겠습니까?
+ </p>
+
+ <div className="p-3 bg-muted rounded-lg space-y-2">
+ <div className="flex items-center gap-2 text-sm">
+ <span className="text-muted-foreground min-w-[80px]">권한 키:</span>
+ <code className="px-2 py-0.5 bg-background rounded">{deletingPermission.permissionKey}</code>
+ </div>
+ <div className="flex items-center gap-2 text-sm">
+ <span className="text-muted-foreground min-w-[80px]">리소스:</span>
+ <span>{deletingPermission.resource}</span>
+ </div>
+ <div className="flex items-center gap-2 text-sm">
+ <span className="text-muted-foreground min-w-[80px]">액션:</span>
+ <span>{deletingPermission.action}</span>
+ </div>
+ </div>
+
+ <div className="p-3 bg-destructive/10 border border-destructive/20 rounded-lg">
+ <p className="text-sm text-destructive font-medium">
+ ⚠️ 주의: 이 작업은 되돌릴 수 없습니다
+ </p>
+ <p className="text-sm text-muted-foreground mt-1">
+ 이 권한과 관련된 모든 역할 및 사용자 할당이 제거됩니다.
+ </p>
+ </div>
+ </div>
+ )}
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel onClick={() => setDeletingPermission(null)}>
+ 취소
+ </AlertDialogCancel>
+ <AlertDialogAction
+ onClick={handleDelete}
+ className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
+ >
+ 삭제
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
</div>
);
}