@ -3,6 +3,8 @@ import { Wrench, FlaskConical, Ticket, Sparkles, GraduationCap, Home } from 'luc
import { Tabs , TabsList , TabsTrigger } from '@/components/ui/tabs'
import { Badge } from '@/components/ui/badge'
type RoleCode = 'private' | 'educator' | 'company'
interface ProductArea {
id : string
label : string
@ -11,6 +13,7 @@ interface ProductArea {
visible : boolean
badge ? : string
route : string
roleVisibility ? : 'all' | RoleCode [ ]
}
const areas : ProductArea [ ] = [
@ -21,6 +24,7 @@ const areas: ProductArea[] = [
enabled : true ,
visible : true ,
route : '/' ,
roleVisibility : 'all' ,
} ,
{
id : 'makerspace' ,
@ -29,6 +33,7 @@ const areas: ProductArea[] = [
enabled : true ,
visible : true ,
route : '/products' ,
roleVisibility : 'all' ,
} ,
{
id : 'educator' ,
@ -38,6 +43,7 @@ const areas: ProductArea[] = [
visible : true ,
badge : 'Demnächst' ,
route : '/educator' ,
roleVisibility : [ 'educator' ] ,
} ,
{
id : 'experimenta' ,
@ -47,6 +53,7 @@ const areas: ProductArea[] = [
visible : true ,
badge : 'Demnächst' ,
route : '/experimenta' ,
roleVisibility : 'all' ,
} ,
{
id : 'labs' ,
@ -56,22 +63,41 @@ const areas: ProductArea[] = [
visible : false ,
badge : 'Demnächst' ,
route : '/labs' ,
roleVisibility : [ 'educator' , 'company' ] ,
} ,
]
const route = useRoute ( )
const { activeRole } = useActiveRole ( )
/ / F i l t e r a r e a s b y r o l e v i s i b i l i t y
const visibleAreas = computed ( ( ) => {
return areas . filter ( area => {
/ / L e g a c y v i s i b l e f l a g c h e c k
if ( ! area . visible ) return false
/ / N o r o l e r e q u i r e m e n t = v i s i b l e t o a l l ( b a c k w a r d c o m p a t i b l e )
if ( ! area . roleVisibility ) return true
/ / E x p l i c i t l y s e t t o ' a l l '
if ( area . roleVisibility === 'all' ) return true
/ / C h e c k i f u s e r ' s a c t i v e r o l e m a t c h e s
return area . roleVisibility . includes ( activeRole . value as RoleCode )
} )
} )
const currentArea = computed ( ( ) => {
/ / D e t e r m i n e c u r r e n t a r e a b a s e d o n r o u t e - c h e c k a r e a s a r r a y d y n a m i c a l l y
/ / D e t e r m i n e c u r r e n t a r e a b a s e d o n r o u t e - c h e c k v i s i b l e A r e a s a r r a y d y n a m i c a l l y
const currentPath = route . path
/ / E x a c t m a t c h f o r r o o t p a t h
if ( currentPath === '/' ) {
return areas . find ( area => area . route === '/' ) ? . id || ''
return visibleAreas . value . find ( area => area . route === '/' ) ? . id || ''
}
/ / F i n d a r e a w h e r e r o u t e p a t h s t a r t s w i t h a r e a . r o u t e
const matchedArea = areas . find ( area =>
const matchedArea = visibleAreas . value . find ( area =>
area . route !== '/' && currentPath . startsWith ( area . route )
)
@ -90,7 +116,7 @@ function navigateToArea(area: ProductArea) {
<!-- Desktop : Tabs -- >
< Tabs :model-value ="currentArea" class = "hidden md:block" >
< TabsList class = "h-auto p-2 bg-white/5" >
< TabsTrigger v -for = " area in areas.filter ( area = > area . visible ) " :key=" area . id " :value=" area . id "
< TabsTrigger v -for = " area in visibleAreas " :key ="area.id" :value ="area.id "
: disabled = "!area.enabled" : class = " [
'gap-2 py-3 md:py-4 data-[state=active]:bg-accent data-[state=active]:text-white data-[state=active]:shadow-md' ,
! area . enabled && 'opacity-50 cursor-not-allowed' ,
@ -112,7 +138,7 @@ function navigateToArea(area: ProductArea) {
<!-- Mobile : Horizontal scroll with cards ( matching desktop styling ) -- >
< div class = "md:hidden overflow-x-auto scrollbar-hide" >
< div class = "inline-flex h-auto items-center justify-center rounded-[35px] bg-white/5 p-2 min-w-max" >
< button v -for = " area in areas.filter ( area = > area . visible ) " :key=" area . id " :disabled=" ! area . enabled " :class=" [
< button v -for = " area in visibleAreas " :key ="area.id" :disabled ="!area.enabled" : class = " [
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-[25px] px-4 py-3 text-lg font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-0' ,
currentArea === area . id
? 'bg-accent text-white shadow-md'