fix: перенёс уровни в бд и пофиксид их отображение на фронте
Backend CI / build-and-test (push) Successful in 52s
Frontend CI / build-and-check (push) Failing after 5m15s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 16s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 1m0s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 32s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 13s
Backend CI / build-and-test (push) Successful in 52s
Frontend CI / build-and-check (push) Failing after 5m15s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 16s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 1m0s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 32s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 13s
This commit is contained in:
@@ -33,8 +33,25 @@ const recommended = computed(() =>
|
||||
)
|
||||
const achievements = computed(() => userStore.achievements.filter(a => a.unlocked).slice(0, 3))
|
||||
const reminders = computed(() => userStore.notifications.slice(0, 3))
|
||||
const xpToNext = 200
|
||||
const xpProgress = computed(() => user.value.xp ?? 120)
|
||||
const currentLevelXp = computed(() => user.value.currentLevelXp ?? 0)
|
||||
const nextLevelXp = computed(() => user.value.nextLevelXp)
|
||||
const userXp = computed(() => user.value.xp ?? 0)
|
||||
const hasLevelProgress = computed(() => nextLevelXp.value !== undefined)
|
||||
const hasNextLevel = computed(() => typeof nextLevelXp.value === 'number' && nextLevelXp.value > currentLevelXp.value)
|
||||
const levelProgressMax = computed(() => hasNextLevel.value ? nextLevelXp.value! - currentLevelXp.value : 1)
|
||||
const levelProgress = computed(() => {
|
||||
if (!hasLevelProgress.value) return 0
|
||||
if (!hasNextLevel.value) return 1
|
||||
return Math.min(Math.max(userXp.value - currentLevelXp.value, 0), levelProgressMax.value)
|
||||
})
|
||||
const levelProgressLabel = computed(() =>
|
||||
!hasLevelProgress.value
|
||||
? `Уровень ${user.value.level}`
|
||||
: hasNextLevel.value ? `Прогресс до уровня ${user.value.level + 1}` : 'Максимальный уровень'
|
||||
)
|
||||
const levelProgressText = computed(() =>
|
||||
hasNextLevel.value ? `${levelProgress.value} / ${levelProgressMax.value} XP` : `${userXp.value} XP`
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([
|
||||
@@ -99,10 +116,10 @@ onMounted(async () => {
|
||||
<GlassCard>
|
||||
<div class="xp-section">
|
||||
<div class="xp-header">
|
||||
<span class="xp-label">Прогресс до уровня {{ user.level + 1 }}</span>
|
||||
<span class="xp-val">{{ xpProgress }} / {{ xpToNext }} XP</span>
|
||||
<span class="xp-label">{{ levelProgressLabel }}</span>
|
||||
<span class="xp-val">{{ levelProgressText }}</span>
|
||||
</div>
|
||||
<ProgressBar :value="xpProgress" :max="xpToNext" />
|
||||
<ProgressBar :value="levelProgress" :max="levelProgressMax" :text="levelProgressText" />
|
||||
</div>
|
||||
</GlassCard>
|
||||
|
||||
|
||||
@@ -24,6 +24,25 @@ const userYearLine = computed(() => {
|
||||
const year = user.value.year ?? 0
|
||||
return Number.isFinite(year) && year > 0 ? `${year} курс` : ''
|
||||
})
|
||||
const currentLevelXp = computed(() => user.value.currentLevelXp ?? 0)
|
||||
const nextLevelXp = computed(() => user.value.nextLevelXp)
|
||||
const userXp = computed(() => user.value.xp ?? 0)
|
||||
const hasLevelProgress = computed(() => nextLevelXp.value !== undefined)
|
||||
const hasNextLevel = computed(() => typeof nextLevelXp.value === 'number' && nextLevelXp.value > currentLevelXp.value)
|
||||
const levelProgressMax = computed(() => hasNextLevel.value ? nextLevelXp.value! - currentLevelXp.value : 1)
|
||||
const levelProgress = computed(() => {
|
||||
if (!hasLevelProgress.value) return 0
|
||||
if (!hasNextLevel.value) return 1
|
||||
return Math.min(Math.max(userXp.value - currentLevelXp.value, 0), levelProgressMax.value)
|
||||
})
|
||||
const levelProgressLabel = computed(() =>
|
||||
!hasLevelProgress.value
|
||||
? `Уровень ${user.value.level}`
|
||||
: hasNextLevel.value ? `Уровень ${user.value.level}` : `Уровень ${user.value.level} · максимум`
|
||||
)
|
||||
const levelProgressText = computed(() =>
|
||||
hasNextLevel.value ? `${levelProgress.value} / ${levelProgressMax.value} XP` : `${userXp.value} XP`
|
||||
)
|
||||
const interestTags = ref([
|
||||
{ label: '#ML', active: true },
|
||||
{ label: '#ИИ', active: true },
|
||||
@@ -66,10 +85,10 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="level">
|
||||
<div class="level-header">
|
||||
<span>Уровень {{ user.level }}</span>
|
||||
<span>{{ user.xp }} / 200 XP</span>
|
||||
<span>{{ levelProgressLabel }}</span>
|
||||
<span>{{ levelProgressText }}</span>
|
||||
</div>
|
||||
<ProgressBar :value="user.xp ?? 0" :max="200" />
|
||||
<ProgressBar :value="levelProgress" :max="levelProgressMax" :text="levelProgressText" />
|
||||
</div>
|
||||
<div class="tags">
|
||||
<div class="section-title">Интересы</div>
|
||||
|
||||
Reference in New Issue
Block a user