Merge branch 'skia/mobile_ui' into 'master'

Add a first version of a mobile friendly UI

Although not perfect and with many flaws, this should still allow far
easier navigation on mobile devices.

See merge request ae/Sith!280
This commit is contained in:
Skia 2021-10-01 17:05:11 +00:00
commit b157a3fa90
6 changed files with 284 additions and 236 deletions

View File

@ -13,145 +13,143 @@
</div> </div>
{% endif %} {% endif %}
<div id="right_column" class="news_column">
<div id="agenda">
<div id="agenda_title">{% trans %}Agenda{% endtrans %}</div>
<div id="agenda_content">
{% for d in NewsDate.objects.filter(end_date__gte=timezone.now(),
news__is_moderated=True, news__type__in=["WEEKLY",
"EVENT"]).order_by('start_date', 'end_date') %}
<div class="agenda_item">
<div class="agenda_date">
<strong>{{ d.start_date|localtime|date('D d M Y') }}</strong>
</div>
<div class="agenda_time">
<span>{{ d.start_date|localtime|time(DATETIME_FORMAT) }}</span> -
<span>{{ d.end_date|localtime|time(DATETIME_FORMAT) }}</span>
</div>
<div>
<strong><a href="{{ url('com:news_detail', news_id=d.news.id) }}">{{ d.news.title }}</a></strong>
<a href="{{ d.news.club.get_absolute_url() }}">{{ d.news.club }}</a>
</div>
<div class="agenda_item_content">{{ d.news.summary|markdown }}</div>
</div>
{% endfor %}
</div>
</div>
<div id="birthdays">
<div id="birthdays_title">{% trans %}Birthdays{% endtrans %}</div>
<div id="birthdays_content">
{% if user.is_subscribed %}
{# Cache request for 1 hour #}
{% cache 3600 "birthdays" %}
<ul class="birthdays_year">
{% for d in birthdays.dates('date_of_birth', 'year', 'DESC') %}
<li>
{% trans age=timezone.now().year - d.year %}{{ age }} year old{% endtrans %}
<ul>
{% for u in birthdays.filter(date_of_birth__year=d.year) %}
<li><a href="{{ u.get_absolute_url() }}">{{ u.get_short_name() }}</a></li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endcache %}
{% else %}
<p>{% trans %}You need an up to date subscription to access this content{% endtrans %}</p>
{% endif %}
</div>
</div>
</div>
<div id="left_column" class="news_column"> <div id="left_column" class="news_column">
{% for news in object_list.filter(type="NOTICE") %} {% for news in object_list.filter(type="NOTICE") %}
<section class="news_notice"> <section class="news_notice">
<h4><a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4> <h4><a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4>
<div class="news_content">{{ news.summary|markdown }}</div> <div class="news_content">{{ news.summary|markdown }}</div>
</section> </section>
{% endfor %} {% endfor %}
{% for news in object_list.filter(dates__start_date__lte=timezone.now(), {% for news in object_list.filter(dates__start_date__lte=timezone.now(), dates__end_date__gte=timezone.now(), type="CALL") %}
dates__end_date__gte=timezone.now(), type="CALL") %} <section class="news_call">
<section class="news_call"> <h4> <a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4>
<h4> <a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4> <div class="news_date">
<div class="news_date"> <span>{{ news.dates.first().start_date|localtime|date(DATETIME_FORMAT) }}
<span>{{ news.dates.first().start_date|localtime|date(DATETIME_FORMAT) }} {{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }}</span> -
{{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }}</span> - <span>{{ news.dates.first().end_date|localtime|date(DATETIME_FORMAT) }}
<span>{{ news.dates.first().end_date|localtime|date(DATETIME_FORMAT) }} {{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span>
{{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span> </div>
</div> <div class="news_content">{{ news.summary|markdown }}</div>
<div class="news_content">{{ news.summary|markdown }}</div> </section>
</section> {% endfor %}
{% endfor %}
{% set events_dates = NewsDate.objects.filter(end_date__gte=timezone.now(), start_date__lte=timezone.now()+timedelta(days=5), {% set events_dates = NewsDate.objects.filter(end_date__gte=timezone.now(), start_date__lte=timezone.now()+timedelta(days=5), news__type="EVENT", news__is_moderated=True).datetimes('start_date', 'day') %}
news__type="EVENT", news__is_moderated=True).datetimes('start_date', 'day') %} <h3>{% trans %}Events today and the next few days{% endtrans %}</h3>
<h3>{% trans %}Events today and the next few days{% endtrans %}</h3> {% if events_dates %}
{% if events_dates %} {% for d in events_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>{{ d|localtime|date('D') }}</div> <div class="day">{{ d|localtime|date('d') }}</div>
<div class="day">{{ d|localtime|date('d') }}</div> <div>{{ d|localtime|date('b') }}</div>
<div>{{ d|localtime|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,
{% for news in object_list.filter(dates__start_date__gte=d, dates__start_date__lte=d+timedelta(days=1),
dates__start_date__lte=d+timedelta(days=1), type="EVENT").exclude(dates__end_date__lt=timezone.now())
type="EVENT").exclude(dates__end_date__lt=timezone.now()) .order_by('dates__start_date') %}
.order_by('dates__start_date') %} <section class="news_event">
<section class="news_event"> <div class="club_logo">
<div class="club_logo"> {% if news.club.logo %}
{% if news.club.logo %} <img src="{{ news.club.logo.url }}" alt="{{ news.club }}" />
<img src="{{ news.club.logo.url }}" alt="{{ news.club }}" /> {% else %}
{% else %} <img src="{{ static("com/img/news.png") }}" alt="{{ news.club }}" />
<img src="{{ static("com/img/news.png") }}" alt="{{ news.club }}" /> {% endif %}
{% endif %} </div>
</div> <h4> <a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4>
<h4> <a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4> <div><a href="{{ news.club.get_absolute_url() }}">{{ news.club }}</a></div>
<div><a href="{{ news.club.get_absolute_url() }}">{{ news.club }}</a></div> <div class="news_date">
<div class="news_date"> <span>{{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }}</span> -
<span>{{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }}</span> - <span>{{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span>
<span>{{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span> </div>
</div> <div class="news_content">{{ news.summary|markdown }}
<div class="news_content">{{ news.summary|markdown }} <div class="button_bar">
<div class="button_bar"> {{ fb_quick(news) }}
{{ fb_quick(news) }} {{ tweet_quick(news) }}
{{ tweet_quick(news) }} </div>
</div> </div>
</div> </section>
</section> {% endfor %}
{% endfor %} </div>
</div> </div>
</div> {% endfor %}
{% 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 %}
{% endif %}
{% set coming_soon = object_list.filter(dates__start_date__gte=timezone.now()+timedelta(days=5), {% set coming_soon = object_list.filter(dates__start_date__gte=timezone.now()+timedelta(days=5),
type="EVENT").order_by('dates__start_date') %} type="EVENT").order_by('dates__start_date') %}
{% if coming_soon %} {% if coming_soon %}
<h3>{% trans %}Coming soon... don't miss!{% endtrans %}</h3> <h3>{% trans %}Coming soon... don't miss!{% endtrans %}</h3>
{% for news in coming_soon %} {% for news in coming_soon %}
<section class="news_coming_soon"> <section class="news_coming_soon">
<a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a> <a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a>
<span class="news_date">{{ news.dates.first().start_date|localtime|date(DATETIME_FORMAT) }} <span class="news_date">{{ news.dates.first().start_date|localtime|date(DATETIME_FORMAT) }}
{{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }} - {{ news.dates.first().start_date|localtime|time(DATETIME_FORMAT) }} -
{{ news.dates.first().end_date|localtime|date(DATETIME_FORMAT) }} {{ news.dates.first().end_date|localtime|date(DATETIME_FORMAT) }}
{{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span> {{ news.dates.first().end_date|localtime|time(DATETIME_FORMAT) }}</span>
</section> </section>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</div> </div>
<div id="right_column" class="news_column">
<div id="agenda">
<div id="agenda_title">{% trans %}Agenda{% endtrans %}</div>
<div id="agenda_content">
{% for d in NewsDate.objects.filter(end_date__gte=timezone.now(),
news__is_moderated=True, news__type__in=["WEEKLY",
"EVENT"]).order_by('start_date', 'end_date') %}
<div class="agenda_item">
<div class="agenda_date">
<strong>{{ d.start_date|localtime|date('D d M Y') }}</strong>
</div>
<div class="agenda_time">
<span>{{ d.start_date|localtime|time(DATETIME_FORMAT) }}</span> -
<span>{{ d.end_date|localtime|time(DATETIME_FORMAT) }}</span>
</div>
<div>
<strong><a href="{{ url('com:news_detail', news_id=d.news.id) }}">{{ d.news.title }}</a></strong>
<a href="{{ d.news.club.get_absolute_url() }}">{{ d.news.club }}</a>
</div>
<div class="agenda_item_content">{{ d.news.summary|markdown }}</div>
</div>
{% endfor %}
</div>
</div>
<div id="birthdays">
<div id="birthdays_title">{% trans %}Birthdays{% endtrans %}</div>
<div id="birthdays_content">
{% if user.is_subscribed %}
{# Cache request for 1 hour #}
{% cache 3600 "birthdays" %}
<ul class="birthdays_year">
{% for d in birthdays.dates('date_of_birth', 'year', 'DESC') %}
<li>
{% trans age=timezone.now().year - d.year %}{{ age }} year old{% endtrans %}
<ul>
{% for u in birthdays.filter(date_of_birth__year=d.year) %}
<li><a href="{{ u.get_absolute_url() }}">{{ u.get_short_name() }}</a></li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endcache %}
{% else %}
<p>{% trans %}You need an up to date subscription to access this content{% endtrans %}</p>
{% endif %}
</div>
</div>
</div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -28,7 +28,7 @@ $twitblue: hsl(206, 82%, 63%);
$shadow-color: rgb(223, 223, 223); $shadow-color: rgb(223, 223, 223);
$background-bouton-color: hsl(0, 0%, 90%); $background-button-color: hsl(0, 0%, 95%);
/*--------------------------MEDIA QUERY HELPERS------------------------*/ /*--------------------------MEDIA QUERY HELPERS------------------------*/
$small-devices: 576px; $small-devices: 576px;
@ -47,10 +47,11 @@ body {
input[type=button], input[type=submit], input[type=reset],input[type=file] { input[type=button], input[type=submit], input[type=reset],input[type=file] {
border: none; border: none;
text-decoration: none; text-decoration: none;
background-color: $background-bouton-color; background-color: $background-button-color;
padding: 10px; padding: 0.4em;
margin: 0.1em;
font-weight: bold; font-weight: bold;
font-size: 16px; font-size: 1.2em;
border-radius: 5px; border-radius: 5px;
cursor: pointer; cursor: pointer;
box-shadow: $shadow-color 0px 0px 1px; box-shadow: $shadow-color 0px 0px 1px;
@ -62,9 +63,10 @@ input[type=button], input[type=submit], input[type=reset],input[type=file] {
button{ button{
border: none; border: none;
text-decoration: none; text-decoration: none;
background-color: $background-bouton-color; background-color: $background-button-color;
padding: 10px; padding: 0.4em;
font-size: 14px; margin: 0.1em;
font-size: 1.18em;
border-radius: 5px; border-radius: 5px;
box-shadow: $shadow-color 0px 0px 1px; box-shadow: $shadow-color 0px 0px 1px;
cursor: pointer; cursor: pointer;
@ -75,24 +77,26 @@ button{
input,textarea[type=text],[type=number]{ input,textarea[type=text],[type=number]{
border: none; border: none;
text-decoration: none; text-decoration: none;
background-color: $background-bouton-color; background-color: $background-button-color;
padding: 7px; padding: 0.4em;
font-size: 16px; margin: 0.1em;
font-size: 1.2em;
border-radius: 5px; border-radius: 5px;
max-width: 95%;
} }
textarea{ textarea{
border: none; border: none;
text-decoration: none; text-decoration: none;
background-color: $background-bouton-color; background-color: $background-button-color;
padding: 7px; padding: 7px;
font-size: 16px; font-size: 1.2em;
border-radius: 5px; border-radius: 5px;
} }
select{ select{
border: none; border: none;
text-decoration: none; text-decoration: none;
font-size: 15px; font-size: 1.2em;
background-color: $background-bouton-color; background-color: $background-button-color;
padding: 10px; padding: 10px;
border-radius: 5px; border-radius: 5px;
cursor: pointer; cursor: pointer;
@ -130,9 +134,10 @@ a {
#header_language_chooser { #header_language_chooser {
position: absolute; position: absolute;
top: 0.2em; top: 2em;
right: 0.5em; left: 0.5em;
width: 3%; width: 3%;
min-width: 2.2em;
text-align: center; text-align: center;
input { input {
display: block; display: block;
@ -157,9 +162,6 @@ header {
border-radius: 0px 0px 10px 10px; border-radius: 0px 0px 10px 10px;
#header_logo { #header_logo {
display: inline-block;
flex: none;
background-size: 100% 100%;
background-color: $white-color; background-color: $white-color;
padding: 0.2em; padding: 0.2em;
border-radius: 0px 0px 0px 9px; border-radius: 0px 0px 0px 9px;
@ -169,11 +171,19 @@ header {
margin: 0px; margin: 0px;
width: 100%; width: 100%;
height: 100%; height: 100%;
img {
max-width: 70%;
max-height: 100%;
margin: auto;
display: block;
}
} }
} }
#header_connect_links { #header_connect_links {
margin: 0.6em 0.6em 0em auto; margin: 0.6em 0.6em 0em auto;
padding: 0.2em;
color: $white-color; color: $white-color;
form { form {
display: inline; display: inline;
@ -190,6 +200,7 @@ header {
#header_bar { #header_bar {
display: flex; display: flex;
flex: auto; flex: auto;
flex-wrap: wrap;
width: 80%; width: 80%;
a { a {
@ -213,12 +224,16 @@ header {
display: inline-block; display: inline-block;
flex: auto; flex: auto;
margin: 0.8em 0em; margin: 0.8em 0em;
input {
width: 12ch;
}
} }
#header_user_links { #header_user_links {
display: flex; display: flex;
width: 120ch; // width: 120ch;
flex: initial; flex: initial;
flex-wrap: wrap;
text-align: right; text-align: right;
margin: 0em; margin: 0em;
div { div {
@ -287,42 +302,34 @@ header {
#info_boxes { #info_boxes {
display: flex; display: flex;
flex-wrap: wrap;
width: 90%; width: 90%;
margin: 1em auto; margin: 1em auto;
p {
margin: 0px;
padding: 7px;
}
#alert_box, #info_box { #alert_box, #info_box {
font-size: 14px; flex: 49%;
display: inline-block; font-size: 0.9em;
flex: auto; margin: 0.2em;
padding: 2px; border-radius: 0.6em;
margin: 0.2em 1.5%; .markdown {
min-width: 10%; margin: 0.5em;
max-width: 46%; }
min-height: 20px;
&:before { &:before {
float: left; font-family: FontAwesome;
font-size: 4em;
float: right;
margin: 0.2em; margin: 0.2em;
} }
} }
#info_box { #info_box {
border-radius: 10px;
background: $primary-neutral-light-color; background: $primary-neutral-light-color;
&:before { &:before {
font-family: FontAwesome;
font-size: 4em;
content: "\f05a"; content: "\f05a";
color: hsl(210, 100%, 56%); color: hsl(210, 100%, 56%);
} }
} }
#alert_box { #alert_box {
border-radius: 10px;
background: $second-color; background: $second-color;
&:before { &:before {
font-family: FontAwesome;
font-size: 4em;
content: "\f06a"; content: "\f06a";
color: $white-color; color: $white-color;
} }
@ -345,7 +352,7 @@ header {
a { a {
flex: auto; flex: auto;
text-align: center; text-align: center;
padding: 20px; padding: 1.5em;
color: $white-color; color: $white-color;
font-style: normal; font-style: normal;
font-weight: bolder; font-weight: bolder;
@ -458,6 +465,8 @@ header {
/*---------------------------------NEWS--------------------------------*/ /*---------------------------------NEWS--------------------------------*/
#news { #news {
display: flex;
flex-wrap: wrap;
.news_column { .news_column {
display: inline-block; display: inline-block;
margin: 0px; margin: 0px;
@ -467,11 +476,13 @@ header {
margin-bottom: 1em; margin-bottom: 1em;
} }
#right_column { #right_column {
width: 20%; flex: 20%;
float: right; float: right;
margin: 0.2em;
} }
#left_column { #left_column {
width: 79%; flex: 79%;
margin: 0.2em;
h3 { h3 {
background: $second-color; background: $second-color;
box-shadow: $shadow-color 1px 1px 1px; box-shadow: $shadow-color 1px 1px 1px;
@ -484,6 +495,11 @@ header {
} }
} }
} }
@media screen and (max-width: $small-devices){
#left_column, #right_column {
flex: 100%;
}
}
/* AGENDA/BIRTHDAYS */ /* AGENDA/BIRTHDAYS */
#agenda,#birthdays { #agenda,#birthdays {
@ -691,6 +707,12 @@ header {
} }
} }
@media screen and (max-width: $small-devices){
#page {
width: 98%;
}
}
#news_details { #news_details {
display: inline-block; display: inline-block;
margin-top: 20px; margin-top: 20px;
@ -723,7 +745,7 @@ header {
text-align: center; text-align: center;
text-decoration: none; text-decoration: none;
display: inline-block; display: inline-block;
font-size: 16px; font-size: 1.2em;
border-radius: 2px; border-radius: 2px;
float: right; float: right;
display: block; display: block;
@ -1111,33 +1133,36 @@ u, .underline {
text-decoration: underline; text-decoration: underline;
} }
#basket { #bar_ui {
width: 40%; padding: 0.4em;
background: $primary-neutral-light-color; display: flex;
float: right; flex-wrap: wrap;
padding: 10px; flex-direction: row-reverse;
border-radius: 10px;
}
#products { #products {
width: 90%; flex-basis: 100%;
margin: 0px auto; margin: 0.2em;
overflow: auto; overflow: auto;
} }
#click_form { #click_form {
float: left; flex: auto;
min-width: 57%; margin: 0.2em;
} }
#user_info_container {} #user_info {
flex: auto;
#user_info { padding: 0.5em;
float: right; margin: 0.2em;
padding: 5px; height: 100%;
width: 40%; background: $secondary-neutral-light-color;
margin: 0px auto; img {
background: $secondary-neutral-light-color; max-width: 70%;
}
input {
background: white;
}
}
} }
/*-----------------------------USER PROFILE----------------------------*/ /*-----------------------------USER PROFILE----------------------------*/
@ -1212,6 +1237,11 @@ u, .underline {
} }
} }
} }
@media screen and (max-width: $small-devices){
#user_profile_infos, #user_profile_pictures {
flex-basis: 50%;
}
}
} }
} }
@ -1412,6 +1442,7 @@ textarea {
.search_bar { .search_bar {
margin: 10px 0px; margin: 10px 0px;
display: flex; display: flex;
flex-wrap: wrap;
height: 20p; height: 20p;
align-items: center; align-items: center;
} }
@ -1551,6 +1582,7 @@ footer {
color: $white-color; color: $white-color;
border-radius: 5px; border-radius: 5px;
display: flex; display: flex;
flex-wrap: wrap;
background-color: $primary-neutral-dark-color; background-color: $primary-neutral-dark-color;
box-shadow: $shadow-color 0px 0px 15px; box-shadow: $shadow-color 0px 0px 15px;
a { a {

View File

@ -3,6 +3,7 @@
<head> <head>
{% block head %} {% block head %}
<title>{% block title %}{% trans %}Welcome!{% endtrans %}{% endblock %} - Association des Étudiants UTBM</title> <title>{% block title %}{% trans %}Welcome!{% endtrans %}{% endblock %} - Association des Étudiants UTBM</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="{{ static('core/img/favicon.ico') }}"> <link rel="shortcut icon" href="{{ static('core/img/favicon.ico') }}">
<link rel="stylesheet" href="{{ static('core/base.css') }}"> <link rel="stylesheet" href="{{ static('core/base.css') }}">
<link rel="stylesheet" href="{{ static('core/jquery.datetimepicker.min.css') }}"> <link rel="stylesheet" href="{{ static('core/jquery.datetimepicker.min.css') }}">
@ -27,6 +28,7 @@
<!-- BEGIN HEADER --> <!-- BEGIN HEADER -->
{% block header %} {% block header %}
{% if not popup %} {% if not popup %}
<header>
<div id="header_language_chooser"> <div id="header_language_chooser">
{% for language in LANGUAGES %} {% for language in LANGUAGES %}
<form action="{{ url('set_language') }}" method="post">{% csrf_token %} <form action="{{ url('set_language') }}" method="post">{% csrf_token %}
@ -37,10 +39,11 @@
{% endfor %} {% endfor %}
</div> </div>
<header>
{% if not user.is_authenticated %} {% if not user.is_authenticated %}
<div id="header_logo" style="background-image: url('{{ static('core/img/logo.png') }}'); width: 185px; height: 100px;"> <div id="header_logo">
<a href="{{ url('core:index') }}"></a> <a href="{{ url('core:index') }}">
<img src="{{ static('core/img/logo.png') }}" alt="AE logo">
</a>
</div> </div>
<div id="header_connect_links"> <div id="header_connect_links">
<form method="post" action="{{ url('core:login') }}"> <form method="post" action="{{ url('core:login') }}">
@ -54,8 +57,10 @@
<a href="{{ url('core:register') }}"><button type="button">{% trans %}Register{% endtrans %}</button></a> <a href="{{ url('core:register') }}"><button type="button">{% trans %}Register{% endtrans %}</button></a>
</div> </div>
{% else %} {% else %}
<div id="header_logo" style="background-image: url('{{ static('core/img/logo.png') }}'); width: 92px; height: 52px;"> <div id="header_logo">
<a href="{{ url('core:index') }}"></a> <a href="{{ url('core:index') }}">
<img src="{{ static('core/img/logo.png') }}" alt="AE logo">
</a>
</div> </div>
<div id="header_bar"> <div id="header_bar">
<ul id="header_bars_infos"> <ul id="header_bars_infos">
@ -85,7 +90,7 @@
<a href="{{ url('core:user_profile', user_id=user.id) }}">{{ user.get_display_name() }}</a> <a href="{{ url('core:user_profile', user_id=user.id) }}">{{ user.get_display_name() }}</a>
</div> </div>
<div> <div>
<a href="#" onclick="display_notif()"><i class="fa fa-bell-o"></i> ({{ user.notifications.filter(viewed=False).count() }})</a> <a href="#" onclick="display_notif()" style="white-space: nowrap;"><i class="fa fa-bell-o"></i> ({{ user.notifications.filter(viewed=False).count() }})</a>
<ul id="header_notif"> <ul id="header_notif">
{% for n in user.notifications.filter(viewed=False).order_by('-date') %} {% for n in user.notifications.filter(viewed=False).order_by('-date') %}
<li> <li>

View File

@ -4,6 +4,12 @@
{% trans %}Delete confirmation{% endtrans %} {% trans %}Delete confirmation{% endtrans %}
{% endblock %} {% endblock %}
{% block info_boxes %}
{% endblock %}
{% block nav %}
{% endblock %}
{% block content %} {% block content %}
<h2>{% trans %}Delete confirmation{% endtrans %}</h2> <h2>{% trans %}Delete confirmation{% endtrans %}</h2>
<form action="" method="post">{% csrf_token %} <form action="" method="post">{% csrf_token %}

View File

@ -14,36 +14,38 @@
{% block content %} {% block content %}
<h4 id="click_interface">{{ counter }}</h4> <h4 id="click_interface">{{ counter }}</h4>
<div id="user_info">
<h5>{% trans %}Customer{% endtrans %}</h5>
{{ user_mini_profile(customer.user) }}
{{ user_subscription(customer.user) }}
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}">
{% csrf_token %}
<input type="hidden" name="action" value="add_student_card">
{% trans %}Add a student card{% endtrans %}
<input type="input" name="student_card_uid" />
{% if request.session['not_valid_student_card_uid'] %}
<p><strong>{% trans %}This is not a valid student card UID{% endtrans %}</strong></p>
{% endif %}
<input type="submit" value="{% trans %}Go{% endtrans %}" />
</form>
<h6>{% trans %}Registered cards{% endtrans %}</h6>
{% if customer.student_cards.exists() %}
<ul>
{% for card in customer.student_cards.all() %}
<li>{{ card.uid }}</li>
{% endfor %}
</ul>
{% else %}
{% trans %}No card registered{% endtrans %}
{% endif %}
</div>
<div id="bar_ui"> <div id="bar_ui">
<noscript> <noscript>
<p class="important">Javascript is required for the counter UI.</p> <p class="important">Javascript is required for the counter UI.</p>
</noscript> </noscript>
<div id="user_info">
<h5>{% trans %}Customer{% endtrans %}</h5>
{{ user_mini_profile(customer.user) }}
{{ user_subscription(customer.user) }}
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}">
{% csrf_token %}
<input type="hidden" name="action" value="add_student_card">
{% trans %}Add a student card{% endtrans %}
<input type="input" name="student_card_uid" />
{% if request.session['not_valid_student_card_uid'] %}
<p><strong>{% trans %}This is not a valid student card UID{% endtrans %}</strong></p>
{% endif %}
<input type="submit" value="{% trans %}Go{% endtrans %}" />
</form>
<h6>{% trans %}Registered cards{% endtrans %}</h6>
{% if customer.student_cards.exists() %}
<ul>
{% for card in customer.student_cards.all() %}
<li>{{ card.uid }}</li>
{% endfor %}
</ul>
{% else %}
{% trans %}No card registered{% endtrans %}
{% endif %}
</div>
<div id="click_form"> <div id="click_form">
<h5>{% trans %}Selling{% endtrans %}</h5> <h5>{% trans %}Selling{% endtrans %}</h5>
<div> <div>
@ -115,6 +117,7 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
<div id="products"> <div id="products">
<ul> <ul>
{% for category in categories.keys() -%} {% for category in categories.keys() -%}

View File

@ -1,7 +1,8 @@
# -*- coding:utf-8 -* # -*- coding:utf-8 -*
# #
# Copyright 2016,2017 # Copyright 2016,2017,2021
# - Sli <antoine@bartuccio.fr> # - Sli <antoine@bartuccio.fr>
# - Skia <skia@hya.sk>
# #
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, # Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr. # http://ae.utbm.fr.
@ -27,7 +28,10 @@ from debug_toolbar.panels.templates import TemplatesPanel as BaseTemplatesPanel
class TemplatesPanel(BaseTemplatesPanel): class TemplatesPanel(BaseTemplatesPanel):
def generate_stats(self, *args): def generate_stats(self, *args):
template = self.templates[0]["template"] try:
if not hasattr(template, "engine") and hasattr(template, "backend"): template = self.templates[0]["template"]
template.engine = template.backend if not hasattr(template, "engine") and hasattr(template, "backend"):
template.engine = template.backend
except IndexError: # No template
pass
return super().generate_stats(*args) return super().generate_stats(*args)