diff --git a/src/get-user/khanegi-nav-sample.ts b/src/get-user/khanegi-nav-sample.ts index f90ad1e..f8d73b4 100644 --- a/src/get-user/khanegi-nav-sample.ts +++ b/src/get-user/khanegi-nav-sample.ts @@ -31,6 +31,20 @@ export const KHANEGI_SAMPLE_BOTTOM: KhanegiNavItem[] = [ { id: 'user', label: 'تنظیمات', icon: 'vuesax-linear:setting-2', route: 'user', order: 4, visible: true }, ] +function cloneJson(value: T): T { + return JSON.parse(JSON.stringify(value)) as T +} + +export function getKhanegiBottomNavChoices(): KhanegiNavItem[] { + const byId = new Map() + for (const item of KHANEGI_SAMPLE_BOTTOM) byId.set(item.id, cloneJson(item)) + for (const item of KHANEGI_SAMPLE_SIDEBAR) { + if (item.id === 'home') continue + if (!byId.has(item.id)) byId.set(item.id, cloneJson(item)) + } + return Array.from(byId.values()) +} + export function mergeNavItemsFromSample( sample: KhanegiNavItem[], stored: unknown, @@ -72,11 +86,52 @@ export function mergeNavItemsFromSample( return kept.map((item, index) => ({ ...item, order: index + 1 })) } +/** دقیقاً ۴ جایگاه؛ انتخاب ذخیره‌شده از کاتالوگ، بقیه از پیش‌فرض پر می‌شود */ +export function mergeBottomNavSlots(stored: unknown): KhanegiNavItem[] { + const choices = getKhanegiBottomNavChoices() + const defaults = KHANEGI_SAMPLE_BOTTOM.slice(0, MAX_BOTTOM_NAV_SLOTS) + const byId = new Map(choices.map((item) => [item.id, item])) + const slots: KhanegiNavItem[] = [] + const seen = new Set() + const storedList = Array.isArray(stored) ? stored : [] + + for (const prev of storedList) { + if (slots.length >= MAX_BOTTOM_NAV_SLOTS) break + if (!prev || typeof prev !== 'object' || typeof prev.id !== 'string') continue + if (seen.has(prev.id)) continue + const base = byId.get(prev.id) + if (!base) continue + seen.add(prev.id) + slots.push({ + ...base, + label: prev.label || base.label, + icon: prev.icon || base.icon, + visible: typeof prev.visible === 'boolean' ? prev.visible : true, + query: prev.query ?? base.query, + }) + } + + for (const item of defaults) { + if (slots.length >= MAX_BOTTOM_NAV_SLOTS) break + if (seen.has(item.id)) continue + seen.add(item.id) + slots.push({ ...item, visible: true }) + } + + for (const item of choices) { + if (slots.length >= MAX_BOTTOM_NAV_SLOTS) break + if (seen.has(item.id)) continue + seen.add(item.id) + slots.push({ ...item, visible: true }) + } + + return slots.slice(0, MAX_BOTTOM_NAV_SLOTS).map((item, index) => ({ + ...item, + order: index + 1, + })) +} + export function applyKhanegiNavSample(navigation: Record) { navigation.sidebar = mergeNavItemsFromSample(KHANEGI_SAMPLE_SIDEBAR, navigation.sidebar) - navigation.bottom = mergeNavItemsFromSample( - KHANEGI_SAMPLE_BOTTOM.slice(0, MAX_BOTTOM_NAV_SLOTS), - navigation.bottom, - MAX_BOTTOM_NAV_SLOTS, - ).slice(0, MAX_BOTTOM_NAV_SLOTS) + navigation.bottom = mergeBottomNavSlots(navigation.bottom) }