Auto-commit before push to git.mycloud24.ru
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
{% block title %}Аналитика — InviteMe{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="mb-4">Аналитика мероприятия</h1>
|
||||
<h1 class="mb-4">Аналитика: {{ event.name }}</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ 'Редактировать' if event else 'Создать' }} мероприятие — InviteMe{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="mb-4">{{ 'Редактировать' if event else 'Создать' }} мероприятие</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Название *</label>
|
||||
<input type="text" class="form-control" id="name" name="name" value="{{ event.name if event else '' }}" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Описание</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="3">{{ event.description if event else '' }}</textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="location" class="form-label">Место проведения</label>
|
||||
<input type="text" class="form-control" id="location" name="location" value="{{ event.location if event else '' }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="event_date" class="form-label">Дата и время</label>
|
||||
<input type="datetime-local" class="form-control" id="event_date" name="event_date"
|
||||
value="{{ event.event_date.strftime('%Y-%m-%dT%H:%M') if event and event.event_date else '' }}">
|
||||
</div>
|
||||
{% if event %}
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="is_active" name="is_active" {% if event.is_active %}checked{% endif %}>
|
||||
<label class="form-check-label" for="is_active">Активно</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||
{% if event %}
|
||||
<a href="{{ url_for('main.admin_event_ticket', event_id=event.id) }}" class="btn btn-outline-info">Конструктор билета</a>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('main.admin_events') }}" class="btn btn-secondary">Отмена</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,51 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Мероприятия — InviteMe{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>Мероприятия</h1>
|
||||
<a href="{{ url_for('main.admin_event_add') }}" class="btn btn-primary">Создать мероприятие</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
{% for event in events %}
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card h-100 {% if not event.is_active %}border-secondary{% endif %}">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ event.name }}</h5>
|
||||
<p class="card-text text-muted">
|
||||
{% if event.event_date %}
|
||||
{{ event.event_date.strftime('%d.%m.%Y %H:%M') }}<br>
|
||||
{% endif %}
|
||||
{% if event.location %}
|
||||
{{ event.location }}<br>
|
||||
{% endif %}
|
||||
Гостей: {{ event.total_guests }} | Пришло: {{ event.checked_in }}
|
||||
</p>
|
||||
{% if event.description %}
|
||||
<p class="card-text">{{ event.description }}</p>
|
||||
{% endif %}
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<form action="{{ url_for('main.admin_event_switch', event_id=event.id) }}" method="POST" class="d-inline">
|
||||
<button type="submit" class="btn btn-success btn-sm">Выбрать</button>
|
||||
</form>
|
||||
<a href="{{ url_for('main.admin_event_edit', event_id=event.id) }}" class="btn btn-outline-primary btn-sm">Изменить</a>
|
||||
<a href="{{ url_for('main.admin_event_ticket', event_id=event.id) }}" class="btn btn-outline-info btn-sm">Билет</a>
|
||||
{% if not event.is_active %}
|
||||
<span class="badge bg-secondary">Неактивно</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer text-muted">
|
||||
Создано: {{ event.created_at.strftime('%d.%m.%Y') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-12">
|
||||
<div class="alert alert-info">Пока нет ни одного мероприятия. <a href="{{ url_for('main.admin_event_add') }}">Создайте первое</a>.</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -4,13 +4,24 @@
|
||||
|
||||
{% block content %}
|
||||
<h1 class="mb-4">{{ 'Редактировать' if guest else 'Добавить' }} гостя</h1>
|
||||
<p class="text-muted">Мероприятие: {{ event.name }}</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form method="POST">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="last_name" class="form-label">Фамилия</label>
|
||||
<input type="text" class="form-control" id="last_name" name="last_name" value="{{ guest.last_name if guest else '' }}" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="first_name" class="form-label">Имя</label>
|
||||
<input type="text" class="form-control" id="first_name" name="first_name" value="{{ guest.first_name if guest else '' }}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="full_name" class="form-label">ФИО</label>
|
||||
<input type="text" class="form-control" id="full_name" name="full_name" value="{{ guest.full_name if guest else '' }}" required>
|
||||
<label for="middle_name" class="form-label">Отчество</label>
|
||||
<input type="text" class="form-control" id="middle_name" name="middle_name" value="{{ guest.middle_name if guest else '' }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="department" class="form-label">Отдел</label>
|
||||
@@ -24,6 +35,10 @@
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="email" class="form-control" id="email" name="email" value="{{ guest.email if guest else '' }}" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="phone" class="form-label">Телефон</label>
|
||||
<input type="text" class="form-control" id="phone" name="phone" value="{{ guest.phone if guest else '' }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="photo_filename" class="form-label">Название фото</label>
|
||||
<input type="text" class="form-control" id="photo_filename" name="photo_filename" value="{{ guest.photo_filename if guest else '' }}">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>Гости</h1>
|
||||
<h1>Гости: {{ event.name }}</h1>
|
||||
<a href="{{ url_for('main.admin_guest_add') }}" class="btn btn-primary">Добавить гостя</a>
|
||||
</div>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<th>Отдел</th>
|
||||
<th>Должность</th>
|
||||
<th>Email</th>
|
||||
<th>Телефон</th>
|
||||
<th>Фото</th>
|
||||
<th>QR</th>
|
||||
<th>Статус</th>
|
||||
@@ -33,10 +34,11 @@
|
||||
<tbody>
|
||||
{% for guest in guests %}
|
||||
<tr class="{{ 'table-secondary' if not guest.is_active }}">
|
||||
<td>{{ guest.full_name }}</td>
|
||||
<td>{{ guest.build_full_name() }}</td>
|
||||
<td>{{ guest.department }}</td>
|
||||
<td>{{ guest.position or '-' }}</td>
|
||||
<td>{{ guest.email }}</td>
|
||||
<td>{{ guest.phone or '-' }}</td>
|
||||
<td>
|
||||
{% if guest.photo_filename %}
|
||||
<span class="badge bg-success">Есть</span>
|
||||
@@ -70,7 +72,7 @@
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="8" class="text-center text-muted">Гости не найдены</td>
|
||||
<td colspan="9" class="text-center text-muted">Гости не найдены</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Конструктор билета — {{ event.name }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>Конструктор пригласительного билета</h1>
|
||||
<a href="{{ url_for('main.admin_events') }}" class="btn btn-secondary">← К мероприятиям</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-5">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Настройки дизайна</h5>
|
||||
<form method="POST" id="ticket-form" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label for="logo_file" class="form-label">Логотип компании</label>
|
||||
<input type="file" class="form-control" id="logo_file" name="logo_file" accept="image/*">
|
||||
{% if event.logo_filename %}
|
||||
<div class="mt-2 d-flex align-items-center gap-2">
|
||||
<img src="{{ url_for('static', filename='uploads/logos/' + event.logo_filename) }}" alt="Логотип" style="max-height: 60px; max-width: 200px;">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="delete_logo" name="delete_logo" value="1">
|
||||
<label class="form-check-label" for="delete_logo">Удалить</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="ticket_title" class="form-label">Заголовок билета</label>
|
||||
<input type="text" class="form-control" id="ticket_title" name="ticket_title" value="{{ event.ticket_title or event.name }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="ticket_subtitle" class="form-label">Подзаголовок</label>
|
||||
<input type="text" class="form-control" id="ticket_subtitle" name="ticket_subtitle" value="{{ event.ticket_subtitle or '' }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="ticket_body_text" class="form-label">Дополнительный текст</label>
|
||||
<textarea class="form-control" id="ticket_body_text" name="ticket_body_text" rows="3">{{ event.ticket_body_text or '' }}</textarea>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="ticket_background_color" class="form-label">Фон</label>
|
||||
<input type="color" class="form-control form-control-color w-100" id="ticket_background_color" name="ticket_background_color" value="{{ event.ticket_background_color or '#ffffff' }}">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="ticket_text_color" class="form-label">Текст</label>
|
||||
<input type="color" class="form-control form-control-color w-100" id="ticket_text_color" name="ticket_text_color" value="{{ event.ticket_text_color or '#000000' }}">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="ticket_accent_color" class="form-label">Акцент</label>
|
||||
<input type="color" class="form-control form-control-color w-100" id="ticket_accent_color" name="ticket_accent_color" value="{{ event.ticket_accent_color or '#0d6efd' }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="ticket_layout" class="form-label">Ориентация</label>
|
||||
<select class="form-select" id="ticket_layout" name="ticket_layout">
|
||||
<option value="portrait" {% if (event.ticket_layout or 'portrait') == 'portrait' %}selected{% endif %}>Портретная (600×900)</option>
|
||||
<option value="landscape" {% if (event.ticket_layout or 'portrait') == 'landscape' %}selected{% endif %}>Альбомная (900×600)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="ticket_show_qr" name="ticket_show_qr" {% if event.ticket_show_qr %}checked{% endif %}>
|
||||
<label class="form-check-label" for="ticket_show_qr">Показывать QR-код</label>
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="ticket_show_photo" name="ticket_show_photo" {% if event.ticket_show_photo %}checked{% endif %}>
|
||||
<label class="form-check-label" for="ticket_show_photo">Показывать фото гостя</label>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||
<button type="button" id="refresh-preview" class="btn btn-outline-secondary">Обновить предпросмотр</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-7">
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<h5 class="card-title">Предпросмотр</h5>
|
||||
<p class="text-muted">Пример билета с тестовыми данными</p>
|
||||
<img id="ticket-preview" src="{{ url_for('main.admin_event_ticket_preview', event_id=event.id) }}" alt="Предпросмотр билета" class="img-fluid border shadow-sm" style="max-height: 80vh;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
document.getElementById('refresh-preview').addEventListener('click', function() {
|
||||
const img = document.getElementById('ticket-preview');
|
||||
img.src = "{{ url_for('main.admin_event_ticket_preview', event_id=event.id) }}?t=" + Date.now();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -4,13 +4,14 @@
|
||||
|
||||
{% block content %}
|
||||
<h1 class="mb-4">Загрузка данных</h1>
|
||||
<p class="text-muted">Мероприятие: {{ event.name }}</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">1. Загрузить Excel со списком гостей</h5>
|
||||
<p class="text-muted">Столбцы: Отдел, ФИО, Должность, e-mail, название фото</p>
|
||||
<p class="text-muted">Столбцы: Отдел, Фамилия, Имя, Отчество, Должность, Почта, Телефон, Название фото</p>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label for="excel_file" class="form-label">Excel-файл</label>
|
||||
@@ -30,7 +31,7 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">2. Загрузить фото гостей</h5>
|
||||
<p class="text-muted">Фото должны называться точно так же, как указано в столбце «название фото»</p>
|
||||
<p class="text-muted">Фото должны называться точно так же, как указано в столбце «Название фото»</p>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label for="photo_files" class="form-label">Фото (можно несколько)</label>
|
||||
@@ -46,4 +47,63 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Пример заполнения Excel-таблицы</h5>
|
||||
<p class="text-muted">Имена столбцов должны совпадать точно. Значение в столбце «Название фото» должно совпадать с именем файла фото, включая расширение.</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Отдел</th>
|
||||
<th>Фамилия</th>
|
||||
<th>Имя</th>
|
||||
<th>Отчество</th>
|
||||
<th>Должность</th>
|
||||
<th>Почта</th>
|
||||
<th>Телефон</th>
|
||||
<th>Название фото</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>IT</td>
|
||||
<td>Иванов</td>
|
||||
<td>Иван</td>
|
||||
<td>Иванович</td>
|
||||
<td>Разработчик</td>
|
||||
<td>ivanov@company.com</td>
|
||||
<td>+7 (999) 111-22-33</td>
|
||||
<td>ivanov.jpg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Маркетинг</td>
|
||||
<td>Петрова</td>
|
||||
<td>Анна</td>
|
||||
<td>Сергеевна</td>
|
||||
<td>Маркетолог</td>
|
||||
<td>petrova@company.com</td>
|
||||
<td>+7 (999) 222-33-44</td>
|
||||
<td>petrova.png</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Продажи</td>
|
||||
<td>Сидоров</td>
|
||||
<td>Алексей</td>
|
||||
<td>Петрович</td>
|
||||
<td>Менеджер</td>
|
||||
<td>sidorov@company.com</td>
|
||||
<td>+7 (999) 333-44-55</td>
|
||||
<td>sidorov.jpg</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ 'Редактировать' if user else 'Добавить' }} пользователя — InviteMe{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="mb-4">{{ 'Редактировать' if user else 'Добавить' }} пользователя</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Логин *</label>
|
||||
<input type="text" class="form-control" id="username" name="username" value="{{ user.username if user else '' }}" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Пароль {% if user %}(оставьте пустым, чтобы не менять){% else %}*{% endif %}</label>
|
||||
<input type="password" class="form-control" id="password" name="password" {% if not user %}required{% endif %}>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="role" class="form-label">Роль *</label>
|
||||
<select class="form-select" id="role" name="role" required>
|
||||
<option value="admin" {% if user and user.role == 'admin' %}selected{% endif %}>Администратор</option>
|
||||
<option value="organizer" {% if user and user.role == 'organizer' %}selected{% endif %}>Организатор</option>
|
||||
<option value="staff" {% if user and user.role == 'staff' %}selected{% endif %} {% if not user %}selected{% endif %}>Сотрудник на входе</option>
|
||||
</select>
|
||||
</div>
|
||||
{% if user %}
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="is_active" name="is_active" {% if user.is_active %}checked{% endif %}>
|
||||
<label class="form-check-label" for="is_active">Активен</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||
<a href="{{ url_for('main.admin_users') }}" class="btn btn-secondary">Отмена</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,58 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Пользователи — InviteMe{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>Пользователи</h1>
|
||||
<a href="{{ url_for('main.admin_user_add') }}" class="btn btn-primary">Добавить пользователя</a>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Логин</th>
|
||||
<th>Роль</th>
|
||||
<th>Статус</th>
|
||||
<th>Создан</th>
|
||||
<th>Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr class="{{ 'table-secondary' if not user.is_active }}">
|
||||
<td>{{ user.username }}</td>
|
||||
<td>
|
||||
{% if user.role == 'admin' %}
|
||||
<span class="badge bg-danger">Админ</span>
|
||||
{% elif user.role == 'organizer' %}
|
||||
<span class="badge bg-warning text-dark">Организатор</span>
|
||||
{% else %}
|
||||
<span class="badge bg-info text-dark">Сотрудник</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if user.is_active %}
|
||||
<span class="badge bg-success">Активен</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">Заблокирован</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ user.created_at.strftime('%d.%m.%Y %H:%M') }}</td>
|
||||
<td>
|
||||
<a href="{{ url_for('main.admin_user_edit', user_id=user.id) }}" class="btn btn-sm btn-outline-primary">Изменить</a>
|
||||
{% if current_user.id != user.id %}
|
||||
<form action="{{ url_for('main.admin_user_delete', user_id=user.id) }}" method="POST" class="d-inline" onsubmit="return confirm('Заблокировать пользователя?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">Блок</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">Пользователи не найдены</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
+38
-6
@@ -8,7 +8,7 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
|
||||
<nav class="navbar navbar-expand-lg navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="{{ url_for('main.index') }}">InviteMe</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
@@ -16,7 +16,11 @@
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto">
|
||||
{% if session.role == 'admin' %}
|
||||
{% if current_user and current_user.role in ('admin', 'organizer') %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('main.admin_events') }}">Мероприятия</a>
|
||||
</li>
|
||||
{% if current_event %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('main.admin_dashboard') }}">Аналитика</a>
|
||||
</li>
|
||||
@@ -27,14 +31,42 @@
|
||||
<a class="nav-link" href="{{ url_for('main.admin_guests') }}">Гости</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if session.role in ('admin', 'staff') %}
|
||||
{% endif %}
|
||||
{% if current_user and current_user.is_admin %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('main.check_in') }}">Вход</a>
|
||||
<a class="nav-link" href="{{ url_for('main.admin_users') }}">Пользователи</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if current_user and current_user.role in ('admin', 'organizer', 'staff') %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('main.check_in') }}">Проверка приглашения</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% if session.role %}
|
||||
<ul class="navbar-nav">
|
||||
|
||||
{% if current_user %}
|
||||
<ul class="navbar-nav align-items-center">
|
||||
{% if current_user.role in ('admin', 'organizer') and available_events %}
|
||||
<li class="nav-item dropdown me-3">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="eventDropdown" role="button" data-bs-toggle="dropdown">
|
||||
{% if current_event %}{{ current_event.name }}{% else %}Выбрать мероприятие{% endif %}
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="eventDropdown">
|
||||
{% for event in available_events %}
|
||||
<li>
|
||||
<form action="{{ url_for('main.admin_event_switch', event_id=event.id) }}" method="POST" class="d-inline">
|
||||
<button type="submit" class="dropdown-item {% if current_event and current_event.id == event.id %}active{% endif %}">
|
||||
{{ event.name }}
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<span class="navbar-text me-3">{{ current_user.username }} ({{ current_user.role }})</span>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('main.logout') }}">Выйти</a>
|
||||
</li>
|
||||
|
||||
@@ -1,16 +1,53 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Отметка входа — InviteMe{% endblock %}
|
||||
{% block title %}Проверка приглашения — InviteMe{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="checkin-container">
|
||||
<h1 class="mb-4 text-center">Отметка входа</h1>
|
||||
<h1 class="mb-4 text-center">Проверка приглашения</h1>
|
||||
|
||||
{% if active_events %}
|
||||
<div class="row justify-content-center mb-4">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Выберите мероприятие</h5>
|
||||
<form method="POST" action="{{ url_for('main.check_in', token=token) }}">
|
||||
<div class="mb-3">
|
||||
<select id="event-select" name="event_id" class="form-select" onchange="this.form.submit()">
|
||||
<option value="">-- Мероприятие --</option>
|
||||
{% for event in active_events %}
|
||||
<option value="{{ event.id }}" {% if checkin_event and checkin_event.id == event.id %}selected{% endif %}>
|
||||
{{ event.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<noscript><button type="submit" class="btn btn-primary">Выбрать</button></noscript>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if checkin_event %}
|
||||
<div class="alert alert-info text-center">
|
||||
Текущее мероприятие: <strong>{{ checkin_event.name }}</strong>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Сканировать QR-код</h5>
|
||||
<div class="mb-3">
|
||||
<label for="camera-select" class="form-label">Камера</label>
|
||||
<select id="camera-select" class="form-select">
|
||||
<option value="">-- Выберите камеру --</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="qr-reader" class="qr-reader"></div>
|
||||
<button id="start-scan" class="btn btn-primary w-100 mt-2">Включить камеру</button>
|
||||
<button id="stop-scan" class="btn btn-secondary w-100 mt-2 d-none">Выключить камеру</button>
|
||||
@@ -36,6 +73,7 @@
|
||||
<p id="guest-department" class="lead"></p>
|
||||
<p id="guest-position" class="text-muted"></p>
|
||||
<p id="guest-email" class="text-muted"></p>
|
||||
<p id="guest-event" class="text-info"></p>
|
||||
|
||||
<div id="check-in-status" class="alert d-none"></div>
|
||||
|
||||
|
||||
@@ -10,17 +10,24 @@
|
||||
<p>Здравствуйте, <strong>{{ guest.full_name }}</strong>!</p>
|
||||
<p>Вы приглашены на мероприятие <strong>{{ event_name }}</strong>.</p>
|
||||
|
||||
{% if ticket_cid %}
|
||||
<p>Ваш персональный пригласительный билет:</p>
|
||||
<div style="text-align: center; margin: 20px 0;">
|
||||
<img src="cid:{{ ticket_cid }}" alt="Пригласительный билет" style="max-width: 100%; border: 1px solid #ddd; border-radius: 8px;">
|
||||
</div>
|
||||
{% else %}
|
||||
<p>Ваш персональный QR-код для входа:</p>
|
||||
<div style="text-align: center; margin: 20px 0;">
|
||||
<img src="cid:qr_code_image" alt="QR-код" style="max-width: 250px;">
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if additional_text %}
|
||||
<p>{{ additional_text }}</p>
|
||||
{% endif %}
|
||||
|
||||
<p style="color: #666; font-size: 14px;">
|
||||
Пожалуйста, предъявите этот QR-код при входе. Не передавайте его другим лицам.
|
||||
Пожалуйста, предъявите этот QR-код или билет при входе. Не передавайте их другим лицам.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
{% block title %}Вход — InviteMe{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="row justify-content-center align-items-center" style="min-height: 70vh;">
|
||||
<div class="col-md-4">
|
||||
<div class="card shadow-sm mt-5">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-center mb-4">InviteMe</h3>
|
||||
<div class="card mt-5">
|
||||
<div class="card-body p-4">
|
||||
<h3 class="card-title text-center mb-4" style="color: var(--accent-color); text-shadow: 0 0 12px var(--accent-glow);">InviteMe</h3>
|
||||
<p class="text-muted text-center mb-4">Система регистрации гостей</p>
|
||||
<form method="POST" action="{{ url_for('main.login') }}">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Логин</label>
|
||||
|
||||
Reference in New Issue
Block a user