Init Repo
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
import type { RouteLocationNormalized } from 'vue-router'
|
||||
import { useProjectsStore } from '@/stores/projects'
|
||||
import { episodeService } from '@/services/episode'
|
||||
|
||||
export interface BreadcrumbItem {
|
||||
label: string
|
||||
href?: string
|
||||
isActive?: boolean
|
||||
}
|
||||
|
||||
export class BreadcrumbService {
|
||||
static async generateBreadcrumbs(route: RouteLocationNormalized): Promise<BreadcrumbItem[]> {
|
||||
const pathSegments = route.path.split('/').filter(Boolean)
|
||||
const crumbs: BreadcrumbItem[] = [{ label: 'Home', href: '/' }]
|
||||
|
||||
// Handle different route patterns
|
||||
if (pathSegments[0] === 'projects' && pathSegments[1]) {
|
||||
const projectId = parseInt(pathSegments[1])
|
||||
|
||||
if (!isNaN(projectId)) {
|
||||
// Get project information - initialize store here when needed
|
||||
const projectsStore = useProjectsStore()
|
||||
let project = projectsStore.getProjectById(projectId)
|
||||
if (!project) {
|
||||
try {
|
||||
project = await projectsStore.getProject(projectId)
|
||||
} catch (error) {
|
||||
console.error('Failed to load project for breadcrumbs:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Add project breadcrumb
|
||||
crumbs.push({
|
||||
label: project ? project.name : `Project ${projectId}`,
|
||||
href: `/projects/${projectId}`
|
||||
})
|
||||
|
||||
// Handle tab-based navigation
|
||||
const tab = route.meta?.tab as string
|
||||
const tabLabel = route.meta?.tabLabel as string || this.getTabLabel(tab)
|
||||
|
||||
if (tab) {
|
||||
// For shots tab with episode context
|
||||
if (tab === 'shots' && route.params.episodeId) {
|
||||
crumbs.push({
|
||||
label: tabLabel,
|
||||
href: `/projects/${projectId}/shots`
|
||||
})
|
||||
|
||||
// Add episode context
|
||||
const episodeId = parseInt(route.params.episodeId as string)
|
||||
if (!isNaN(episodeId)) {
|
||||
try {
|
||||
const episodes = await episodeService.getProjectEpisodes(projectId)
|
||||
const episode = episodes.find(ep => ep.id === episodeId)
|
||||
crumbs.push({
|
||||
label: episode ? episode.name : `Episode ${episodeId}`,
|
||||
isActive: true
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Failed to load episode for breadcrumbs:', error)
|
||||
crumbs.push({
|
||||
label: `Episode ${episodeId}`,
|
||||
isActive: true
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if (pathSegments[2] || tab !== 'overview') {
|
||||
// Regular tab navigation (don't show Overview in breadcrumbs unless explicitly navigated to)
|
||||
crumbs.push({
|
||||
label: tabLabel,
|
||||
isActive: true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Handle other routes
|
||||
let currentPath = ''
|
||||
pathSegments.forEach((segment, index) => {
|
||||
currentPath += `/${segment}`
|
||||
const isLast = index === pathSegments.length - 1
|
||||
|
||||
// Format segment label
|
||||
const label = this.formatSegmentLabel(segment)
|
||||
|
||||
crumbs.push({
|
||||
label,
|
||||
href: isLast ? undefined : currentPath,
|
||||
isActive: isLast
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return crumbs
|
||||
}
|
||||
|
||||
private static getTabLabel(tab: string): string {
|
||||
switch (tab) {
|
||||
case 'overview': return 'Overview'
|
||||
case 'shots': return 'Shots'
|
||||
case 'assets': return 'Assets'
|
||||
case 'technical-specs': return 'Technical Specs'
|
||||
default: return tab.charAt(0).toUpperCase() + tab.slice(1).replace(/-/g, ' ')
|
||||
}
|
||||
}
|
||||
|
||||
private static formatSegmentLabel(segment: string): string {
|
||||
// Handle special cases
|
||||
if (segment === 'api-keys') return 'API Keys'
|
||||
if (segment === 'technical-specs') return 'Technical Specs'
|
||||
|
||||
// Default formatting
|
||||
return segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ')
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user