10-04-2026

This commit is contained in:
Kevin Adametz 2026-04-22 12:57:10 +02:00
parent 70a7776da5
commit 761b1156c1
50 changed files with 11997 additions and 150 deletions

View file

@ -0,0 +1,278 @@
<template>
<Transition name="slide-right">
<div v-if="open" class="user-menu glass--panel">
<!-- User header -->
<div class="user-menu__header">
<div class="user-menu__avatar">
<span>K</span>
</div>
<div class="user-menu__info">
<div class="user-menu__name">k-adam</div>
<div class="user-menu__handle">@k-adam</div>
</div>
</div>
<div class="user-menu__divider" />
<!-- Menu items -->
<div class="user-menu__items">
<button class="user-menu__item" @click="$emit('navigate', 'upgrade')">
<q-icon name="auto_awesome" size="20px" />
<span>Plan upgraden</span>
</button>
<button class="user-menu__item" @click="$emit('navigate', 'personalize')">
<q-icon name="palette" size="20px" />
<span>Personalisierung</span>
</button>
<button class="user-menu__item" @click="$emit('navigate', 'settings')">
<q-icon name="settings" size="20px" />
<span>Einstellungen</span>
</button>
</div>
<div class="user-menu__divider" />
<!-- Help with submenu -->
<div class="user-menu__items">
<button
class="user-menu__item"
:class="{ 'user-menu__item--active': helpOpen }"
@click="helpOpen = !helpOpen"
>
<q-icon name="support_agent" size="20px" />
<span>Hilfe</span>
<q-icon
name="chevron_right"
size="18px"
class="user-menu__chevron"
:class="{ 'user-menu__chevron--open': helpOpen }"
/>
</button>
<!-- Help sub-items -->
<Transition name="expand">
<div v-if="helpOpen" class="user-menu__sub">
<button class="user-menu__item user-menu__item--sub" @click="$emit('navigate', 'help-center')">
<q-icon name="help_outline" size="18px" />
<span>Hilfecenter</span>
</button>
<button class="user-menu__item user-menu__item--sub" @click="$emit('navigate', 'release-notes')">
<q-icon name="new_releases" size="18px" />
<span>Release-Hinweise</span>
</button>
<button class="user-menu__item user-menu__item--sub" @click="$emit('navigate', 'terms')">
<q-icon name="description" size="18px" />
<span>AGB und Richtlinien</span>
</button>
<button class="user-menu__item user-menu__item--sub" @click="$emit('navigate', 'report-bug')">
<q-icon name="bug_report" size="18px" />
<span>Fehler melden</span>
</button>
<button class="user-menu__item user-menu__item--sub" @click="$emit('navigate', 'download')">
<q-icon name="download" size="18px" />
<span>Apps herunterladen</span>
</button>
<button class="user-menu__item user-menu__item--sub" @click="$emit('navigate', 'shortcuts')">
<q-icon name="keyboard" size="18px" />
<span>Tastaturkuerzel</span>
</button>
</div>
</Transition>
</div>
<div class="user-menu__divider" />
<div class="user-menu__items">
<button class="user-menu__item" @click="$emit('navigate', 'logout')">
<q-icon name="logout" size="20px" />
<span>Abmelden</span>
</button>
</div>
<!-- Footer: user + plan -->
<div class="user-menu__footer">
<div class="user-menu__avatar user-menu__avatar--sm">
<span>K</span>
</div>
<div class="user-menu__info">
<div class="user-menu__name user-menu__name--sm">Kevin Ada</div>
<div class="user-menu__plan">Free</div>
</div>
</div>
</div>
</Transition>
</template>
<script setup>
import { ref } from 'vue'
defineProps({ open: { type: Boolean, default: false } })
defineEmits(['close', 'navigate'])
const helpOpen = ref(false)
</script>
<style scoped>
.user-menu {
position: fixed;
top: 0;
right: 0;
bottom: 0;
z-index: 25;
width: 280px;
max-width: 85vw;
display: flex;
flex-direction: column;
border-radius: 20px 0 0 20px;
border-top: none;
border-left: 1px solid rgba(255, 255, 255, 0.08);
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
/* User header */
.user-menu__header {
display: flex;
align-items: center;
gap: 12px;
padding: 24px 20px 16px;
}
.user-menu__avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background: #e05a33;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
font-weight: 700;
color: #fff;
flex-shrink: 0;
}
.user-menu__avatar--sm {
width: 32px;
height: 32px;
font-size: 13px;
}
.user-menu__info {
min-width: 0;
}
.user-menu__name {
font-size: 15px;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.user-menu__name--sm {
font-size: 13px;
}
.user-menu__handle {
font-size: 12px;
opacity: 0.5;
}
.user-menu__plan {
font-size: 11px;
opacity: 0.45;
}
/* Divider */
.user-menu__divider {
height: 1px;
margin: 4px 16px;
background: rgba(128, 128, 128, 0.15);
}
/* Menu items */
.user-menu__items {
padding: 4px 8px;
}
.user-menu__item {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
padding: 10px 12px;
border: none;
background: none;
color: inherit;
font-family: inherit;
font-size: 14px;
cursor: pointer;
border-radius: 10px;
transition: background 0.15s ease;
text-align: left;
}
.user-menu__item:hover,
.user-menu__item--active {
background: rgba(128, 128, 128, 0.12);
}
.user-menu__item:active {
background: rgba(128, 128, 128, 0.2);
}
.user-menu__item--sub {
padding-left: 24px;
font-size: 13px;
}
.user-menu__chevron {
margin-left: auto;
transition: transform 0.2s ease;
}
.user-menu__chevron--open {
transform: rotate(90deg);
}
/* Help sub-items */
.user-menu__sub {
overflow: hidden;
}
/* Footer */
.user-menu__footer {
margin-top: auto;
display: flex;
align-items: center;
gap: 10px;
padding: 16px 20px 24px;
border-top: 1px solid rgba(128, 128, 128, 0.1);
}
/* Slide-right transition */
.slide-right-enter-active,
.slide-right-leave-active {
transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}
.slide-right-enter-from,
.slide-right-leave-to {
transform: translateX(100%);
}
/* Expand transition for help sub-menu */
.expand-enter-active,
.expand-leave-active {
transition: max-height 0.25s ease, opacity 0.2s ease;
max-height: 300px;
opacity: 1;
}
.expand-enter-from,
.expand-leave-to {
max-height: 0;
opacity: 0;
}
</style>