'use client'; /** * 재고현황 상세 페이지 * IntegratedDetailTemplate 마이그레이션 완료 (2026-01-20) * API 연동 버전 (2025-12-26) */ import { useState, useMemo, useCallback, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { AlertCircle } from 'lucide-react'; import { Badge } from '@/components/ui/badge'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate'; import { stockStatusConfig } from './stockStatusConfig'; import { ServerErrorPage } from '@/components/common/ServerErrorPage'; import { getStockById } from './actions'; import { ITEM_TYPE_LABELS, ITEM_TYPE_STYLES, STOCK_STATUS_LABELS, LOT_STATUS_LABELS, } from './types'; import type { StockDetail, LotDetail } from './types'; import { isNextRedirectError } from '@/lib/utils/redirect-error'; interface StockStatusDetailProps { id: string; } export function StockStatusDetail({ id }: StockStatusDetailProps) { const router = useRouter(); // API 데이터 상태 const [detail, setDetail] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // API 데이터 로드 const loadData = useCallback(async () => { setIsLoading(true); setError(null); try { const result = await getStockById(id); if (result.success && result.data) { setDetail(result.data); } else { setError(result.error || '재고 정보를 찾을 수 없습니다.'); } } catch (err) { if (isNextRedirectError(err)) throw err; console.error('[StockStatusDetail] loadData error:', err); setError('데이터를 불러오는 중 오류가 발생했습니다.'); } finally { setIsLoading(false); } }, [id]); // 데이터 로드 useEffect(() => { loadData(); }, [loadData]); // 가장 오래된 LOT 찾기 (FIFO 권장용) const oldestLot = useMemo(() => { if (!detail || detail.lots.length === 0) return null; return detail.lots.reduce((oldest, lot) => lot.daysElapsed > oldest.daysElapsed ? lot : oldest ); }, [detail]); // 총 수량 계산 const totalQty = useMemo(() => { if (!detail) return 0; return detail.lots.reduce((sum, lot) => sum + lot.qty, 0); }, [detail]); // 커스텀 헤더 액션 (품목코드와 상태 뱃지) const customHeaderActions = useMemo(() => { if (!detail) return null; return ( <> {detail.itemCode} {STOCK_STATUS_LABELS[detail.status]} ); }, [detail]); // 폼 콘텐츠 렌더링 const renderFormContent = useCallback(() => { if (!detail) return null; return (
{/* 기본 정보 */} 기본 정보
품목코드
{detail.itemCode}
품목명
{detail.itemName}
품목유형
{ITEM_TYPE_LABELS[detail.itemType]}
카테고리
{detail.category}
규격
{detail.specification || '-'}
단위
{detail.unit}
{/* 재고 현황 */} 재고 현황
현재 재고량
{detail.currentStock} {detail.unit}
안전 재고
{detail.safetyStock} {detail.unit}
재고 위치
{detail.location}
LOT 개수
{detail.lotCount}개
최근 입고일
{detail.lastReceiptDate}
재고 상태
{STOCK_STATUS_LABELS[detail.status]}
{/* LOT별 상세 재고 */}
LOT별 상세 재고
FIFO 순서 · 오래된 LOT부터 사용 권장
FIFO LOT번호 입고일 경과일 공급업체 발주번호 수량 위치 상태 {detail.lots.map((lot: LotDetail) => (
{lot.fifoOrder}
{lot.lotNo} {lot.receiptDate} 30 ? 'text-orange-600 font-medium' : ''}> {lot.daysElapsed}일 {lot.supplier} {lot.poNumber} {lot.qty} {lot.unit} {lot.location} {LOT_STATUS_LABELS[lot.status]}
))} {/* 합계 행 */} 합계: {totalQty} {detail.unit}
{/* FIFO 권장 메시지 */} {oldestLot && oldestLot.daysElapsed > 30 && (
FIFO 권장: LOT {oldestLot.lotNo}가{' '} {oldestLot.daysElapsed}일 경과되었습니다. 우선 사용을 권장합니다.
)}
); }, [detail, totalQty, oldestLot]); // 에러 상태 표시 if (!isLoading && (error || !detail)) { return ( ); } return ( renderFormContent()} renderForm={() => renderFormContent()} /> ); }