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,88 @@
<script setup lang="ts">
import GlassCard from '@/components/ui/GlassCard.vue'
import StatsWidget from '@/components/ui/StatsWidget.vue'
import ProgressBar from '@/components/ui/ProgressBar.vue'
import StatusBadge from '@/components/ui/StatusBadge.vue'
const disciplines = [
{ name: 'Информатика и ИИ', value: 80 },
{ name: 'Экономика и маркетинг', value: 55 },
{ name: 'Философия и этика', value: 42 },
{ name: 'Право и политика', value: 36 },
]
</script>
<template>
<div class="admin-dashboard page-content">
<h1 class="page-title">Дашборд администратора</h1>
<div class="stats-row">
<StatsWidget label="Пользователей" :value="1247" icon="👥" color="green" />
<StatsWidget label="Лекций" :value="89" icon="📚" color="aqua" />
<StatsWidget label="Записей" :value="3421" icon="🗓️" color="orange" />
<StatsWidget label="Отзывов" :value="1089" icon="💬" color="purple" />
</div>
<div class="grid">
<GlassCard>
<div class="section-title">Популярные дисциплины</div>
<div class="bars">
<div class="bar-row" v-for="d in disciplines" :key="d.name">
<span>{{ d.name }}</span>
<div class="bar">
<div class="bar-fill" :style="{ width: `${d.value}%` }"></div>
</div>
<span class="percent">{{ d.value }}%</span>
</div>
</div>
</GlassCard>
<GlassCard>
<div class="section-title">Межфакультетская вовлеченность</div>
<div class="metric">46% студентов посещают лекции вне своего института</div>
<ProgressBar :value="46" :max="100" />
<div class="section-title">Активность студентов</div>
<div class="activity">
<div class="day" v-for="n in 7" :key="n">
<div class="day-bar" :style="{ height: `${40 + n * 6}px` }"></div>
<span>Д{{ n }}</span>
</div>
</div>
</GlassCard>
</div>
<div class="grid">
<GlassCard>
<div class="section-title">Состояние синхронизации расписания</div>
<StatusBadge status="open" />
<div class="sync-meta">Последняя синхронизация: сегодня, 09:15</div>
<div class="sync-error">Ошибка: 2 аудитории не сопоставлены с корпусами</div>
</GlassCard>
<GlassCard>
<div class="section-title">Очередь LLM-анализа</div>
<div class="queue-meta">В очереди: 24 отзыва · Обработка: 6/час</div>
<ProgressBar :value="60" :max="100" />
<div class="queue-status">Следующая проверка через 12 минут</div>
</GlassCard>
</div>
</div>
</template>
<style scoped>
.admin-dashboard { display: flex; flex-direction: column; gap: 18px; }
.stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; }
.bars { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.bar-row { display: grid; grid-template-columns: 1fr 2fr auto; align-items: center; gap: 8px; font-size: 13px; }
.bar { background: rgba(0,0,0,0.08); border-radius: 6px; height: 8px; overflow: hidden; }
.bar-fill { background: linear-gradient(90deg, #22C55E, #86EFAC); height: 100%; }
.percent { color: var(--color-text-secondary); font-size: 12px; }
.metric { margin-bottom: 10px; color: var(--color-text-secondary); }
.activity { display: flex; gap: 10px; margin-top: 12px; align-items: flex-end; }
.day { display: flex; flex-direction: column; align-items: center; gap: 4px; font-size: 11px; color: var(--color-text-secondary); }
.day-bar { width: 16px; background: linear-gradient(180deg, #7DD3FC, #BAE6FD); border-radius: 6px 6px 0 0; }
.sync-meta { font-size: 12px; color: var(--color-text-secondary); margin-top: 6px; }
.sync-error { font-size: 12px; color: var(--color-error); margin-top: 8px; }
.queue-meta { font-size: 12px; color: var(--color-text-secondary); margin-bottom: 8px; }
.queue-status { font-size: 12px; color: var(--color-text-secondary); margin-top: 6px; }
</style>