"use client" import * as React from "react" import { type Table } from "@tanstack/react-table" import { Plus, Check, MessageSquare, X, Download, Upload, RefreshCw, Settings } from "lucide-react" import { toast } from "sonner" import { useRouter } from "next/navigation" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { ManualCreateEvaluationTargetDialog } from "./manual-create-evaluation-target-dialog" import { EvaluationTargetWithDepartments } from "@/db/schema" interface EvaluationTargetsTableToolbarActionsProps { table: Table onRefresh?: () => void } export function EvaluationTargetsTableToolbarActions({ table, onRefresh }: EvaluationTargetsTableToolbarActionsProps) { const [isLoading, setIsLoading] = React.useState(false) const [manualCreateDialogOpen, setManualCreateDialogOpen] = React.useState(false) const router = useRouter() // 선택된 행들 const selectedRows = table.getFilteredSelectedRowModel().rows const hasSelection = selectedRows.length > 0 const selectedTargets = selectedRows.map(row => row.original) // 선택된 항목들의 상태 분석 const selectedStats = React.useMemo(() => { const pending = selectedTargets.filter(t => t.status === "PENDING").length const confirmed = selectedTargets.filter(t => t.status === "CONFIRMED").length const excluded = selectedTargets.filter(t => t.status === "EXCLUDED").length const consensusTrue = selectedTargets.filter(t => t.consensusStatus === true).length const consensusFalse = selectedTargets.filter(t => t.consensusStatus === false).length const consensusNull = selectedTargets.filter(t => t.consensusStatus === null).length return { pending, confirmed, excluded, consensusTrue, consensusFalse, consensusNull, canConfirm: pending > 0 && consensusTrue > 0, canExclude: pending > 0, canRequestReview: pending > 0 } }, [selectedTargets]) // ---------------------------------------------------------------- // 신규 평가 대상 생성 (자동) // ---------------------------------------------------------------- const handleAutoGenerate = async () => { setIsLoading(true) try { // TODO: 발주실적에서 자동 추출 API 호출 toast.success("평가 대상이 자동으로 생성되었습니다.") router.refresh() } catch (error) { console.error('Error auto generating targets:', error) toast.error("자동 생성 중 오류가 발생했습니다.") } finally { setIsLoading(false) } } // ---------------------------------------------------------------- // 신규 평가 대상 생성 (수동) // ---------------------------------------------------------------- const handleManualCreate = () => { setManualCreateDialogOpen(true) } // ---------------------------------------------------------------- // 선택된 항목들 확정 // ---------------------------------------------------------------- const handleConfirmSelected = async () => { if (!hasSelection || !selectedStats.canConfirm) return setIsLoading(true) try { // TODO: 확정 API 호출 const confirmableTargets = selectedTargets.filter( t => t.status === "PENDING" && t.consensusStatus === true ) toast.success(`${confirmableTargets.length}개 항목이 확정되었습니다.`) table.resetRowSelection() router.refresh() } catch (error) { console.error('Error confirming targets:', error) toast.error("확정 처리 중 오류가 발생했습니다.") } finally { setIsLoading(false) } } // ---------------------------------------------------------------- // 선택된 항목들 제외 // ---------------------------------------------------------------- const handleExcludeSelected = async () => { if (!hasSelection || !selectedStats.canExclude) return setIsLoading(true) try { // TODO: 제외 API 호출 const excludableTargets = selectedTargets.filter(t => t.status === "PENDING") toast.success(`${excludableTargets.length}개 항목이 제외되었습니다.`) table.resetRowSelection() router.refresh() } catch (error) { console.error('Error excluding targets:', error) toast.error("제외 처리 중 오류가 발생했습니다.") } finally { setIsLoading(false) } } // ---------------------------------------------------------------- // 선택된 항목들 의견 요청 // ---------------------------------------------------------------- const handleRequestReview = async () => { if (!hasSelection || !selectedStats.canRequestReview) return // TODO: 의견 요청 다이얼로그 열기 toast.info("의견 요청 다이얼로그를 구현해주세요.") } // ---------------------------------------------------------------- // Excel 내보내기 // ---------------------------------------------------------------- const handleExport = () => { try { // TODO: Excel 내보내기 구현 toast.success("Excel 파일이 다운로드되었습니다.") } catch (error) { console.error('Error exporting to Excel:', error) toast.error("Excel 내보내기 중 오류가 발생했습니다.") } } // ---------------------------------------------------------------- // 새로고침 // ---------------------------------------------------------------- const handleRefresh = () => { if (onRefresh) { onRefresh() } else { router.refresh() } toast.success("데이터가 새로고침되었습니다.") } return ( <>
{/* 신규 생성 드롭다운 */} 자동 생성 (발주실적 기반) 수동 생성 {/* 유틸리티 버튼들 */}
{/* 선택된 항목 액션 버튼들 */} {hasSelection && (
{/* 확정 버튼 */} {selectedStats.canConfirm && ( )} {/* 제외 버튼 */} {selectedStats.canExclude && ( )} {/* 의견 요청 버튼 */} {selectedStats.canRequestReview && ( )}
)}
{/* 수동 생성 다이얼로그 */} {/* 선택 정보 표시 */} {hasSelection && (
선택된 {selectedRows.length}개 항목: 대기중 {selectedStats.pending}개, 확정 {selectedStats.confirmed}개, 제외 {selectedStats.excluded}개 {selectedStats.consensusTrue > 0 && ` | 의견일치 ${selectedStats.consensusTrue}개`} {selectedStats.consensusFalse > 0 && ` | 의견불일치 ${selectedStats.consensusFalse}개`}
)} ) }