"use client"; import React, { useState, useCallback } from "react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { ProcurementItemSelector } from "./procurement-item-selector"; import { ProcurementSearchItem } from "./procurement-item-service"; export interface ProcurementItemSelectorDialogSingleProps { triggerLabel?: string; triggerVariant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"; triggerSize?: "default" | "sm" | "lg" | "icon"; selectedProcurementItem?: ProcurementSearchItem | null; onProcurementItemSelect?: (item: ProcurementSearchItem | null) => void; title?: string; description?: string; showConfirmButtons?: boolean; disabled?: boolean; } /** * 품목 단일 선택 Dialog 컴포넌트 * * @description * - ProcurementItemSelector를 Dialog로 래핑한 단일 선택 컴포넌트 * - 버튼 클릭 시 Dialog가 열리고, 품목을 선택하면 Dialog가 닫히며 결과를 반환 * * @ProcurementSearchItem_Structure * 상태에서 관리되는 품목 객체의 형태: * ```typescript * interface ProcurementSearchItem { * itemCode: string; // 품목코드 * itemName: string; // 품목명 * material?: string; // 재질 * specification?: string; // 규격 * unit?: string; // 단위 * displayText: string; // 표시용 텍스트 (code + " - " + name) * } * ``` * * @state * - open: Dialog 열림/닫힘 상태 * - selectedProcurementItem: 현재 선택된 품목 (단일) * - tempSelectedProcurementItem: Dialog 내에서 임시로 선택된 품목 (확인 버튼 클릭 전까지) * * @callback * - onProcurementItemSelect: 품목 선택 완료 시 호출되는 콜백 * - 매개변수: ProcurementSearchItem | null * - 선택된 품목 정보 또는 null (선택 해제 시) * * @usage * ```tsx * { * console.log('선택된 품목:', item); * setSelectedProcurementItem(item); * }} * title="품목 선택" * description="품목을 검색하고 선택해주세요." * /> * ``` */ export function ProcurementItemSelectorDialogSingle({ triggerLabel = "1회성 품목 선택", triggerVariant = "outline", triggerSize = "default", selectedProcurementItem = null, onProcurementItemSelect, title = "1회성 품목 선택", description = "1회성 품목을 검색하고 선택해주세요.", showConfirmButtons = false, disabled = false, }: ProcurementItemSelectorDialogSingleProps) { const [open, setOpen] = useState(false); const [tempSelectedProcurementItem, setTempSelectedProcurementItem] = useState(selectedProcurementItem); // Dialog가 열릴 때 임시 선택 상태 초기화 const handleOpenChange = useCallback((newOpen: boolean) => { setOpen(newOpen); if (newOpen) { // Dialog 열 때 현재 선택된 값으로 임시 상태 초기화 setTempSelectedProcurementItem(selectedProcurementItem); } }, [selectedProcurementItem]); // 품목 선택 시 임시 상태 업데이트 const handleProcurementItemSelect = useCallback((item: ProcurementSearchItem | null) => { setTempSelectedProcurementItem(item); // 확인 버튼이 없는 경우 즉시 적용하고 Dialog 닫기 if (!showConfirmButtons) { onProcurementItemSelect?.(item); setOpen(false); } }, [onProcurementItemSelect, showConfirmButtons]); // 확인 버튼 클릭 시 선택 적용 const handleConfirm = useCallback(() => { onProcurementItemSelect?.(tempSelectedProcurementItem); setOpen(false); }, [onProcurementItemSelect, tempSelectedProcurementItem]); // 취소 버튼 클릭 시 Dialog 닫기 (변경사항 적용 안 함) const handleCancel = useCallback(() => { setOpen(false); }, []); // 선택 해제 const handleClear = useCallback(() => { const newSelection = null; setTempSelectedProcurementItem(newSelection); if (!showConfirmButtons) { onProcurementItemSelect?.(newSelection); setOpen(false); } }, [onProcurementItemSelect, showConfirmButtons]); return ( {title} {description}
{showConfirmButtons && ( )}
); }