diff --git a/assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx b/assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx index 4adf92ef..0404a26a 100644 --- a/assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx +++ b/assets/admin/components/layout/PurchaseSubscriptionSidebar.tsx @@ -3,7 +3,7 @@ import { Link } from 'react-router'; import { SearchHeaderP } from '../../pages/subscriptionIcons'; import { useAuthStore } from '../../stores/authStore'; import { usePermissions } from '../../hooks/usePermissions'; -import { menuForRole, type SettingsMenuItem } from './settingsMenu'; +import { groupMenu, menuForRole, type SettingsMenuItem } from './settingsMenu'; /** * سایدبار تنظیمات — همان فهرستی که `SettingsMenuPage` روی موبایل نشان می‌دهد @@ -21,6 +21,7 @@ const SECURITY_ITEM: SettingsMenuItem = { key: 'security', label: 'تنظیمات', icon: () => null, + group: 'account', alwaysOpen: true, disabled: true, }; @@ -30,13 +31,18 @@ export default function PurchaseSubscriptionSidebar({ active }: { active: string const primaryRole = useAuthStore((s) => s.primaryRole); const scope = useAuthStore((s) => s.context?.scope); const { can } = usePermissions(); - const items = useMemo( - () => [ - ...menuForRole(primaryRole, can, scope).filter((i) => !HIDDEN_KEYS.has(i.key)), - SECURITY_ITEM, - ].filter((i) => i.label.includes(query.trim())), + // گروه‌ها بعد از فیلترِ جستجو ساخته می‌شوند تا تیترِ دسته‌ای که هیچ نتیجه‌ای ندارد + // بالای فضای خالی نماند. + const groups = useMemo( + () => groupMenu( + [ + ...menuForRole(primaryRole, can, scope).filter((i) => !HIDDEN_KEYS.has(i.key)), + SECURITY_ITEM, + ].filter((i) => i.label.includes(query.trim())), + ), [query, primaryRole, scope, can], ); + const itemCount = groups.reduce((sum, g) => sum + g.items.length, 0); return (