diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index b5d4a49..add61c2 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -147,7 +147,7 @@ --gradient-coin-chip-hover: linear-gradient(135deg, var(--color-primary-a40) 0%, var(--color-aqua-a40) 100%); --color-coin-chip-border: var(--color-primary-a45); --color-coin-chip-text: var(--color-primary-border); - --color-coin-chip-label: var(--color-aqua-dark); + --color-coin-chip-label: var(--color-primary-border); --radius-sm: 8px; --radius-md: 12px; diff --git a/frontend/src/components/layout/AppTopbar.vue b/frontend/src/components/layout/AppTopbar.vue index 56f32ca..0a1a989 100644 --- a/frontend/src/components/layout/AppTopbar.vue +++ b/frontend/src/components/layout/AppTopbar.vue @@ -5,6 +5,7 @@ import { useAuthStore } from '@/stores/auth' import { useUserStore } from '@/stores/user' import CoinChip from '@/components/ui/CoinChip.vue' import AppIcon from '@/components/ui/AppIcon.vue' +import ModalDialog from '@/components/ui/ModalDialog.vue' import { formatUserName } from '@/utils/formatUserName' import type { UserRole } from '@/types' @@ -12,6 +13,7 @@ const auth = useAuthStore() const userStore = useUserStore() const router = useRouter() const isProfileMenuOpen = ref(false) +const isCoinDialogOpen = ref(false) const profileMenuRef = ref(null) const unreadCount = computed(() => userStore.unreadCount()) @@ -42,10 +44,20 @@ function closeProfileMenu() { isProfileMenuOpen.value = false } +function closeCoinDialog() { + isCoinDialogOpen.value = false +} + function toggleProfileMenu() { + closeCoinDialog() isProfileMenuOpen.value = !isProfileMenuOpen.value } +function openCoinDialog() { + closeProfileMenu() + isCoinDialogOpen.value = true +} + function openProfile() { closeProfileMenu() router.push('/profile') @@ -65,9 +77,9 @@ async function logout() { } function handleDocumentPointerDown(event: PointerEvent) { - if (!isProfileMenuOpen.value) return const target = event.target if (!(target instanceof Node)) return + if (!profileMenuRef.value?.contains(target)) closeProfileMenu() } @@ -90,9 +102,20 @@ onBeforeUnmount(() => {
- + -
+ + +
+
+ + Монеты UniVerse +
+

+ В будущем монеты можно будет использовать во внутреннем магазине. Сейчас магазин еще не запущен, поэтому монеты просто копятся на вашем балансе. +

+ +
+
@@ -185,13 +221,74 @@ onBeforeUnmount(() => { gap: 12px; flex-shrink: 0; } +.coin-dialog-content { + display: flex; + flex-direction: column; + align-items: stretch; + gap: 14px; +} +.coin-dialog-title { + display: flex; + align-items: center; + gap: 9px; + color: var(--color-text); + font-size: 17px; + font-weight: 800; +} +.coin-dialog-icon { + flex: 0 0 auto; + color: var(--color-coin-chip-text); +} +.coin-dialog-content p { + margin: 0; + color: var(--color-text-secondary); + font-size: 14px; + line-height: 1.5; +} +.coin-dialog-ok { + min-width: 92px; + align-self: center; + justify-content: center; + margin-top: 2px; +} +.level-chip { + display: inline-flex; + align-items: center; + gap: 5px; + height: 28px; + padding: 0 11px; + border: 1px solid var(--color-primary-a20); + border-radius: 20px; + background: var(--color-primary-a10); + color: var(--color-primary-dark); + cursor: default; + white-space: nowrap; +} +.level-icon { + color: var(--color-primary); +} +.level-label { + color: var(--color-text-secondary); + font-size: 12px; + font-weight: 700; +} +.level-value { + color: var(--color-primary-dark); + font-size: 14px; + font-weight: 800; +} .notif-btn { position: relative; - background: none; - border: none; - font-size: 20px; + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + background: transparent; + border: 0; + color: var(--color-text-secondary); cursor: pointer; - padding: 4px; + padding: 0; border-radius: 50%; transition: background 0.2s; } diff --git a/frontend/src/components/ui/CoinChip.vue b/frontend/src/components/ui/CoinChip.vue index df7c4ed..5ba3b35 100644 --- a/frontend/src/components/ui/CoinChip.vue +++ b/frontend/src/components/ui/CoinChip.vue @@ -2,14 +2,15 @@ import AppIcon from '@/components/ui/AppIcon.vue' defineProps<{ amount: number }>() +defineEmits<{ click: [] }>()