habits.andr33v.ru/app/pages/leaderboard.vue

84 lines
1.7 KiB
Vue

<template>
<div class="leaderboard-container">
<h3>Monthly Leaderboard</h3>
<div v-if="pending" class="loading">Loading leaderboard...</div>
<div v-else-if="error" class="error-container">
<p>An error occurred while fetching the leaderboard. Please try again.</p>
</div>
<ul v-else class="leaderboard-list">
<li
v-for="entry in leaderboard"
:key="entry.rank + entry.nickname"
class="leaderboard-item"
:class="{ 'self': currentUser && currentUser.nickname === entry.nickname }"
>
<span class="rank">{{ entry.rank }}.</span>
<span class="name">{{ entry.nickname }}</span>
<span class="exp">{{ entry.exp }} EXP</span>
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { useAuth } from '~/composables/useAuth';
const { user: currentUser } = useAuth(); // Get current authenticated user
const { data, pending, error } = await useFetch('/api/leaderboard', {
lazy: true,
server: false,
});
const leaderboard = computed(() => data.value?.leaderboard || []);
</script>
<style scoped>
.leaderboard-container {
max-width: 600px;
margin: 0 auto;
}
h3 {
text-align: center;
margin-bottom: 20px;
}
.leaderboard-list {
list-style: none;
padding: 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.leaderboard-item {
display: flex;
align-items: center;
padding: 15px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.leaderboard-item.self {
background-color: #d8e1e9;
border: 1px solid #81a1c1;
}
.rank {
font-weight: bold;
width: 40px;
}
.name {
flex-grow: 1;
}
.exp {
font-weight: bold;
color: #4c566a;
}
</style>