import React, { useEffect, useState } from 'react' import { useComponents } from '../../contexts/ComponentContext' import { FaPlus, FaSearch, FaRegEdit, FaTrashAlt, FaEye, FaEyeSlash, FaFilter, FaCalendarAlt, FaExternalLinkAlt, FaCog, FaSyncAlt, FaTh, FaList, } from 'react-icons/fa' import Widget from '@/components/common/Widget' import { ROUTES_ENUM } from '@/routes/route.constant' import { useLocalization } from '@/utils/hooks/useLocalization' import { Loading } from '../../components/shared' import PageTitle from '@/components/shared/PageTitle' import { Button } from '@/components/ui' import Dialog from '@/components/ui/Dialog' import ComponentEditor from './ComponentEditor' import { parseComponentDependencies } from '@/contexts/componentRuntime' import { usePermission } from '@/utils/hooks/usePermission' import { COMPONENT_PERMISSION } from '@/constants/permission.constant' import Input from '@/components/ui/Input' import Select from '@/components/ui/Select' import type { CustomComponent } from '@/proxy/developerKit/models' import { useStoreActions, useStoreState } from '@/store/store' import type { ListViewLayoutType } from '../admin/listForm/edit/types' /** Layout tercihi diger listelerle ayni yerde (admin.lists.states) saklanir. */ const VIEW_STATE_CODE = 'developerkit-components' const ComponentManager: React.FC = () => { const { components, loading, componentErrors, updateComponent, deleteComponent, refreshComponents, } = useComponents() const [searchTerm, setSearchTerm] = useState('') const [filterActive, setFilterActive] = useState<'all' | 'active' | 'inactive'>('all') const [isRefreshing, setIsRefreshing] = useState(false) const [editorComponentId, setEditorComponentId] = useState(undefined) const { states } = useStoreState((state) => state.admin.lists) const { setStates } = useStoreActions((a) => a.admin.lists) const viewMode: ListViewLayoutType = states.find((s) => s.listFormCode === VIEW_STATE_CODE)?.layout === 'grid' ? 'grid' : 'card' const setViewMode = (layout: ListViewLayoutType) => setStates({ listFormCode: VIEW_STATE_CODE, layout }) // Calculate statistics const totalComponents = components?.length || 0 const activeComponents = components?.filter((c) => c.isActive).length || 0 const inactiveComponents = totalComponents - activeComponents const { translate } = useLocalization() const filterActiveOptions = [ { value: 'all' as const, label: translate('::App.ComponentFilter.All') }, { value: 'active' as const, label: translate('::App.EntityFilter.Active') }, { value: 'inactive' as const, label: translate('::App.EntityFilter.Inactive') }, ] const { checkPermission } = usePermission() const canCreate = checkPermission(COMPONENT_PERMISSION.CREATE) const canUpdate = checkPermission(COMPONENT_PERMISSION.UPDATE) const canDelete = checkPermission(COMPONENT_PERMISSION.DELETE) useEffect(() => { void refreshComponents() }, [refreshComponents]) const handleRefresh = async () => { setIsRefreshing(true) try { await refreshComponents() } finally { setIsRefreshing(false) } } const filteredComponents = components?.filter((component) => { const matchesSearch = component.name.toLowerCase().includes(searchTerm.toLowerCase()) || (component.description || '').toLowerCase().includes(searchTerm.toLowerCase()) const matchesFilter = filterActive === 'all' || (filterActive === 'active' && component.isActive) || (filterActive === 'inactive' && !component.isActive) return matchesSearch && matchesFilter }) const handleToggleActive = async (id: string, isActive: boolean) => { try { const component = components?.find((c) => c.id === id) if (component) { await updateComponent(id, { ...component, isActive }) } } catch (err) { console.error('Failed to toggle component status:', err) } } const handleDelete = async (id: string) => { if (window.confirm(translate('::App.DeveloperKitComponent.ConfirmDelete'))) { try { await deleteComponent(id) } catch (err) { console.error('Failed to delete component:', err) } } } const renderStatusToggle = (component: CustomComponent) => ( ) const renderActions = (component: CustomComponent) => (
{canUpdate && ( )} {canDelete && ( )}
) return (
{/* Filters */}
setSearchTerm(e.target.value)} />