refactor: 품목기준관리 hooks 분리 및 다이얼로그 개선

- ItemMasterDataManagement 컴포넌트에서 hooks 분리
- 다이얼로그 컴포넌트들 타입 및 구조 개선
- BOMManagementSection 개선
- HierarchyTab 업데이트

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2025-11-26 14:06:48 +09:00
parent 593644922a
commit b73603822b
25 changed files with 3559 additions and 1703 deletions

View File

@@ -41,6 +41,13 @@ export function BOMManagementSection({
const [unit, setUnit] = useState('EA');
const [itemType, setItemType] = useState('part');
const [note, setNote] = useState('');
const [isSubmitted, setIsSubmitted] = useState(false);
// 유효성 검사
const isItemCodeEmpty = !itemCode.trim();
const isItemNameEmpty = !itemName.trim();
const qty = parseFloat(quantity);
const isQuantityInvalid = isNaN(qty) || qty <= 0;
const handleOpenDialog = (item?: BOMItem) => {
if (item) {
@@ -61,16 +68,25 @@ export function BOMManagementSection({
setNote('');
}
setIsDialogOpen(true);
setIsSubmitted(false);
};
const handleClose = () => {
setIsDialogOpen(false);
setEditingId(null);
setItemCode('');
setItemName('');
setQuantity('1');
setUnit('EA');
setItemType('part');
setNote('');
setIsSubmitted(false);
};
const handleSave = () => {
if (!itemCode.trim() || !itemName.trim()) {
return toast.error('품목코드와 품목명을 입력해주세요');
}
const qty = parseFloat(quantity);
if (isNaN(qty) || qty <= 0) {
return toast.error('올바른 수량을 입력해주세요');
setIsSubmitted(true);
if (isItemCodeEmpty || isItemNameEmpty || isQuantityInvalid) {
return;
}
const itemData = {
@@ -89,7 +105,7 @@ export function BOMManagementSection({
toast.success('BOM 품목이 추가되었습니다');
}
setIsDialogOpen(false);
handleClose();
};
const handleDelete = (id: number) => {
@@ -170,10 +186,7 @@ export function BOMManagementSection({
<Dialog
open={isDialogOpen}
onOpenChange={(open) => {
setIsDialogOpen(open);
if (!open) {
setEditingId(null);
}
if (!open) handleClose();
}}
>
<DialogContent className="max-w-2xl">
@@ -191,7 +204,11 @@ export function BOMManagementSection({
value={itemCode}
onChange={(e) => setItemCode(e.target.value)}
placeholder="예: PART-001"
className={isSubmitted && isItemCodeEmpty ? 'border-red-500 focus-visible:ring-red-500' : ''}
/>
{isSubmitted && isItemCodeEmpty && (
<p className="text-xs text-red-500 mt-1"> </p>
)}
</div>
<div>
<Label> *</Label>
@@ -199,7 +216,11 @@ export function BOMManagementSection({
value={itemName}
onChange={(e) => setItemName(e.target.value)}
placeholder="예: 샤프트"
className={isSubmitted && isItemNameEmpty ? 'border-red-500 focus-visible:ring-red-500' : ''}
/>
{isSubmitted && isItemNameEmpty && (
<p className="text-xs text-red-500 mt-1"> </p>
)}
</div>
</div>
@@ -213,7 +234,11 @@ export function BOMManagementSection({
placeholder="1"
min="0"
step="0.01"
className={isSubmitted && isQuantityInvalid ? 'border-red-500 focus-visible:ring-red-500' : ''}
/>
{isSubmitted && isQuantityInvalid && (
<p className="text-xs text-red-500 mt-1"> (0 )</p>
)}
</div>
<div>
<Label> *</Label>
@@ -257,9 +282,7 @@ export function BOMManagementSection({
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setIsDialogOpen(false)}>
</Button>
<Button variant="outline" onClick={handleClose}></Button>
<Button onClick={handleSave}></Button>
</DialogFooter>
</DialogContent>