main features
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
{% load static %}
|
||||
{% load static ui_extras %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
@@ -17,42 +17,37 @@
|
||||
.card { background:#fff; border:1px solid #e5e7eb; border-radius:12px; padding:18px; box-shadow: 0 1px 2px rgba(0,0,0,.03); }
|
||||
.grid { display:grid; gap:16px; }
|
||||
.grid-2 { grid-template-columns: 1fr 1fr; }
|
||||
dl { display:grid; grid-template-columns: 200px 1fr; gap:8px 14px; margin: 0; }
|
||||
dt { font-weight:600; color:#374151; }
|
||||
dd { margin:0; color:#111827; }
|
||||
.pill { display:inline-block; padding:4px 10px; border-radius:999px; background:#eef2ff; color:#3730a3; font-size:12px; margin:2px 6px 2px 0; }
|
||||
.row { display:flex; gap:18px; align-items:center; }
|
||||
.avatar { width:96px; height:96px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-weight:700; font-size:32px; background:#e5e7eb; color:#374151; }
|
||||
.avatar img { width:96px; height:96px; object-fit:cover; border-radius:50%; display:block; }
|
||||
.form { display:grid; gap:14px; }
|
||||
.form label { font-weight:600; font-size:14px; }
|
||||
.form input[type="text"], .form select, .form textarea {
|
||||
width:100%; border:1px solid #d1d5db; border-radius:8px; padding:10px 12px; font:inherit; background:#fff;
|
||||
}
|
||||
.form small { color:#6b7280; }
|
||||
.form input[type="text"], .form select, .form textarea { width:100%; border:1px solid #d1d5db; border-radius:8px; padding:10px 12px; font:inherit; background:#fff; }
|
||||
.btnrow { display:flex; gap:10px; margin-top:8px; }
|
||||
.btn { display:inline-block; padding:10px 14px; border-radius:10px; border:1px solid transparent; font-weight:600; cursor:pointer; }
|
||||
.btn-primary { background:#2563eb; color:#fff; }
|
||||
.btn { display:inline-block; padding:10px 14px; border-radius:10px; border:1px solid #d1d5db; background:#fff; cursor:pointer; font-weight:600; color:#111; }
|
||||
.btn-primary { background:#2563eb; color:#fff; border-color:#2563eb; }
|
||||
.btn-outline { background:#fff; color:#111; border-color:#d1d5db; }
|
||||
.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; }
|
||||
.messages li.error { background:#fef2f2; color:#991b1b; border:1px solid #fecaca; }
|
||||
.messages li.info { background:#eff6ff; color:#1e40af; border:1px solid #bfdbfe; }
|
||||
dl { display:grid; grid-template-columns: 200px 1fr; gap:8px 14px; margin: 0; }
|
||||
dt { font-weight:600; color:#374151; }
|
||||
dd { margin:0; color:#111827; }
|
||||
.pill { display:inline-block; padding:4px 10px; border-radius:999px; background:#eef2ff; color:#3730a3; font-size:12px; margin:2px 6px 2px 0; }
|
||||
details summary { cursor:pointer; }
|
||||
code, pre { background:#111827; color:#e5e7eb; padding:10px 12px; border-radius:10px; display:block; overflow:auto; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="topbar">
|
||||
<div style="flex:1 1 auto;">
|
||||
{% with header_name=header_name|default:request.session.user_full_name|default:request.session.user_email %}
|
||||
Здравствуйте, <strong>{{ header_name }}</strong>!
|
||||
{% endwith %}
|
||||
Здравствуйте, <strong>{{ request.session.user_full_name|default:request.session.user_email }}</strong>!
|
||||
</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>
|
||||
|
||||
@@ -75,118 +70,129 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Две колонки: Аккаунт + Профиль -->
|
||||
<div class="grid grid-2">
|
||||
<!-- ======= ДАННЫЕ АККАУНТА ======= -->
|
||||
<!-- Аккаунт -->
|
||||
<section class="card">
|
||||
<h2 class="muted" style="margin-top:0;">Данные аккаунта</h2>
|
||||
<dl>
|
||||
<dt>Имя</dt>
|
||||
<dd>{{ request.session.user_full_name|default:"—" }}</dd>
|
||||
<div class="row" style="margin-bottom:14px;">
|
||||
<div class="avatar">
|
||||
{% if request.session.user_email %}
|
||||
<img src="{{ request.session.user_email|gravatar_url:96 }}" alt="">
|
||||
{% else %}
|
||||
{{ request.session.user_full_name|default:request.session.user_email|initial }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight:700;">{{ request.session.user_full_name|default:"Без имени" }}</div>
|
||||
<div class="muted">{{ request.session.user_email }}</div>
|
||||
<div class="pill" style="margin-top:6px;">{{ request.session.user_role|default:"CLIENT" }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dt>Email</dt>
|
||||
<dd>{{ request.session.user_email|default:"—" }}</dd>
|
||||
|
||||
<dt>Роль</dt>
|
||||
<dd><span class="pill">{{ request.session.user_role|default:"—" }}</span></dd>
|
||||
|
||||
<dt>ID пользователя</dt>
|
||||
<dd><code>{{ request.session.user_id|default:"—" }}</code></dd>
|
||||
</dl>
|
||||
<form class="form" method="post" action="{% url 'ui:cabinet' %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="action" value="update_name">
|
||||
<label for="full_name">Имя / ФИО</label>
|
||||
<input id="full_name" name="full_name" type="text" value="{{ request.session.user_full_name|default_if_none:'' }}" placeholder="Ваше имя">
|
||||
<div class="btnrow">
|
||||
<button class="btn btn-primary" type="submit">Сохранить имя</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<!-- ======= ДАННЫЕ ПРОФИЛЯ ======= -->
|
||||
<section class="card">
|
||||
<h2 class="muted" style="margin-top:0;">Данные профиля</h2>
|
||||
|
||||
{% if has_profile and profile %}
|
||||
<dl>
|
||||
<dt>Пол</dt>
|
||||
<dd>{{ profile.gender|default:"—" }}</dd>
|
||||
|
||||
<dt>Город</dt>
|
||||
<dd>{{ profile.city|default:"—" }}</dd>
|
||||
|
||||
<dt>Языки</dt>
|
||||
<dd>
|
||||
{% if profile.languages %}
|
||||
{% for lang in profile.languages %}<span class="pill">{{ lang }}</span>{% endfor %}
|
||||
{% else %} — {% endif %}
|
||||
</dd>
|
||||
|
||||
<dt>Интересы</dt>
|
||||
<dd>
|
||||
{% if profile.interests %}
|
||||
{% for it in profile.interests %}<span class="pill">{{ it }}</span>{% endfor %}
|
||||
{% else %} — {% endif %}
|
||||
</dd>
|
||||
|
||||
<dt>ID профиля</dt>
|
||||
<dd><code>{{ profile.id }}</code></dd>
|
||||
|
||||
<dt>ID пользователя (в профиле)</dt>
|
||||
<dd><code>{{ profile.user_id }}</code></dd>
|
||||
</dl>
|
||||
|
||||
<details style="margin-top:12px;">
|
||||
<summary class="muted">Показать сырой JSON профиля</summary>
|
||||
<pre>{{ profile|safe }}</pre>
|
||||
</details>
|
||||
|
||||
{% else %}
|
||||
<p class="muted">Профиль ещё не создан. Заполните форму ниже.</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
</div>
|
||||
{% if has_profile and profile %}
|
||||
<section class="card" style="margin-top:16px;">
|
||||
<h2 class="muted" style="margin-top:0;">Фото профиля</h2>
|
||||
<div style="display:flex; gap:16px; align-items:center;">
|
||||
<div style="width:120px; height:120px; border-radius:12px; overflow:hidden; background:#e5e7eb;">
|
||||
{% if profile.photo_url %}
|
||||
<img src="{{ profile.photo_url }}" alt="" style="width:100%; height:100%; object-fit:cover;">
|
||||
{% elif profile.photo %}
|
||||
<img src="{{ profile.photo }}" alt="" style="width:100%; height:100%; object-fit:cover;">
|
||||
{% elif request.session.user_email %}
|
||||
<img src="{{ request.session.user_email|gravatar_url:240 }}" alt="" style="width:100%; height:100%; object-fit:cover;">
|
||||
{% else %}
|
||||
<div style="display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:#374151;font-weight:700;">—</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<form method="post" action="{% url 'ui:cabinet_upload_photo' %}" enctype="multipart/form-data" style="display:flex; gap:10px; align-items:center;">
|
||||
{% csrf_token %}
|
||||
<input type="file" name="file" accept="image/*" required>
|
||||
<button class="btn btn-primary" type="submit">Загрузить фото</button>
|
||||
</form>
|
||||
</div>
|
||||
<p class="muted" style="margin-top:10px;">Поддерживается multipart загрузка изображения в поле <code>file</code>. Эндпоинт: <code>/profiles/v1/profiles/me/photo</code>. :contentReference[oaicite:4]{index=4}</p>
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if not has_profile or not profile %}
|
||||
<!-- ======= ФОРМА СОЗДАНИЯ ПРОФИЛЯ ======= -->
|
||||
<section class="card" style="margin-top:16px;" aria-labelledby="section-create">
|
||||
<h2 id="section-create" class="muted" style="margin-top:0;">Создать профиль</h2>
|
||||
|
||||
<form class="form" method="post" action="{% url 'cabinet' %}">
|
||||
<form class="form" method="post" action="{% url 'ui:cabinet' %}">
|
||||
{% csrf_token %}
|
||||
<div class="grid grid-2">
|
||||
<input type="hidden" name="action" value="create_profile">
|
||||
|
||||
<div style="display:grid; grid-template-columns: 1fr 1fr; gap:16px;">
|
||||
<div>
|
||||
<label for="gender">Пол</label>
|
||||
<select id="gender" name="gender" required>
|
||||
<option value="">— выберите —</option>
|
||||
<option value="male" {% if request.POST.gender == "male" %}selected{% endif %}>Мужской</option>
|
||||
<option value="female" {% if request.POST.gender == "female" %}selected{% endif %}>Женский</option>
|
||||
<option value="other" {% if request.POST.gender == "other" %}selected{% endif %}>Другое</option>
|
||||
<option value="male">Мужской</option>
|
||||
<option value="female">Женский</option>
|
||||
<option value="other">Другое</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="city">Город</label>
|
||||
<input id="city" name="city" type="text" required
|
||||
value="{{ request.POST.city|default_if_none:'' }}" placeholder="Москва">
|
||||
<input id="city" name="city" type="text" required placeholder="Москва">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="languages">Языки</label>
|
||||
<input id="languages" name="languages" type="text"
|
||||
value="{{ request.POST.languages|default_if_none:'' }}" placeholder="ru,en">
|
||||
<small>Несколько — через запятую: <code>ru,en</code></small>
|
||||
<input id="languages" name="languages" type="text" placeholder="ru,en">
|
||||
<small class="muted">Несколько — через запятую</small>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="interests">Интересы</label>
|
||||
<input id="interests" name="interests" type="text"
|
||||
value="{{ request.POST.interests|default_if_none:'' }}" placeholder="music,travel">
|
||||
<small>Несколько — через запятую: <code>music,travel</code></small>
|
||||
<input id="interests" name="interests" type="text" placeholder="music,travel">
|
||||
<small class="muted">Несколько — через запятую</small>
|
||||
</div>
|
||||
|
||||
<div class="btnrow">
|
||||
<button class="btn btn-primary" type="submit">Создать профиль</button>
|
||||
<a class="btn btn-outline" href="{% url 'cabinet' %}">Сбросить</a>
|
||||
<a class="btn btn-outline" href="{% url 'ui:cabinet' %}">Сбросить</a>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
{% else %}
|
||||
<section class="card" style="margin-top:16px;">
|
||||
<h2 class="muted" style="margin-top:0;">Данные профиля</h2>
|
||||
<dl>
|
||||
<dt>Пол</dt><dd>{{ profile.gender|default:"—" }}</dd>
|
||||
<dt>Город</dt><dd>{{ profile.city|default:"—" }}</dd>
|
||||
<dt>Языки</dt>
|
||||
<dd>
|
||||
{% if profile.languages %}
|
||||
{% for lang in profile.languages %}<span class="pill">{{ lang }}</span>{% endfor %}
|
||||
{% else %} — {% endif %}
|
||||
</dd>
|
||||
<dt>Интересы</dt>
|
||||
<dd>
|
||||
{% if profile.interests %}
|
||||
{% for it in profile.interests %}<span class="pill">{{ it }}</span>{% endfor %}
|
||||
{% else %} — {% endif %}
|
||||
</dd>
|
||||
<dt>ID профиля</dt><dd><code>{{ profile.id }}</code></dd>
|
||||
<dt>ID пользователя</dt><dd><code>{{ profile.user_id }}</code></dd>
|
||||
</dl>
|
||||
<p class="muted" style="margin-top:8px;">Редактирование полей профиля появится, как только сервер добавит PATCH /profiles/v1/profiles/me.</p>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user