"use client"; import React, { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { LoadingSpinner } from "@/components/common/LoadingSpinner"; import { CodeInfoFormModal } from "./CodeInfoFormModal"; import { CodeInfoItem } from "./CodeInfoItem"; import { AlertModal } from "@/components/common/AlertModal"; import { Search, Plus } from "lucide-react"; import { useDeleteCodeInfo } from "@/hooks/queries/useCodeInfo"; import { useCodeInfoInfinite } from "@/hooks/queries/useCodeInfoInfinite"; interface CodeInfoPanelProps { selectedCodeInfo: string; onSelectCodeInfo: (codeInfo: string) => void; } export function CodeInfoPanel({ selectedCodeInfo, onSelectCodeInfo }: CodeInfoPanelProps) { const [searchTerm, setSearchTerm] = useState(""); const [showActiveOnly, setShowActiveOnly] = useState(false); const { data: rows = [], isLoading, error, handleScroll, isFetchingNextPage, hasNextPage, } = useCodeInfoInfinite({ search: searchTerm || undefined, active: showActiveOnly || undefined, }); const deleteMutation = useDeleteCodeInfo(); const [showFormModal, setShowFormModal] = useState(false); const [editingCode, setEditingCode] = useState(""); const [showDeleteModal, setShowDeleteModal] = useState(false); const [deletingCode, setDeletingCode] = useState(""); const handleNew = () => { setEditingCode(""); setShowFormModal(true); }; const handleEdit = (code: string) => { setEditingCode(code); setShowFormModal(true); }; const handleDelete = (code: string) => { setDeletingCode(code); setShowDeleteModal(true); }; const handleConfirmDelete = async () => { if (!deletingCode) return; try { await deleteMutation.mutateAsync(deletingCode); if (selectedCodeInfo === deletingCode) { onSelectCodeInfo(""); } setShowDeleteModal(false); setDeletingCode(""); } catch (error) { console.error("그룹 삭제 실패:", error); } }; if (error) { return (

그룹을 불러오는 중 오류가 발생했습니다.

); } return (
{/* 검색 + 등록 */}
setSearchTerm(e.target.value)} className="h-10 pl-10 text-sm" />
setShowActiveOnly(e.target.checked)} className="h-4 w-4 rounded border-input" />
{/* 목록 */}
{isLoading ? (
) : rows.length === 0 ? (

{searchTerm ? "검색 결과가 없습니다." : "그룹이 없습니다."}

) : ( <> {rows.map((row, index) => ( onSelectCodeInfo(row.code_info)} onEdit={() => handleEdit(row.code_info)} onDelete={() => handleDelete(row.code_info)} /> ))} {isFetchingNextPage && (
추가 로딩 중...
)} {!hasNextPage && rows.length > 0 && (
모든 그룹을 불러왔습니다.
)} )}
{showFormModal && ( setShowFormModal(false)} editingCodeInfo={editingCode} existingRows={rows} /> )} {showDeleteModal && ( setShowDeleteModal(false)} type="error" title="그룹 삭제" message="정말로 이 그룹을 삭제하시겠습니까? 그룹의 모든 디테일 코드도 함께 삭제됩니다 (CASCADE)." confirmText="삭제" onConfirm={handleConfirmDelete} /> )}
); }