summaryrefslogtreecommitdiff
path: root/lib/b-rfq/initial/initial-rfq-detail-toolbar-actions.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/b-rfq/initial/initial-rfq-detail-toolbar-actions.tsx')
-rw-r--r--lib/b-rfq/initial/initial-rfq-detail-toolbar-actions.tsx287
1 files changed, 0 insertions, 287 deletions
diff --git a/lib/b-rfq/initial/initial-rfq-detail-toolbar-actions.tsx b/lib/b-rfq/initial/initial-rfq-detail-toolbar-actions.tsx
deleted file mode 100644
index c26bda28..00000000
--- a/lib/b-rfq/initial/initial-rfq-detail-toolbar-actions.tsx
+++ /dev/null
@@ -1,287 +0,0 @@
-"use client"
-
-import * as React from "react"
-import { type Table } from "@tanstack/react-table"
-import { useRouter } from "next/navigation"
-import { toast } from "sonner"
-import { Button } from "@/components/ui/button"
-import {
- Download,
- Mail,
- RefreshCw,
- Settings,
- Trash2,
- FileText,
- CheckCircle2,
- Loader
-} from "lucide-react"
-import { AddInitialRfqDialog } from "./add-initial-rfq-dialog"
-import { DeleteInitialRfqDialog } from "./delete-initial-rfq-dialog"
-import { ShortListConfirmDialog } from "./short-list-confirm-dialog"
-import { InitialRfqDetailView } from "@/db/schema"
-import { sendBulkInitialRfqEmails } from "../service"
-
-interface InitialRfqDetailTableToolbarActionsProps {
- table: Table<InitialRfqDetailView>
- rfqId?: number
- onRefresh?: () => void // 데이터 새로고침 콜백
-}
-
-export function InitialRfqDetailTableToolbarActions({
- table,
- rfqId,
- onRefresh
-}: InitialRfqDetailTableToolbarActionsProps) {
- const router = useRouter()
-
- // 선택된 행들 가져오기
- const selectedRows = table.getFilteredSelectedRowModel().rows
- const selectedDetails = selectedRows.map((row) => row.original)
- const selectedCount = selectedRows.length
-
- // 상태 관리
- const [showDeleteDialog, setShowDeleteDialog] = React.useState(false)
- const [showShortListDialog, setShowShortListDialog] = React.useState(false)
- const [isEmailSending, setIsEmailSending] = React.useState(false)
-
- // 전체 벤더 리스트 가져오기 (ShortList 확정용)
- const allVendors = table.getRowModel().rows.map(row => row.original)
-
-const handleBulkEmail = async () => {
- if (selectedCount === 0) return
-
- setIsEmailSending(true)
-
- try {
- const initialRfqIds = selectedDetails
- .map(detail => detail.initialRfqId)
- .filter((id): id is number => id !== null);
-
- if (initialRfqIds.length === 0) {
- toast.error("유효한 RFQ ID가 없습니다.")
- return
- }
-
- const result = await sendBulkInitialRfqEmails({
- initialRfqIds,
- language: "en" // 기본 영어, 필요시 사용자 설정으로 변경
- })
-
- if (result.success) {
- toast.success(result.message)
-
- // 에러가 있다면 별도 알림
- if (result.errors && result.errors.length > 0) {
- setTimeout(() => {
- toast.warning(`일부 오류 발생: ${result.errors?.join(', ')}`)
- }, 1000)
- }
-
- // 선택 해제
- table.toggleAllRowsSelected(false)
-
- // 데이터 새로고침
- if (onRefresh) {
- onRefresh()
- }
- } else {
- toast.error(result.message || "RFQ 발송에 실패했습니다.")
- }
-
- } catch (error) {
- console.error("Email sending error:", error)
- toast.error("RFQ 발송 중 오류가 발생했습니다.")
- } finally {
- setIsEmailSending(false)
- }
- }
-
- const handleBulkDelete = () => {
- // DRAFT가 아닌 상태의 RFQ 확인
- const nonDraftRfqs = selectedDetails.filter(
- detail => detail.initialRfqStatus !== "DRAFT"
- )
-
- if (nonDraftRfqs.length > 0) {
- const statusMessages = {
- "Init. RFQ Sent": "이미 발송된",
- "S/L Decline": "Short List 거절 처리된",
- "Init. RFQ Answered": "답변 완료된"
- }
-
- const nonDraftStatuses = [...new Set(nonDraftRfqs.map(rfq => rfq.initialRfqStatus))]
- const statusText = nonDraftStatuses
- .map(status => statusMessages[status as keyof typeof statusMessages] || status)
- .join(", ")
-
- toast.error(
- `${statusText} RFQ는 삭제할 수 없습니다. DRAFT 상태의 RFQ만 삭제 가능합니다.`
- )
- return
- }
-
- setShowDeleteDialog(true)
- }
-
- // S/L 확정 버튼 클릭
- const handleSlConfirm = () => {
- if (!rfqId || allVendors.length === 0) {
- toast.error("S/L 확정할 벤더가 없습니다.")
- return
- }
-
- // 진행 가능한 상태 확인
- const validVendors = allVendors.filter(vendor =>
- vendor.initialRfqStatus === "Init. RFQ Answered" ||
- vendor.initialRfqStatus === "Init. RFQ Sent"
- )
-
- if (validVendors.length === 0) {
- toast.error("S/L 확정이 가능한 벤더가 없습니다. (RFQ 발송 또는 응답 완료된 벤더만 가능)")
- return
- }
-
- setShowShortListDialog(true)
- }
-
- // 초기 RFQ 추가 성공 시 처리
- const handleAddSuccess = () => {
- // 선택 해제
- table.toggleAllRowsSelected(false)
-
- // 데이터 새로고침
- if (onRefresh) {
- onRefresh()
- } else {
- // fallback으로 페이지 새로고침
- setTimeout(() => {
- window.location.reload()
- }, 1000)
- }
- }
-
- // 삭제 성공 시 처리
- const handleDeleteSuccess = () => {
- // 선택 해제
- table.toggleAllRowsSelected(false)
- setShowDeleteDialog(false)
-
- // 데이터 새로고침
- if (onRefresh) {
- onRefresh()
- }
- }
-
- // Short List 확정 성공 시 처리
- const handleShortListSuccess = () => {
- // 선택 해제
- table.toggleAllRowsSelected(false)
- setShowShortListDialog(false)
-
- // 데이터 새로고침
- if (onRefresh) {
- onRefresh()
- }
-
- // 최종 RFQ 페이지로 이동
- if (rfqId) {
- toast.success("Short List가 확정되었습니다. 최종 RFQ 페이지로 이동합니다.")
- setTimeout(() => {
- router.push(`/evcp/b-rfq/${rfqId}`)
- }, 1500)
- }
- }
-
- // 선택된 항목 중 첫 번째를 기본값으로 사용
- const defaultValues = selectedCount > 0 ? selectedDetails[0] : undefined
-
- const canDelete = selectedDetails.every(detail => detail.initialRfqStatus === "DRAFT")
- const draftCount = selectedDetails.filter(detail => detail.initialRfqStatus === "DRAFT").length
-
- // S/L 확정 가능한 벤더 수
- const validForShortList = allVendors.filter(vendor =>
- vendor.initialRfqStatus === "Init. RFQ Answered" ||
- vendor.initialRfqStatus === "Init. RFQ Sent"
- ).length
-
- return (
- <>
- <div className="flex items-center gap-2">
- {/** 선택된 항목이 있을 때만 표시되는 액션들 */}
- {selectedCount > 0 && (
- <>
- <Button
- variant="outline"
- size="sm"
- onClick={handleBulkEmail}
- className="h-8"
- disabled={isEmailSending}
- >
- {isEmailSending ? <Loader className="mr-2 h-4 w-4 animate-spin" /> : <Mail className="mr-2 h-4 w-4" />}
- RFQ 발송 ({selectedCount})
- </Button>
-
- <Button
- variant="outline"
- size="sm"
- onClick={handleBulkDelete}
- className="h-8 text-red-600 hover:text-red-700"
- disabled={!canDelete || selectedCount === 0}
- title={!canDelete ? "DRAFT 상태의 RFQ만 삭제할 수 있습니다" : ""}
- >
- <Trash2 className="mr-2 h-4 w-4" />
- 삭제 ({draftCount}/{selectedCount})
- </Button>
- </>
- )}
-
- {/* S/L 확정 버튼 */}
- {rfqId && (
- <Button
- variant="default"
- size="sm"
- onClick={handleSlConfirm}
- className="h-8"
- disabled={validForShortList === 0}
- title={validForShortList === 0 ? "S/L 확정이 가능한 벤더가 없습니다" : `${validForShortList}개 벤더 중 Short List 선택`}
- >
- <CheckCircle2 className="mr-2 h-4 w-4" />
- S/L 확정 ({validForShortList})
- </Button>
- )}
-
- {/* 초기 RFQ 추가 버튼 */}
- {rfqId && (
- <AddInitialRfqDialog
- rfqId={rfqId}
- onSuccess={handleAddSuccess}
- defaultValues={defaultValues}
- />
- )}
- </div>
-
- {/* 삭제 다이얼로그 */}
- <DeleteInitialRfqDialog
- open={showDeleteDialog}
- onOpenChange={setShowDeleteDialog}
- initialRfqs={selectedDetails}
- showTrigger={false}
- onSuccess={handleDeleteSuccess}
- />
-
- {/* Short List 확정 다이얼로그 */}
- {rfqId && (
- <ShortListConfirmDialog
- open={showShortListDialog}
- onOpenChange={setShowShortListDialog}
- rfqId={rfqId}
- vendors={allVendors.filter(vendor =>
- vendor.initialRfqStatus === "Init. RFQ Answered" ||
- vendor.initialRfqStatus === "Init. RFQ Sent"
- )}
- onSuccess={handleShortListSuccess}
- />
- )}
- </>
- )
-} \ No newline at end of file