import React, { useState, useEffect } from 'react'; import { Dialog, DialogTitle, DialogContent, DialogActions, Button, TextField, Grid, Box, Typography, MenuItem, IconButton, Avatar, Alert } from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; import DeleteIcon from '@mui/icons-material/Delete'; import CloseIcon from '@mui/icons-material/Close'; import { onCreateNewComponent, onGetDetailsForNewComponent } from '../pages/dashboard/admin/adminDashboard.telefunc'; const COMPONENT_TYPES = [ { value: 'cpu', label: 'CPU' }, { value: 'gpu', label: 'Graphics Card' }, { value: 'motherboard', label: 'Motherboard' }, { value: 'memory', label: 'Memory' }, { value: 'storage', label: 'Storage' }, { value: 'power_supply', label: 'Power Supply' }, { value: 'case', label: 'Case' }, { value: 'cooler', label: 'CPU Cooler' }, ]; export default function AddComponentDialog({ open, onClose, onSuccess, prefillData }: { open: boolean; onClose: () => void; onSuccess: () => void; prefillData?: { type?: string; suggestionLink?: string; suggestionDescription?: string; }; }) { const [name, setName] = useState(''); const [brand, setBrand] = useState(''); const [price, setPrice] = useState(''); const [imgUrl, setImgUrl] = useState(''); const [type, setType] = useState(''); const [requiredFields, setRequiredFields] = useState([]); const [multiTables, setMultiTables] = useState({}); const [specificData, setSpecificData] = useState({}); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); useEffect(() => { if (type) { setLoading(true); onGetDetailsForNewComponent({ type }) .then((details) => { console.log('Component details:', details); setRequiredFields(details.requiredFields || []); setMultiTables(details.multiTables || {}); const initialData: any = {}; (details.requiredFields || []).forEach((field: any) => { const fieldName = typeof field === 'string' ? field : field.name; initialData[fieldName] = ''; }); Object.keys(details.multiTables || {}).forEach((tableName) => { initialData[tableName] = []; }); setSpecificData(initialData); }) .catch((err) => { console.error('Field load error:', err); setError('Failed to load component fields'); }) .finally(() => setLoading(false)); } }, [type]); useEffect(() => { if (open && prefillData) { if (prefillData.type) setType(prefillData.type); } }, [open, prefillData]); const handleFieldChange = (fieldName: string, value: any) => { setSpecificData((prev: any) => ({ ...prev, [fieldName]: value })); }; const handleAddMultiTableRow = (tableName: string) => { const tableConfig = multiTables[tableName]; const newRow: any = {}; tableConfig.forEach((field: string) => { newRow[field] = ''; }); setSpecificData((prev: any) => ({ ...prev, [tableName]: [...(prev[tableName] || []), newRow] })); }; const handleRemoveMultiTableRow = (tableName: string, index: number) => { setSpecificData((prev: any) => ({ ...prev, [tableName]: prev[tableName].filter((_: any, i: number) => i !== index) })); }; const handleMultiTableFieldChange = (tableName: string, index: number, fieldName: string, value: any) => { setSpecificData((prev: any) => { const updated = [...prev[tableName]]; updated[index] = { ...updated[index], [fieldName]: value }; return { ...prev, [tableName]: updated }; }); }; const handleSubmit = async () => { setError(''); if (!name.trim()) return setError('Name is required'); if (!brand.trim()) return setError('Brand is required'); if (!price || isNaN(Number(price)) || Number(price) <= 0) return setError('Valid price is required'); if (!imgUrl.trim()) return setError('Image URL is required'); if (!type) return setError('Component type is required'); setLoading(true); try { await onCreateNewComponent({ name: name.trim(), brand: brand.trim(), price: Number(price), imgUrl: imgUrl.trim(), type, specificData }); onSuccess(); handleClose(); } catch (err) { setError('Failed to create component. Please check all fields.'); } finally { setLoading(false); } }; const handleClose = () => { setName(''); setBrand(''); setPrice(''); setImgUrl(''); setType(''); setSpecificData({}); setRequiredFields([]); setMultiTables({}); setError(''); onClose(); }; const formatFieldLabel = (fieldName: string): string => { return fieldName .replace(/([A-Z])/g, ' $1') .replace(/^./, (str: string) => str.toUpperCase()); }; const renderAllFields = () => { const allFields = [...(requiredFields || []), ...(Object.values(multiTables).flat() || [])]; return ( {allFields.map((field: any, index: number) => { const fieldName = typeof field === 'string' ? field : field.name; const isNumber = fieldName.includes('height') || fieldName.includes('length') || fieldName.includes('wattage') || fieldName.includes('capacity') || fieldName.includes('speed') || fieldName.includes('cores') || fieldName.includes('threads') || fieldName.includes('vram') || fieldName.includes('slots') || fieldName.includes('numSlots'); return ( handleFieldChange(fieldName, isNumber ? Number(e.target.value) : e.target.value)} type={isNumber ? 'number' : 'text'} required sx={{ mb: 2 }} /> ); })} ); }; return ( Add New Component {error && {error}} Basic Information setType(e.target.value)} required sx={{ mb: 2 }} > {COMPONENT_TYPES.map((option) => ( {option.label} ))} setBrand(e.target.value)} required /> setName(e.target.value)} required /> setPrice(e.target.value)} required inputProps={{ step: '0.01', min: '0' }} /> setImgUrl(e.target.value)} required /> {imgUrl && ( )} {type && (requiredFields.length > 0 || Object.keys(multiTables).length > 0) && ( {COMPONENT_TYPES.find(ct => ct.value === type)?.label} Specifications {renderAllFields()} )} {Object.keys(multiTables).map((tableName) => ( {tableName.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())} {(specificData[tableName] || []).map((row: any, index: number) => ( Row {index + 1} handleRemoveMultiTableRow(tableName, index)} > {multiTables[tableName].map((fieldName: string) => ( str.toUpperCase())} value={row[fieldName] || ''} onChange={(e) => handleMultiTableFieldChange(tableName, index, fieldName, e.target.value)} /> ))} ))} ))} ); }