import React, { useState, useEffect } from 'react' import { useComponents } from '../../contexts/ComponentContext' import { FaRegSave, FaSync, FaCog } from 'react-icons/fa' import { useLocalization } from '@/utils/hooks/useLocalization' import { Formik, Form, Field } from 'formik' import * as Yup from 'yup' import { Button, Checkbox, FormContainer, FormItem, Input } from '@/components/ui' import Dialog from '@/components/ui/Dialog' import { generateDesignerCode } from '@/components/visualDesigner/codeGenerator' import { createDesignerId, createEmptyDesignerDocument, type DesignerDocument, } from '@/components/visualDesigner/types' // Validation schema const validationSchema = Yup.object({ name: Yup.string().required(), routePath: Yup.string().required().matches(/^\//, 'Route path must start with /'), description: Yup.string(), dependencies: Yup.array().of(Yup.string()), isActive: Yup.boolean(), }) interface ComponentEditorProps { componentId?: string | null onClose?: () => void onSaved?: () => void | Promise } const ComponentEditor: React.FC = ({ componentId, onClose, onSaved, }) => { const id = componentId || undefined const { translate } = useLocalization() const { getComponent, addComponent, updateComponent, refreshComponent } = useComponents() const [isLoaded, setIsLoaded] = useState(false) const isEditing = !!id // Initial values for Formik const [initialValues, setInitialValues] = useState({ name: '', routePath: '', description: '', dependencies: [] as string[], isActive: true, }) // Load existing component data - sadece edit modunda useEffect(() => { if (isEditing && id && !isLoaded) { let cancelled = false void refreshComponent(id).then((freshComponent) => { if (cancelled) return const component = freshComponent if (!component) { setIsLoaded(true) return } // Parse dependencies from JSON string let deps: string[] = [] try { deps = component.dependencies ? JSON.parse(component.dependencies) : [] deps = Array.isArray(deps) ? deps : [] } catch { deps = [] } const values = { name: component.name, routePath: component.routePath, description: component.description || '', dependencies: deps, isActive: component.isActive, } setInitialValues(values) setIsLoaded(true) }) return () => { cancelled = true } } else if (!isEditing && !isLoaded) { // Yeni komponent için boş başla - TEMPLATE YOK setIsLoaded(true) } }, [id, isEditing, isLoaded, refreshComponent]) const createDefaultVisualDocument = (componentName: string): DesignerDocument => { const document = createEmptyDesignerDocument('visual') document.nodes = [ { id: createDesignerId(), type: 'span', kind: 'html', props: { children: componentName.trim() }, events: {}, bindings: {}, children: [], }, ] return document } const handleSubmit = async (values: typeof initialValues, { setSubmitting }: any) => { if (!values.name.trim()) { alert('Please enter a component name') setSubmitting(false) return } try { const existingComponent = isEditing && id ? getComponent(id) : undefined const defaultDocument = createDefaultVisualDocument(values.name) const componentData = { name: values.name.trim(), routePath: values.routePath.trim(), description: values.description.trim(), dependencies: JSON.stringify(values.dependencies), // Serialize dependencies to JSON string code: existingComponent ? existingComponent.code : generateDesignerCode(values.name, defaultDocument), props: existingComponent ? existingComponent.props : JSON.stringify({ visualDesigner: defaultDocument }), isActive: values.isActive, } if (isEditing && id) { await updateComponent(id, componentData) } else { await addComponent(componentData) } await onSaved?.() onClose?.() } catch (error) { console.error('Error saving component:', error) alert('Failed to save component. Please try again.') } finally { setSubmitting(false) } } // Loading state - komponent yüklenene kadar bekle if (isEditing && !isLoaded) { return (

{translate('::App.Platform.LoadingWithThreeDot')}

) } return ( {({ values, touched, errors, isSubmitting, setFieldValue, submitForm, isValid }) => { return ( <>

Component Settings

) => { setFieldValue('name', e.target.value) }} /> {() => ( setFieldValue( 'dependencies', e.target.value .split(',') .map((s) => s.trim()) .filter(Boolean), ) } /> )}
) }}
) } export default ComponentEditor