mirror of
https://github.com/ae-utbm/sith.git
synced 2025-01-22 06:51:09 +00:00
Improve news list display
This commit is contained in:
parent
3a06cefea8
commit
185fb70dda
@ -172,6 +172,22 @@ def news_notification_callback(notif):
|
|||||||
notif.viewed = True
|
notif.viewed = True
|
||||||
|
|
||||||
|
|
||||||
|
class NewsDateQuerySet(models.QuerySet):
|
||||||
|
def viewable_by(self, user: User) -> Self:
|
||||||
|
"""Filter the event dates that the given user can view.
|
||||||
|
|
||||||
|
- If the can view non moderated news, he can view all news dates
|
||||||
|
- else, he can view the dates of news that are either
|
||||||
|
authored by him or moderated.
|
||||||
|
"""
|
||||||
|
if user.has_perm("com.view_unmoderated_news"):
|
||||||
|
return self
|
||||||
|
q_filter = Q(news__is_moderated=True)
|
||||||
|
if user.is_authenticated:
|
||||||
|
q_filter |= Q(news__author_id=user.id)
|
||||||
|
return self.filter(q_filter)
|
||||||
|
|
||||||
|
|
||||||
class NewsDate(models.Model):
|
class NewsDate(models.Model):
|
||||||
"""A date associated with news.
|
"""A date associated with news.
|
||||||
|
|
||||||
@ -187,6 +203,8 @@ class NewsDate(models.Model):
|
|||||||
start_date = models.DateTimeField(_("start_date"))
|
start_date = models.DateTimeField(_("start_date"))
|
||||||
end_date = models.DateTimeField(_("end_date"))
|
end_date = models.DateTimeField(_("end_date"))
|
||||||
|
|
||||||
|
objects = NewsDateQuerySet.as_manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("news date")
|
verbose_name = _("news date")
|
||||||
verbose_name_plural = _("news dates")
|
verbose_name_plural = _("news dates")
|
||||||
|
@ -172,54 +172,22 @@
|
|||||||
|
|
||||||
.news_event {
|
.news_event {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0.4em;
|
padding: 1em;
|
||||||
|
|
||||||
&:not(:last-child) {
|
header {
|
||||||
border-bottom: 1px solid grey;
|
img {
|
||||||
}
|
height: 75px;
|
||||||
|
|
||||||
div {
|
|
||||||
margin: 0.2em;
|
|
||||||
}
|
}
|
||||||
|
.header_content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
gap: .2rem;
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
margin-top: 1em;
|
margin-top: 0;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.club_logo {
|
|
||||||
float: left;
|
|
||||||
min-width: 7em;
|
|
||||||
max-width: 9em;
|
|
||||||
margin: 0;
|
|
||||||
margin-right: 1em;
|
|
||||||
margin-top: 0.8em;
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-height: 6em;
|
|
||||||
max-width: 8em;
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.news_date {
|
|
||||||
font-size: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.news_content {
|
|
||||||
clear: left;
|
|
||||||
|
|
||||||
.button_bar {
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
.fb {
|
|
||||||
color: $faceblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.twitter {
|
|
||||||
color: $twitblue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,70 +196,6 @@
|
|||||||
|
|
||||||
/* END EVENTS TODAY AND NEXT FEW DAYS */
|
/* END EVENTS TODAY AND NEXT FEW DAYS */
|
||||||
|
|
||||||
/* COMING SOON */
|
|
||||||
.news_coming_soon {
|
|
||||||
display: list-item;
|
|
||||||
list-style-type: square;
|
|
||||||
list-style-position: inside;
|
|
||||||
margin-left: 1em;
|
|
||||||
padding-left: 0;
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-weight: bold;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.news_date {
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END COMING SOON */
|
|
||||||
|
|
||||||
/* NOTICES */
|
|
||||||
.news_notice {
|
|
||||||
margin: 0 0 1em 1em;
|
|
||||||
padding: 0.4em;
|
|
||||||
padding-left: 1em;
|
|
||||||
background: $secondary-neutral-light-color;
|
|
||||||
box-shadow: $shadow-color 0 0 2px;
|
|
||||||
border-radius: 18px 5px 18px 5px;
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.news_content {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END NOTICES */
|
|
||||||
|
|
||||||
/* CALLS */
|
|
||||||
.news_call {
|
|
||||||
margin: 0 0 1em 1em;
|
|
||||||
padding: 0.4em;
|
|
||||||
padding-left: 1em;
|
|
||||||
background: $secondary-neutral-light-color;
|
|
||||||
border: 1px solid grey;
|
|
||||||
box-shadow: $shadow-color 1px 1px 1px;
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.news_date {
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.news_content {
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END CALLS */
|
|
||||||
|
|
||||||
.news_empty {
|
.news_empty {
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
{% extends "core/base.jinja" %}
|
{% extends "core/base.jinja" %}
|
||||||
{% from 'core/macros.jinja' import tweet_quick, fb_quick %}
|
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% trans %}News{% endtrans %}
|
{% trans %}News{% endtrans %}
|
||||||
@ -18,10 +17,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div id="news">
|
<div id="news">
|
||||||
<div id="left_column" class="news_column">
|
<div id="left_column" class="news_column">
|
||||||
{% set events_dates = NewsDate.objects.filter(end_date__gte=timezone.now(), start_date__lte=timezone.now()+timedelta(days=5), news__is_moderated=True).datetimes('start_date', 'day') %}
|
|
||||||
<h3>
|
<h3>
|
||||||
{% trans %}Events today and the next few days{% endtrans %}
|
{% trans %}Events today and the next few days{% endtrans %}
|
||||||
<a target="#" href="{{ url("com:news_feed") }}"><i class="fa fa-rss feed"></i></a>
|
<a target="#" href="{{ url("com:news_feed") }}"><i class="fa fa-rss feed"></i></a>
|
||||||
@ -33,51 +30,58 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.is_com_admin %}
|
{% if user.is_com_admin %}
|
||||||
<a class="btn btn-blue" href="{{ url('com:news_admin_list') }}">{% trans %}Administrate news{% endtrans %}</a>
|
<a class="btn btn-blue" href="{{ url('com:news_admin_list') }}">
|
||||||
|
{% trans %}Administrate news{% endtrans %}
|
||||||
|
</a>
|
||||||
<br>
|
<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if events_dates %}
|
{% for day, dates_group in news_dates %}
|
||||||
{% for d in events_dates %}
|
|
||||||
<div class="news_events_group">
|
<div class="news_events_group">
|
||||||
<div class="news_events_group_date">
|
<div class="news_events_group_date">
|
||||||
<div>
|
<div>
|
||||||
<div>{{ d|localtime|date('D') }}</div>
|
<div>{{ day|date('D') }}</div>
|
||||||
<div class="day">{{ d|localtime|date('d') }}</div>
|
<div class="day">{{ day|date('d') }}</div>
|
||||||
<div>{{ d|localtime|date('b') }}</div>
|
<div>{{ day|date('b') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="news_events_group_items">
|
<div class="news_events_group_items">
|
||||||
{% for news in object_list.filter(dates__start_date__gte=d,dates__start_date__lte=d+timedelta(days=1)).exclude(dates__end_date__lt=timezone.now()).order_by('dates__start_date') %}
|
{% for date in dates_group %}
|
||||||
<section class="news_event">
|
<article class="news_event">
|
||||||
<div class="club_logo">
|
<header class="row gap">
|
||||||
{% if news.club.logo %}
|
{% if date.news.club.logo %}
|
||||||
<img src="{{ news.club.logo.url }}" alt="{{ news.club }}" />
|
<img src="{{ date.news.club.logo.url }}" alt="{{ date.news.club }}"/>
|
||||||
{% else %}
|
{% else %}
|
||||||
<img src="{{ static("com/img/news.png") }}" alt="{{ news.club }}" />
|
<img src="{{ static("com/img/news.png") }}" alt="{{ date.news.club }}"/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
<div class="header_content">
|
||||||
<h4> <a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4>
|
<h4>
|
||||||
<div><a href="{{ news.club.get_absolute_url() }}">{{ news.club }}</a></div>
|
<a href="{{ url('com:news_detail', news_id=date.news_id) }}">
|
||||||
|
{{ date.news.title }}
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
<a href="{{ date.news.club.get_absolute_url() }}">{{ date.news.club }}</a>
|
||||||
<div class="news_date">
|
<div class="news_date">
|
||||||
<span>{{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }}</span> -
|
<time datetime="{{ date.start_date.isoformat(timespec="seconds") }}">
|
||||||
<span>{{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span>
|
{{ date.start_date|localtime|time(DATETIME_FORMAT) }}
|
||||||
</div>
|
</time> -
|
||||||
<div class="news_content">{{ news.summary|markdown }}
|
<time datetime="{{ date.end_date.isoformat(timespec="seconds") }}">
|
||||||
<div class="button_bar">
|
{{ date.end_date|localtime|time(DATETIME_FORMAT) }}
|
||||||
{{ fb_quick(news) }}
|
</time>
|
||||||
{{ tweet_quick(news) }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</header>
|
||||||
|
<div class="news_content markdown">
|
||||||
|
{{ date.news.summary|markdown }}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="news_empty">
|
<div class="news_empty">
|
||||||
<em>{% trans %}Nothing to come...{% endtrans %}</em>
|
<em>{% trans %}Nothing to come...{% endtrans %}</em>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
|
|
||||||
<h3>
|
<h3>
|
||||||
{% trans %}All coming events{% endtrans %}
|
{% trans %}All coming events{% endtrans %}
|
||||||
@ -110,18 +114,26 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<i class="fa-brands fa-discord fa-xl"></i>
|
<i class="fa-brands fa-discord fa-xl"></i>
|
||||||
<a rel="nofollow" target="#" href="https://discord.gg/QvTm3XJrHR">{% trans %}Discord AE{% endtrans %}</a>
|
<a rel="nofollow" target="#" href="https://discord.gg/QvTm3XJrHR">
|
||||||
|
{% trans %}Discord AE{% endtrans %}
|
||||||
|
</a>
|
||||||
{% if user.was_subscribed %}
|
{% if user.was_subscribed %}
|
||||||
- <a rel="nofollow" target="#" href="https://discord.gg/u6EuMfyGaJ">{% trans %}Dev Team{% endtrans %}</a>
|
- <a rel="nofollow" target="#" href="https://discord.gg/u6EuMfyGaJ">
|
||||||
|
{% trans %}Dev Team{% endtrans %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i class="fa-brands fa-facebook fa-xl"></i>
|
<i class="fa-brands fa-facebook fa-xl"></i>
|
||||||
<a rel="nofollow" target="#" href="https://www.facebook.com/@AEUTBM/">{% trans %}Facebook{% endtrans %}</a>
|
<a rel="nofollow" target="#" href="https://www.facebook.com/@AEUTBM/">
|
||||||
|
Facebook
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i class="fa-brands fa-square-instagram fa-xl"></i>
|
<i class="fa-brands fa-square-instagram fa-xl"></i>
|
||||||
<a rel="nofollow" target="#" href="https://www.instagram.com/ae_utbm">{% trans %}Instagram{% endtrans %}</a>
|
<a rel="nofollow" target="#" href="https://www.instagram.com/ae_utbm">
|
||||||
|
Instagram
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -130,7 +142,7 @@
|
|||||||
<div id="birthdays">
|
<div id="birthdays">
|
||||||
<h3>{% trans %}Birthdays{% endtrans %}</h3>
|
<h3>{% trans %}Birthdays{% endtrans %}</h3>
|
||||||
<div id="birthdays_content">
|
<div id="birthdays_content">
|
||||||
{%- if user.was_subscribed -%}
|
{%- if user.has_perm("core.view_user") -%}
|
||||||
<ul class="birthdays_year">
|
<ul class="birthdays_year">
|
||||||
{%- for year, users in birthdays -%}
|
{%- for year, users in birthdays -%}
|
||||||
<li>
|
<li>
|
||||||
@ -143,8 +155,13 @@
|
|||||||
</li>
|
</li>
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
</ul>
|
</ul>
|
||||||
{%- else -%}
|
{%- elif not user.was_subscribed -%}
|
||||||
|
{# The user cannot view birthdays, because he never subscribed #}
|
||||||
<p>{% trans %}You need to subscribe to access this content{% endtrans %}</p>
|
<p>{% trans %}You need to subscribe to access this content{% endtrans %}</p>
|
||||||
|
{%- else -%}
|
||||||
|
{# There is another reason why user cannot view birthdays (maybe he is banned)
|
||||||
|
but we cannot know exactly what is this reason #}
|
||||||
|
<p>{% trans %}You cannot access this content{% endtrans %}</p>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
37
com/views.py
37
com/views.py
@ -37,9 +37,9 @@ from django.http import HttpResponseRedirect
|
|||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.timezone import localdate
|
from django.utils.timezone import localdate, now
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.views.generic import DetailView, ListView, View
|
from django.views.generic import DetailView, ListView, TemplateView, View
|
||||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
||||||
|
|
||||||
from club.models import Club, Mailing
|
from club.models import Club, Mailing
|
||||||
@ -236,28 +236,37 @@ class NewsAdminListView(PermissionRequiredMixin, ListView):
|
|||||||
permission_required = ["com.moderate_news", "com.delete_news"]
|
permission_required = ["com.moderate_news", "com.delete_news"]
|
||||||
|
|
||||||
|
|
||||||
class NewsListView(ListView):
|
class NewsListView(TemplateView):
|
||||||
model = News
|
|
||||||
template_name = "com/news_list.jinja"
|
template_name = "com/news_list.jinja"
|
||||||
queryset = News.objects.filter(is_moderated=True)
|
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_birthdays(self):
|
||||||
return super().get_queryset().viewable_by(self.request.user)
|
if not self.request.user.has_perm("core.view_user"):
|
||||||
|
return []
|
||||||
def get_context_data(self, **kwargs):
|
return itertools.groupby(
|
||||||
kwargs = super().get_context_data(**kwargs)
|
|
||||||
kwargs["NewsDate"] = NewsDate
|
|
||||||
kwargs["timedelta"] = timedelta
|
|
||||||
kwargs["birthdays"] = itertools.groupby(
|
|
||||||
User.objects.filter(
|
User.objects.filter(
|
||||||
date_of_birth__month=localdate().month,
|
date_of_birth__month=localdate().month,
|
||||||
date_of_birth__day=localdate().day,
|
date_of_birth__day=localdate().day,
|
||||||
|
is_subscriber_viewable=True,
|
||||||
)
|
)
|
||||||
.filter(role__in=["STUDENT", "FORMER STUDENT"])
|
.filter(role__in=["STUDENT", "FORMER STUDENT"])
|
||||||
.order_by("-date_of_birth"),
|
.order_by("-date_of_birth"),
|
||||||
key=lambda u: u.date_of_birth.year,
|
key=lambda u: u.date_of_birth.year,
|
||||||
)
|
)
|
||||||
return kwargs
|
|
||||||
|
def get_news_dates(self):
|
||||||
|
return itertools.groupby(
|
||||||
|
NewsDate.objects.viewable_by(self.request.user)
|
||||||
|
.filter(end_date__gt=now(), start_date__lt=now() + timedelta(days=6))
|
||||||
|
.order_by("start_date")
|
||||||
|
.select_related("news", "news__club"),
|
||||||
|
key=lambda d: d.start_date.date(),
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
return super().get_context_data(**kwargs) | {
|
||||||
|
"news_dates": self.get_news_dates(),
|
||||||
|
"birthdays": self.get_birthdays(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class NewsDetailView(CanViewMixin, DetailView):
|
class NewsDetailView(CanViewMixin, DetailView):
|
||||||
|
@ -39,14 +39,6 @@
|
|||||||
<a rel="nofollow" target="#" class="share_button twitter" href="https://twitter.com/intent/tweet?text={{ news.get_full_url() }}">{% trans %}Tweet{% endtrans %}</a>
|
<a rel="nofollow" target="#" class="share_button twitter" href="https://twitter.com/intent/tweet?text={{ news.get_full_url() }}">{% trans %}Tweet{% endtrans %}</a>
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
{% macro fb_quick(news) -%}
|
|
||||||
<a rel="nofollow" target="#" href="https://www.facebook.com/sharer/sharer.php?u={{ news.get_full_url() }}" class="fb fa-brands fa-facebook fa-2x"></a>
|
|
||||||
{%- endmacro %}
|
|
||||||
|
|
||||||
{% macro tweet_quick(news) -%}
|
|
||||||
<a rel="nofollow" target="#" href="https://twitter.com/intent/tweet?text={{ news.get_full_url() }}" class="twitter fa-brands fa-twitter-square fa-2x"></a>
|
|
||||||
{%- endmacro %}
|
|
||||||
|
|
||||||
{% macro user_mini_profile(user) %}
|
{% macro user_mini_profile(user) %}
|
||||||
<div class="user_mini_profile">
|
<div class="user_mini_profile">
|
||||||
<div class="user_mini_profile_infos">
|
<div class="user_mini_profile_infos">
|
||||||
|
Loading…
Reference in New Issue
Block a user