655ba8c31a
Список публикаций, форма создания/редактирования, детальная (комментарии,
публикация в Mattermost, важное/закреплённое), JS-строки (загрузка картинок,
свернуть/развернуть) помечены {% trans %} и переведены на uk/en.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
114 lines
8.7 KiB
HTML
114 lines
8.7 KiB
HTML
{% load common_tags %}
|
|
{% load i18n %}
|
|
<div class="page-content">
|
|
|
|
<!-- Назад + дії -->
|
|
<div style="display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1rem;">
|
|
<a href="/news/" hx-get="/news/" hx-target="#main-content" hx-push-url="/news/" hx-indicator="#loader"
|
|
style="display:inline-flex; align-items:center; gap:0.375rem; font-size:0.8125rem; color:var(--color-muted-foreground); text-decoration:none;">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>
|
|
</svg>
|
|
{% trans "Ко всем новостям" %}
|
|
</a>
|
|
<div style="display:flex; align-items:center; gap:0.375rem;">
|
|
{% if can_edit %}
|
|
<a href="/news/{{ post.pk }}/edit/" hx-get="/news/{{ post.pk }}/edit/" hx-target="#main-content" hx-push-url="/news/{{ post.pk }}/edit/" hx-indicator="#loader"
|
|
class="btn btn-secondary" style="font-size:0.8125rem; padding:0.3rem 0.75rem; text-decoration:none;">{% trans "Редактировать" %}</a>
|
|
{% endif %}
|
|
{% if can_delete %}
|
|
<form hx-post="/news/{{ post.pk }}/delete/" hx-target="#main-content" hx-push-url="/news/" hx-indicator="#loader"
|
|
hx-confirm="{% trans 'Удалить публикацию' %} «{{ post.title }}»? {% trans 'Это необратимо.' %}"
|
|
style="display:inline; margin:0;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-ghost" style="font-size:0.8125rem; padding:0.3rem 0.75rem; color:var(--color-destructive);">{% trans "Удалить" %}</button>
|
|
</form>
|
|
{% endif %}
|
|
{% if request.user.is_staff and post.mattermost_targets %}
|
|
<form hx-post="/news/{{ post.pk }}/publish-mattermost/" hx-target="#main-content" hx-push-url="/news/{{ post.pk }}/" hx-indicator="#loader"
|
|
hx-confirm="{% trans 'Обновить' %} «{{ post.title }}» {% trans 'в чате Mattermost?' %}"
|
|
style="display:inline; margin:0;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-secondary" style="font-size:0.8125rem; padding:0.3rem 0.75rem;">💬 {% trans "Обновить в чате" %}</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
{% if post.mattermost_posted_at %}
|
|
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:-0.75rem; margin-bottom:1.25rem;">
|
|
✓ {% trans "Опубликовано в чат Mattermost" %} {{ post.mattermost_posted_at|date:"d.m.Y H:i" }}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Пост -->
|
|
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); padding:2rem; margin-bottom:1.25rem;">
|
|
<div style="display:flex; gap:0.5rem; margin-bottom:0.875rem; align-items:center; flex-wrap:wrap;">
|
|
{% if post.is_pinned %}
|
|
<span style="font-size:0.6875rem; font-weight:600; text-transform:uppercase; letter-spacing:0.05em; color:var(--color-primary); background:hsl(0 72% 44% / 0.1); border-radius:999px; padding:0.1875rem 0.625rem;">📌 {% trans "Закреплено" %}</span>
|
|
{% endif %}
|
|
{% if post.is_important %}<span class="badge badge-danger">{% trans "Важно" %}</span>{% endif %}
|
|
<span class="badge {{ post.badge_class }}">{{ post.get_category_display }}</span>
|
|
</div>
|
|
|
|
<h1 style="font-size:1.375rem; font-weight:600; color:var(--color-foreground); margin-bottom:0.875rem; line-height:1.35;">{{ post.title }}</h1>
|
|
|
|
<div style="display:flex; align-items:center; gap:0.5rem; font-size:0.8125rem; color:var(--color-muted-foreground); padding-bottom:1.25rem; border-bottom:1px solid var(--color-border); margin-bottom:1.25rem;">
|
|
<div style="width:1.75rem; height:1.75rem; border-radius:50%; background:hsl(270 60% 55% / 0.12); color:hsl(270 60% 42%); display:flex; align-items:center; justify-content:center; font-size:0.625rem; font-weight:700;">{{ post.author|initials }}</div>
|
|
{{ post.author.get_full_name|default:"—" }}
|
|
<span style="opacity:0.5;">·</span>
|
|
{{ post.created_at|date:"d.m.Y H:i" }}
|
|
</div>
|
|
|
|
{# body — HTML из редактора, санитизирован nh3 при сохранении #}
|
|
<style>
|
|
/* flow-root — щоб плаваючі картинки (TinyMCE-вирівнювання float:left/right)
|
|
не вилазили за межі картки, коли тексту менше за висоту картинки */
|
|
.post-body { display: flow-root; }
|
|
.post-body img { max-width: 100%; height: auto; border-radius: 0.5rem; }
|
|
.post-body table { border-collapse: collapse; }
|
|
.post-body td, .post-body th { border: 1px solid var(--color-border); padding: 0.375rem 0.625rem; }
|
|
</style>
|
|
<div class="post-body" style="font-size:0.9375rem; color:var(--color-foreground); line-height:1.7;">{{ post.body|safe }}</div>
|
|
</div>
|
|
|
|
<!-- Комментарии -->
|
|
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
|
|
<div style="padding:0.875rem 1.25rem; border-bottom:1px solid var(--color-border);">
|
|
<span style="font-size:0.8125rem; font-weight:500; color:var(--color-foreground);">{% trans "Комментарии" %} · {{ comments|length }}</span>
|
|
</div>
|
|
|
|
{% for comment in comments %}
|
|
<div style="padding:1rem 1.25rem; {% if not forloop.last %}border-bottom:1px solid var(--color-border);{% endif %} display:flex; gap:0.75rem; align-items:flex-start;">
|
|
<div style="width:2rem; height:2rem; border-radius:50%; background:color-mix(in srgb, var(--color-primary) 10%, transparent); color:var(--color-primary); display:flex; align-items:center; justify-content:center; font-size:0.625rem; font-weight:600; flex-shrink:0;">{{ comment.author|initials }}</div>
|
|
<div style="flex:1; min-width:0;">
|
|
<div style="display:flex; align-items:center; gap:0.5rem; margin-bottom:0.25rem;">
|
|
<span style="font-size:0.8125rem; font-weight:500; color:var(--color-card-foreground);">{{ comment.author.get_full_name|default:"—" }}</span>
|
|
<span style="font-size:0.75rem; color:var(--color-muted-foreground);">{{ comment.created_at|date:"d.m.Y H:i" }}</span>
|
|
{% if comment.mattermost_source_id %}
|
|
<span style="font-size:0.6875rem; color:var(--color-muted-foreground); opacity:0.75;">· {% trans "из Mattermost" %}</span>
|
|
{% endif %}
|
|
</div>
|
|
<div style="font-size:0.875rem; color:var(--color-foreground); line-height:1.55; white-space:pre-line;">{{ comment.text }}</div>
|
|
</div>
|
|
</div>
|
|
{% empty %}
|
|
<div style="padding:1.5rem; text-align:center; color:var(--color-muted-foreground); font-size:0.8125rem;">{% trans "Комментариев пока нет — будьте первым" %}</div>
|
|
{% endfor %}
|
|
|
|
<!-- Форма комментария -->
|
|
<form hx-post="/news/{{ post.pk }}/" hx-target="#main-content" hx-indicator="#loader"
|
|
style="padding:1rem 1.25rem; border-top:1px solid var(--color-border); display:flex; gap:0.75rem; align-items:flex-start; margin:0;">
|
|
{% csrf_token %}
|
|
<div style="width:2rem; height:2rem; border-radius:50%; background:var(--color-accent); color:var(--color-accent-foreground); display:flex; align-items:center; justify-content:center; font-size:0.625rem; font-weight:700; flex-shrink:0;">{{ request.user|initials }}</div>
|
|
<textarea name="text" required placeholder="{% trans 'Написать комментарий...' %}"
|
|
style="flex:1; min-height:2.5rem; resize:vertical; background:var(--color-muted); border:1px solid var(--color-border); border-radius:var(--radius); padding:0.5rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
|
|
<button type="submit" class="btn btn-primary" style="flex-shrink:0;">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>
|
|
{% trans "Отправить" %}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
</div>
|