diff options
Diffstat (limited to 'lib/basic-contract/gtc-vendor/gtc-clauses-table-floating-bar.tsx')
| -rw-r--r-- | lib/basic-contract/gtc-vendor/gtc-clauses-table-floating-bar.tsx | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/lib/basic-contract/gtc-vendor/gtc-clauses-table-floating-bar.tsx b/lib/basic-contract/gtc-vendor/gtc-clauses-table-floating-bar.tsx new file mode 100644 index 00000000..5b701df6 --- /dev/null +++ b/lib/basic-contract/gtc-vendor/gtc-clauses-table-floating-bar.tsx @@ -0,0 +1,239 @@ +"use client" + +import * as React from "react" +import { type Table } from "@tanstack/react-table" +import { + Edit, + Trash2, + ArrowUpDown, + Download, + Copy, + Wand2, + X +} from "lucide-react" + +import { Button } from "@/components/ui/button" +import { Separator } from "@/components/ui/separator" +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip" + +import { type GtcClauseTreeView } from "@/db/schema/gtc" +import { DeleteGtcClausesDialog } from "./delete-gtc-clauses-dialog" + +interface GtcClausesTableFloatingBarProps { + table: Table<GtcClauseTreeView> +} + +export function GtcClausesTableFloatingBar({ table }: GtcClausesTableFloatingBarProps) { + const selectedRows = table.getSelectedRowModel().rows + const selectedCount = selectedRows.length + + const [showDeleteDialog, setShowDeleteDialog] = React.useState(false) + + if (selectedCount === 0) return null + + const selectedClauses = selectedRows.map(row => row.original) + + const handleClearSelection = () => { + table.toggleAllRowsSelected(false) + } + + const handleBulkEdit = () => { + console.log("Bulk edit:", selectedClauses) + } + + const handleReorder = () => { + console.log("Reorder:", selectedClauses) + } + + const handleExport = () => { + console.log("Export:", selectedClauses) + } + + const handleDuplicate = () => { + console.log("Duplicate:", selectedClauses) + } + + const handleGenerateVariables = () => { + console.log("Generate variables:", selectedClauses) + } + + const canReorder = selectedClauses.every(clause => + clause.parentId === selectedClauses[0].parentId + ) + + const hasVariablesMissing = selectedClauses.some(clause => + !clause.hasAllVariableNames + ) + + return ( + <div className="fixed bottom-4 left-1/2 z-50 w-fit -translate-x-1/2"> + <div className="w-fit rounded-lg border bg-card p-2 shadow-2xl animate-in fade-in-0 slide-in-from-bottom-2"> + <div className="flex items-center gap-2"> + {/* 선택된 항목 수 */} + <div className="flex items-center gap-2 px-2"> + <span className="text-sm font-medium"> + {selectedCount}개 선택됨 + </span> + </div> + + <Separator orientation="vertical" className="h-6" /> + + {/* 액션 버튼들 */} + <div className="flex items-center gap-1"> + {/* 일괄 수정 */} + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="ghost" + size="sm" + onClick={handleBulkEdit} + > + <Edit className="h-4 w-4" /> + </Button> + </TooltipTrigger> + <TooltipContent> + <p>선택한 조항들을 일괄 수정</p> + </TooltipContent> + </Tooltip> + </TooltipProvider> + + {/* 순서 변경 (같은 부모의 조항들만) */} + {canReorder && ( + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="ghost" + size="sm" + onClick={handleReorder} + > + <ArrowUpDown className="h-4 w-4" /> + </Button> + </TooltipTrigger> + <TooltipContent> + <p>선택한 조항들의 순서 변경</p> + </TooltipContent> + </Tooltip> + </TooltipProvider> + )} + + {/* 복제 */} + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="ghost" + size="sm" + onClick={handleDuplicate} + > + <Copy className="h-4 w-4" /> + </Button> + </TooltipTrigger> + <TooltipContent> + <p>선택한 조항들을 복제</p> + </TooltipContent> + </Tooltip> + </TooltipProvider> + + {/* 변수명 생성 (변수가 없는 조항이 있을 때만) */} + {hasVariablesMissing && ( + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="ghost" + size="sm" + onClick={handleGenerateVariables} + > + <Wand2 className="h-4 w-4" /> + </Button> + </TooltipTrigger> + <TooltipContent> + <p>선택한 조항들의 PDFTron 변수명 생성</p> + </TooltipContent> + </Tooltip> + </TooltipProvider> + )} + + {/* 내보내기 */} + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="ghost" + size="sm" + onClick={handleExport} + > + <Download className="h-4 w-4" /> + </Button> + </TooltipTrigger> + <TooltipContent> + <p>선택한 조항들을 Excel로 내보내기</p> + </TooltipContent> + </Tooltip> + </TooltipProvider> + </div> + + <Separator orientation="vertical" className="h-6" /> + + {/* 삭제 버튼 */} + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="ghost" + size="sm" + onClick={() => setShowDeleteDialog(true)} + className="text-destructive hover:text-destructive" + > + <Trash2 className="h-4 w-4" /> + </Button> + </TooltipTrigger> + <TooltipContent> + <p>선택한 조항들을 삭제</p> + </TooltipContent> + </Tooltip> + </TooltipProvider> + + <Separator orientation="vertical" className="h-6" /> + + {/* 선택 해제 버튼 */} + <TooltipProvider> + <Tooltip> + <TooltipTrigger asChild> + <Button + variant="ghost" + size="sm" + onClick={handleClearSelection} + > + <X className="h-4 w-4" /> + </Button> + </TooltipTrigger> + <TooltipContent> + <p>선택 해제</p> + </TooltipContent> + </Tooltip> + </TooltipProvider> + </div> + </div> + + {/* 삭제 다이얼로그 */} + <DeleteGtcClausesDialog + open={showDeleteDialog} + onOpenChange={setShowDeleteDialog} + gtcClauses={selectedClauses} + showTrigger={false} + onSuccess={() => { + table.toggleAllRowsSelected(false) + setShowDeleteDialog(false) + }} + /> + </div> + ) +}
\ No newline at end of file |
