diff options
Diffstat (limited to 'lib/avl/table/avl-detail-table.tsx')
| -rw-r--r-- | lib/avl/table/avl-detail-table.tsx | 127 |
1 files changed, 96 insertions, 31 deletions
diff --git a/lib/avl/table/avl-detail-table.tsx b/lib/avl/table/avl-detail-table.tsx index 04384ec8..4408340a 100644 --- a/lib/avl/table/avl-detail-table.tsx +++ b/lib/avl/table/avl-detail-table.tsx @@ -6,42 +6,92 @@ import { useDataTable } from "@/hooks/use-data-table" import { DataTable } from "@/components/data-table/data-table" import { Button } from "@/components/ui/button" import { toast } from "sonner" +import { createAvlRfqItbAction, prepareAvlRfqItbInput } from "../avl-itb-rfq-service" -import { columns, type AvlDetailItem } from "./columns-detail" +import { columns } from "./columns-detail" +import type { AvlDetailItem } from "../types" +import { BackButton } from "@/components/ui/back-button" +import { useSession } from "next-auth/react" interface AvlDetailTableProps { data: AvlDetailItem[] pageCount?: number avlType?: '프로젝트AVL' | '선종별표준AVL' // AVL 타입 - projectCode?: string // 프로젝트 코드 - shipOwnerName?: string // 선주명 + projectInfo?: { + code?: string + pspid?: string + OWN_NM?: string + kunnrNm?: string + } // 프로젝트 정보 businessType?: string // 사업 유형 (예: 조선/해양) } export function AvlDetailTable({ data, pageCount, - avlType = '프로젝트AVL', - projectCode, - shipOwnerName, - businessType = '조선' + avlType, + projectInfo, + businessType, }: AvlDetailTableProps) { + // 견적요청 처리 상태 관리 + const [isProcessingQuote, setIsProcessingQuote] = React.useState(false) + const { data: session } = useSession() + + // 견적요청 처리 함수 + const handleQuoteRequest = React.useCallback(async () => { + if (!businessType || !['조선', '해양'].includes(businessType)) { + toast.error("공사구분이 올바르지 않습니다. 견적요청 처리 불가.") + return + } + + if (data.length === 0) { + toast.error("견적요청할 AVL 데이터가 없습니다.") + return + } + + setIsProcessingQuote(true) + + try { + // 현재 사용자 세션에서 ID 가져오기 + const currentUserId = session?.user?.id ? Number(session.user.id) : undefined + + // 견적요청 입력 데이터 준비 (전체 데이터를 사용) + const quoteInput = await prepareAvlRfqItbInput( + data, // 전체 데이터를 사용 + businessType as '조선' | '해양', + { + picUserId: currentUserId, + rfqTitle: `${businessType} AVL 견적요청 - ${data[0]?.materialNameCustomerSide || 'AVL 아이템'}${data.length > 1 ? ` 외 ${data.length - 1}건` : ''}` + } + ) + + // 견적요청 실행 + const result = await createAvlRfqItbAction(quoteInput) + + if (result.success) { + toast.success(`${result.data?.type}가 성공적으로 생성되었습니다. (코드: ${result.data?.rfqCode})`) + } else { + toast.error(result.error || "견적요청 처리 중 오류가 발생했습니다.") + } + + } catch (error) { + console.error('견적요청 처리 오류:', error) + toast.error("견적요청 처리 중 오류가 발생했습니다.") + } finally { + setIsProcessingQuote(false) + } + }, [businessType, data, session?.user?.id]) + // 액션 핸들러 const handleAction = React.useCallback(async (action: string) => { switch (action) { - case 'avl-form': - toast.info("AVL 양식을 준비 중입니다.") - // TODO: AVL 양식 다운로드 로직 구현 - break case 'quote-request': - toast.info("견적 요청을 처리 중입니다.") - // TODO: 견적 요청 로직 구현 + await handleQuoteRequest() break case 'vendor-pool': - toast.info("Vendor Pool을 열고 있습니다.") - // TODO: Vendor Pool 페이지 이동 또는 모달 열기 로직 구현 + window.open('/evcp/vendor-pool', '_blank') break case 'download': @@ -49,13 +99,18 @@ export function AvlDetailTable({ // TODO: 데이터 다운로드 로직 구현 break + case 'avl-form': + toast.info("AVL 양식을 준비 중입니다.") + // TODO: AVL 양식 다운로드 로직 구현 + break + default: toast.error(`알 수 없는 액션: ${action}`) } - }, []) + }, [handleQuoteRequest]) - // 테이블 메타 설정 (읽기 전용) + // 테이블 메타 설정 const tableMeta = React.useMemo(() => ({ onAction: handleAction, }), [handleAction]) @@ -76,36 +131,46 @@ export function AvlDetailTable({ meta: tableMeta, }) - return ( <div className="space-y-4"> {/* 상단 정보 표시 영역 */} - <div className="flex items-center justify-between p-4 bg-muted/50 rounded-lg"> + <div className="flex items-center justify-between p-4"> <div className="flex items-center gap-4"> <h2 className="text-lg font-semibold">AVL 상세내역</h2> - <span className="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium"> + <span className="px-3 py-1 bg-secondary-foreground text-secondary-foreground-foreground rounded-full text-sm font-medium"> {avlType} </span> + <span className="text-sm text-muted-foreground"> - [{businessType}] {projectCode || '프로젝트코드'} ({shipOwnerName || '선주명'}) + [{businessType}] {projectInfo?.code || projectInfo?.pspid || '코드정보없음(표준AVL)'} ({projectInfo?.OWN_NM || projectInfo?.kunnrNm || '선주정보 없음'}) </span> </div> + + <div className="justify-end"> + <BackButton>목록으로</BackButton> + </div> </div> {/* 상단 버튼 영역 */} - <div className="flex items-center gap-2"> - <Button variant="outline" size="sm" onClick={() => handleAction('avl-form')}> - AVL양식 - </Button> - <Button variant="outline" size="sm" onClick={() => handleAction('quote-request')}> - 견적요청 - </Button> + <div className="flex items-center gap-2 ml-auto justify-end"> + { + // 표준AVL로는 견적요청하지 않으며, 프로젝트 AVL로만 견적요청처리 + avlType === '프로젝트AVL' && businessType && ['조선', '해양'].includes(businessType) && + <Button + variant="outline" + size="sm" + onClick={() => handleAction('quote-request')} + disabled={data.length === 0 || isProcessingQuote} + > + {isProcessingQuote ? '처리중...' : `${businessType} 견적요청 (${businessType === '조선' ? 'RFQ' : 'ITB'})`} + </Button> + } + + {/* 단순 이동 버튼 */} <Button variant="outline" size="sm" onClick={() => handleAction('vendor-pool')}> Vendor Pool </Button> - <Button variant="outline" size="sm" onClick={() => handleAction('download')}> - 다운로드 - </Button> + </div> {/* 데이터 테이블 */} |
