added notification cound badge in navbar

This commit is contained in:
2025-12-31 15:58:39 +01:00
parent e3f9b3b8e9
commit 631d70528f
3 changed files with 64 additions and 10 deletions

View File

@@ -11,6 +11,7 @@
<router-link to="/notifications" class="nav-item">
<i class="fa-solid fa-bell"></i>
<span v-if="totalCount > 0" class="badge">{{ totalCount }}</span>
</router-link>
<button class="nav-item logout" @click="logout">
@@ -22,27 +23,32 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { onMounted } from 'vue'
import { logout as authLogout } from '../store.ts'
import { useNotifications } from '../store'
const router = useRouter()
const { totalCount, refreshNotifications } = useNotifications()
function logout() {
authLogout()
router.push('/login')
}
onMounted(() => {
refreshNotifications()
})
</script>
<style scoped>
#bottom-nav {
display: flex;
gap: 28px;
padding: 5px 22px;
background: var(--panel);
border: 1px solid var(--border);
border-radius: 100vh;
z-index: 50;
user-select: none;
-webkit-user-select: none;
@@ -50,18 +56,16 @@ function logout() {
.nav-item {
all: unset;
cursor: pointer;
position: relative;
cursor: pointer;
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.25rem;
border-radius: 50%;
border-radius: 100vh;
transition:
color 0.2s ease,
background-color 0.2s ease,
@@ -75,6 +79,25 @@ function logout() {
transform 0.15s ease;
}
.badge {
position: absolute;
top: 4px;
right: 4px;
background-color: var(--accent);
color: black;
font-size: 0.65rem;
font-weight: bold;
min-width: 18px;
height: 18px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
padding: 2px;
border: 2px solid var(--panel);
pointer-events: none;
}
@media (hover: hover) {
.nav-item:hover {
background: rgba(255, 255, 255, 0.04);

View File

@@ -35,13 +35,13 @@
import { onMounted, ref } from 'vue'
import { fetchFriendRequests, acceptFriendRequest } from '../api/friends'
import { fetchRoomInvites, acceptRoomInvite } from '../api/rooms.ts'
import type { FriendRequest, RoomInvite } from '../types'
import { useNotifications } from '../store'
const requests = ref<FriendRequest[]>([])
const invites = ref<RoomInvite[]>([])
const errorMessage = ref('')
const { requests, invites, refreshNotifications } = useNotifications()
onMounted(async () => {
await refreshNotifications()
requests.value = await fetchFriendRequests()
invites.value = await fetchRoomInvites()
})

View File

@@ -1,6 +1,10 @@
import { apiFetch } from './api/client'
import type { LoginResponse, User } from './types'
import * as authStore from './authStore'
import { ref, computed } from 'vue'
import { fetchFriendRequests } from './api/friends'
import { fetchRoomInvites } from './api/rooms'
import type { FriendRequest, RoomInvite } from './types'
export const initAuth = authStore.getAuthData
export const getLastRoom = authStore.getLastRoom
@@ -36,3 +40,30 @@ export async function validateToken(): Promise<boolean> {
return false
}
}
const requests = ref<FriendRequest[]>([])
const invites = ref<RoomInvite[]>([])
export function useNotifications() {
const totalCount = computed(() => requests.value.length + invites.value.length)
async function refreshNotifications() {
try {
const [fReqs, rInvs] = await Promise.all([
fetchFriendRequests(),
fetchRoomInvites()
])
requests.value = fReqs
invites.value = rInvs
} catch (err) {
console.error("Failed to fetch notifications", err)
}
}
return {
requests,
invites,
totalCount,
refreshNotifications
}
}