DispelEvilBot/admin/templates/users/card.html

264 lines
12 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}{{ user.nick or user.id_user }}{% endblock %}
{% block content %}
<p class="text-sm text-slate-500"><a href="/users" class="hover:underline">← Пользователи</a></p>
<div class="mt-2 flex flex-wrap items-start justify-between gap-4">
<div>
<h1 class="text-2xl font-semibold">{{ user.nick or "Без ника" }}</h1>
<p class="mt-1 text-slate-600">
{% if user.username %}<span class="font-mono">@{{ user.username }}</span> · {% endif %}
<span class="font-mono">{{ user.id_user }}</span>
{% if user.first_name or user.last_name %}
· {{ user.first_name or "" }} {{ user.last_name or "" }}
{% endif %}
</p>
</div>
<div class="flex items-center gap-2">
{% if user.title %}
<span class="rounded bg-indigo-100 px-3 py-1 text-sm text-indigo-800">{{ user.title }}</span>
{% endif %}
{% if user.subscribed %}
<span class="rounded bg-emerald-100 px-3 py-1 text-sm text-emerald-800">подписан на рассылки</span>
{% else %}
<span class="rounded bg-slate-100 px-3 py-1 text-sm text-slate-500">без рассылок</span>
{% endif %}
</div>
</div>
{% if saved %}
<div class="mt-4 rounded-lg border border-emerald-200 bg-emerald-50 p-3 text-sm text-emerald-800">
{% if saved == 'nick' %}Ник обновлён.
{% elif saved == 'title' %}Звание обновлено.
{% elif saved == 'subscription' %}Подписка обновлена.
{% elif saved == 'balance' %}Баланс скорректирован.
{% else %}Изменения сохранены.{% endif %}
</div>
{% endif %}
{% if errors %}
<ul class="mt-4 list-disc rounded-lg border border-red-200 bg-red-50 p-3 pl-8 text-sm text-red-700">
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
</ul>
{% endif %}
<div class="mt-6 grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
<div class="rounded-lg border border-slate-200 bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Уровень</div>
<div class="mt-1 text-xl font-semibold">{{ user.lvl }}</div>
</div>
<div class="rounded-lg border border-slate-200 bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Опыт</div>
<div class="mt-1 text-xl font-semibold">{{ user.expr }}</div>
<div class="text-xs text-slate-500">серия: {{ user.expr_streak }}</div>
</div>
<div class="rounded-lg border border-slate-200 bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Баланс DE</div>
<div class="mt-1 text-xl font-semibold">{{ user.balance }}</div>
</div>
{% if eggs_visible %}
<div class="rounded-lg border border-slate-200 bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Яички</div>
<div class="mt-1 text-xl font-semibold">{{ user.eggs }}</div>
</div>
{% endif %}
<div class="rounded-lg border border-slate-200 bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Сообщения</div>
<div class="mt-1 text-xl font-semibold">{{ user.msg_count }}</div>
<div class="text-xs text-slate-500">
последняя активность: {{ user.last_message_at.strftime("%d.%m.%Y") if user.last_message_at else "—" }}
</div>
</div>
<div class="rounded-lg border border-slate-200 bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Очищения</div>
<div class="mt-1 text-xl font-semibold">{{ user.purification_count }}</div>
<div class="text-xs text-slate-500">
последнее: {{ user.last_purification_at.strftime("%d.%m.%Y %H:%M") if user.last_purification_at else "—" }}
</div>
</div>
<div class="rounded-lg border border-slate-200 bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">В клане с</div>
<div class="mt-1 text-xl font-semibold">
{{ user.dt_create.strftime("%d.%m.%Y") if user.dt_create else "—" }}
</div>
</div>
<div class="rounded-lg border border-slate-200 bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Telegram-ID</div>
<div class="mt-1 font-mono text-sm">{{ user.id_user }}</div>
</div>
</div>
<div class="mt-8">
<h2 class="text-lg font-medium">Управление</h2>
<div class="mt-3 grid gap-4 lg:grid-cols-2">
<form method="post" action="/users/{{ user.id_user }}/nick" class="rounded-lg border border-slate-200 bg-white p-4">
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
<label for="nick" class="text-sm font-medium text-slate-700">Ник</label>
<div class="mt-2 flex gap-2">
<input
id="nick"
name="nick"
type="text"
value="{{ user.nick or '' }}"
maxlength="{{ max_nick_length }}"
class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
/>
<button type="submit" class="rounded-lg bg-sky-600 px-4 py-2 text-sm font-medium text-white hover:bg-sky-700">
Сохранить
</button>
</div>
</form>
<form method="post" action="/users/{{ user.id_user }}/title" class="rounded-lg border border-slate-200 bg-white p-4">
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
<label for="title_id" class="text-sm font-medium text-slate-700">Звание</label>
<div class="mt-2 flex gap-2">
<select
id="title_id"
name="title_id"
class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
>
{% for title in titles %}
<option value="{{ title.id_title }}" {% if title.id_title == user.id_title %}selected{% endif %}>
{{ title.title }}
</option>
{% endfor %}
</select>
<button type="submit" class="rounded-lg bg-sky-600 px-4 py-2 text-sm font-medium text-white hover:bg-sky-700">
Сохранить
</button>
</div>
</form>
<form method="post" action="/users/{{ user.id_user }}/subscription" class="rounded-lg border border-slate-200 bg-white p-4">
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
<input type="hidden" name="subscribed" value="{{ '0' if user.subscribed else '1' }}" />
<div class="text-sm font-medium text-slate-700">Рассылки</div>
<p class="mt-1 text-sm text-slate-600">
{% if user.subscribed %}Сейчас подписан.{% else %}Сейчас не подписан.{% endif %}
</p>
<button type="submit" class="mt-2 rounded-lg border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">
{% if user.subscribed %}Отписать{% else %}Подписать{% endif %}
</button>
</form>
<form method="post" action="/users/{{ user.id_user }}/balance" class="rounded-lg border border-slate-200 bg-white p-4">
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
<div class="text-sm font-medium text-slate-700">Корректировка баланса</div>
<div class="mt-2 flex gap-2">
<input
name="amount"
type="number"
step="1"
placeholder="+50 или -20"
class="w-32 rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
/>
<input
name="reason"
type="text"
maxlength="{{ max_comment_length }}"
placeholder="Причина"
class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
/>
<button type="submit" class="rounded-lg bg-sky-600 px-4 py-2 text-sm font-medium text-white hover:bg-sky-700">
Провести
</button>
</div>
<p class="mt-1 text-xs text-slate-500">Запись уйдёт в журнал денег с действием «Корректировка админом».</p>
</form>
</div>
</div>
{% if can_kick %}
<div class="mt-6 rounded-lg border border-red-200 bg-red-50 p-4">
<h2 class="text-lg font-medium text-red-800">Исключить из чата</h2>
<p class="mt-1 text-sm text-red-700">
Бот заблокирует пользователя и сразу разблокирует (чтобы мог вернуться),
а данные из бота будут удалены.
</p>
<form
method="post"
action="/users/{{ user.id_user }}/kick"
class="mt-3"
onsubmit="return confirm('Исключить {{ user.nick or user.id_user }} из чата?');"
>
<input type="hidden" name="csrf_token" value="{{ request.session.get('csrf', '') }}" />
<button type="submit" class="rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700">
Выгнать из чата
</button>
</form>
</div>
{% endif %}
<div class="mt-8">
<h2 class="text-lg font-medium">История изменений</h2>
{% if history %}
<div class="mt-3 overflow-x-auto rounded-lg border border-slate-200 bg-white">
<table class="min-w-full divide-y divide-slate-200 text-sm">
<thead class="bg-slate-50 text-left text-slate-600">
<tr>
<th class="px-4 py-3 font-medium">Когда</th>
<th class="px-4 py-3 font-medium">Что</th>
<th class="px-4 py-3 font-medium">Было → стало</th>
<th class="px-4 py-3 font-medium">Комментарий</th>
<th class="px-4 py-3 font-medium">Источник</th>
<th class="px-4 py-3 font-medium">Админ</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100">
{% set field_labels = {"nick": "Ник", "title": "Звание", "subscription": "Подписка", "balance": "Баланс"} %}
{% for item in history %}
<tr>
<td class="px-4 py-3 text-slate-600">{{ item.changed_at.strftime("%d.%m.%Y %H:%M") }}</td>
<td class="px-4 py-3">{{ field_labels.get(item.field, item.field) }}</td>
<td class="px-4 py-3 text-slate-700">{{ item.old_value or "—" }} → {{ item.new_value or "—" }}</td>
<td class="px-4 py-3 text-slate-600">{{ item.comment or "—" }}</td>
<td class="px-4 py-3 text-slate-600">
{% if item.source == 'user' %}Пользователь{% else %}Админ{% endif %}
</td>
<td class="px-4 py-3 font-mono text-xs text-slate-500">{{ item.editor_id or "—" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="mt-2 text-sm text-slate-500">Ручных изменений ещё не было.</p>
{% endif %}
</div>
<div class="mt-8">
<h2 class="text-lg font-medium">Последние операции по балансу</h2>
{% if money %}
<div class="mt-3 overflow-x-auto rounded-lg border border-slate-200 bg-white">
<table class="min-w-full divide-y divide-slate-200 text-sm">
<thead class="bg-slate-50 text-left text-slate-600">
<tr>
<th class="px-4 py-3 font-medium">Когда</th>
<th class="px-4 py-3 font-medium">Сумма</th>
<th class="px-4 py-3 font-medium">Действие</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100">
{% for item in money %}
<tr>
<td class="px-4 py-3 text-slate-600">
{{ item.dt_action.strftime("%d.%m.%Y %H:%M") if item.dt_action else "—" }}
</td>
<td class="px-4 py-3 font-medium {% if item.amount < 0 %}text-red-600{% else %}text-emerald-700{% endif %}">
{{ "%+d" | format(item.amount) }}
</td>
<td class="px-4 py-3 text-slate-700">{{ item.action or "—" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="mt-2 text-sm text-slate-500">Операций по балансу не было.</p>
{% endif %}
</div>
{% endblock %}