You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.3 KiB
129 lines
4.3 KiB
<script setup lang="ts">
|
|
import { User, GraduationCap, Building2, Check } from 'lucide-vue-next'
|
|
import { Badge } from '@/components/ui/badge'
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from '@/components/ui/dropdown-menu'
|
|
import { Button } from '@/components/ui/button'
|
|
|
|
// User role types matching our database schema
|
|
type UserRole = 'individual' | 'educator' | 'company'
|
|
|
|
interface RoleOption {
|
|
value: UserRole
|
|
label: string
|
|
description: string
|
|
icon: any
|
|
color: string
|
|
enabled: boolean
|
|
badge?: string
|
|
}
|
|
|
|
const roles: RoleOption[] = [
|
|
{
|
|
value: 'individual',
|
|
label: 'Privatperson',
|
|
description: 'Private Nutzung',
|
|
icon: User,
|
|
color: 'text-purple-600',
|
|
enabled: true,
|
|
},
|
|
{
|
|
value: 'educator',
|
|
label: 'Pädagoge',
|
|
description: 'Lehrkräfte und Schulen',
|
|
icon: GraduationCap,
|
|
color: 'text-orange-500',
|
|
enabled: true,
|
|
// badge: 'Demnächst',
|
|
},
|
|
{
|
|
value: 'company',
|
|
label: 'Firma',
|
|
description: 'Geschäftskunden',
|
|
icon: Building2,
|
|
color: 'text-blue-600',
|
|
enabled: true,
|
|
// badge: 'Demnächst',
|
|
},
|
|
]
|
|
|
|
// Current role - will come from user session later
|
|
const currentRole = ref<UserRole>('individual')
|
|
|
|
const currentRoleData = computed(() => {
|
|
return roles.find((r) => r.value === currentRole.value) || roles[0]
|
|
})
|
|
|
|
function switchRole(role: UserRole) {
|
|
if (roles.find((r) => r.value === role)?.enabled) {
|
|
currentRole.value = role
|
|
// TODO: Update user session/store with new role
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<DropdownMenu>
|
|
<dropdownMenuTrigger as-child>
|
|
<Button variant="outline"
|
|
class="gap-2 border-2 border-white/30 bg-white/5 text-white hover:bg-white/10 hover:border-white/50 transition-all duration-200 group"
|
|
title="Rolle wechseln">
|
|
<!-- Context label + role -->
|
|
<span class="text-xs text-white/70 font-normal hidden md:inline">Du kaufst als:</span>
|
|
<component :is="currentRoleData.icon" class="h-4 w-4 text-white" />
|
|
<span class="font-medium text-white">{{ currentRoleData.label }}</span>
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
|
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
|
class="ml-1 opacity-70 text-white group-hover:opacity-100 transition-opacity">
|
|
<polyline points="6 9 12 15 18 9" />
|
|
</svg>
|
|
</Button>
|
|
</dropdownMenuTrigger>
|
|
<DropdownMenuContent align="start" class="w-[312px]">
|
|
<DropdownMenuLabel class="text-sm font-normal text-muted-foreground py-3">
|
|
Ich kaufe als...
|
|
</DropdownMenuLabel>
|
|
<DropdownMenuSeparator />
|
|
|
|
<DropdownMenuItem v-for="role in roles" :key="role.value" :disabled="!role.enabled" :class="[
|
|
'gap-3 py-3 cursor-pointer group',
|
|
!role.enabled && 'opacity-60 cursor-not-allowed',
|
|
currentRole === role.value && 'bg-purple-50 dark:bg-purple-950',
|
|
]" @click="switchRole(role.value)">
|
|
<component :is="role.icon" :class="['h-5 w-5', role.color]" />
|
|
|
|
<div class="flex-1 flex flex-col gap-1">
|
|
<span class="text-sm font-semibold">{{ role.label }}</span>
|
|
<span class="text-sm text-muted-foreground group-hover:text-foreground group-data-[highlighted]:text-accent-foreground transition-colors">{{
|
|
role.description }}</span>
|
|
</div>
|
|
|
|
<!-- High-contrast checkmark for colorblind accessibility -->
|
|
<div v-if="currentRole === role.value" class="relative flex-shrink-0">
|
|
<!-- Background circle for contrast -->
|
|
<div class="absolute inset-0 bg-white dark:bg-gray-900 rounded-full opacity-90"></div>
|
|
<!-- Checkmark icon with high contrast -->
|
|
<Check class="h-5 w-5 text-gray-900 dark:text-white relative z-10" />
|
|
</div>
|
|
|
|
<Badge v-if="role.badge" variant="secondary" class="text-xs px-2 py-0.5 flex-shrink-0">
|
|
{{ role.badge }}
|
|
</Badge>
|
|
</DropdownMenuItem>
|
|
|
|
<DropdownMenuSeparator />
|
|
|
|
<div class="px-3 py-2.5 text-sm text-muted-foreground">
|
|
<p class="leading-relaxed">
|
|
💡 Die Rolle bestimmt, welche Produkte und Konditionen dir angezeigt werden.
|
|
</p>
|
|
</div>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</template>
|
|
|