import React, { useState, useEffect } from 'react'; import { Typography, Box, Card, CardContent, Button, TextField, Dialog, DialogTitle, DialogContent, DialogActions, Grid, Chip, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, CircularProgress, IconButton, FormControl, InputLabel, Select, MenuItem, Alert } from '@mui/material'; import { Add, Build, CheckCircle, Error, Visibility, Edit, Delete, MoreVert } from '@mui/icons-material'; import { fetchProjectSpools, validateSpoolIdentifier, generateSpoolIdentifier } from '../api'; import Toast from './Toast'; function SpoolManager({ selectedProject }) { const [spools, setSpools] = useState([]); const [loading, setLoading] = useState(false); const [dialogOpen, setDialogOpen] = useState(false); const [validationDialogOpen, setValidationDialogOpen] = useState(false); const [toast, setToast] = useState({ open: false, message: '', type: 'info' }); // 스풀 생성 폼 상태 const [newSpool, setNewSpool] = useState({ dwg_name: '', area_number: '', spool_number: '' }); // 유효성 검증 상태 const [validationResult, setValidationResult] = useState(null); const [validating, setValidating] = useState(false); useEffect(() => { if (selectedProject) { fetchSpools(); } else { setSpools([]); } }, [selectedProject]); const fetchSpools = async () => { if (!selectedProject) return; setLoading(true); try { const response = await fetchProjectSpools(selectedProject.id); if (response.data && response.data.spools) { setSpools(response.data.spools); } } catch (error) { console.error('스풀 조회 실패:', error); setToast({ open: true, message: '스풀 데이터를 불러오는데 실패했습니다.', type: 'error' }); } finally { setLoading(false); } }; const handleCreateSpool = async () => { if (!newSpool.dwg_name || !newSpool.area_number || !newSpool.spool_number) { setToast({ open: true, message: '도면명, 에리어 번호, 스풀 번호를 모두 입력해주세요.', type: 'warning' }); return; } setLoading(true); try { const response = await generateSpoolIdentifier( newSpool.dwg_name, newSpool.area_number, newSpool.spool_number ); if (response.data && response.data.success) { setToast({ open: true, message: '스풀이 성공적으로 생성되었습니다.', type: 'success' }); setDialogOpen(false); setNewSpool({ dwg_name: '', area_number: '', spool_number: '' }); fetchSpools(); // 목록 새로고침 } else { setToast({ open: true, message: response.data?.message || '스풀 생성에 실패했습니다.', type: 'error' }); } } catch (error) { console.error('스풀 생성 실패:', error); setToast({ open: true, message: '스풀 생성 중 오류가 발생했습니다.', type: 'error' }); } finally { setLoading(false); } }; const handleValidateSpool = async (identifier) => { setValidating(true); try { const response = await validateSpoolIdentifier(identifier); setValidationResult(response.data); setValidationDialogOpen(true); } catch (error) { console.error('스풀 유효성 검증 실패:', error); setToast({ open: true, message: '스풀 유효성 검증에 실패했습니다.', type: 'error' }); } finally { setValidating(false); } }; const getStatusColor = (status) => { switch (status) { case 'active': return 'success'; case 'inactive': return 'warning'; case 'completed': return 'info'; default: return 'default'; } }; if (!selectedProject) { return ( 🔧 스풀 관리 프로젝트를 선택해주세요 프로젝트 관리 탭에서 프로젝트를 선택하면 스풀을 관리할 수 있습니다. ); } return ( 🔧 스풀 관리 {selectedProject.project_name} ({selectedProject.official_project_code}) {/* 전역 Toast */} setToast({ open: false, message: '', type: 'info' })} /> {loading ? ( 스풀 데이터 로딩 중... ) : spools.length === 0 ? ( 스풀이 없습니다 새 스풀을 생성하여 시작하세요! ) : ( 총 {spools.length}개 스풀 스풀 식별자 도면명 에리어 스풀 번호 자재 수 총 수량 상태 작업 {spools.map((spool) => ( {spool.spool_identifier} {spool.dwg_name} {spool.area_number} {spool.spool_number} handleValidateSpool(spool.spool_identifier)} disabled={validating} > ))}
)} {/* 새 스풀 생성 다이얼로그 */} setDialogOpen(false)} maxWidth="sm" fullWidth> 새 스풀 생성 setNewSpool({ ...newSpool, dwg_name: e.target.value })} sx={{ mb: 2 }} /> setNewSpool({ ...newSpool, area_number: e.target.value })} sx={{ mb: 2 }} /> setNewSpool({ ...newSpool, spool_number: e.target.value })} /> {/* 스풀 유효성 검증 결과 다이얼로그 */} setValidationDialogOpen(false)} maxWidth="md" fullWidth> 스풀 유효성 검증 결과 {validationResult && ( {validationResult.validation.is_valid ? '유효한 스풀 식별자입니다.' : '유효하지 않은 스풀 식별자입니다.'} 스풀 식별자 {validationResult.spool_identifier} 검증 시간 {new Date(validationResult.timestamp).toLocaleString()} 검증 세부사항 {validationResult.validation.details && Object.entries(validationResult.validation.details).map(([key, value]) => ( )) } )}
); } export default SpoolManager;