import React, { useState, useEffect } from 'react' import { useParams, useNavigate } from 'react-router-dom' import { useEntities, EntityFieldType } from '../../contexts/EntityContext' import { Save, ArrowLeft, Plus, Trash2, Database, HelpCircle } from 'lucide-react' import { CreateUpdateCustomEntityFieldDto, CustomEntityField } from '@/proxy/developerKit/models' import { ROUTES_ENUM } from '@/routes/route.constant' import { useLocalization } from '@/utils/hooks/useLocalization' const EntityEditor: React.FC = () => { const { id } = useParams() const navigate = useNavigate() const { translate } = useLocalization() const { getEntity, addEntity, updateEntity } = useEntities() const [name, setName] = useState('') const [displayName, setDisplayName] = useState('') const [tableName, setTableName] = useState('') const [description, setDescription] = useState('') const [fields, setFields] = useState([]) const [isActive, setIsActive] = useState(true) const [hasAuditFields, setHasAuditFields] = useState(true) const [hasSoftDelete, setHasSoftDelete] = useState(true) const [isSaving, setIsSaving] = useState(false) const isEditing = !!id // Check if migration is applied to disable certain fields const isMigrationApplied = Boolean( isEditing && id && getEntity(id)?.migrationStatus === 'applied', ) useEffect(() => { if (isEditing && id) { const entity = getEntity(id) if (entity) { setName(entity.name) setDisplayName(entity.displayName) setTableName(entity.tableName) setDescription(entity.description || '') setFields(entity.fields) setIsActive(entity.isActive) setHasAuditFields(entity.hasAuditFields) setHasSoftDelete(entity.hasSoftDelete) } } else { // Initialize with default field setFields([ { id: crypto.randomUUID(), entityId: id || '', name: 'Name', type: 'string', isRequired: true, maxLength: 100, description: 'Entity name', }, ]) } }, [id, isEditing, getEntity]) const addField = () => { const newField: CustomEntityField = { id: crypto.randomUUID(), entityId: id || '', name: '', type: 'string', isRequired: false, description: '', } setFields((prev) => [...prev, newField]) } const updateField = (fieldKey: string, updates: Partial) => { setFields((prev) => prev.map((field) => (field.id === fieldKey ? { ...field, ...updates } : field)), ) } const removeField = (fieldKey: string) => { setFields((prev) => prev.filter((field) => field.id !== fieldKey)) } const handleSave = async () => { if (!name.trim()) { alert('Please enter an entity name') return } if (!displayName.trim()) { alert('Please enter a display name') return } if (!tableName.trim()) { alert('Please enter a table name') return } if (fields.length === 0) { alert('Please add at least one field') return } const invalidFields = fields.filter((f) => !f.name.trim()) if (invalidFields.length > 0) { alert('Please fill in all field names') return } setIsSaving(true) try { const sanitizedFields = fields.map((f) => { const sanitized: CreateUpdateCustomEntityFieldDto = { ...(f.id && isEditing ? { id: f.id } : {}), // sadece güncelleme modunda varsa gönder name: f.name.trim(), type: f.type, isRequired: f.isRequired, maxLength: f.maxLength, isUnique: f.isUnique || false, defaultValue: f.defaultValue, description: f.description, } return sanitized }) const entityData = { name: name.trim(), displayName: displayName.trim(), tableName: tableName.trim(), description: description.trim(), fields: sanitizedFields, isActive, hasAuditFields, hasSoftDelete, } if (isEditing && id) { updateEntity(id, entityData) } else { addEntity(entityData) } navigate(ROUTES_ENUM.protected.saas.developerKitEntities) } catch (error) { console.error('Error saving entity:', error) alert('Failed to save entity. Please try again.') } finally { setIsSaving(false) } } const fieldTypes = [ { value: 'string', label: 'String (Text)' }, { value: 'number', label: 'Number (Integer)' }, { value: 'decimal', label: 'Decimal' }, { value: 'boolean', label: 'Boolean (True/False)' }, { value: 'date', label: 'Date' }, { value: 'guid', label: 'GUID (Unique ID)' }, ] return (
{/* Header */}

{isEditing ? translate('::App.DeveloperKit.EntityEditor.Title.Edit') : translate('::App.DeveloperKit.EntityEditor.Title.Create')}

{/* Help Tooltip */}

{translate('::App.DeveloperKit.EntityEditor.Tooltip.Title')}

{translate('::App.DeveloperKit.EntityEditor.Tooltip.Content')}

{/* Entity Basic Info */}

{translate('::App.DeveloperKit.EntityEditor.BasicInfo')}

setName(e.target.value)} onBlur={() => { if (!tableName) { setTableName(name + 's') } if (!displayName) { setDisplayName(name) } }} disabled={isMigrationApplied} className={`w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-transparent ${ isMigrationApplied ? 'bg-slate-100 text-slate-500 cursor-not-allowed' : '' }`} placeholder="e.g., Product, User, Order" /> {isMigrationApplied && (

{translate('::App.DeveloperKit.EntityEditor.CannotChange')}

)}
setDisplayName(e.target.value)} className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-transparent" placeholder="e.g., Product, User, Order" />
setTableName(e.target.value)} disabled={isMigrationApplied} className={`w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-transparent ${ isMigrationApplied ? 'bg-slate-100 text-slate-500 cursor-not-allowed' : '' }`} placeholder="e.g., Products, Users, Orders" /> {isMigrationApplied && (

Cannot be changed after migration is applied

)}
setDescription(e.target.value)} className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-transparent" placeholder="Brief description of this entity" />
{isEditing && (

{translate('::App.DeveloperKit.EntityEditor.Status')}

{translate('::App.DeveloperKit.EntityEditor.Status.Migration')} {getEntity(id!)?.migrationStatus || 'pending'}
{translate('::App.DeveloperKit.EntityEditor.Status.Endpoint')} {getEntity(id!)?.endpointStatus || 'pending'}
)}
{/* Entity Fields */}

{translate('::App.DeveloperKit.EntityEditor.Fields')}

{fields.map((field, index) => (
updateField(field.id, { name: e.target.value })} className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" placeholder="e.g., Name, Price, IsActive" />
{field.type === 'string' && (
updateField(field.id, { maxLength: e.target.value ? parseInt(e.target.value) : undefined, }) } className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" placeholder="e.g., 100" />
)}
updateField(field.id, { defaultValue: e.target.value })} className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" placeholder="Optional default value" />
updateField(field.id, { description: e.target.value })} className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm" placeholder="Field description" />
))}
{fields.length === 0 && (

{translate('::App.DeveloperKit.EntityEditor.NoFields')}

{translate('::App.DeveloperKit.EntityEditor.NoFieldsDescription')}

)}
) } export default EntityEditor