import { type RouteLocationNormalizedLoaded } from 'vue-router' /** Tab order for vertical transitions between main navigation items */ const TAB_ORDER = [ '/dashboard', '/dashboard/apps', '/dashboard/marketplace', '/dashboard/cloud', '/dashboard/mesh', '/dashboard/server', '/dashboard/web5', '/dashboard/fleet', '/dashboard/chat', '/dashboard/settings' ] /** Web5 group sub-tab order for mobile horizontal swipe transitions */ const WEB5_TAB_ORDER = ['/dashboard/web5', '/dashboard/cloud', '/dashboard/server', '/dashboard/mesh'] /** Route-to-background image mapping */ export const ROUTE_BACKGROUNDS: Record = { '/dashboard': 'bg-home.jpg', '/dashboard/': 'bg-home.jpg', '/dashboard/apps': 'bg-myapps.jpg', '/dashboard/discover': 'bg-appstore.jpg', '/dashboard/marketplace': 'bg-appstore.jpg', '/dashboard/cloud': 'bg-cloud.jpg', '/dashboard/mesh': 'bg-mesh.jpg', '/dashboard/server': 'bg-network.jpg', '/dashboard/web5': 'bg-web5.jpg', '/dashboard/federation': 'bg-web5.jpg', '/dashboard/settings': 'bg-settings.jpg', '/dashboard/chat': 'bg-aiui.jpg', } export function isDetailRoute(path: string): boolean { return (path.includes('/apps/') && !path.endsWith('/apps')) || (path.includes('/marketplace/') && !path.endsWith('/marketplace')) } /** * Creates a route transition tracker that determines the appropriate * CSS transition name based on navigation direction and route depth. */ export function useRouteTransitions() { let previousPath = '' let previousTab = '' function getTransitionName(currentRoute: RouteLocationNormalizedLoaded): string { const currentPath = currentRoute.path if (!previousPath) { previousPath = currentPath return 'fade' } // Chat transitions: directional slide const isChat = currentPath === '/dashboard/chat' const wasChat = previousPath === '/dashboard/chat' if (isChat) { previousPath = currentPath return 'chat-open' } if (wasChat) { previousPath = currentPath return 'chat-close' } const isAppDetails = currentPath.includes('/apps/') && !currentPath.endsWith('/apps') const isAppsList = currentPath === '/dashboard/apps' const wasAppDetails = previousPath.includes('/apps/') && !previousPath.endsWith('/apps') const wasAppsList = previousPath === '/dashboard/apps' const isMarketplaceDetails = currentPath.includes('/marketplace/') && !currentPath.endsWith('/marketplace') const isMarketplaceList = currentPath === '/dashboard/marketplace' const wasMarketplaceDetails = previousPath.includes('/marketplace/') && !previousPath.endsWith('/marketplace') const wasMarketplaceList = previousPath === '/dashboard/marketplace' const isCloudFolder = currentPath.includes('/cloud/') && !currentPath.endsWith('/cloud') const isCloudList = currentPath === '/dashboard/cloud' const wasCloudFolder = previousPath.includes('/cloud/') && !previousPath.endsWith('/cloud') const wasCloudList = previousPath === '/dashboard/cloud' let transitionName = 'fade' // Mobile: Horizontal slide transitions between sub-tabs if (typeof window !== 'undefined' && window.innerWidth < 768) { const isServices = currentPath === '/dashboard/apps' && currentRoute.query.tab === 'services' const wasServices = previousTab === 'services' const currentAppsIdx = isServices ? 2 : currentPath === '/dashboard/marketplace' ? 1 : currentPath === '/dashboard/apps' ? 0 : -1 const prevAppsIdx = wasServices ? 2 : previousPath === '/dashboard/marketplace' ? 1 : previousPath === '/dashboard/apps' ? 0 : -1 const currentWeb5Idx = WEB5_TAB_ORDER.indexOf(currentPath) const prevWeb5Idx = WEB5_TAB_ORDER.indexOf(previousPath) if (currentAppsIdx !== -1 && prevAppsIdx !== -1 && currentAppsIdx !== prevAppsIdx) { transitionName = currentAppsIdx > prevAppsIdx ? 'slide-left' : 'slide-right' } else if (currentWeb5Idx !== -1 && prevWeb5Idx !== -1 && currentWeb5Idx !== prevWeb5Idx) { transitionName = currentWeb5Idx > prevWeb5Idx ? 'slide-left' : 'slide-right' } else { const currentIndex = TAB_ORDER.indexOf(currentPath) const previousIndex = TAB_ORDER.indexOf(previousPath) if (currentIndex !== -1 && previousIndex !== -1 && currentIndex !== previousIndex) { transitionName = currentIndex > previousIndex ? 'slide-down' : 'slide-up' } } } // Desktop depth transitions: list <-> detail else if (wasAppsList && isAppDetails) { transitionName = 'depth-forward' } else if (wasAppDetails && isAppsList) { transitionName = 'depth-back' } else if (wasMarketplaceList && isMarketplaceDetails) { transitionName = 'depth-forward' } else if (wasMarketplaceDetails && isMarketplaceList) { transitionName = 'depth-back' } else if (wasCloudList && isCloudFolder) { transitionName = 'depth-forward' } else if (wasCloudFolder && isCloudList) { transitionName = 'depth-back' } else if (wasMarketplaceList && isAppDetails) { transitionName = 'depth-forward' } else if (wasAppDetails && isMarketplaceList) { transitionName = 'depth-back' } // Desktop: no transition between Apps <-> Marketplace (same-page tab feel) else if ((wasAppsList && isMarketplaceList) || (wasMarketplaceList && isAppsList)) { transitionName = 'fade' } // Vertical transition: between main tabs (desktop) else { const currentIndex = TAB_ORDER.indexOf(currentPath) const previousIndex = TAB_ORDER.indexOf(previousPath) if (currentIndex !== -1 && previousIndex !== -1 && currentIndex !== previousIndex) { transitionName = currentIndex > previousIndex ? 'slide-down' : 'slide-up' } } previousPath = currentPath previousTab = (currentRoute.query.tab as string) || '' return transitionName } return { getTransitionName } }