import React, { useState, useEffect } from 'react' import configLoader from '../utils/configLoader' interface ConfigPanelProps { visible: boolean onToggle: () => void } export const ConfigPanel: React.FC = ({ visible, onToggle }) => { const [config, setConfig] = useState(null) const [activeSection, setActiveSection] = useState('particles') const [searchTerm, setSearchTerm] = useState('') useEffect(() => { const loadConfig = async () => { const loadedConfig = await configLoader.loadConfig() setConfig(loadedConfig) } loadConfig() }, []) const updateConfig = (path: string, value: any) => { if (!config) return const pathArray = path.split('.') const newConfig = { ...config } let current = newConfig // Navigate to the parent object for (let i = 0; i < pathArray.length - 1; i++) { current = current[pathArray[i]] } // Set the value current[pathArray[pathArray.length - 1]] = value setConfig(newConfig) // Apply to configLoader (this would trigger re-render of visualizer) configLoader['config'] = newConfig console.log(`🔧 Config updated: ${path} = ${value}`) } const applyPreset = (presetName: string) => { configLoader.applyPreset(presetName) const newConfig = configLoader.getConfig() setConfig(newConfig) console.log(`🎨 Applied preset: ${presetName}`) } const exportConfig = () => { if (!config) return const configBlob = new Blob([JSON.stringify(config, null, 2)], { type: 'application/json' }) const url = URL.createObjectURL(configBlob) const a = document.createElement('a') a.href = url a.download = 'visualizer-config.json' a.click() URL.revokeObjectURL(url) } const reloadConfig = async () => { const newConfig = await configLoader.reloadConfig() setConfig(newConfig) console.log('🔄 Config reloaded from file') } const renderConfigSection = (sectionData: any, basePath: string = '') => { if (!sectionData) return null return Object.keys(sectionData).map(key => { const value = sectionData[key] const fullPath = basePath ? `${basePath}.${key}` : key // Filter by search term if (searchTerm && !fullPath.toLowerCase().includes(searchTerm.toLowerCase()) && typeof value !== 'object') { return null } if (typeof value === 'object' && !Array.isArray(value)) { return (
{key}
{renderConfigSection(value, fullPath)}
) } return (
{typeof value === 'boolean' ? ( updateConfig(fullPath, e.target.checked)} style={{ marginBottom: '4px' }} /> ) : typeof value === 'number' ? ( updateConfig(fullPath, parseFloat(e.target.value) || 0)} step={value < 1 ? 0.001 : value < 10 ? 0.1 : 1} style={{ width: '100%', padding: '4px', background: 'rgba(0, 0, 0, 0.5)', color: '#FFD700', border: '1px solid rgba(255, 215, 0, 0.3)', borderRadius: '3px', fontSize: '10px' }} /> ) : typeof value === 'string' ? ( value.startsWith('#') ? ( updateConfig(fullPath, e.target.value)} style={{ width: '100%', height: '24px' }} /> ) : ( updateConfig(fullPath, e.target.value)} style={{ width: '100%', padding: '4px', background: 'rgba(0, 0, 0, 0.5)', color: '#FFD700', border: '1px solid rgba(255, 215, 0, 0.3)', borderRadius: '3px', fontSize: '10px' }} /> ) ) : Array.isArray(value) ? (