new-marketplace
84 строки · 3.6 Кб
1'use client';
2import { useRouter } from 'next/navigation';
3import Link from 'next/link';
4import { Ripple } from 'primereact/ripple';
5import { classNames } from 'primereact/utils';
6import React, { useEffect, useContext } from 'react';
7import { CSSTransition } from 'react-transition-group';
8import { MenuContext } from './context/menucontext';
9import { AppMenuItemProps } from '@/types';
10import { usePathname, useSearchParams } from 'next/navigation';
11
12const AppMenuitem = (props: AppMenuItemProps) => {
13const pathname = usePathname();
14const searchParams = useSearchParams();
15const { activeMenu, setActiveMenu } = useContext(MenuContext);
16const item = props.item;
17const key = props.parentKey ? props.parentKey + '-' + props.index : String(props.index);
18const isActiveRoute = item!.to && pathname === item!.to;
19const active = activeMenu === key || activeMenu.startsWith(key + '-');
20const onRouteChange = (url: string) => {
21if (item!.to && item!.to === url) {
22setActiveMenu(key);
23}
24};
25
26useEffect(() => {
27onRouteChange(pathname);
28// eslint-disable-next-line react-hooks/exhaustive-deps
29}, [pathname, searchParams]);
30
31const itemClick = (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
32//avoid processing disabled items
33if (item!.disabled) {
34event.preventDefault();
35return;
36}
37
38//execute command
39if (item!.command) {
40item!.command({ originalEvent: event, item: item });
41}
42
43// toggle active state
44if (item!.items) setActiveMenu(active ? (props.parentKey as string) : key);
45else setActiveMenu(key);
46};
47
48const subMenu = item!.items && item!.visible !== false && (
49<CSSTransition timeout={{ enter: 1000, exit: 450 }} classNames="layout-submenu" in={props.root ? true : active} key={item!.label}>
50<ul>
51{item!.items.map((child, i) => {
52return <AppMenuitem item={child} index={i} className={child.badgeClass} parentKey={key} key={child.label} />;
53})}
54</ul>
55</CSSTransition>
56);
57
58return (
59<li className={classNames({ 'layout-root-menuitem': props.root, 'active-menuitem': active })}>
60{props.root && item!.visible !== false && <div className="layout-menuitem-root-text">{item!.label}</div>}
61{(!item!.to || item!.items) && item!.visible !== false ? (
62<a href={item!.url} onClick={(e) => itemClick(e)} className={classNames(item!.class, 'p-ripple')} target={item!.target} tabIndex={0}>
63<i className={classNames('layout-menuitem-icon', item!.icon)}></i>
64<span className="layout-menuitem-text">{item!.label}</span>
65{item!.items && <i className="pi pi-fw pi-angle-down layout-submenu-toggler"></i>}
66<Ripple />
67</a>
68) : null}
69
70{item!.to && !item!.items && item!.visible !== false ? (
71<Link href={item!.to} replace={item!.replaceUrl} target={item!.target} onClick={(e) => itemClick(e)} className={classNames(item!.class, 'p-ripple', { 'active-route': isActiveRoute })} tabIndex={0}>
72<i className={classNames('layout-menuitem-icon', item!.icon)}></i>
73<span className="layout-menuitem-text">{item!.label}</span>
74{item!.items && <i className="pi pi-fw pi-angle-down layout-submenu-toggler"></i>}
75<Ripple />
76</Link>
77) : null}
78
79{subMenu}
80</li>
81);
82};
83
84export default AppMenuitem;
85