Added achievement data

This commit is contained in:
2026-04-28 22:16:21 +10:00
parent 14aed7bf6e
commit b94b1d8ec2
43 changed files with 1559 additions and 130 deletions
+91 -4
View File
@@ -3,17 +3,48 @@ import MainHeader from "@/Components/FlightsGoneBy/MainHeader.vue";
import MainFooter from "@/Components/FlightsGoneBy/MainFooter.vue";
import Radar from "@/Components/FlightsGoneBy/Radar.vue";
import { usePage, router } from "@inertiajs/vue3";
import { ref } from "vue";
import {SharedProps} from "@/Types/types";
import { ref, watch } from "vue";
import { SharedProps, Notification } from "@/Types/types";
import axios from "axios";
const page = usePage<SharedProps>().props;
const transitionKey = ref(0);
router.on('success', () => {
const seenNotificationIds = ref<Set<number>>(new Set())
const achievementSound = new Audio('/sounds/seatBelt.wav')
function handleNewNotifications(notifications: Notification[]) {
if (!notifications?.length) return
const unseen = notifications.filter(n => !seenNotificationIds.value.has(n.id))
if (!unseen.length) return
unseen.forEach(n => seenNotificationIds.value.add(n.id))
activeToasts.value.push(...unseen)
achievementSound.play().catch(() => {})
}
// ── Toasts ────────────────────────────────────────────────────────────────────
const activeToasts = ref<Notification[]>([])
async function dismissToast(notification: Notification) {
activeToasts.value = activeToasts.value.filter(n => n.id !== notification.id)
await axios.patch(`/notifications/${notification.id}/read`)
}
console.log(page.achievement_notifications)
watch(
() => page.achievement_notifications,
handleNewNotifications,
{ immediate: true }
)
router.on('success', (event) => {
transitionKey.value++;
handleNewNotifications(event.detail.page.props.achievement_notifications as Notification[] ?? [])
});
</script>
<template>
<Radar>
<div class="layoutContainer">
@@ -25,9 +56,65 @@ router.on('success', () => {
</Transition>
<MainFooter :key="transitionKey" />
</div>
<div class="toast-stack">
<TransitionGroup name="toast">
<v-card
v-for="notification in activeToasts"
:key="notification.id"
class="toast-card glass"
rounded="lg"
elevation="4"
max-width="360"
>
<v-card-text class="d-flex align-center ga-3">
<v-icon icon="mdi-trophy" color="amber" size="32" />
<div>
<div class="text-subtitle-2 font-weight-bold">{{ notification.title }}</div>
<div class="text-body-2 text-medium-emphasis">{{ notification.body }}</div>
</div>
<v-btn
icon="mdi-close"
variant="text"
size="small"
class="ml-auto"
@click="dismissToast(notification)"
/>
</v-card-text>
</v-card>
</TransitionGroup>
</div>
</Radar>
</template>
<style scoped>
.toast-stack {
position: fixed;
bottom: 1.5rem;
right: 1.5rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
z-index: 9999;
max-height: 50dvh;
overflow-y: scroll;
scrollbar-width: none;
}
.toast-stack::-webkit-scrollbar {
display: none;
}
.toast-card {
flex-shrink: 0;
background: rgb(var(--v-theme-surface)) !important;
}
.toast-enter-from { opacity: 0; transform: translateX(100%); }
.toast-leave-to { opacity: 0; transform: translateX(100%); }
.toast-enter-active,
.toast-leave-active { transition: all 0.3s ease; }
</style>
<style scoped>
.layoutContainer {
display: flex;