annoucment logic implemented, fixing looks
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load markdown %}
|
||||
|
||||
{% block title %}{{ announcement.title }} - Packs Site{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="announce-detail">
|
||||
<article class="card announce-card">
|
||||
<h1>{{ announcement.title }}</h1>
|
||||
<p class="announce-meta">
|
||||
<i class="fas fa-user"></i> {{ announcement.created_by.username|default:"Staff" }}
|
||||
<span class="separator">•</span>
|
||||
{{ announcement.created_at|date:"F j, Y, g:i a" }}
|
||||
</p>
|
||||
<div class="markdown-body">{{ announcement.body|markdown }}</div>
|
||||
{% if user.is_staff %}
|
||||
<div class="announce-admin">
|
||||
<a href="{% url 'announcements:edit' announcement.pk %}" class="btn btn-secondary btn-sm"><i class="fas fa-edit"></i> Edit</a>
|
||||
<form method="post" action="{% url 'announcements:delete' announcement.pk %}" class="inline" onsubmit="return confirm('Delete this announcement and all its comments?');">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-secondary btn-sm"><i class="fas fa-trash"></i> Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</article>
|
||||
|
||||
<section class="card">
|
||||
<h2><i class="fas fa-comments"></i> Discussion</h2>
|
||||
|
||||
{% if can_comment %}
|
||||
<form method="post" action="{% url 'announcements:add_comment' announcement.pk %}" class="comment-form">
|
||||
{% csrf_token %}
|
||||
<textarea name="body" rows="4" placeholder="Write a comment… Markdown supported." required></textarea>
|
||||
<button type="submit" class="btn btn-primary"><i class="fas fa-paper-plane"></i> Comment</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<p class="empty-hint"><a href="{% url 'profiles:login' %}?next={{ request.path }}" class="btn btn-secondary btn-sm">Log in</a> to join the discussion.</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="comment-list">
|
||||
{% for comment in comments %}
|
||||
<div class="comment" id="comment-{{ comment.pk }}">
|
||||
<div class="comment-head">
|
||||
<strong>{{ comment.user.username }}</strong>
|
||||
<span class="comment-time">{{ comment.created_at|timesince }} ago</span>
|
||||
{% if comment.updated_at != comment.created_at %}<span class="comment-edited">· edited</span>{% endif %}
|
||||
{% if can_comment and comment.user == user %}
|
||||
<span class="comment-actions">
|
||||
<a href="#" class="comment-edit btn btn-secondary btn-sm" data-comment="{{ comment.pk }}"><i class="fas fa-edit"></i> Edit</a>
|
||||
<form method="post" action="{% url 'announcements:delete_comment' announcement.pk comment.pk %}" class="inline">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="link-btn" title="Delete"><i class="fas fa-trash"></i></button>
|
||||
</form>
|
||||
</span>
|
||||
{% elif can_comment and user.is_staff %}
|
||||
<span class="comment-actions">
|
||||
<form method="post" action="{% url 'announcements:delete_comment' announcement.pk comment.pk %}" class="inline" title="Delete this comment">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-secondary btn-sm"><i class="fas fa-trash"></i> Delete</button>
|
||||
</form>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="comment-body markdown-body">{{ comment.body|markdown }}</div>
|
||||
{% if can_comment and comment.user == user %}
|
||||
<form method="post" action="{% url 'announcements:edit_comment' announcement.pk comment.pk %}" class="comment-edit-form" data-comment="{{ comment.pk }}" hidden>
|
||||
{% csrf_token %}
|
||||
<textarea name="body" rows="3" required>{{ comment.body }}</textarea>
|
||||
<div class="comment-edit-actions">
|
||||
<button type="submit" class="btn btn-primary btn-sm">Save</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm comment-edit-cancel">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% empty %}
|
||||
<p class="empty-hint">No comments yet.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
(function () {
|
||||
document.querySelectorAll('.comment-edit').forEach(link => {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const id = link.dataset.comment;
|
||||
const body = document.querySelector(`#comment-${id} .comment-body`);
|
||||
const form = document.querySelector(`#comment-${id} .comment-edit-form`);
|
||||
if (body) body.hidden = true;
|
||||
if (form) form.hidden = false;
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.comment-edit-cancel').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const form = btn.closest('.comment-edit-form');
|
||||
const id = form.dataset.comment;
|
||||
const body = document.querySelector(`#comment-${id} .comment-body`);
|
||||
if (body) body.hidden = false;
|
||||
form.hidden = true;
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,33 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}{% if editing %}Edit announcement{% else %}New announcement{% endif %} - Packs Site{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{% if editing %}<i class="fas fa-edit"></i> Edit announcement{% else %}<i class="fas fa-plus"></i> New announcement{% endif %}</h1>
|
||||
|
||||
<form method="post" class="announce-form">
|
||||
{% csrf_token %}
|
||||
{% if form.non_field_errors %}<div class="form-errors">{{ form.non_field_errors }}</div>{% endif %}
|
||||
<div class="form-group">
|
||||
{{ form.title.label_tag }}
|
||||
{{ form.title.errors }}
|
||||
{{ form.title }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ form.body.label_tag }}
|
||||
{{ form.body.errors }}
|
||||
{{ form.body }}
|
||||
<p class="bio-help"><i class="fas fa-info-circle"></i> Supports Markdown — headings, lists, links, code, tables and more.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
{{ form.published }}
|
||||
Publish (visible to everyone)
|
||||
</label>
|
||||
</div>
|
||||
<div class="announce-form-actions">
|
||||
<button type="submit" class="btn btn-primary">{% if editing %}Save changes{% else %}Publish{% endif %}</button>
|
||||
<a href="{% if editing %}{% url 'announcements:detail' announcement.pk %}{% else %}{% url 'announcements:list' %}{% endif %}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,48 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load markdown %}
|
||||
|
||||
{% block title %}Announcements - Packs Site{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="home-section-header">
|
||||
<h1><i class="fas fa-bullhorn"></i> Announcements</h1>
|
||||
{% if user.is_staff %}
|
||||
<a href="{% url 'announcements:create' %}" class="btn btn-primary"><i class="fas fa-plus"></i> New announcement</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="announce-list">
|
||||
{% for a in page %}
|
||||
<article class="card announce-card">
|
||||
<h2>
|
||||
<a href="{% url 'announcements:detail' a.pk %}">{{ a.title }}</a>
|
||||
{% if user.is_authenticated and a.pk not in read_ids %}
|
||||
<span class="announce-badge">new</span>
|
||||
{% endif %}
|
||||
</h2>
|
||||
<div class="markdown-body announce-excerpt">{{ a.body|markdown|truncatechars_html:320 }}</div>
|
||||
<p class="announce-meta">
|
||||
<i class="fas fa-user"></i> {{ a.created_by.username|default:"Staff" }}
|
||||
<span class="separator">•</span>
|
||||
{{ a.created_at|date:"F j, Y" }}
|
||||
<span class="separator">•</span>
|
||||
<i class="fas fa-comments"></i> {{ a.comments_count }} comment{{ a.comments_count|pluralize }}
|
||||
</p>
|
||||
</article>
|
||||
{% empty %}
|
||||
<p class="empty-hint">No announcements yet.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if page.has_other_pages %}
|
||||
<div class="pagination">
|
||||
{% if page.has_previous %}
|
||||
<a href="?page={{ page.previous_page_number }}">«</a>
|
||||
{% endif %}
|
||||
<span>Page {{ page.number }} of {{ page.paginator.num_pages }}</span>
|
||||
{% if page.has_next %}
|
||||
<a href="?page={{ page.next_page_number }}">»</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,39 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Your alerts - Packs Site{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="home-section-header">
|
||||
<h1><i class="fas fa-bell"></i> Your alerts</h1>
|
||||
<form method="post" action="{% url 'announcements:mark_all_read' %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{{ request.path }}">
|
||||
<button type="submit" class="btn btn-secondary"><i class="fas fa-check-double"></i> Mark all read</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<ul class="notify-list">
|
||||
{% for n in page %}
|
||||
<li class="notify-item{% if not n.read %} notify-unread{% endif %}">
|
||||
<a href="{% url 'library:project_detail' n.project.slug %}">{{ n.text }}</a>
|
||||
<span class="announce-meta">{{ n.created_at|timesince }} ago{% if not n.read %} · <span class="notify-new">new</span>{% endif %}</span>
|
||||
</li>
|
||||
{% empty %}
|
||||
<li class="empty-hint">You have no alerts yet.</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% if page.has_other_pages %}
|
||||
<div class="pagination">
|
||||
{% if page.has_previous %}
|
||||
<a href="?page={{ page.previous_page_number }}">«</a>
|
||||
{% endif %}
|
||||
<span>Page {{ page.number }} of {{ page.paginator.num_pages }}</span>
|
||||
{% if page.has_next %}
|
||||
<a href="?page={{ page.next_page_number }}">»</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -45,6 +45,9 @@
|
||||
<a href="{% url 'profiles:user_list' %}">
|
||||
<i class="fas fa-users"></i><span class="nav-text"> Users</span>
|
||||
</a>
|
||||
<a href="{% url 'announcements:list' %}">
|
||||
<i class="fas fa-bullhorn"></i><span class="nav-text"> Announcements</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,44 @@
|
||||
|
||||
<div class="home-placeholder">
|
||||
<h2><i class="fas fa-bullhorn"></i> Announcements</h2>
|
||||
<p class="home-placeholder-text">Placeholder — news and updates will live here.</p>
|
||||
<div class="announce-panel">
|
||||
{% for a in announcements %}
|
||||
<div class="announce-item{% if a.pk not in global_read_ids and user.is_authenticated %} announce-unread{% endif %}">
|
||||
<a href="{% url 'announcements:detail' a.pk %}">{{ a.title }}</a>
|
||||
<span class="announce-meta">{{ a.created_at|date:"M j" }}{% if a.comments_count %} · {{ a.comments_count }} comment{{ a.comments_count|pluralize }}{% endif %}</span>
|
||||
</div>
|
||||
{% empty %}
|
||||
<p class="empty-hint">No announcements yet.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if announcements_total > 4 %}
|
||||
<a href="{% url 'announcements:list' %}" class="announce-more">View all ({{ announcements_total }}) <i class="fas fa-arrow-right"></i></a>
|
||||
{% endif %}
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<h2 class="announce-subhead"><i class="fas fa-bell"></i> For you
|
||||
{% if unread_notifications %}<span class="announce-badge">{{ unread_notifications }}</span>{% endif %}
|
||||
</h2>
|
||||
<div class="announce-panel">
|
||||
{% for n in notifications %}
|
||||
<div class="announce-item{% if not n.read %} announce-unread{% endif %}">
|
||||
<a href="{% url 'library:project_detail' n.project.slug %}">{{ n.text }}</a>
|
||||
<span class="announce-meta">{{ n.created_at|timesince }} ago</span>
|
||||
</div>
|
||||
{% empty %}
|
||||
<p class="empty-hint">Nothing new for you yet.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="announce-actions">
|
||||
<a href="{% url 'announcements:personal' %}" class="announce-more">All your alerts <i class="fas fa-arrow-right"></i></a>
|
||||
{% if unread_notifications %}
|
||||
<form method="post" action="{% url 'announcements:mark_all_read' %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="link-btn">Mark all read</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="home-stats">
|
||||
|
||||
Reference in New Issue
Block a user