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
🚀 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:
@@ -0,0 +1,124 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import GlassCard from '@/components/ui/GlassCard.vue'
|
||||
import DataTable from '@/components/ui/DataTable.vue'
|
||||
|
||||
type TabKey = 'lectures' | 'courses' | 'rooms' | 'tags'
|
||||
type TabConfig = {
|
||||
title: string
|
||||
columns: Array<{ key: string; label: string; align?: string }>
|
||||
rows: Record<string, any>[]
|
||||
}
|
||||
|
||||
const activeTab = ref<TabKey>('lectures')
|
||||
|
||||
const tabConfig: Record<TabKey, TabConfig> = {
|
||||
lectures: {
|
||||
title: 'Лекции',
|
||||
columns: [
|
||||
{ key: 'title', label: 'Название' },
|
||||
{ key: 'teacher', label: 'Преподаватель' },
|
||||
{ key: 'format', label: 'Формат' },
|
||||
{ key: 'status', label: 'Синхронизация', align: 'center' },
|
||||
],
|
||||
rows: [
|
||||
{ id: '1', title: 'Введение в нейронные сети', teacher: 'Волков М.С.', format: 'Офлайн', status: 'Синхронизировано' },
|
||||
{ id: '2', title: 'Квантовые вычисления', teacher: 'Петров А.И.', format: 'Офлайн', status: 'Синхронизировано' },
|
||||
{ id: '3', title: 'Философия цифровой эпохи', teacher: 'Дмитриев К.О.', format: 'Онлайн', status: 'Ошибка' },
|
||||
],
|
||||
},
|
||||
courses: {
|
||||
title: 'Курсы',
|
||||
columns: [
|
||||
{ key: 'title', label: 'Курс' },
|
||||
{ key: 'institute', label: 'Институт' },
|
||||
{ key: 'tags', label: 'Теги' },
|
||||
],
|
||||
rows: [
|
||||
{ id: '1', title: 'Машинное обучение', institute: 'ИКТИБ', tags: '#ML #ИИ #Python' },
|
||||
{ id: '2', title: 'Цифровая этика', institute: 'ИФиСН', tags: '#философия #этика' },
|
||||
],
|
||||
},
|
||||
rooms: {
|
||||
title: 'Аудитории',
|
||||
columns: [
|
||||
{ key: 'building', label: 'Корпус' },
|
||||
{ key: 'room', label: 'Аудитория' },
|
||||
{ key: 'capacity', label: 'Вместимость', align: 'center' },
|
||||
],
|
||||
rows: [
|
||||
{ id: '1', building: 'ИКТИБ', room: '305', capacity: 30 },
|
||||
{ id: '2', building: 'ИФиМКН', room: '201', capacity: 25 },
|
||||
],
|
||||
},
|
||||
tags: {
|
||||
title: 'Теги',
|
||||
columns: [
|
||||
{ key: 'tag', label: 'Тег' },
|
||||
{ key: 'category', label: 'Категория' },
|
||||
{ key: 'linked', label: 'Привязки', align: 'center' },
|
||||
],
|
||||
rows: [
|
||||
{ id: '1', tag: '#ML', category: 'Data Science', linked: 12 },
|
||||
{ id: '2', tag: '#философия', category: 'Гуманитарные', linked: 6 },
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
const current = computed(() => tabConfig[activeTab.value])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="admin-lectures page-content">
|
||||
<div class="header">
|
||||
<h1 class="page-title">Управление лекциями и справочниками</h1>
|
||||
<button class="btn-primary">Создать запись</button>
|
||||
</div>
|
||||
|
||||
<div class="tabs">
|
||||
<button :class="{ active: activeTab === 'lectures' }" @click="activeTab = 'lectures'">Лекции</button>
|
||||
<button :class="{ active: activeTab === 'courses' }" @click="activeTab = 'courses'">Курсы</button>
|
||||
<button :class="{ active: activeTab === 'rooms' }" @click="activeTab = 'rooms'">Аудитории</button>
|
||||
<button :class="{ active: activeTab === 'tags' }" @click="activeTab = 'tags'">Теги</button>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<GlassCard>
|
||||
<div class="section-title">{{ current.title }}</div>
|
||||
<DataTable :columns="current.columns" :rows="current.rows" />
|
||||
</GlassCard>
|
||||
|
||||
<GlassCard>
|
||||
<div class="section-title">Создать / редактировать</div>
|
||||
<form class="form">
|
||||
<label>Название</label>
|
||||
<input class="glass-input" placeholder="Введите название" />
|
||||
<label>Описание</label>
|
||||
<textarea rows="4" placeholder="Описание записи"></textarea>
|
||||
<label>Статус синхронизации</label>
|
||||
<select class="glass-input">
|
||||
<option>Синхронизировано</option>
|
||||
<option>Ожидает</option>
|
||||
<option>Ошибка</option>
|
||||
</select>
|
||||
<div class="form-actions">
|
||||
<button class="btn-primary" type="button">Сохранить</button>
|
||||
<button class="btn-secondary" type="button">Отменить</button>
|
||||
</div>
|
||||
</form>
|
||||
</GlassCard>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.admin-lectures { display: flex; flex-direction: column; gap: 16px; }
|
||||
.header { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
|
||||
.tabs { display: inline-flex; border: 1px solid var(--color-border-glass); border-radius: 12px; overflow: hidden; }
|
||||
.tabs button { background: rgba(255,255,255,0.7); border: none; padding: 8px 18px; font-size: 13px; cursor: pointer; color: var(--color-text-secondary); }
|
||||
.tabs button.active { background: rgba(34,197,94,0.18); color: var(--color-primary-dark); font-weight: 600; }
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; }
|
||||
.form { display: flex; flex-direction: column; gap: 10px; }
|
||||
textarea { padding: 10px; border-radius: var(--radius-sm); border: 1px solid var(--color-border-glass); background: rgba(255,255,255,0.8); }
|
||||
.form-actions { display: flex; gap: 10px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user