feat: первое подключение фронтенда
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 8s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 54s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 27s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 6s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 8s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 54s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Successful in 27s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 6s
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useLecturesStore } from '@/stores/lectures'
|
||||
@@ -9,6 +9,7 @@ import StatsWidget from '@/components/ui/StatsWidget.vue'
|
||||
import LectureCard from '@/components/ui/LectureCard.vue'
|
||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||
import AchievementBadge from '@/components/ui/AchievementBadge.vue'
|
||||
import EmptyState from '@/components/ui/EmptyState.vue'
|
||||
|
||||
const auth = useAuthStore()
|
||||
const lectures = useLecturesStore()
|
||||
@@ -16,7 +17,7 @@ const userStore = useUserStore()
|
||||
const router = useRouter()
|
||||
|
||||
const user = computed(() => auth.user!)
|
||||
const nextLecture = computed(() => lectures.registeredLectures[0] ?? lectures.all[0]!)
|
||||
const nextLecture = computed(() => lectures.registeredLectures[0] ?? lectures.all[0])
|
||||
const recommended = computed(() =>
|
||||
lectures.all.filter(l => !lectures.registeredIds.includes(l.id)).slice(0, 3)
|
||||
)
|
||||
@@ -24,6 +25,14 @@ const achievements = computed(() => userStore.achievements.filter(a => a.unlocke
|
||||
const reminders = computed(() => userStore.notifications.slice(0, 3))
|
||||
const xpToNext = 200
|
||||
const xpProgress = computed(() => user.value.xp ?? 120)
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([
|
||||
lectures.all.length ? Promise.resolve() : lectures.fetchLectures(),
|
||||
userStore.fetchStudentData(user.value.id),
|
||||
])
|
||||
await lectures.fetchRegisteredForUser(user.value.id)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -36,11 +45,11 @@ const xpProgress = computed(() => user.value.xp ?? 120)
|
||||
<div class="quick-actions">
|
||||
<button class="btn-primary" @click="router.push('/catalog')">Найти лекцию</button>
|
||||
<button class="btn-secondary" @click="router.push('/my-lectures')">Мои записи</button>
|
||||
<button class="btn-secondary" @click="router.push(`/review/${nextLecture?.id ?? '1'}`)">Оставить отзыв</button>
|
||||
<button class="btn-secondary" :disabled="!nextLecture" @click="nextLecture && router.push(`/review/${nextLecture.id}`)">Оставить отзыв</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<GlassCard>
|
||||
<GlassCard v-if="nextLecture">
|
||||
<div class="next-lecture">
|
||||
<div>
|
||||
<div class="section-title">Ближайшая лекция</div>
|
||||
@@ -57,6 +66,7 @@ const xpProgress = computed(() => user.value.xp ?? 120)
|
||||
</div>
|
||||
</div>
|
||||
</GlassCard>
|
||||
<EmptyState v-else-if="!lectures.loading" title="Пока нет лекций" subtitle="Каталог пуст или данные ещё не синхронизированы." />
|
||||
|
||||
<div class="stats-row">
|
||||
<StatsWidget label="Посещено лекций" :value="user.lecturesAttended ?? 12" icon="📚" color="green" />
|
||||
@@ -80,7 +90,8 @@ const xpProgress = computed(() => user.value.xp ?? 120)
|
||||
<h2 class="section-title">✨ Рекомендуемые лекции</h2>
|
||||
<button class="link-btn" @click="router.push('/catalog')">Все лекции →</button>
|
||||
</div>
|
||||
<div class="cards-grid">
|
||||
<EmptyState v-if="lectures.loading" title="Загружаем рекомендации" subtitle="Получаем данные с backend." />
|
||||
<div v-else class="cards-grid">
|
||||
<LectureCard
|
||||
v-for="l in recommended"
|
||||
:key="l.id"
|
||||
|
||||
Reference in New Issue
Block a user