TEST UPD
-front works for student profile
This commit is contained in:
@@ -1,176 +1,424 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="min-h-screen bg-surface-gray-1">
|
||||
<NoPermission v-if="!$user.data" />
|
||||
<div v-else-if="profile.error">
|
||||
<p class="text-red-500">Ошибка загрузки профиля: {{ profile.error.message }}</p>
|
||||
|
||||
<div v-else-if="profile.error" class="p-6">
|
||||
<div class="max-w-4xl mx-auto bg-white rounded-xl shadow-sm p-6 border border-red-200">
|
||||
<p class="text-red-500 text-lg font-medium">Ошибка загрузки профиля: {{ profile.error.message }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="profile.data">
|
||||
<header class="sticky top-0 z-10 flex items-center justify-between border-b bg-surface-white px-3 py-2.5">
|
||||
<header class="sticky top-0 z-10 flex items-center justify-between border-b border-gray-200 bg-white px-6 py-4 shadow-sm">
|
||||
<Breadcrumbs class="h-7" :items="breadcrumbs" />
|
||||
</header>
|
||||
|
||||
<div class="mx-auto -mt-10 max-w-4xl px-5">
|
||||
<div class="flex items-center min-h-[100px]">
|
||||
<div class="ml-6">
|
||||
<h2 class="mt-2 text-3xl font-semibold text-ink-gray-9">{{ displayName }}</h2>
|
||||
<div class="mt-2 text-base text-ink-gray-7">{{ profile.data.headline || '' }}</div>
|
||||
</div>
|
||||
<div class="ml-auto" v-if="$user.data && isSessionUser()">
|
||||
<Button @click="toggleEdit()">
|
||||
<template #prefix>
|
||||
<Edit class="w-4 h-4 stroke-1.5 text-ink-gray-7" />
|
||||
</template>
|
||||
{{ editMode ? 'Отмена' : 'Редактировать' }}
|
||||
</Button>
|
||||
<div class="mx-auto max-w-6xl px-4 py-6">
|
||||
<!-- Profile Header -->
|
||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-200 p-6 -mt-4 relative">
|
||||
<div class="flex flex-col md:flex-row md:items-center gap-6">
|
||||
<div class="flex-1">
|
||||
<h2 class="text-3xl font-bold text-gray-900">{{ displayName }}</h2>
|
||||
<p class="mt-2 text-lg text-gray-600">{{ profile.data.headline || 'Нет информации о себе' }}</p>
|
||||
</div>
|
||||
|
||||
<div v-if="$user.data && isSessionUser()" class="md:ml-auto">
|
||||
<Button @click="toggleEdit()" class="bg-primary-600 hover:bg-primary-700 text-white px-5 py-2.5 rounded-lg transition-colors duration-200">
|
||||
<template #prefix>
|
||||
<Edit class="w-4 h-4 stroke-1.5" />
|
||||
</template>
|
||||
{{ editMode ? 'Отменить редактирование' : 'Редактировать профиль' }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- VIEW MODE -->
|
||||
<div v-if="!editMode" class="mt-4 space-y-3">
|
||||
<div v-if="schoolProfile.loading">
|
||||
<p>Загрузка данных профиля студента...</p>
|
||||
<div v-if="!editMode" class="mt-6">
|
||||
<div v-if="schoolProfile.loading" class="bg-white rounded-2xl shadow-sm border border-gray-200 p-8">
|
||||
<div class="flex items-center justify-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="schoolProfile.error">
|
||||
<p class="text-red-500">Ошибка загрузки данных студента: {{ schoolProfile.error.message }}</p>
|
||||
|
||||
<div v-else-if="schoolProfile.error" class="bg-white rounded-2xl shadow-sm border border-red-200 p-6">
|
||||
<p class="text-red-500 text-lg font-medium">Ошибка загрузки данных студента: {{ schoolProfile.error.message }}</p>
|
||||
</div>
|
||||
<div v-else-if="schoolProfile.data">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<b>Фамилия:</b> {{ schoolProfile.data.last_name || '-' }}<br/>
|
||||
<b>Имя:</b> {{ schoolProfile.data.first_name || '-' }}<br/>
|
||||
<b>Отчество:</b> {{ schoolProfile.data.middle_name || '-' }}<br/>
|
||||
<b>Дата рождения:</b> {{ formattedDate(schoolProfile.data.birth_date) || '-' }}
|
||||
<b>Телефон (приватный):</b> {{ maskPrivate(schoolProfile.data.phone) }}<br/>
|
||||
<b>Email (приватный):</b> {{ maskPrivate(schoolProfile.data.email_private) }}<br/>
|
||||
<b>Telegram:</b>
|
||||
<a v-if="schoolProfile.data.telegram" :href="formatTelegram(schoolProfile.data.telegram)" target="_blank">{{ schoolProfile.data.telegram }}</a>
|
||||
|
||||
<div v-else-if="schoolProfile.data" class="space-y-6">
|
||||
<!-- Основная информация -->
|
||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-200 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-100 bg-gray-50">
|
||||
<h3 class="text-xl font-semibold text-gray-900">Основная информация</h3>
|
||||
</div>
|
||||
<div>
|
||||
<b>Университет:</b> {{ schoolProfile.data.school || '-' }}<br/>
|
||||
<b>Уровень образования:</b> {{ schoolProfile.data.education_level || '-' }}<br/>
|
||||
<b>Направление подготовки:</b> {{ schoolProfile.data.major || '-' }}<br/>
|
||||
<b>Образовательная программа:</b> {{ schoolProfile.data.program || '-' }}<br/>
|
||||
<b>Курс:</b> {{ schoolProfile.data.course || '-' }}<br/>
|
||||
<b>Староста в группе или нет?</b> {{ schoolProfile.data.group_leader || '-' }}<br/>
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Фамилия:</span>
|
||||
<span class="text-gray-900">{{ schoolProfile.data.last_name || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Имя:</span>
|
||||
<span class="text-gray-900">{{ schoolProfile.data.first_name || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Отчество:</span>
|
||||
<span class="text-gray-900">{{ schoolProfile.data.middle_name || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Дата рождения:</span>
|
||||
<span class="text-gray-900">{{ formattedDate(schoolProfile.data.birth_date) || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Телефон:</span>
|
||||
<span class="text-gray-900 font-mono">{{ maskPrivate(schoolProfile.data.phone) }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Email:</span>
|
||||
<span class="text-gray-900 font-mono">{{ maskPrivate(schoolProfile.data.email_private) }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Telegram:</span>
|
||||
<div class="flex-1">
|
||||
<a v-if="schoolProfile.data.telegram"
|
||||
:href="formatTelegram(schoolProfile.data.telegram)"
|
||||
target="_blank"
|
||||
class="inline-flex items-center gap-2 text-primary-600 hover:text-primary-700 font-medium transition-colors">
|
||||
<span>@{{ schoolProfile.data.telegram.replace('@', '') }}</span>
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<span v-else class="text-gray-500">—</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Университет:</span>
|
||||
<span class="text-gray-900">{{ schoolProfile.data.school || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Уровень образования:</span>
|
||||
<span class="text-gray-900">{{ schoolProfile.data.education_level || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Направление подготовки:</span>
|
||||
<span class="text-gray-900">{{ schoolProfile.data.major || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Образовательная программа:</span>
|
||||
<span class="text-gray-900">{{ schoolProfile.data.program || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Курс:</span>
|
||||
<span class="text-gray-900">{{ schoolProfile.data.course || '—' }}</span>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<span class="inline-block w-40 text-gray-700 font-medium">Староста в группе:</span>
|
||||
<span class="text-gray-900">
|
||||
<span :class="schoolProfile.data.group_leader === 'Да' ? 'text-green-600' : 'text-gray-600'">
|
||||
{{ schoolProfile.data.group_leader || '—' }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Коротко о интересах:</b>
|
||||
<div class="mt-1 p-3 bg-surface-gray-1 rounded">{{ schoolProfile.data.interests || '-' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<b>Коротко о себе:</b>
|
||||
<div class="mt-1 p-3 bg-surface-gray-1 rounded">{{ schoolProfile.data.about_me || '-' }}</div>
|
||||
<!-- О себе -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-200 overflow-hidden lg:col-span-2">
|
||||
<div class="px-6 py-4 border-b border-gray-100 bg-gray-50">
|
||||
<h3 class="text-xl font-semibold text-gray-900">Коротко о своих интересах</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<p class="text-gray-700 leading-relaxed whitespace-pre-line">{{ schoolProfile.data.interests || 'Информация не указана' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<b>Коротко о мечтах:</b>
|
||||
<div class="mt-1 p-3 bg-surface-gray-1 rounded">{{ schoolProfile.data.dreams || '-' }}</div>
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-200 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-100 bg-gray-50">
|
||||
<h3 class="text-xl font-semibold text-gray-900">О себе</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<p class="text-gray-700 leading-relaxed whitespace-pre-line">{{ schoolProfile.data.about_me || 'Информация не указана' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-200 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-100 bg-gray-50">
|
||||
<h3 class="text-xl font-semibold text-gray-900">О мечтах</h3>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<p class="text-gray-700 leading-relaxed whitespace-pre-line">{{ schoolProfile.data.dreams || 'Информация не указана' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>Данные профиля студента не найдены.</p>
|
||||
|
||||
<div v-else class="bg-white rounded-2xl shadow-sm border border-gray-200 p-8">
|
||||
<div class="text-center py-12">
|
||||
<div class="mx-auto w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4">
|
||||
<svg class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Данные профиля не найдены</h3>
|
||||
<p class="text-gray-600">Информация о студенте отсутствует</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- EDIT MODE -->
|
||||
<div v-else class="mt-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<Input v-model="form.last_name" label="Фамилия" />
|
||||
<Input v-model="form.first_name" label="Имя" />
|
||||
<Input v-model="form.middle_name" label="Отчество" />
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-ink-gray-7 mb-1">Дата рождения</label>
|
||||
<DatePicker v-model="form.birth_date" label="Дата рождения" />
|
||||
<div v-else class="mt-6">
|
||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-200 overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-gray-100 bg-gray-50">
|
||||
<h3 class="text-xl font-semibold text-gray-900">Редактирование профиля</h3>
|
||||
<p class="text-sm text-gray-600 mt-1">Заполните информацию о себе</p>
|
||||
</div>
|
||||
<Input v-model="form.phone" label="Телефон (не публиковать)" />
|
||||
<Input v-model="form.email_private" label="Email (не публиковать)" />
|
||||
<Input v-model="form.telegram" label="Telegram (например t.me/username)" />
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-ink-gray-7 mb-1">Университет</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="schoolQuery"
|
||||
@input="debouncedSearchSchool"
|
||||
class="w-full border rounded p-2"
|
||||
placeholder="Начните вводить название университета"
|
||||
/>
|
||||
<div v-if="schoolResults.length" class="border rounded mt-1 max-h-44 overflow-auto bg-white">
|
||||
<div
|
||||
v-for="s in schoolResults"
|
||||
:key="s.school"
|
||||
class="p-2 cursor-pointer hover:bg-surface-gray-2"
|
||||
@click="selectSchool(s)"
|
||||
>
|
||||
<div class="font-medium">{{ s.school}}</div>
|
||||
<div class="text-xs text-ink-gray-6">{{ s.adress }}</div>
|
||||
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
<!-- Левая колонка -->
|
||||
<div class="space-y-6">
|
||||
<h4 class="text-lg font-semibold text-gray-900 border-b pb-2">Личная информация</h4>
|
||||
|
||||
<Input
|
||||
v-model="form.last_name"
|
||||
label="Фамилия"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
|
||||
<Input
|
||||
v-model="form.first_name"
|
||||
label="Имя"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
|
||||
<Input
|
||||
v-model="form.middle_name"
|
||||
label="Отчество"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Дата рождения</label>
|
||||
<DatePicker
|
||||
v-model="form.birth_date"
|
||||
class="w-full bg-gray-50 border-gray-300 rounded-lg focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Input
|
||||
v-model="form.phone"
|
||||
label="Телефон (не публиковать)"
|
||||
placeholder="+7 (XXX) XXX-XX-XX"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
|
||||
<Input
|
||||
v-model="form.email_private"
|
||||
label="Email (не публиковать)"
|
||||
type="email"
|
||||
placeholder="example@email.com"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
|
||||
<Input
|
||||
v-model="form.telegram"
|
||||
label="Telegram"
|
||||
placeholder="username или t.me/username"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Правая колонка -->
|
||||
<div class="space-y-6">
|
||||
<h4 class="text-lg font-semibold text-gray-900 border-b pb-2">Образование</h4>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Университет</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="schoolQuery"
|
||||
@input="debouncedSearchSchool"
|
||||
class="w-full bg-gray-50 border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-colors"
|
||||
placeholder="Начните вводить название университета"
|
||||
/>
|
||||
<div v-if="schoolResults.length" class="mt-2 border border-gray-300 rounded-lg overflow-hidden shadow-lg bg-white">
|
||||
<div
|
||||
v-for="s in schoolResults"
|
||||
:key="s.school"
|
||||
class="p-3 cursor-pointer hover:bg-primary-50 border-b border-gray-100 last:border-b-0 transition-colors"
|
||||
@click="selectSchool(s)"
|
||||
>
|
||||
<div class="font-medium text-gray-900">{{ s.school }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">{{ s.adress }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="form.school_name && !schoolResults.length" class="mt-2 text-sm text-gray-600">
|
||||
<span class="font-medium">Выбрана:</span> {{ form.school }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Уровень образования</label>
|
||||
<Select
|
||||
v-model="form.education_level"
|
||||
:options="['Бакалавриат','Магистратура','Аспирантура','Базовое высшее образование','Специализированное высшее образование','Профессиональная переподготовка','Повышение квалификации']"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Направление подготовки</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="majorQuery"
|
||||
@input="debouncedSearchMajor"
|
||||
class="w-full bg-gray-50 border border-gray-300 rounded-lg px-4 py-2.5 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-colors"
|
||||
placeholder="Начните вводить название направления"
|
||||
/>
|
||||
<div v-if="majorResults.length" class="mt-2 border border-gray-300 rounded-lg overflow-hidden shadow-lg bg-white">
|
||||
<div
|
||||
v-for="m in majorResults"
|
||||
:key="m.major"
|
||||
class="p-3 cursor-pointer hover:bg-primary-50 border-b border-gray-100 last:border-b-0 transition-colors"
|
||||
@click="selectMajor(m)"
|
||||
>
|
||||
<div class="font-medium text-gray-900">{{ m.major_name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="form.major_name && !majorResults.length" class="mt-2 text-sm text-gray-600">
|
||||
<span class="font-medium">Выбрано:</span> {{ form.major_name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Input
|
||||
v-model="form.program"
|
||||
label="Образовательная программа"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Курс</label>
|
||||
<Select
|
||||
v-model="form.course"
|
||||
:options="['1','2','3','4','5','6']"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500 w-full"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Староста в группе</label>
|
||||
<Select
|
||||
v-model="form.group_leader"
|
||||
:options="['Да','Нет']"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500 w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="form.school_name && !schoolResults.length" class="text-xs text-ink-gray-6 mt-1">
|
||||
Выбрана: {{ form.school }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-ink-gray-7 mb-1">Уровень образования</label>
|
||||
<Select v-model="form.education_level" :options="['Бакалавриат','Магистратура','Аспирантура','Базовое высшее образование',
|
||||
'Специализированное высшее образование','Профессиональная переподготовка','Повышение квалификации']" label="Уровень образования" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-ink-gray-7 mb-1">Направление подготовки</label>
|
||||
<input
|
||||
type="text"
|
||||
v-model="majorQuery"
|
||||
@input="debouncedSearchMajor"
|
||||
class="w-full border rounded p-2"
|
||||
placeholder="Начните вводить название направления"
|
||||
/>
|
||||
<div v-if="majorResults.length" class="border rounded mt-1 max-h-44 overflow-auto bg-white">
|
||||
<div
|
||||
v-for="m in majorResults"
|
||||
:key="m.major"
|
||||
class="p-2 cursor-pointer hover:bg-surface-gray-2"
|
||||
@click="selectMajor(m)"
|
||||
<!-- Текстовые поля -->
|
||||
<div class="mt-8 space-y-6">
|
||||
<h4 class="text-lg font-semibold text-gray-900 border-b pb-2">Дополнительная информация</h4>
|
||||
|
||||
<Textarea
|
||||
v-model="form.interests"
|
||||
label="Коротко о своих интересах (2-3 предложения)"
|
||||
rows="4"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
v-model="form.about_me"
|
||||
label="Коротко о себе"
|
||||
rows="4"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
|
||||
<Textarea
|
||||
v-model="form.dreams"
|
||||
label="Коротко о своих мечтах"
|
||||
rows="4"
|
||||
class="bg-gray-50 border-gray-300 focus:border-primary-500 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Кнопки действий -->
|
||||
<div class="mt-8 pt-6 border-t border-gray-200 flex gap-3">
|
||||
<Button
|
||||
@click="saveProfile"
|
||||
:loading="saving"
|
||||
class="bg-primary-600 hover:bg-primary-700 text-white px-6 py-3 rounded-lg font-medium transition-colors duration-200 flex items-center gap-2"
|
||||
>
|
||||
<div class="font-medium">{{ m.major_name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="form.major_name && !majorResults.length" class="text-xs text-ink-gray-6 mt-1">
|
||||
Выбрано: {{ form.major_name }}
|
||||
<svg v-if="!saving" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
||||
</svg>
|
||||
{{ saving ? 'Сохранение...' : 'Сохранить изменения' }}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
@click="toggleEdit()"
|
||||
class="border-gray-300 text-gray-700 hover:bg-gray-50 px-6 py-3 rounded-lg font-medium transition-colors duration-200"
|
||||
>
|
||||
Отмена
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Input v-model="form.program" label="Образовательная программа" />
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-ink-gray-7 mb-1">Курс</label>
|
||||
<Select v-model="form.course" :options="['1','2','3','4','5','6']" label="Курс" />
|
||||
<label class="block text-sm font-medium text-ink-gray-7 mb-1">Староста в группе или нет?</label>
|
||||
<Select v-model="form.group_leader" :options="['Да','Нет']" label="Староста в группе или нет?" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 grid md:grid-cols-2 gap-4">
|
||||
<Textarea v-model="form.interests" label="Коротко о своих интересах (2-3 предложения)" />
|
||||
<Textarea v-model="form.about_me" label="Коротко о себе" />
|
||||
<Textarea class="md:col-span-2" v-model="form.dreams" label="Коротко о своих мечтах" />
|
||||
</div>
|
||||
|
||||
<div class="mt-4 flex space-x-2">
|
||||
<Button @click="saveProfile" :loading="saving">Сохранить</Button>
|
||||
<Button variant="outline" @click="toggleEdit()">Отмена</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>Загрузка профиля...</p>
|
||||
|
||||
<div v-else class="flex items-center justify-center min-h-screen">
|
||||
<div class="text-center">
|
||||
<div class="animate-spin rounded-full h-16 w-16 border-b-2 border-primary-600 mx-auto"></div>
|
||||
<p class="mt-4 text-lg text-gray-600">Загрузка профиля...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Плавные переходы для интерактивных элементов */
|
||||
.border-gray-300 {
|
||||
transition: border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.bg-primary-50 {
|
||||
background-color: rgba(59, 130, 246, 0.05);
|
||||
}
|
||||
|
||||
/* Стилизация скроллбара для выпадающих списков */
|
||||
.overflow-auto::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.overflow-auto::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.overflow-auto::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.overflow-auto::-webkit-scrollbar-thumb:hover {
|
||||
background: #a1a1a1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, inject, watch, onMounted } from 'vue';
|
||||
import { Breadcrumbs, createResource, Button, Input, DatePicker, Select, Textarea } from 'frappe-ui';
|
||||
@@ -600,4 +848,4 @@ watch(
|
||||
});
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user