355 lines
24 KiB
HTML
355 lines
24 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}{{ project.title }} — Morozovka Portal{% endblock %}
|
||
{% block main_class %}container{% endblock %}
|
||
|
||
{% block head %}
|
||
<style>
|
||
.breadcrumbs { color: #8b949e; font-size: 13px; margin-bottom: 16px; }
|
||
.breadcrumbs a { color: #8b949e; }
|
||
.breadcrumbs a:hover { color: #58a6ff; }
|
||
.ws-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 24px; }
|
||
.ws-header-left { flex: 1; }
|
||
.ws-title { font-size: 24px; font-weight: 600; margin: 0 0 12px; color: #e6edf3; }
|
||
.badges { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
|
||
.badge { display: inline-block; padding: 0 7px; border-radius: 2em; font-size: 12px; font-weight: 500; line-height: 18px; border: 1px solid; }
|
||
.status-in_progress { background: rgba(31,111,235,0.15); color: #1f6feb; border-color: rgba(31,111,235,0.4); }
|
||
.status-idea { background: rgba(139,148,158,0.15); color: #8b949e; border-color: rgba(139,148,158,0.4); }
|
||
.status-completed { background: rgba(35,134,54,0.15); color: #3fb950; border-color: rgba(35,134,54,0.4); }
|
||
.status-frozen { background: rgba(218,54,51,0.15); color: #f85149; border-color: rgba(218,54,51,0.4); }
|
||
.vis-public { background: rgba(63,185,80,0.15); color: #3fb950; border-color: rgba(63,185,80,0.4); }
|
||
.vis-internal { background: rgba(210,153,34,0.15); color: #d29922; border-color: rgba(210,153,34,0.4); }
|
||
.vis-private { background: rgba(248,81,73,0.15); color: #f85149; border-color: rgba(248,81,73,0.4); }
|
||
.ws-actions { display: flex; gap: 8px; flex-wrap: wrap; }
|
||
.layout { display: grid; grid-template-columns: 2fr 1fr; gap: 24px; }
|
||
@media (max-width: 768px) { .layout { grid-template-columns: 1fr; } }
|
||
.section { background: #161b22; border: 1px solid #30363d; border-radius: 6px; padding: 20px; margin-bottom: 16px; }
|
||
.section h2 { font-size: 16px; font-weight: 600; margin: 0 0 12px; color: #e6edf3; padding-bottom: 8px; border-bottom: 1px solid #30363d; display: flex; justify-content: space-between; align-items: center; }
|
||
.section h2 .counter { color: #8b949e; font-size: 13px; font-weight: normal; }
|
||
.section-content { color: #c9d1d9; white-space: pre-wrap; line-height: 1.6; }
|
||
.tabs { display: flex; gap: 4px; border-bottom: 1px solid #30363d; margin-bottom: 20px; }
|
||
.tab { padding: 8px 16px; color: #8b949e; text-decoration: none; border-bottom: 2px solid transparent; font-weight: 600; font-size: 14px; }
|
||
.tab:hover { color: #e6edf3; text-decoration: none; }
|
||
.tab.active { color: #58a6ff; border-bottom-color: #58a6ff; }
|
||
.tab .badge-count { background: #30363d; color: #e6edf3; padding: 0 6px; border-radius: 10px; font-size: 11px; margin-left: 4px; font-weight: 500; }
|
||
.post-card { background: #0d1117; border: 1px solid #30363d; border-radius: 6px; padding: 14px 16px; margin-bottom: 12px; position: relative; }
|
||
.post-card:last-child { margin-bottom: 0; }
|
||
.post-card.pinned { border-color: #d29922; background: rgba(210,153,34,0.05); }
|
||
.post-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 6px; }
|
||
.post-title { font-size: 15px; font-weight: 600; color: #e6edf3; margin: 0 0 4px; }
|
||
.post-title .pin-mark { color: #d29922; margin-right: 4px; font-size: 12px; }
|
||
.post-meta { color: #8b949e; font-size: 12px; }
|
||
.post-body { color: #c9d1d9; line-height: 1.6; white-space: pre-wrap; margin: 8px 0; }
|
||
.post-attachments { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; padding-top: 8px; border-top: 1px solid #21262d; }
|
||
.post-attachment { display: flex; align-items: center; gap: 8px; padding: 4px 8px; background: #161b22; border-radius: 4px; font-size: 12px; }
|
||
.post-attachment a { color: #58a6ff; }
|
||
.post-image-wrap { margin: 6px 0; }
|
||
.post-image-wrap img { max-width: 100%; max-height: 400px; border-radius: 6px; border: 1px solid #30363d; display: block; cursor: zoom-in; }
|
||
.post-image-name { color: #6e7681; font-size: 11px; margin-top: 3px; }
|
||
.post-actions { display: flex; gap: 4px; margin-left: auto; opacity: 0; transition: opacity .15s; }
|
||
.post-card:hover .post-actions { opacity: 1; }
|
||
.post-actions form { display: inline; }
|
||
.post-actions button { background: none; border: none; color: #8b949e; cursor: pointer; padding: 2px 6px; font-size: 12px; border-radius: 3px; }
|
||
.post-actions button:hover { background: #30363d; color: #e6edf3; }
|
||
.post-actions .del:hover { color: #f85149; }
|
||
.post-form-card { background: #0d1117; border: 1px dashed #30363d; border-radius: 6px; padding: 14px 16px; margin-top: 12px; }
|
||
.post-form-row { display: grid; grid-template-columns: 1fr; gap: 8px; margin-bottom: 8px; }
|
||
.post-form-row label { color: #8b949e; font-size: 11px; font-weight: 600; text-transform: uppercase; }
|
||
.post-form-row input, .post-form-row textarea { padding: 5px 10px; background: #161b22; border: 1px solid #30363d; border-radius: 6px; color: #e6edf3; font-size: 13px; font-family: inherit; width: 100%; }
|
||
.post-form-row textarea { min-height: 80px; resize: vertical; }
|
||
.post-form-row input:focus, .post-form-row textarea:focus { outline: none; border-color: #58a6ff; }
|
||
.post-form-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
||
.post-form-actions input[type=file] { font-size: 12px; color: #8b949e; }
|
||
.post-form-actions button { padding: 5px 14px; background: #238636; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 13px; }
|
||
.post-form-actions button:hover { background: #2ea043; }
|
||
.checkbox-line { display: flex; align-items: center; gap: 6px; color: #8b949e; font-size: 12px; }
|
||
.meta-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 20px; padding: 14px; background: #0d1117; border: 1px solid #30363d; border-radius: 6px; }
|
||
.meta-item .label { color: #8b949e; font-size: 11px; text-transform: uppercase; margin-bottom: 3px; font-weight: 600; }
|
||
.meta-item .value { color: #e6edf3; font-size: 14px; }
|
||
.tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
|
||
.tag { font-size: 12px; background: rgba(88,166,255,.1); color: #58a6ff; padding: 2px 10px; border-radius: 12px; border: 1px solid rgba(88,166,255,.3); }
|
||
.member-row { background: #0d1117; border: 1px solid #30363d; border-radius: 6px; padding: 12px 14px; margin-bottom: 10px; }
|
||
.member-row:last-child { margin-bottom: 0; }
|
||
.member-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
|
||
.member-name { font-weight: 600; color: #e6edf3; }
|
||
.member-name .username { color: #8b949e; font-weight: normal; font-size: 12px; margin-left: 4px; }
|
||
.role-pill { font-size: 10px; padding: 2px 8px; border-radius: 10px; font-weight: 600; text-transform: uppercase; }
|
||
.role-manager { background: #d29922; color: #000; }
|
||
.role-editor { background: #1f6feb; color: #fff; }
|
||
.role-viewer { background: #30363d; color: #e6edf3; }
|
||
.role-owner { background: #a371f7; color: #fff; }
|
||
.perm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 6px; margin-top: 6px; }
|
||
.perm-item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #c9d1d9; }
|
||
.perm-item input { width: 14px; height: 14px; }
|
||
.perm-actions { display: flex; gap: 8px; margin-top: 8px; align-items: center; flex-wrap: wrap; }
|
||
.add-form { background: #0d1117; border: 1px solid #30363d; padding: 12px; border-radius: 6px; margin-bottom: 12px; }
|
||
.add-form form { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
|
||
.add-form .form-group { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 140px; }
|
||
.add-form label { color: #8b949e; font-size: 11px; font-weight: 600; text-transform: uppercase; }
|
||
.add-form input, .add-form select { padding: 5px 10px; background: #161b22; border: 1px solid #30363d; border-radius: 6px; color: #e6edf3; font-size: 13px; font-family: inherit; }
|
||
.add-form input:focus, .add-form select:focus { outline: none; border-color: #58a6ff; }
|
||
.files-list { background: #0d1117; border: 1px solid #30363d; border-radius: 6px; overflow: hidden; }
|
||
.file-row { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid #21262d; }
|
||
.file-row:last-child { border-bottom: none; }
|
||
.file-row:hover { background: #161b22; }
|
||
.file-info { flex: 1; min-width: 0; }
|
||
.file-name { color: #e6edf3; font-weight: 500; font-size: 13px; overflow: hidden; text-overflow: ellipsis; }
|
||
.file-meta { color: #8b949e; font-size: 11px; margin-top: 2px; }
|
||
.file-actions { display: flex; gap: 8px; flex-shrink: 0; }
|
||
.file-actions a { color: #58a6ff; font-size: 12px; }
|
||
.sub-btn { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; padding: 8px; border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 14px; border: 1px solid; }
|
||
.sub-btn.on { background: rgba(88,166,255,0.15); border-color: #58a6ff; color: #58a6ff; }
|
||
.sub-btn.on:hover { background: rgba(88,166,255,0.25); }
|
||
.sub-btn.off { background: #21262d; border-color: #30363d; color: #c9d1d9; }
|
||
.sub-btn.off:hover { background: #30363d; }
|
||
.empty-small { color: #8b949e; font-size: 13px; padding: 12px; text-align: center; background: #0d1117; border: 1px dashed #30363d; border-radius: 6px; }
|
||
.repo-btn { display: inline-block; background: #21262d; color: #58a6ff; text-decoration: none; padding: 8px 16px; border-radius: 5px; border: 1px solid #30363d; font-weight: 500; margin-bottom: 16px; font-size: 13px; }
|
||
.repo-btn:hover { background: #30363d; text-decoration: none; }
|
||
</style>
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="breadcrumbs"><a href="/projects">Проекты</a> / {{ project.title }}</div>
|
||
|
||
<div class="ws-header">
|
||
<div class="ws-header-left">
|
||
<h1 class="ws-title">{{ project.title }}</h1>
|
||
<div class="badges">
|
||
<span class="badge status-{{ project.status }}">
|
||
{% if project.status == 'idea' %}Идея
|
||
{% elif project.status == 'in_progress' %}В работе
|
||
{% elif project.status == 'completed' %}Завершён
|
||
{% else %}Заморожен{% endif %}
|
||
</span>
|
||
<span class="badge vis-{{ project.visibility }}">
|
||
{% if project.visibility == 'public' %}Публичный
|
||
{% elif project.visibility == 'internal' %}Внутренний
|
||
{% else %}Приватный{% endif %}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
<div class="ws-actions">
|
||
{% if perms.can_manage_members or perms.is_admin or perms.is_owner %}
|
||
<a href="/projects/{{ project.id }}/edit" class="btn btn-default">✎ Редактировать</a>
|
||
{% endif %}
|
||
{% if perms.can_delete %}
|
||
<form action="/projects/{{ project.id }}/delete" method="POST" onsubmit="return confirm('Удалить проект?');" style="display:inline;">
|
||
<button type="submit" class="btn btn-danger">Удалить</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tabs">
|
||
<a href="/projects/{{ project.id }}" class="tab active">Обзор</a>
|
||
<a href="/projects/{{ project.id }}/board" class="tab">Доска {% if task_counts %}<span class="badge-count">{{ task_counts.values()|sum }}</span>{% endif %}</a>
|
||
<a href="#files" class="tab">Файлы <span class="badge-count">{{ files|length }}</span></a>
|
||
</div>
|
||
|
||
<div class="layout">
|
||
<div>
|
||
{% if project.tags %}
|
||
<div class="tags">{% for t in project.tags.split(',') %}<span class="tag">#{{ t.strip() }}</span>{% endfor %}</div>
|
||
{% endif %}
|
||
|
||
<div class="meta-grid">
|
||
<div class="meta-item"><div class="label">Начало</div><div class="value">{{ project.start_date|date_ru or '—' }}</div></div>
|
||
<div class="meta-item"><div class="label">Завершение</div><div class="value">{{ project.end_date|date_ru or '—' }}</div></div>
|
||
<div class="meta-item"><div class="label">Контакт</div><div class="value">{{ project.contact_person or '—' }}</div></div>
|
||
<div class="meta-item"><div class="label">Ваша роль</div><div class="value">{{ perms.project_role or '—' }}</div></div>
|
||
</div>
|
||
|
||
<div class="section"><h2>Описание</h2><div class="section-content">{{ project.description or 'Описание пока не добавлено.' }}</div></div>
|
||
|
||
{% if project.gitea_url %}
|
||
<a href="{{ project.gitea_url }}" target="_blank" class="repo-btn">📦 Репозиторий Gitea</a>
|
||
{% endif %}
|
||
|
||
<div class="section">
|
||
<h2>📢 Лента <span class="counter">{{ posts|length }}</span></h2>
|
||
{% if posts %}
|
||
{% for p in posts %}
|
||
<div class="post-card{% if p.is_pinned %} pinned{% endif %}">
|
||
<div class="post-head">
|
||
<div style="flex:1;min-width:0;">
|
||
<div class="post-title">{% if p.is_pinned %}<span class="pin-mark">📌</span>{% endif %}{{ p.title }}</div>
|
||
<div class="post-meta">
|
||
{% set au = authors_map.get(p.author_id) %}
|
||
{% if au %}{{ au.full_name or au.username }}{% endif %}
|
||
· {{ p.created_at|msk_strftime('%d.%m.%Y %H:%M') }}
|
||
</div>
|
||
</div>
|
||
{% if perms.can_edit_any_post or (perms.can_edit_own_posts and p.author_id == user_id) %}
|
||
<div class="post-actions">
|
||
<button type="button" onclick="toggleEdit({{ p.id }})">✎</button>
|
||
<form action="/projects/{{ project.id }}/posts/{{ p.id }}/delete" method="POST" onsubmit="return confirm('Удалить пост?');">
|
||
<button type="submit" class="del">✕</button>
|
||
</form>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
{% if p.body %}<div class="post-body">{{ p.body }}</div>{% endif %}
|
||
{% if attachments_by_post.get(p.id) %}
|
||
<div class="post-attachments">
|
||
{% for a in attachments_by_post.get(p.id) %}
|
||
{% set f = files_map.get(a.file_id) %}
|
||
{% if f %}
|
||
{% if f.original_name|is_image %}
|
||
<div class="post-image-wrap">
|
||
<a href="/files/preview/{{ f.id }}" target="_blank">
|
||
<img src="/files/preview/{{ f.id }}" alt="{{ f.original_name }}" loading="lazy">
|
||
</a>
|
||
<div class="post-image-name">{{ f.original_name }} · {{ (f.size_bytes/1024)|round(1) }} КБ</div>
|
||
</div>
|
||
{% else %}
|
||
<div class="post-attachment">{{ f.original_name|file_icon }} <a href="/files/download/{{ f.id }}">{{ f.original_name }}</a> <span style="color:#6e7681;">({{ (f.size_bytes/1024)|round(1) }} КБ)</span></div>
|
||
{% endif %}
|
||
{% endif %}
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
{% if perms.can_edit_any_post or (perms.can_edit_own_posts and p.author_id == user_id) %}
|
||
<form id="edit-post-{{ p.id }}" action="/projects/{{ project.id }}/posts/{{ p.id }}/edit" method="POST" style="display:none;margin-top:10px;">
|
||
<div class="post-form-row"><label>Заголовок</label><input type="text" name="title" value="{{ p.title }}" required></div>
|
||
<div class="post-form-row"><label>Текст</label><textarea name="body">{{ p.body or '' }}</textarea></div>
|
||
<div class="post-form-actions">
|
||
{% if perms.can_edit_any_post %}
|
||
<label class="checkbox-line"><input type="checkbox" name="is_pinned" {% if p.is_pinned %}checked{% endif %}> Закрепить</label>
|
||
{% endif %}
|
||
<button type="submit">Сохранить</button>
|
||
<button type="button" class="btn btn-default" onclick="toggleEdit({{ p.id }})">Отмена</button>
|
||
</div>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
{% else %}
|
||
<div class="empty-small">Пока нет постов. Начните первым.</div>
|
||
{% endif %}
|
||
|
||
{% if perms.can_post_feed %}
|
||
<form action="/projects/{{ project.id }}/posts/new" method="POST" enctype="multipart/form-data" class="post-form-card">
|
||
<div class="post-form-row"><label>Заголовок *</label><input type="text" name="title" required maxlength="200"></div>
|
||
<div class="post-form-row"><label>Текст</label><textarea name="body"></textarea></div>
|
||
<div class="post-form-actions">
|
||
<input type="file" name="files" multiple>
|
||
{% if perms.can_edit_any_post %}
|
||
<label class="checkbox-line"><input type="checkbox" name="is_pinned"> Закрепить</label>
|
||
{% endif %}
|
||
<button type="submit">Опубликовать</button>
|
||
</div>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<div class="section">
|
||
<h2>Участники <span class="counter">{{ members|length }}</span></h2>
|
||
{% if perms.can_manage_members %}
|
||
<div class="add-form">
|
||
<form action="/projects/{{ project.id }}/members/add" method="POST">
|
||
<div class="form-group"><label>Логин</label><input type="text" name="username" placeholder="username" required></div>
|
||
<div class="form-group" style="flex:0.5;"><label>Роль</label>
|
||
<select name="role"><option value="viewer">Viewer</option><option value="editor" selected>Editor</option><option value="manager">Manager</option></select>
|
||
</div>
|
||
<button type="submit" class="btn btn-primary">+</button>
|
||
</form>
|
||
</div>
|
||
{% endif %}
|
||
{% for member_obj, user in members %}
|
||
<div class="member-row">
|
||
<div class="member-head">
|
||
<div>
|
||
<span class="member-name">{{ user.full_name or user.username }} <span class="username">@{{ user.username }}</span></span>
|
||
{% if user.id == project.owner_id %}
|
||
<span class="role-pill role-owner">Владелец</span>
|
||
{% else %}
|
||
<span class="role-pill role-{{ member_obj.role }}">{{ member_obj.role }}</span>
|
||
{% endif %}
|
||
</div>
|
||
{% if perms.can_manage_members and user.id != project.owner_id %}
|
||
<form action="/projects/{{ project.id }}/members/{{ user.id }}/remove" method="POST" onsubmit="return confirm('Удалить участника?');">
|
||
<button type="submit" class="btn btn-danger btn-sm">✕</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
{% if perms.can_manage_members and user.id != project.owner_id %}
|
||
<form action="/projects/{{ project.id }}/members/{{ user.id }}/permissions" method="POST">
|
||
<div class="perm-grid">
|
||
<label class="perm-item"><input type="checkbox" name="can_view_files" {% if member_obj.can_view_files %}checked{% endif %}> 📁 Видеть файлы</label>
|
||
<label class="perm-item"><input type="checkbox" name="can_edit_files" {% if member_obj.can_edit_files %}checked{% endif %}> 📁✎ Загружать/удалять файлы</label>
|
||
<label class="perm-item"><input type="checkbox" name="can_view_repo" {% if member_obj.can_view_repo %}checked{% endif %}> 📦 Видеть репо</label>
|
||
<label class="perm-item"><input type="checkbox" name="can_post_feed" {% if member_obj.can_post_feed %}checked{% endif %}> 📢 Писать в ленту</label>
|
||
<label class="perm-item"><input type="checkbox" name="can_edit_own_posts" {% if member_obj.can_edit_own_posts %}checked{% endif %}> ✎ Редактировать свои посты</label>
|
||
<label class="perm-item"><input type="checkbox" name="can_edit_any_post" {% if member_obj.can_edit_any_post %}checked{% endif %}> ✎ Редактировать любые посты</label>
|
||
<label class="perm-item"><input type="checkbox" name="can_manage_members" {% if member_obj.can_manage_members %}checked{% endif %}> 👥 Управлять участниками</label>
|
||
</div>
|
||
<div class="perm-actions">
|
||
<button type="submit" class="btn btn-default btn-sm">Сохранить права</button>
|
||
</div>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
|
||
<div class="section" id="files">
|
||
<h2>Файлы <span class="counter">{{ files|length }}</span></h2>
|
||
{% if perms.can_upload %}
|
||
<div class="add-form">
|
||
<form action="/projects/{{ project.id }}/files/upload" method="POST" enctype="multipart/form-data">
|
||
<div class="form-group"><label>Загрузить файл (до 100 МБ)</label><input type="file" name="file" required></div>
|
||
<button type="submit" class="btn btn-primary">Загрузить</button>
|
||
</form>
|
||
</div>
|
||
{% endif %}
|
||
{% if files %}
|
||
<div class="files-list">
|
||
{% for file, uploader in files %}
|
||
<div class="file-row">
|
||
<div class="file-info">
|
||
<div class="file-name">{{ file.original_name|file_icon }} {{ file.original_name }}</div>
|
||
<div class="file-meta">{{ (file.size_bytes/1024/1024)|round(2) }} МБ · {{ uploader }} · {{ file.uploaded_at|msk_strftime('%d.%m.%Y %H:%M') }}</div>
|
||
</div>
|
||
<div class="file-actions">
|
||
<a href="/files/download/{{ file.id }}">Скачать</a>
|
||
{% if perms.can_edit_files or perms.is_admin or file.uploaded_by == user_id %}
|
||
<form action="/files/{{ file.id }}/delete" method="POST" onsubmit="return confirm('Удалить?');" style="display:inline;">
|
||
<input type="hidden" name="next" value="/projects/{{ project.id }}">
|
||
<button type="submit" class="btn btn-danger btn-sm">✕</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% else %}
|
||
<div class="empty-small">Файлов нет.{% if perms.can_upload %} Загрузите первый.{% endif %}</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
{% if user_id %}
|
||
<div class="section">
|
||
<h2>Подписка</h2>
|
||
<form action="/projects/{{ project.id }}/subscribe" method="POST">
|
||
{% if my_sub %}
|
||
<button type="submit" class="sub-btn on">🔔 Вы подписаны</button>
|
||
{% else %}
|
||
<button type="submit" class="sub-btn off">🔔 Подписаться на новости</button>
|
||
{% endif %}
|
||
</form>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block scripts %}
|
||
<script>
|
||
function toggleEdit(postId) {
|
||
var el = document.getElementById('edit-post-' + postId);
|
||
if (el) el.style.display = (el.style.display === 'none' || !el.style.display) ? 'block' : 'none';
|
||
}
|
||
</script>
|
||
{% endblock %}
|