import React, { useState } from 'react' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { MenuItem } from '@/proxy/menus/menu' import { useLocalization } from '@/utils/hooks/useLocalization' import { MenuService } from '@/services/menu.service' import navigationIcon from '@/proxy/menus/navigation-icon.config' import { FaQuestionCircle } from 'react-icons/fa' import { Button, Dialog, FormContainer, FormItem, Input, Switcher, Notification, toast, Select, } from '@/components/ui' import { Field, FieldProps, Form, Formik } from 'formik' import { SelectBoxOption } from '@/types/shared' import * as Yup from 'yup' import { FaExternalLinkAlt, FaPlus, FaTrashAlt } from 'react-icons/fa' import { MenuDto } from '@/proxy/menus/models' interface MenuItemComponentProps { item: MenuItem isDesignMode: boolean depth: number children?: React.ReactNode isDragOverlay?: boolean refetch: () => void permissions: SelectBoxOption[] } export const MenuItemComponent: React.FC = ({ item, isDesignMode, depth, children, isDragOverlay = false, refetch, permissions, }) => { const { translate } = useLocalization() const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item.id || '', data: { type: 'menu-item', item, }, disabled: !isDesignMode, }) const validationSchema = Yup.object().shape({ code: Yup.string().required('Code is required'), displayName: Yup.string().required('Display Name is required'), order: Yup.number().typeError('Order must be a number').required('Order is required'), url: Yup.string().nullable(), icon: Yup.string().nullable(), cssClass: Yup.string().nullable(), requiredPermissionName: Yup.string().nullable(), target: Yup.string().nullable(), elementId: Yup.string().nullable(), isDisabled: Yup.boolean(), }) const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, } const [isExpanded, setIsExpanded] = useState(true) const [isModalOpen, setIsModalOpen] = useState(false) const [modalMode, setModalMode] = useState<'create' | 'edit'>('create') const getCreateInitialValues = (): Partial => ({ code: '', displayName: '', order: (item.children?.length || 0) + 1, parentCode: item.code, url: '', icon: '', cssClass: '', requiredPermissionName: '', target: '', isDisabled: false, elementId: '', }) const getEditInitialValues = (): Partial => ({ id: item.id, code: item.code || '', displayName: item.displayName || '', order: item.order, parentCode: item.parentCode || '', url: item.url || '', icon: item.icon || '', cssClass: item.cssClass || '', requiredPermissionName: item.requiredPermissionName || '', target: item.target || '', isDisabled: item.isDisabled ?? false, elementId: item.elementId || '', }) const [formData, setFormData] = useState>(getCreateInitialValues()) const toggleExpanded = () => { if (!isDesignMode) setIsExpanded(!isExpanded) } const openCreateModal = () => { setModalMode('create') setFormData(getCreateInitialValues()) setIsModalOpen(true) } const openEditModal = (event: React.MouseEvent) => { if (!isDesignMode) return event.stopPropagation() setModalMode('edit') setFormData(getEditInitialValues()) setIsModalOpen(true) } const handleDelete = async () => { const confirmed = window.confirm(`Delete "${item.displayName}"?`) if (!confirmed) return const menuService = new MenuService() await menuService.delete(item.id!) refetch() } return (
0 ? 'bg-blue-50' : depth === 0 ? 'bg-white' : 'bg-gray-50'} `} {...(isDesignMode ? { ...attributes, ...listeners } : { onClick: toggleExpanded })} > {isDesignMode && (
)}
{navigationIcon[item.icon || ''] ? ( React.createElement(navigationIcon[item.icon || ''], { className: 'text-gray-400' }) ) : ( )}
{item.url && }
{isDesignMode && (
#{item.order}
)} {item.children && item.children.length > 0 && ( {item.children.length} )}
{children && (!isDesignMode ? isExpanded : true) &&
{children}
} {isModalOpen && ( setIsModalOpen(false)} onRequestClose={() => setIsModalOpen(false)} width={600} >
{modalMode === 'edit' ? translate('::Edit Menu Item') : translate('::New Item')}
{ try { const menuService = new MenuService() if (modalMode === 'edit' && item.id) { await menuService.update(item.id, values as MenuDto) } else { await menuService.create(values as MenuDto) } toast.push( {modalMode === 'edit' ? translate('::KayitGuncellendi') : translate('::KayitEklendi')} , { placement: 'top-end' }, ) setIsModalOpen(false) refetch() } catch (error) { toast.push( {translate('::IslemBasarisiz')} , { placement: 'top-end' }, ) } finally { setSubmitting(false) } }} > {({ values, isSubmitting }) => (
{({ field, form }: FieldProps) => (