"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 { MaterialGroupSelector } from "./material-group-selector"; import { MaterialSearchItem } from "@/lib/material/material-group-service"; /** * 자재그룹 단일 선택 Dialog 컴포넌트 * * @description * - MaterialGroupSelector를 Dialog로 래핑한 단일 선택 컴포넌트 * - 버튼 클릭 시 Dialog가 열리고, 자재를 선택하면 Dialog가 닫히며 결과를 반환 * * @MaterialSearchItem_Structure * 상태에서 관리되는 자재그룹 객체의 형태: * ```typescript * interface MaterialSearchItem { * materialGroupCode: string; // 자재그룹코드 (예: "BG2001") * materialGroupDescription: string; // 자재그룹명 (예: "DOUBLE WETDOOR HINGE") * materialGroupUom?: string; // 단위 (예: "EA", "KG") * displayText: string; // 표시용 텍스트 (code + " - " + description) * } * ``` * * @state * - open: Dialog 열림/닫힘 상태 * - selectedMaterial: 현재 선택된 자재 (단일) * - tempSelectedMaterial: Dialog 내에서 임시로 선택된 자재 (확인 버튼 클릭 전까지) * * @callback * - onMaterialSelect: 자재 선택 완료 시 호출되는 콜백 * - 매개변수: MaterialSearchItem | null * - 선택된 자재 정보 또는 null (선택 해제 시) * * @usage * ```tsx * { * setSelectedMaterial(material); * console.log('선택된 자재:', material); * }} * placeholder="자재를 검색하세요..." * /> * ``` */ interface MaterialGroupSelectorDialogSingleProps { /** Dialog를 여는 트리거 버튼 텍스트 */ triggerLabel?: string; /** 현재 선택된 자재 */ selectedMaterial?: MaterialSearchItem | null; /** 자재 선택 완료 시 호출되는 콜백 */ onMaterialSelect?: (material: MaterialSearchItem | null) => void; /** 검색 입력창 placeholder */ placeholder?: string; /** Dialog 제목 */ title?: string; /** Dialog 설명 */ description?: string; /** 트리거 버튼 비활성화 여부 */ disabled?: boolean; /** 트리거 버튼 variant */ triggerVariant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"; /** 제외할 자재그룹코드들 */ excludeMaterialCodes?: Set; /** 초기 데이터 표시 여부 */ showInitialData?: boolean; } export function MaterialGroupSelectorDialogSingle({ triggerLabel = "자재 선택", selectedMaterial = null, onMaterialSelect, placeholder = "자재를 검색하세요...", title = "자재 선택", description = "원하는 자재를 검색하고 선택해주세요.", disabled = false, triggerVariant = "outline", excludeMaterialCodes, showInitialData = true, }: MaterialGroupSelectorDialogSingleProps) { // Dialog 열림/닫힘 상태 const [open, setOpen] = useState(false); // Dialog 내에서 임시로 선택된 자재 (확인 버튼 클릭 전까지) const [tempSelectedMaterial, setTempSelectedMaterial] = useState(null); // Dialog 열림 시 현재 선택된 자재로 임시 선택 초기화 const handleOpenChange = useCallback((newOpen: boolean) => { setOpen(newOpen); if (newOpen) { setTempSelectedMaterial(selectedMaterial || null); } }, [selectedMaterial]); // 자재 선택 처리 (Dialog 내에서) const handleMaterialChange = useCallback((materials: MaterialSearchItem[]) => { setTempSelectedMaterial(materials.length > 0 ? materials[0] : null); }, []); // 확인 버튼 클릭 시 선택 완료 const handleConfirm = useCallback(() => { onMaterialSelect?.(tempSelectedMaterial); setOpen(false); }, [tempSelectedMaterial, onMaterialSelect]); // 취소 버튼 클릭 시 const handleCancel = useCallback(() => { setTempSelectedMaterial(selectedMaterial || null); setOpen(false); }, [selectedMaterial]); // 선택 해제 const handleClear = useCallback(() => { setTempSelectedMaterial(null); }, []); return ( {title} {description}
{tempSelectedMaterial && ( )}
); } /** * 사용 예시: * * ```tsx * const [selectedMaterial, setSelectedMaterial] = useState(null); * * return ( * { * setSelectedMaterial(material); * if (material) { * console.log('선택된 자재:', { * code: material.materialGroupCode, * description: material.materialGroupDescription, * uom: material.materialGroupUom * }); * } else { * console.log('자재 선택이 해제되었습니다.'); * } * }} * title="자재 선택" * description="필요한 자재를 검색하고 선택해주세요." * /> * ); * ``` */