main features

This commit is contained in:
2025-08-10 17:28:38 +09:00
parent 3e4a21d5b1
commit 95bef94c53
30 changed files with 4246 additions and 1066 deletions

View File

@@ -1,4 +1,4 @@
{% load static %}
{% load static ui_extras %}
<!DOCTYPE html>
<html lang="ru">
<head>
@@ -11,6 +11,7 @@
.topbar { display:flex; gap:16px; align-items:center; padding:14px 18px; background:#111827; color:#fff; }
.topbar a { color:#cfe3ff; text-decoration:none; }
.container { max-width:1100px; margin:24px auto; padding:0 16px; }
.messages { list-style:none; padding:0; margin:0 0 16px; }
.messages li { padding:10px 12px; margin-bottom:8px; border-radius:10px; }
.messages li.success { background:#ecfdf5; color:#065f46; border:1px solid #a7f3d0; }
@@ -18,43 +19,37 @@
.messages li.info { background:#eff6ff; color:#1e40af; border:1px solid #bfdbfe; }
.filters { display:grid; grid-template-columns: repeat(8, 1fr); gap:10px; background:#fff; border:1px solid #e5e7eb; border-radius:12px; padding:14px; }
.filters .full { grid-column: 1 / -1; }
.filters input[type="text"], .filters select {
width:100%; border:1px solid #d1d5db; border-radius:8px; padding:8px 10px; font:inherit; background:#fff;
.filters input[type="text"], .filters select { width:100%; border:1px solid #d1d5db; border-radius:8px; padding:8px 10px; font:inherit; background:#fff; }
/* Фото‑карточки */
.list { margin-top:16px; display:grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap:14px; }
.card-photo { position:relative; display:block; border-radius:14px; overflow:hidden; border:1px solid #e5e7eb; background:#e5e7eb; }
.card-photo img { width:100%; height:280px; object-fit:cover; display:block; }
.card-photo__overlay {
position:absolute; left:0; right:0; bottom:0;
padding:12px 14px;
background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.65) 90%);
color:#fff;
}
.btn { display:inline-block; padding:9px 12px; border-radius:10px; border:1px solid #d1d5db; background:#fff; cursor:pointer; font-weight:600; }
.btn-primary { background:#2563eb; color:#fff; border-color:#2563eb; }
.list { margin-top:16px; display:grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap:14px; }
.card { background:#fff; border:1px solid #e5e7eb; border-radius:12px; padding:14px; }
.row { display:flex; align-items:center; gap:12px; }
.grow { flex:1 1 auto; }
.muted { color:#6b7280; font-size:14px; }
.pill { display:inline-block; padding:4px 10px; border-radius:999px; background:#eef2ff; color:#3730a3; font-size:12px; margin:2px 6px 2px 0; }
.meta { margin-top:8px; display:flex; flex-wrap:wrap; gap:10px 18px; }
.meta .k { color:#6b7280; }
.meta .v { color:#111827; font-weight:600; }
.card-photo__title { font-weight:700; font-size:18px; text-shadow:0 1px 2px rgba(0,0,0,.4); }
.pagination { display:flex; gap:10px; margin:16px 0; align-items:center; }
.pagination a, .pagination span {
padding:8px 12px; border-radius:10px; border:1px solid #d1d5db; text-decoration:none; color:#111;
background:#fff;
}
.pagination a, .pagination span { padding:8px 12px; border-radius:10px; border:1px solid #d1d5db; text-decoration:none; color:#111; background:#fff; }
.pagination .disabled { opacity:.5; pointer-events:none; }
.btn { padding:9px 12px; border-radius:10px; border:1px solid #d1d5db; background:#fff; cursor:pointer; font-weight:600; }
.muted { color:#6b7280; font-size:14px; }
.pill { display:inline-block; padding:4px 10px; border-radius:999px; background:#eef2ff; color:#3730a3; font-size:12px; margin:2px 6px 2px 0; }
</style>
</head>
<body>
<header class="topbar">
<div style="flex:1 1 auto;">
Каталог анкет (ADMIN)
</div>
<div style="flex:1 1 auto;">Каталог анкет (ADMIN)</div>
<nav style="display:flex; gap:14px;">
<a href="{% url 'index' %}">Главная</a>
<a href="{% url 'cabinet' %}">Кабинет</a>
<a href="{% url 'profiles' %}">Каталог</a>
<a href="{% url 'logout' %}">Выход</a>
<a href="{% url 'ui:index' %}">Главная</a>
<a href="{% url 'ui:cabinet' %}">Кабинет</a>
<a href="{% url 'ui:profiles' %}">Каталог</a>
<a href="{% url 'ui:logout' %}">Выход</a>
</nav>
</header>
@@ -68,7 +63,8 @@
</ul>
{% endif %}
<form class="filters" method="get" action="{% url 'profiles' %}">
<!-- Фильтры оставил: админ всё ещё может искать/сортировать -->
<form class="filters" method="get" action="{% url 'ui:profiles' %}">
<div>
<label class="muted">Поиск</label>
<input type="text" name="q" value="{{ filters.q }}" placeholder="имя или email">
@@ -81,25 +77,12 @@
<option value="ADMIN" {% if filters.role == "ADMIN" %}selected{% endif %}>ADMIN</option>
</select>
</div>
<div>
<label class="muted">Активность</label>
<select name="active">
<option value="">Любая</option>
<option value="1" {% if filters.active == "1" %}selected{% endif %}>Активные</option>
<option value="0" {% if filters.active == "0" %}selected{% endif %}>Неактивные</option>
</select>
</div>
<div>
<label class="muted">Домен</label>
<input type="text" name="domain" value="{{ filters.domain }}" placeholder="example.com">
</div>
<div>
<label class="muted">Сортировка</label>
<select name="sort">
<option value="name" {% if filters.sort == "name" %}selected{% endif %}>Имя ↑</option>
<option value="name_desc" {% if filters.sort == "name_desc" %}selected{% endif %}>Имя ↓</option>
<option value="email" {% if filters.sort == "email" %}selected{% endif %}>Email ↑</option>
<option value="email_desc" {% if filters.sort == "email_desc" %}selected{% endif %}>Email ↓</option>
</select>
</div>
<div>
@@ -115,7 +98,7 @@
<input type="text" name="page" value="{{ filters.page }}" style="width:90px;">
</div>
<div style="display:flex; align-items:flex-end;">
<button class="btn btn-primary" type="submit">Применить</button>
<button class="btn" type="submit">Применить</button>
</div>
</form>
@@ -139,33 +122,25 @@
<div class="messages"><li class="error">{{ error }}</li></div>
{% endif %}
<!-- Фото‑плитка карточек -->
<div class="list">
{% for p in profiles %}
<div class="card">
<div class="row">
<div class="grow">
<div style="font-weight:700; font-size:16px;">{{ p.name }}</div>
</div>
<div>
<form method="post" action="{% url 'like_profile' p.id %}">
{% csrf_token %}
{% include "ui/components/like_button.html" with profile_id=p.id liked=p.liked %}
</form>
<a class="card-photo" href="{% url 'ui:profile_detail' p.id %}" aria-label="Открыть {{ p.name }}">
{% if p.photo_url %}
<img src="{{ p.photo_url }}" alt="{{ p.name }}">
{% elif p.photo %}
<img src="{{ p.photo }}" alt="{{ p.name }}">
{% elif p.email %}
<img src="{{ p.email|gravatar_url:600 }}" alt="{{ p.name }}">
{% else %}
<img src="{% static 'img/profile_placeholder.jpg' %}" alt="{{ p.name }}">
{% endif %}
<div class="card-photo__overlay">
<div class="card-photo__title">
{{ p.name }}{% if p.age %}, {{ p.age }}{% endif %}
</div>
</div>
<div class="meta">
<div><span class="pill">{{ p.verified|yesno:"ACTIVE,INACTIVE" }}</span></div>
<div class="pill">{{ p.role|default:"USER" }}</div>
</div>
<div class="row" style="margin-top:10px;">
<div class="grow"></div>
<a class="btn" href="{% url 'profile_detail' p.id %}">Открыть</a>
</div>
</div>
</a>
{% empty %}
<div class="card">
<div class="muted">Ничего не найдено. Попробуйте изменить фильтры.</div>
@@ -190,6 +165,5 @@
</div>
</main>
</body>
</html>