summaryrefslogtreecommitdiff
path: root/lib/avl/table/avl-detail-table.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/avl/table/avl-detail-table.tsx')
-rw-r--r--lib/avl/table/avl-detail-table.tsx127
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>
{/* 데이터 테이블 */}