import type { ReactNode } from 'react'; import { useEffect, useRef, useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { ROUTES } from '../../config/routes'; import { eventBus, Events } from '../../lib/event-bus'; import { animateLogo, animateStaggerIn } from '../../lib/anime-utils'; import { LayoutDashboard, ListTodo, FileText, Package, Wallet, Users, MessageSquare, Download } from 'lucide-react'; interface LayoutProps { children: ReactNode; } const NAV_ICONS: Record = { [ROUTES.DASHBOARD.path]: LayoutDashboard, [ROUTES.TASKS.path]: ListTodo, [ROUTES.CONTROL_PANEL.path]: LayoutDashboard, [ROUTES.UPDATES.path]: Download, [ROUTES.DIAGNOSTICS.path]: LayoutDashboard, [ROUTES.REGLAMENTY.path]: FileText, [ROUTES.TMC_ZAKUPKI.path]: Package, [ROUTES.FINANCES.path]: Wallet, [ROUTES.PERSONNEL.path]: Users, [ROUTES.CHAT_AGENT.path]: MessageSquare, }; async function checkAndInstallUpdate(): Promise<{ ok: boolean; message: string }> { try { const { check } = await import('@tauri-apps/plugin-updater'); const { relaunch } = await import('@tauri-apps/plugin-process'); const update = await check(); if (!update) return { ok: true, message: 'Обновлений нет. У вас актуальная версия.' }; await update.downloadAndInstall(); await relaunch(); return { ok: true, message: 'Установка обновления…' }; } catch (e) { const msg = e instanceof Error ? e.message : String(e); const friendly = msg && (msg.includes('fetch') || msg.includes('valid') || msg.includes('signature') || msg.includes('network')) ? 'Обновления пока недоступны (сервер или подпись не настроены).' : msg || 'Ошибка проверки обновлений.'; return { ok: false, message: friendly }; } } export function Layout({ children }: LayoutProps) { const location = useLocation(); const logoRef = useRef(null); const navRef = useRef(null); const [updateStatus, setUpdateStatus] = useState(null); const [isCheckingUpdate, setIsCheckingUpdate] = useState(false); const handleCheckUpdate = async () => { setIsCheckingUpdate(true); setUpdateStatus(null); const result = await checkAndInstallUpdate(); setUpdateStatus(result.message); setIsCheckingUpdate(false); }; useEffect(() => { if (logoRef.current) animateLogo(logoRef.current); }, []); useEffect(() => { if (!navRef.current) return; const links = navRef.current.querySelectorAll('.nav-item-anime'); if (links.length) animateStaggerIn(links, { staggerDelay: 70, duration: 450 }); }, [location.pathname]); const handleNav = (path: string) => { try { eventBus.emit(Events.NAVIGATE, { path }); eventBus.emit(Events.ROUTE_CHANGED, { path }); } catch (_) {} }; const navItems = [ ROUTES.TASKS, ROUTES.CONTROL_PANEL, ROUTES.UPDATES, ROUTES.DIAGNOSTICS, ].map((r) => ({ path: r.path, name: r.name, icon: NAV_ICONS[r.path] ?? FileText })); return (
{children}
); }