Dev #11
@@ -73,7 +73,7 @@ export function mapApiLecture(lecture: LectureDto): Lecture {
|
|||||||
time: startsAt.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }),
|
time: startsAt.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }),
|
||||||
duration,
|
duration,
|
||||||
building: lecture.format === 'Online' ? 'Онлайн' : locationName,
|
building: lecture.format === 'Online' ? 'Онлайн' : locationName,
|
||||||
room: lecture.format === 'Online' ? undefined : locationName,
|
room: undefined,
|
||||||
format: lecture.format === 'Online' ? 'online' : 'offline',
|
format: lecture.format === 'Online' ? 'online' : 'offline',
|
||||||
totalSeats,
|
totalSeats,
|
||||||
enrolledSeats: enrolled,
|
enrolledSeats: enrolled,
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ input, textarea, select {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.badge-green { color: #15803D; border: 1.5px solid rgba(34,197,94,0.3); }
|
.badge-green { color: #15803D; border: 1.3px solid rgba(34,197,94,0.3); }
|
||||||
.badge-blue { background: rgba(6,182,212,0.15); color: #0E7490; border: 1px solid rgba(6,182,212,0.3); }
|
.badge-blue { background: rgba(6,182,212,0.15); color: #0E7490; border: 1px solid rgba(6,182,212,0.3); }
|
||||||
.badge-orange { background: rgba(251,146,60,0.15); color: #C2410C; border: 1px solid rgba(251,146,60,0.3); }
|
.badge-orange { background: rgba(251,146,60,0.15); color: #C2410C; border: 1px solid rgba(251,146,60,0.3); }
|
||||||
.badge-gray { background: rgba(100,116,139,0.1); color: #64748B; border: 1px solid rgba(100,116,139,0.2); }
|
.badge-gray { background: rgba(100,116,139,0.1); color: #64748B; border: 1px solid rgba(100,116,139,0.2); }
|
||||||
|
|||||||
@@ -50,9 +50,15 @@ function goDetail() {
|
|||||||
<h3 class="card-title">{{ lecture.title }}</h3>
|
<h3 class="card-title">{{ lecture.title }}</h3>
|
||||||
|
|
||||||
<div class="card-teacher">
|
<div class="card-teacher">
|
||||||
<AppIcon class="teacher-icon" icon="user" :size="16" />
|
<template v-if="lecture.teacher && lecture.teacher !== 'Преподаватель уточняется'">
|
||||||
<span>{{ lecture.teacher }}</span>
|
<AppIcon class="teacher-icon" icon="user" :size="16" />
|
||||||
<span class="text-secondary">· {{ lecture.institute }}</span>
|
<span>{{ lecture.teacher }}</span>
|
||||||
|
<span class="text-secondary">{{ lecture.institute }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<AppIcon class="teacher-icon" icon="building" :size="16" />
|
||||||
|
<span class="text-secondary">{{ lecture.institute }}</span>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-meta">
|
<div class="card-meta">
|
||||||
|
|||||||
@@ -222,10 +222,10 @@ function isRegistered(id: string) {
|
|||||||
<div class="text-secondary text-sm">{{ row.tags.join(' ') }}</div>
|
<div class="text-secondary text-sm">{{ row.tags.join(' ') }}</div>
|
||||||
</template>
|
</template>
|
||||||
<template #date="{ row }">
|
<template #date="{ row }">
|
||||||
{{ new Date(row.date).toLocaleDateString('ru-RU') }} · {{ row.time }}
|
{{ new Date(row.date).toLocaleDateString('ru-RU') }} {{ row.time }}
|
||||||
</template>
|
</template>
|
||||||
<template #place="{ row }">
|
<template #place="{ row }">
|
||||||
{{ row.building }} {{ row.room ? `· ауд. ${row.room}` : '' }}
|
{{ row.building }} {{ row.room ? `ауд. ${row.room}` : '' }}
|
||||||
</template>
|
</template>
|
||||||
<template #seats="{ row }">
|
<template #seats="{ row }">
|
||||||
<span :class="row.freeSeats === 0 ? 'badge badge-gray' : 'badge badge-green'">
|
<span :class="row.freeSeats === 0 ? 'badge badge-gray' : 'badge badge-green'">
|
||||||
@@ -251,7 +251,7 @@ function isRegistered(id: string) {
|
|||||||
<div class="calendar-items">
|
<div class="calendar-items">
|
||||||
<div v-for="l in items" :key="l.id" class="calendar-item">
|
<div v-for="l in items" :key="l.id" class="calendar-item">
|
||||||
<div class="calendar-title">{{ l.title }}</div>
|
<div class="calendar-title">{{ l.title }}</div>
|
||||||
<div class="calendar-meta">{{ l.time }} · {{ l.building }} {{ l.room ? `· ауд. ${l.room}` : '' }}</div>
|
<div class="calendar-meta">{{ l.time }} {{ l.building }} {{ l.room ? `ауд. ${l.room}` : '' }}</div>
|
||||||
<button class="btn-secondary btn-sm">Подробнее</button>
|
<button class="btn-secondary btn-sm">Подробнее</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const userMetaLine = computed(() => {
|
|||||||
const parts: string[] = []
|
const parts: string[] = []
|
||||||
if (user.value.institute) parts.push(user.value.institute)
|
if (user.value.institute) parts.push(user.value.institute)
|
||||||
if (user.value.direction) parts.push(user.value.direction)
|
if (user.value.direction) parts.push(user.value.direction)
|
||||||
if (user.value.year !== null && user.value.year !== undefined) parts.push(`${user.value.year} курс`)
|
if (Number.isFinite(user.value.year) && (user.value.year as number) > 0) parts.push(`${user.value.year} курс`)
|
||||||
return parts.join(' · ')
|
return parts.join(' · ')
|
||||||
})
|
})
|
||||||
const nextLecture = computed(() => lectures.registeredLectures[0] ?? lectures.all[0])
|
const nextLecture = computed(() => lectures.registeredLectures[0] ?? lectures.all[0])
|
||||||
|
|||||||
@@ -63,14 +63,14 @@ onMounted(async () => {
|
|||||||
<GlassCard>
|
<GlassCard>
|
||||||
<div class="info-section">
|
<div class="info-section">
|
||||||
<h3>Преподаватель</h3>
|
<h3>Преподаватель</h3>
|
||||||
<div class="info-value">{{ lecture.teacher }} · {{ lecture.teacherTitle }}</div>
|
<div class="info-value">{{ lecture.teacher }}<span v-if="lecture.teacherTitle"> {{ lecture.teacherTitle }}</span></div>
|
||||||
<div class="info-sub">{{ lecture.department }}, {{ lecture.institute }}</div>
|
<div class="info-sub">{{ [lecture.department, lecture.institute].filter(Boolean).join(', ') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-section">
|
<div class="info-section">
|
||||||
<h3>Детали занятия</h3>
|
<h3>Детали занятия</h3>
|
||||||
<div class="info-value">📅 {{ new Date(lecture.date).toLocaleDateString('ru-RU') }} · {{ lecture.time }}</div>
|
<div class="info-value">{{ new Date(lecture.date).toLocaleDateString('ru-RU') }} {{ lecture.time }}</div>
|
||||||
<div class="info-sub">Длительность: {{ lecture.duration }} мин</div>
|
<div class="info-sub">Длительность: {{ lecture.duration }} мин</div>
|
||||||
<div class="info-sub">Локация: {{ lecture.building }} {{ lecture.room ? `· ауд. ${lecture.room}` : '' }}</div>
|
<div class="info-sub">Локация: {{ lecture.building }} {{ lecture.room ? `ауд. ${lecture.room}` : '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-section">
|
<div class="info-section">
|
||||||
<h3>Места</h3>
|
<h3>Места</h3>
|
||||||
@@ -93,7 +93,7 @@ onMounted(async () => {
|
|||||||
</p>
|
</p>
|
||||||
<div class="reviews" v-if="reviews.length">
|
<div class="reviews" v-if="reviews.length">
|
||||||
<div v-for="review in reviews" :key="review.id" class="review">
|
<div v-for="review in reviews" :key="review.id" class="review">
|
||||||
<div class="review-head">{{ review.userName }} · {{ review.sentiment }}</div>
|
<div class="review-head">{{ review.userName }} {{ review.sentiment }}</div>
|
||||||
<div class="review-body">{{ review.text }}</div>
|
<div class="review-body">{{ review.text }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ async function confirmCancel() {
|
|||||||
<GlassCard v-for="item in upcoming" :key="item.id" class="lecture-row">
|
<GlassCard v-for="item in upcoming" :key="item.id" class="lecture-row">
|
||||||
<div>
|
<div>
|
||||||
<div class="lecture-title">{{ item.title }}</div>
|
<div class="lecture-title">{{ item.title }}</div>
|
||||||
<div class="lecture-meta">📅 {{ new Date(item.date).toLocaleDateString('ru-RU') }} · {{ item.time }}</div>
|
<div class="lecture-meta">{{ new Date(item.date).toLocaleDateString('ru-RU') }} {{ item.time }}</div>
|
||||||
<div class="lecture-meta">🏛 {{ item.building }} {{ item.room ? `· ауд. ${item.room}` : '' }}</div>
|
<div class="lecture-meta">{{ item.building }} {{ item.room ? `ауд. ${item.room}` : '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lecture-actions">
|
<div class="lecture-actions">
|
||||||
<StatusBadge status="registered" />
|
<StatusBadge status="registered" />
|
||||||
@@ -73,8 +73,8 @@ async function confirmCancel() {
|
|||||||
<GlassCard v-for="item in history" :key="item.id" class="lecture-row">
|
<GlassCard v-for="item in history" :key="item.id" class="lecture-row">
|
||||||
<div>
|
<div>
|
||||||
<div class="lecture-title">{{ item.title }}</div>
|
<div class="lecture-title">{{ item.title }}</div>
|
||||||
<div class="lecture-meta">📅 {{ new Date(item.date).toLocaleDateString('ru-RU') }} · {{ item.time }}</div>
|
<div class="lecture-meta">{{ new Date(item.date).toLocaleDateString('ru-RU') }} {{ item.time }}</div>
|
||||||
<div class="lecture-meta">🏛 {{ item.building }} {{ item.room ? `· ауд. ${item.room}` : '' }}</div>
|
<div class="lecture-meta">{{ item.building }} {{ item.room ? `ауд. ${item.room}` : '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lecture-actions">
|
<div class="lecture-actions">
|
||||||
<StatusBadge :status="item.status ?? 'completed'" />
|
<StatusBadge :status="item.status ?? 'completed'" />
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ const userMetaLine = computed(() => {
|
|||||||
const parts: string[] = []
|
const parts: string[] = []
|
||||||
if (user.value.institute) parts.push(user.value.institute)
|
if (user.value.institute) parts.push(user.value.institute)
|
||||||
if (user.value.direction) parts.push(user.value.direction)
|
if (user.value.direction) parts.push(user.value.direction)
|
||||||
return parts.join(' · ')
|
return parts.join(' ')
|
||||||
})
|
})
|
||||||
|
|
||||||
const userYearLine = computed(() => {
|
const userYearLine = computed(() => {
|
||||||
const year = user.value.year
|
const year = user.value.year
|
||||||
return year === null || year === undefined ? '' : `${year} курс`
|
return Number.isFinite(year) && year > 0 ? `${year} курс` : ''
|
||||||
})
|
})
|
||||||
const interestTags = ref([
|
const interestTags = ref([
|
||||||
{ label: '#ML', active: true },
|
{ label: '#ML', active: true },
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ onMounted(() => {
|
|||||||
<div class="section-title">Заметность за пределами направления</div>
|
<div class="section-title">Заметность за пределами направления</div>
|
||||||
<div class="visibility">
|
<div class="visibility">
|
||||||
<div class="visibility-meta">
|
<div class="visibility-meta">
|
||||||
{{ visibility }}% студентов из других институтов · Цель 50%
|
{{ visibility }}% студентов из других институтов Цель 50%
|
||||||
</div>
|
</div>
|
||||||
<ProgressBar :value="visibility" :max="100" />
|
<ProgressBar :value="visibility" :max="100" />
|
||||||
</div>
|
</div>
|
||||||
@@ -59,7 +59,7 @@ onMounted(() => {
|
|||||||
<div class="upcoming-item" v-for="l in upcoming" :key="l.id">
|
<div class="upcoming-item" v-for="l in upcoming" :key="l.id">
|
||||||
<div>
|
<div>
|
||||||
<div class="upcoming-title">{{ l.title }}</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 class="upcoming-meta">Записалось {{ l.enrolledSeats }} студентов</div>
|
||||||
</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>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const rows = computed(() => {
|
|||||||
return (owned.length ? owned : lecturesStore.all).map(l => ({
|
return (owned.length ? owned : lecturesStore.all).map(l => ({
|
||||||
id: l.id,
|
id: l.id,
|
||||||
title: l.title,
|
title: l.title,
|
||||||
date: `${new Date(l.date).toLocaleDateString('ru-RU')} · ${l.time}`,
|
date: `${new Date(l.date).toLocaleDateString('ru-RU')} ${l.time}`,
|
||||||
status: l.status ?? 'upcoming',
|
status: l.status ?? 'upcoming',
|
||||||
stats: `${l.enrolledSeats} / — / ${l.reviewCount}`,
|
stats: `${l.enrolledSeats} / — / ${l.reviewCount}`,
|
||||||
}))
|
}))
|
||||||
|
|||||||
Reference in New Issue
Block a user