"use client"; import React from "react"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Edit, Trash2, CornerDownRight, Plus, ChevronRight, ChevronDown } from "lucide-react"; import { cn } from "@/lib/utils"; import { useUpdateCode } from "@/hooks/queries/useCodes"; import type { CodeInfo } from "@/types/commonCode"; interface SortableCodeItemProps { code: CodeInfo; categoryCode: string; onEdit: () => void; onDelete: () => void; onAddChild: () => void; // 하위 코드 추가 isDragOverlay?: boolean; maxDepth?: number; // 최대 깊이 (기본값 3) hasChildren?: boolean; // 자식이 있는지 여부 childCount?: number; // 자식 개수 isExpanded?: boolean; // 펼쳐진 상태 onToggleExpand?: () => void; // 접기/펼치기 토글 } export function SortableCodeItem({ code, categoryCode, onEdit, onDelete, onAddChild, isDragOverlay = false, maxDepth = 3, hasChildren = false, childCount = 0, isExpanded = true, onToggleExpand, }: SortableCodeItemProps) { const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: code.codeValue || code.code_value || "", disabled: isDragOverlay, }); const updateCodeMutation = useUpdateCode(); const style = { transform: CSS.Transform.toString(transform), transition, }; // 활성/비활성 토글 핸들러 const handleToggleActive = async (checked: boolean) => { try { const codeValue = code.codeValue || code.code_value; if (!codeValue) { return; } await updateCodeMutation.mutateAsync({ categoryCode, codeValue: codeValue, data: { codeName: code.codeName || code.code_name, codeNameEng: code.codeNameEng || code.code_name_eng || "", description: code.description || "", sortOrder: code.sortOrder || code.sort_order, isActive: checked ? "Y" : "N", }, }); } catch (error) { console.error("코드 활성 상태 변경 실패:", error); } }; // 계층구조 깊이에 따른 들여쓰기 const depth = code.depth || 1; const indentLevel = (depth - 1) * 28; // 28px per level const hasParent = !!(code.parentCodeValue || code.parent_code_value); return (
{/* 계층구조 들여쓰기 영역 */} {depth > 1 && (
)}
{/* 접기/펼치기 버튼 (자식이 있을 때만 표시) */} {hasChildren && onToggleExpand && ( )}

{code.codeName || code.code_name}

{/* 접힌 상태에서 자식 개수 표시 */} {hasChildren && !isExpanded && ({childCount})} {/* 깊이 표시 배지 */} {depth === 1 && ( 대분류 )} {depth === 2 && ( 중분류 )} {depth === 3 && ( 소분류 )} {depth > 3 && ( {depth}단계 )} { e.preventDefault(); e.stopPropagation(); if (!updateCodeMutation.isPending) { const isActive = code.isActive === "Y" || code.is_active === "Y"; handleToggleActive(!isActive); } }} onPointerDown={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()} > {code.isActive === "Y" || code.is_active === "Y" ? "활성" : "비활성"}

{code.codeValue || code.code_value}

{/* 부모 코드 표시 */} {hasParent && (

상위: {code.parentCodeValue || code.parent_code_value}

)} {code.description &&

{code.description}

}
{/* 액션 버튼 */}
e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()} > {/* 하위 코드 추가 버튼 (최대 깊이 미만일 때만 표시) */} {depth < maxDepth && ( )}
); }