refactor: натравил форматтер на весь фронт
This commit is contained in:
@@ -14,9 +14,15 @@ const router = useRouter()
|
||||
const teacherLectures = computed(() => {
|
||||
return lecturesStore.all
|
||||
})
|
||||
const upcoming = computed(() => teacherLectures.value.filter(l => l.status !== 'completed').slice(0, 3))
|
||||
const enrolledTotal = computed(() => teacherLectures.value.reduce((sum, l) => sum + l.enrolledSeats, 0))
|
||||
const visibility = computed(() => (teacherLectures.value.length ? Math.min(100, Math.round(enrolledTotal.value * 4)) : 0))
|
||||
const upcoming = computed(() =>
|
||||
teacherLectures.value.filter((l) => l.status !== 'completed').slice(0, 3),
|
||||
)
|
||||
const enrolledTotal = computed(() =>
|
||||
teacherLectures.value.reduce((sum, l) => sum + l.enrolledSeats, 0),
|
||||
)
|
||||
const visibility = computed(() =>
|
||||
teacherLectures.value.length ? Math.min(100, Math.round(enrolledTotal.value * 4)) : 0,
|
||||
)
|
||||
|
||||
function fetchTeacherLectures() {
|
||||
if (!auth.user?.id) return
|
||||
@@ -33,7 +39,9 @@ watch(() => auth.user?.id, fetchTeacherLectures)
|
||||
<h1 class="page-title">Дашборд преподавателя</h1>
|
||||
<div class="actions">
|
||||
<button class="btn-primary" @click="router.push('/teacher/lectures')">Мои лекции</button>
|
||||
<button class="btn-secondary" @click="router.push('/teacher/analytics')">Посмотреть отзывы</button>
|
||||
<button class="btn-secondary" @click="router.push('/teacher/analytics')">
|
||||
Посмотреть отзывы
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -41,20 +49,33 @@ watch(() => auth.user?.id, fetchTeacherLectures)
|
||||
<StatsWidget label="Предстоящие лекции" :value="upcoming.length" icon="📅" color="green" />
|
||||
<StatsWidget label="Записавшихся" :value="enrolledTotal" icon="👥" color="aqua" />
|
||||
<StatsWidget label="Средняя оценка" :value="'—'" icon="⭐" color="orange" />
|
||||
<StatsWidget label="Вовлеченность вне направления" :value="`${visibility}%`" icon="🌍" color="purple" />
|
||||
<StatsWidget
|
||||
label="Вовлеченность вне направления"
|
||||
:value="`${visibility}%`"
|
||||
icon="🌍"
|
||||
color="purple"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<GlassCard>
|
||||
<div class="section-title">Ближайшие лекции</div>
|
||||
<EmptyState v-if="!upcoming.length" title="Лекций пока нет" subtitle="После синхронизации или назначения лекции появятся здесь." />
|
||||
<EmptyState
|
||||
v-if="!upcoming.length"
|
||||
title="Лекций пока нет"
|
||||
subtitle="После синхронизации или назначения лекции появятся здесь."
|
||||
/>
|
||||
<div v-else 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">
|
||||
{{ new Date(l.date).toLocaleDateString('ru-RU') }} {{ l.time }}
|
||||
</div>
|
||||
<div class="upcoming-meta">Записалось {{ l.enrolledSeats }} студентов</div>
|
||||
</div>
|
||||
<button class="btn-secondary btn-sm" @click="router.push('/teacher/lectures')">Управлять</button>
|
||||
<button class="btn-secondary btn-sm" @click="router.push('/teacher/lectures')">
|
||||
Управлять
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</GlassCard>
|
||||
@@ -62,16 +83,63 @@ watch(() => auth.user?.id, fetchTeacherLectures)
|
||||
</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; }
|
||||
.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>
|
||||
|
||||
Reference in New Issue
Block a user