import React, { useState } from 'react'; import { exportMaterialsToExcel, createExcelBlob } from '../../../utils/excelExport'; import api from '../../../api'; import { FilterableHeader } from '../shared'; const SupportMaterialsView = ({ materials, selectedMaterials, setSelectedMaterials, userRequirements, setUserRequirements, purchasedMaterials, fileId, user }) => { const [sortConfig, setSortConfig] = useState({ key: null, direction: 'asc' }); const [columnFilters, setColumnFilters] = useState({}); const [showFilterDropdown, setShowFilterDropdown] = useState(null); const parseSupportInfo = (material) => { const desc = material.original_description || ''; const isUrethaneBlock = desc.includes('URETHANE') || desc.includes('BLOCK SHOE') || desc.includes('우레탄'); const isClamp = desc.includes('CLAMP') || desc.includes('클램프'); let subtypeText = ''; if (isUrethaneBlock) { subtypeText = '우레탄블럭슈'; } else if (isClamp) { subtypeText = '클램프'; } else { subtypeText = '유볼트'; } return { type: 'SUPPORT', subtype: subtypeText, size: material.main_nom || material.size_inch || material.size_spec || '-', pressure: '-', // 서포트는 압력 등급 없음 schedule: '-', // 서포트는 스케줄 없음 description: material.original_description || '-', grade: material.full_material_grade || material.material_grade || '-', additionalReq: '-', quantity: Math.round(material.quantity || 0), unit: '개', isSupport: true }; }; // 정렬 처리 const handleSort = (key) => { let direction = 'asc'; if (sortConfig.key === key && sortConfig.direction === 'asc') { direction = 'desc'; } setSortConfig({ key, direction }); }; // 필터링된 및 정렬된 자재 목록 const getFilteredAndSortedMaterials = () => { let filtered = materials.filter(material => { return Object.entries(columnFilters).every(([key, filterValue]) => { if (!filterValue) return true; const info = parseSupportInfo(material); const value = info[key]?.toString().toLowerCase() || ''; return value.includes(filterValue.toLowerCase()); }); }); if (sortConfig && sortConfig.key) { filtered.sort((a, b) => { const aInfo = parseSupportInfo(a); const bInfo = parseSupportInfo(b); if (!aInfo || !bInfo) return 0; const aValue = aInfo[sortConfig.key]; const bValue = bInfo[sortConfig.key]; // 값이 없는 경우 처리 if (aValue === undefined && bValue === undefined) return 0; if (aValue === undefined) return 1; if (bValue === undefined) return -1; // 숫자인 경우 숫자로 비교 if (typeof aValue === 'number' && typeof bValue === 'number') { return sortConfig.direction === 'asc' ? aValue - bValue : bValue - aValue; } // 문자열로 비교 const aStr = String(aValue).toLowerCase(); const bStr = String(bValue).toLowerCase(); if (sortConfig.direction === 'asc') { return aStr.localeCompare(bStr); } else { return bStr.localeCompare(aStr); } }); } return filtered; }; // 전체 선택/해제 (구매신청된 자재 제외) const handleSelectAll = () => { const filteredMaterials = getFilteredAndSortedMaterials(); const selectableMaterials = filteredMaterials.filter(m => !purchasedMaterials.has(m.id)); if (selectedMaterials.size === selectableMaterials.length) { setSelectedMaterials(new Set()); } else { setSelectedMaterials(new Set(selectableMaterials.map(m => m.id))); } }; // 개별 선택 (구매신청된 자재는 선택 불가) const handleMaterialSelect = (materialId) => { if (purchasedMaterials.has(materialId)) { return; // 구매신청된 자재는 선택 불가 } const newSelected = new Set(selectedMaterials); if (newSelected.has(materialId)) { newSelected.delete(materialId); } else { newSelected.add(materialId); } setSelectedMaterials(newSelected); }; // 엑셀 내보내기 const handleExportToExcel = async () => { const selectedMaterialsData = materials.filter(m => selectedMaterials.has(m.id)); if (selectedMaterialsData.length === 0) { alert('내보낼 자재를 선택해주세요.'); return; } const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-'); const excelFileName = `SUPPORT_Materials_${timestamp}.xlsx`; const dataWithRequirements = selectedMaterialsData.map(material => ({ ...material, user_requirement: userRequirements[material.id] || '' })); try { await api.post('/files/save-excel', { file_id: fileId, category: 'SUPPORT', materials: dataWithRequirements, filename: excelFileName, user_id: user?.id }); exportMaterialsToExcel(dataWithRequirements, excelFileName, { category: 'SUPPORT', filename: excelFileName, uploadDate: new Date().toLocaleDateString() }); alert('엑셀 파일이 생성되고 서버에 저장되었습니다.'); } catch (error) { console.error('엑셀 저장 실패:', error); exportMaterialsToExcel(dataWithRequirements, excelFileName, { category: 'SUPPORT', filename: excelFileName, uploadDate: new Date().toLocaleDateString() }); } }; const filteredMaterials = getFilteredAndSortedMaterials(); return (
{/* 헤더 */}

Support Materials

{filteredMaterials.length} items • {selectedMaterials.size} selected

{/* 테이블 */}
{/* 헤더 */}
{ const selectableMaterials = filteredMaterials.filter(m => !purchasedMaterials.has(m.id)); return selectedMaterials.size === selectableMaterials.length && selectableMaterials.length > 0; })()} onChange={handleSelectAll} style={{ cursor: 'pointer' }} />
Type Size Pressure Schedule Material Grade Quantity
Unit
User Requirement
{/* 데이터 행들 */}
{filteredMaterials.map((material, index) => { const info = parseSupportInfo(material); const isSelected = selectedMaterials.has(material.id); const isPurchased = purchasedMaterials.has(material.id); return (
{ if (!isSelected && !isPurchased) { e.target.style.background = '#f8fafc'; } }} onMouseLeave={(e) => { if (!isSelected && !isPurchased) { e.target.style.background = 'white'; } }} >
handleMaterialSelect(material.id)} disabled={isPurchased} style={{ cursor: isPurchased ? 'not-allowed' : 'pointer', opacity: isPurchased ? 0.5 : 1 }} />
{info.subtype} {isPurchased && ( PURCHASED )}
{info.size}
{info.pressure}
{info.schedule}
{info.grade}
{info.quantity}
{info.unit}
setUserRequirements({ ...userRequirements, [material.id]: e.target.value })} placeholder="Enter requirement..." style={{ width: '100%', padding: '6px 8px', border: '1px solid #d1d5db', borderRadius: '4px', fontSize: '12px' }} />
); })}
{filteredMaterials.length === 0 && (
No Support Materials Found
{Object.keys(columnFilters).some(key => columnFilters[key]) ? 'Try adjusting your filters' : 'No support materials available in this BOM'}
)}
); }; export default SupportMaterialsView;