import React, { useEffect, 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 [formData, setFormData] = useState>({ code: '', displayName: '', order: (item.children?.length || 0) + 1, parentCode: item.code, url: '', icon: '', cssClass: '', requiredPermissionName: '', target: '', isDisabled: false, elementId: '', }) const toggleExpanded = () => { if (!isDesignMode) setIsExpanded(!isExpanded) } const handleCreate = async () => { const menuService = new MenuService() await menuService.create(formData as MenuDto) setIsModalOpen(false) refetch() } 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' }) ) : ( )}
0 ? 'font-semibold' : 'font-normal'} `} > {translate('::' + item.displayName)} {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} >
{translate('::New Item')}
{ try { const menuService = new MenuService() await menuService.create(values as MenuDto) toast.push( {translate('::KayitEklendi')} , { placement: 'top-end' }, ) setIsModalOpen(false) refetch() } catch (error) { toast.push( {translate('::IslemBasarisiz')} , { placement: 'top-end' }, ) } finally { setSubmitting(false) } }} > {({ values, errors, touched, isSubmitting, handleChange }) => (
{({ field, form }: FieldProps) => (