feat: подготовил дизайн (изменения из другого репозитория)
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 5s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 8s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 3s

This commit is contained in:
2026-05-08 01:06:22 +03:00
parent 655ab1b5c5
commit 047611fd24
54 changed files with 4497 additions and 28 deletions
@@ -0,0 +1,69 @@
<script setup lang="ts">
import { computed } from 'vue'
import { useLecturesStore } from '@/stores/lectures'
import GlassCard from '@/components/ui/GlassCard.vue'
import StatsWidget from '@/components/ui/StatsWidget.vue'
import ProgressBar from '@/components/ui/ProgressBar.vue'
const lecturesStore = useLecturesStore()
const upcoming = computed(() => lecturesStore.all.slice(0, 3))
</script>
<template>
<div class="teacher-dashboard page-content">
<div class="header">
<h1 class="page-title">Дашборд преподавателя</h1>
<div class="actions">
<button class="btn-primary">Анонсировать лекцию</button>
<button class="btn-secondary">Посмотреть отзывы</button>
<button class="btn-secondary">Отметить посещение</button>
</div>
</div>
<div class="stats-row">
<StatsWidget label="Предстоящие лекции" :value="3" icon="📅" color="green" />
<StatsWidget label="Записавшихся" :value="47" icon="👥" color="aqua" />
<StatsWidget label="Средняя оценка" :value="4.6" icon="⭐" color="orange" />
<StatsWidget label="Вовлеченность вне направления" :value="'38%'" icon="🌍" color="purple" />
</div>
<GlassCard>
<div class="section-title">Заметность за пределами направления</div>
<div class="visibility">
<div class="visibility-meta">
38% студентов из других институтов · Цель 50%
</div>
<ProgressBar :value="38" :max="100" />
</div>
</GlassCard>
<GlassCard>
<div class="section-title">Ближайшие открытые лекции</div>
<div class="upcoming">
<div class="upcoming-item" v-for="l in upcoming" :key="l.id">
<div>
<div class="upcoming-title">{{ l.title }}</div>
<div class="upcoming-meta">📅 {{ new Date(l.date).toLocaleDateString('ru-RU') }} · {{ l.time }}</div>
<div class="upcoming-meta">Записалось {{ l.totalSeats - l.freeSeats }} студентов</div>
</div>
<button class="btn-secondary btn-sm">Управлять</button>
</div>
</div>
</GlassCard>
</div>
</template>
<style scoped>
.teacher-dashboard { display: flex; flex-direction: column; gap: 18px; }
.header { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.actions { display: flex; gap: 10px; flex-wrap: wrap; }
.stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; }
.visibility { display: flex; flex-direction: column; gap: 8px; }
.visibility-meta { font-size: 13px; color: var(--color-text-secondary); }
.upcoming { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.upcoming-item { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding-bottom: 10px; border-bottom: 1px solid var(--color-border-glass); }
.upcoming-item:last-child { border-bottom: none; padding-bottom: 0; }
.upcoming-title { font-weight: 700; }
.upcoming-meta { font-size: 13px; color: var(--color-text-secondary); }
.btn-sm { padding: 6px 12px; font-size: 12px; }
</style>