"use client" import * as React from "react" import { Table } from "@tanstack/react-table" import { toast } from "sonner" import { Calendar, type CalendarProps } from "@/components/ui/calendar" import { Button } from "@/components/ui/button" import { Portal } from "@/components/ui/portal" import { Select, SelectTrigger, SelectContent, SelectGroup, SelectItem, SelectValue, } from "@/components/ui/select" import { Separator } from "@/components/ui/separator" import { Tooltip, TooltipTrigger, TooltipContent, } from "@/components/ui/tooltip" import { Kbd } from "@/components/kbd" import { ActionConfirmDialog } from "@/components/ui/action-dialog" import { ArrowUp, CheckCircle2, Download, Loader, Trash2, X, CalendarIcon } from "lucide-react" import { exportTableToExcel } from "@/lib/export" import { RfqWithItemCount, rfqs } from "@/db/schema/rfq" import { modifyRfqs, removeRfqs } from "../service" interface RfqsTableFloatingBarProps { table: Table } /** * 추가된 로직: * - 달력(캘린더) 아이콘 버튼 * - 눌렀을 때 Popover로 Calendar 표시 * - 날짜 선택 시 Confirm 다이얼로그 → modifyRfqs({ dueDate }) */ export function RfqsTableFloatingBar({ table }: RfqsTableFloatingBarProps) { const rows = table.getFilteredSelectedRowModel().rows const [isPending, startTransition] = React.useTransition() const [action, setAction] = React.useState<"update-status" | "export" | "delete" | "update-dueDate">() const [confirmDialogOpen, setConfirmDialogOpen] = React.useState(false) const [confirmProps, setConfirmProps] = React.useState<{ title: string description?: string onConfirm: () => Promise | void }>({ title: "", description: "", onConfirm: () => {}, }) // 캘린더 Popover 열림 여부 const [calendarOpen, setCalendarOpen] = React.useState(false) const [selectedDate, setSelectedDate] = React.useState(null) // Clear selection on Escape key press React.useEffect(() => { function handleKeyDown(event: KeyboardEvent) { if (event.key === "Escape") { table.toggleAllRowsSelected(false) } } window.addEventListener("keydown", handleKeyDown) return () => window.removeEventListener("keydown", handleKeyDown) }, [table]) function handleDeleteConfirm() { setAction("delete") setConfirmProps({ title: `Delete ${rows.length} RFQ${rows.length > 1 ? "s" : ""}?`, description: "This action cannot be undone.", onConfirm: async () => { startTransition(async () => { const { error } = await removeRfqs({ ids: rows.map((row) => row.original.rfqId), }) if (error) { toast.error(error) return } toast.success("RFQs deleted") table.toggleAllRowsSelected(false) setConfirmDialogOpen(false) }) }, }) setConfirmDialogOpen(true) } function handleSelectStatus(newStatus: RfqWithItemCount["status"]) { setAction("update-status") setConfirmProps({ title: `Update ${rows.length} RFQ${rows.length > 1 ? "s" : ""} with status: ${newStatus}?`, description: "This action will override their current status.", onConfirm: async () => { startTransition(async () => { const { error } = await modifyRfqs({ ids: rows.map((row) => row.original.rfqId), status: newStatus as "DRAFT" | "PUBLISHED" | "EVALUATION" | "AWARDED", }) if (error) { toast.error(error) return } toast.success("RFQs updated") setConfirmDialogOpen(false) }) }, }) setConfirmDialogOpen(true) } // 1) 달력에서 날짜를 선택했을 때 → Confirm 다이얼로그 function handleDueDateSelect(newDate: Date) { setAction("update-dueDate") setConfirmProps({ title: `Update ${rows.length} RFQ${rows.length > 1 ? "s" : ""} Due Date to ${newDate.toDateString()}?`, description: "This action will override their current due date.", onConfirm: async () => { startTransition(async () => { const { error } = await modifyRfqs({ ids: rows.map((r) => r.original.rfqId), dueDate: newDate, }) if (error) { toast.error(error) return } toast.success("Due date updated") setConfirmDialogOpen(false) setCalendarOpen(false) }) }, }) setConfirmDialogOpen(true) } // 2) Export function handleExport() { setAction("export") startTransition(() => { exportTableToExcel(table, { excludeColumns: ["select", "actions"], onlySelected: true, }) }) } // Floating bar UI return (
{/* Selection Info + Clear */}
{rows.length} selected

Clear selection

Esc
{/* 1) Status Update */} {/* 2) Due Date Update: Calendar Popover */}

Update Due Date

{/* Calendar Popover (간단 구현) */} {calendarOpen && (
{ if (date) { setSelectedDate(date) handleDueDateSelect(date) } }} initialFocus />
)} {/* 3) Export */}

Export tasks

{/* 4) Delete */}

Delete tasks

{/* 공용 Confirm Dialog */}
) }