Files
2026-04-28 22:16:21 +10:00

147 lines
3.9 KiB
Vue

<script setup lang="ts">
import {computed} from "vue"
import ProfileLayout from "@/Components/FlightsGoneBy/ProfileLayout.vue"
import ProfileViewSwitcher from "@/Components/FlightsGoneBy/ProfileViewSwitcher.vue"
import AchievementCard from "@/Components/FlightsGoneBy/AchievementCard.vue"
import {Achievement, User, UserAchievement} from "@/Types/types"
import { Head } from "@inertiajs/vue3";
import MainLayout from "@/Layouts/MainLayout.vue";
defineOptions({ layout: MainLayout })
const props = defineProps<{
user: User
canEdit: boolean
isFollowing: boolean
achievements: Record<string, Achievement[]>
userAchievements: Record<number, UserAchievement>
}>()
const totalAchievements = computed(() =>
Object.values(props.achievements).reduce((sum, group) => sum + group.length, 0)
)
const unlockedCount = computed(() =>
Object.values(props.achievements)
.flat()
.filter(a => {
const ua = props.userAchievements[a.id]
if (!ua) return false
if (!a.progressive || !a.threshold) return true
return (ua.progress ?? 0) >= a.threshold
}).length
)
</script>
<template>
<Head :title="`${user.name}'s Achievements`" />
<ProfileLayout
:user="user"
:achievementCount="unlockedCount"
:is-following="isFollowing"
:loading="false"
>
<ProfileViewSwitcher active-view="achievements" :user="user" />
<div class="achievements-page">
<div class="achievements-summary">
<span class="summary-text">
{{ unlockedCount }} / {{ totalAchievements }} achievements unlocked
</span>
<v-progress-linear
:model-value="Math.round((unlockedCount / totalAchievements) * 100)"
color="amber"
rounded
height="6"
bg-color="rgba(255,255,255,0.1)"
/>
</div>
<div
v-for="(categoryAchievements, categoryName) in achievements"
:key="categoryName"
class="achievement-category"
>
<div class="category-header">
<h2 class="category-name">{{ categoryName }}</h2>
<span class="category-count">
{{ categoryAchievements.filter(a => userAchievements[a.id]).length }}
/ {{ categoryAchievements.length }}
</span>
</div>
<div class="achievement-grid">
<AchievementCard
v-for="achievement in categoryAchievements"
:key="achievement.id"
:achievement="achievement"
:user-achievement="userAchievements[achievement.id]"
/>
</div>
</div>
</div>
</ProfileLayout>
</template>
<style scoped>
.achievements-page {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 1.5rem 1rem;
display: flex;
flex-direction: column;
gap: 2.5rem;
}
.achievements-summary {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.summary-text {
font-size: 0.9rem;
opacity: 0.7;
}
.achievement-category {
display: flex;
flex-direction: column;
gap: 1rem;
}
.category-header {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding-bottom: 0.5rem;
}
.category-name {
font-size: 1.1rem;
font-weight: 700;
letter-spacing: 0.05em;
text-transform: uppercase;
opacity: 0.9;
}
.category-count {
font-size: 0.85rem;
opacity: 0.5;
}
.achievement-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 0.75rem;
}
@media (max-width: 600px) {
.achievement-grid {
grid-template-columns: 1fr;
}
}
</style>