8
0
Fork 0
mirror of https://gitlab.federez.net/re2o/re2o synced 2024-07-07 06:34:06 +00:00

Merge branch 'frontend_fix' into 'dev'

Frontend changes

See merge request federez/re2o!296
This commit is contained in:
klafyvel 2018-09-22 10:24:37 +02:00
commit 38e1cabddd
16 changed files with 624 additions and 427 deletions

View file

@ -150,3 +150,17 @@ On some database engines (postgreSQL) you also need to update the id sequences:
```bash ```bash
python3 manage.py sqlsequencereset cotisations | python3 manage.py dbshell python3 manage.py sqlsequencereset cotisations | python3 manage.py dbshell
``` ```
## MR 296: Frontend changes
Install fonts-font-awesome
```bash
apt-get -y install fonts-font-awesome
```
Collec new statics
```bash
python3 manage.py collectstatic
```

View file

@ -14,4 +14,5 @@ libjs-jquery
libjs-jquery-ui libjs-jquery-ui
libjs-jquery-timepicker libjs-jquery-timepicker
libjs-bootstrap libjs-bootstrap
fonts-font-awesome
graphviz graphviz

View file

@ -29,15 +29,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block sidebar %} {% block sidebar %}
{% can_view_app logs %} {% can_view_app logs %}
<a class="list-group-item list-group-item-info" href="{% url "logs:index" %}"> <a class="list-group-item list-group-item-info" href="{% url "logs:index" %}">
<i class="fa fa-clipboard-list"></i> <i class="fa fa-clipboard"></i>
{% trans "Summary" %} {% trans "Summary" %}
</a> </a>
<a class="list-group-item list-group-item-info" href="{% url "logs:stats-logs" %}"> <a class="list-group-item list-group-item-info" href="{% url "logs:stats-logs" %}">
<i class="fa fa-calendar-alt"></i> <i class="fa fa-calendar"></i>
{% trans "Events" %} {% trans "Events" %}
</a> </a>
<a class="list-group-item list-group-item-info" href="{% url "logs:stats-general" %}"> <a class="list-group-item list-group-item-info" href="{% url "logs:stats-general" %}">
<i class="fa fa-chart-area"></i> <i class="fa fa-area-chart"></i>
{% trans "General" %} {% trans "General" %}
</a> </a>
<a class="list-group-item list-group-item-info" href="{% url "logs:stats-models" %}"> <a class="list-group-item list-group-item-info" href="{% url "logs:stats-models" %}">

Binary file not shown.

View file

@ -87,7 +87,7 @@ msgstr "À propos de %(AssoName)s"
#: templates/re2o/about.html:36 #: templates/re2o/about.html:36
msgid "" msgid ""
"Re2o is an administration tool initiated by <a href=\"https://rezometz.org/" "Re2o is an administration tool initiated by <a href=\"https://rezometz.org/"
"\">Rezo Supelec Metz</a> and a few members of other <a href=\"https://" "\">Rezo Metz</a> and a few members of other <a href=\"https://"
"federez.net\">FedeRez</a> associations around the summer 2016.<br /> It is " "federez.net\">FedeRez</a> associations around the summer 2016.<br /> It is "
"intended to be a tool independant from any network infrastructure so it can " "intended to be a tool independant from any network infrastructure so it can "
"be setup in \"a few steps\". This tool is entirely free and available under " "be setup in \"a few steps\". This tool is entirely free and available under "
@ -98,11 +98,11 @@ msgid ""
"to contact us and come help us build the future of Re2o." "to contact us and come help us build the future of Re2o."
msgstr "" msgstr ""
"Re2o est un outil d'administration initié par <a href=\"https://rezometz.org/" "Re2o est un outil d'administration initié par <a href=\"https://rezometz.org/"
"\">Rézo Supélec Metz</a> et quelques membres d'autres assocations de <a href=" "\">Rézo Metz</a> et quelques membres d'autres associations de <a href="
"\"https://federez.net\">FedeRez</a> autour de l'été 2016.<br /> Il se veut " "\"https://federez.net\">FedeRez</a> autour de l'été 2016.<br /> Il se veut "
"être un outil indépendant de toute infrastructure réseau pour pouvoir être " "être un outil indépendant de toute infrastructure réseau pour pouvoir être "
"installé en \"quelques étapes\". Cet outil est entièrement gratuit et est " "installé en \"quelques étapes\". Cet outil est entièrement gratuit et est "
"disponible sous license GNU Public License v2 (GPLv2) sur le<a href=" "disponible sous licence GNU Public Licence v2 (GPLv2) sur le <a href="
"\"https://gitlab.federez.net/federez/re2o/\">gitlab de FedeRez</a>.<br />\n" "\"https://gitlab.federez.net/federez/re2o/\">gitlab de FedeRez</a>.<br />\n"
"Les mainteneurs de Re2o sont de fiers bénévoles venant principalement " "Les mainteneurs de Re2o sont de fiers bénévoles venant principalement "
"d'écoles d'ingénieurs françaises (mais pas seulement) qui ont donné beaucoup " "d'écoles d'ingénieurs françaises (mais pas seulement) qui ont donné beaucoup "

View file

@ -174,6 +174,7 @@ BOOTSTRAP_BASE_URL = '/javascript/bootstrap/'
# Use only absolute paths with '/' delimiters even on Windows # Use only absolute paths with '/' delimiters even on Windows
STATICFILES_DIRS = ( STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static').replace('\\', '/'), os.path.join(BASE_DIR, 'static').replace('\\', '/'),
"/usr/share/fonts-font-awesome/",
) )
# Directory where the static files served by the server are stored # Directory where the static files served by the server are stored
STATIC_ROOT = os.path.join(BASE_DIR, 'static_files') STATIC_ROOT = os.path.join(BASE_DIR, 'static_files')

View file

@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<h2>{% trans "About Re2o" %}</h2> <h2>{% trans "About Re2o" %}</h2>
<p>{% blocktrans trimmed %} <p>{% blocktrans trimmed %}
Re2o is an administration tool initiated by Re2o is an administration tool initiated by
<a href="https://rezometz.org/">Rezo Supelec Metz</a> and a few <a href="https://rezometz.org/">Rezo Metz</a> and a few
members of other <a href="https://federez.net">FedeRez</a> associations members of other <a href="https://federez.net">FedeRez</a> associations
around the summer 2016.<br /> around the summer 2016.<br />
It is intended to be a tool independant from any network infrastructure It is intended to be a tool independant from any network infrastructure

View file

@ -31,9 +31,9 @@ def tick(valeur, autoescape=False):
if isinstance(valeur,bool): if isinstance(valeur,bool):
if valeur == True: if valeur == True:
result = '<i style="color: #1ECA18;" class="fas fa-check"></i>' result = '<i style="color: #1ECA18;" class="fa fa-check"></i>'
else: else:
result = '<i style="color: #D10115;" class="fas fa-times"></i>' result = '<i style="color: #D10115;" class="fa fa-times"></i>'
return mark_safe(result) return mark_safe(result)
else: # if the value is not a boolean, display it as if tick was not called else: # if the value is not a boolean, display it as if tick was not called

View file

@ -1,38 +1,22 @@
/* Sticky footer hacks */ /* Footer */
html, body {
height: 100%;
}
#wrap {
min-height: 100%;
}
#main {
overflow: auto;
padding-bottom:60px; /* this needs to be bigger than footer height*/
}
footer { footer {
position: relative; padding-top: 3rem;
margin-top: -50px; /* negative value of footer height */ padding-bottom: 3rem;
height: 50px;
clear:both;
padding-top:20px;
background-color: #222222;
/*background: -webkit-linear-gradient(left, red, red 16.6%, orange 16.6%, orange, orange 33.3%, yellow 33.3%, yellow, yellow 50%, green 50%, green, green 66.6%, blue 66.6%, blue, blue 83.3%, violet 83.3%,violet); */
color: white;
padding: 15px;
} }
footer a { footer p {
color: white; margin-bottom: .25rem;
text-decoration: underline;
} }
/* Remove the navbar's default margin-bottom and rounded borders */ /* Move the space between navbar and content in the content */
.navbar { .navbar { margin-bottom: 0; }
margin-bottom: 0; .pt4 { padding-top: 1.5rem!important; }
border-radius: 0;
/* Reserv space for icons and align */
a > i.fa {
display: inline-block;
width: 26px;
text-align: center;
} }
/* Reduce the padding for the logo in the navbar-brand so the 32px-high logo /* Reduce the padding for the logo in the navbar-brand so the 32px-high logo
@ -47,6 +31,20 @@ footer a {
display: initial; display: initial;
} }
/* Make navbar look less Bootstraped */
.navbar-inverse {
background-color: #612210;
border-color: #f9a01b;
}
.navbar-inverse .navbar-brand {
color: #ffffff;
}
.navbar-inverse .navbar-nav > li > a {
color: #d6d6d6;
}
/* Add right colors for buttons in dropdown in navbar-inverse (else it is light /* Add right colors for buttons in dropdown in navbar-inverse (else it is light
* gray on white bg and white when hovered */ * gray on white bg and white when hovered */
.navbar-inverse .dropdown-menu .btn-link { .navbar-inverse .dropdown-menu .btn-link {
@ -73,10 +71,11 @@ footer a {
overflow: auto; overflow: auto;
} }
/* Set gray background color and 100% height */ /* Set gray background color */
.sidenav { .sidenav {
padding-top: 20px;
background-color: #f1f1f1; background-color: #f1f1f1;
border: 1px solid #e0e0e0;
border-radius: 0 0 5px 5px;
} }
.table > tbody > tr > td, .table > tbody > tr > th, .table > tfoot > tr > td, .table > tfoot > tr > th, .table > thead > tr > td, .table > thead > tr > th { .table > tbody > tr > td, .table > tbody > tr > th, .table > tfoot > tr > td, .table > tfoot > tr > th, .table > thead > tr > td, .table > thead > tr > th {
vertical-align: middle; vertical-align: middle;

View file

@ -21,51 +21,75 @@
// General options // General options
//===================================== //=====================================
// Times the canvas is refreshed a second // Times the canvas is refreshed a second
var FPS = 30; let FPS = 30;
// Determine the length of the trail (0=instant disappear, maximum=window.innerHeight=no disappear) // Determine the length of the trail (0=instant disappear, maximum=window.innerHeight=no disappear)
var TRAIL_TIME = 5; let TRAIL_TIME = 5;
// The color of the characters // The color of the characters
var RAIN_COLOR = "#00F"; let RAIN_COLOR = "#00F";
// The characters displayed // The characters displayed
var CHARACTERS = "田由甲申甴电甶男甸甹町画甼甽甾甿畀畁畂畃畄畅畆畇畈畉畊畋界畍畎畏畐畑".split(""); let CHARACTERS = "田由甲申甴电甶男甸甹町画甼甽甾甿畀畁畂畃畄畅畆畇畈畉畊畋界畍畎畏畐畑".split("");
// The font size used to display the characters // The font size used to display the characters
var FONT_SIZE = 10; let FONT_SIZE = 10;
// The maximum number of characters displayed by column // The maximum number of characters displayed by column
var MAX_CHAR = 7; let MAX_CHAR = 7;
var Sapphire = function () { let Sapphire;
var sapphire = {
Sapphire = function () {
let sapphire = {
triggerHandle: undefined, triggerHandle: undefined,
activated: false, activated: false,
runOnce: false, runOnce: false,
getClass: function(elt, main, name) { elt.obj = main.getElementsByClassName(name); }, getClass: function (elt, main, name) {
getTag: function(elt, main, name) { elt.obj = main.getElementsByTagName(name); }, elt.obj = main.getElementsByClassName(name);
},
getTag: function (elt, main, name) {
elt.obj = main.getElementsByTagName(name);
},
getProp: function(elt) { getProp: function (elt) {
for (var i=0 ; i<elt.obj.length ; i++) { for (let i = 0; i < elt.obj.length; i++) {
for (var p in elt.prop) { for (let p in elt.prop) {
if ( p === "color" ) { elt.prop[p][i] = elt.obj[i].style.color; } if (p === "color") {
else if ( p === "bgColor" ) { elt.prop[p][i] = elt.obj[i].style.backgroundColor; } elt.prop[p][i] = elt.obj[i].style.color;
else if ( p === "display" ) { elt.prop[p][i] = elt.obj[i].style.display; } }
else if (p === "bgColor") {
elt.prop[p][i] = elt.obj[i].style.backgroundColor;
}
else if (p === "display") {
elt.prop[p][i] = elt.obj[i].style.display;
}
} }
} }
}, },
alterProp: function(elt) { alterProp: function (elt) {
for (var i=0 ; i<elt.obj.length ; i++) { for (let i = 0; i < elt.obj.length; i++) {
for (var p in elt.prop) { for (let p in elt.prop) {
if ( p === "color" ) { elt.obj[i].style.color = "white"; } if (p === "color") {
else if ( p === "bgColor" ) { elt.obj[i].style.backgroundColor = "transparent"; } elt.obj[i].style.color = "white";
else if ( p === "display" ) { elt.obj[i].style.display = "none"; } }
else if (p === "bgColor") {
elt.obj[i].style.backgroundColor = "transparent";
}
else if (p === "display") {
elt.obj[i].style.display = "none";
}
} }
} }
}, },
revertProp: function(elt) { revertProp: function (elt) {
for (var i=0 ; i<elt.obj.length ; i++) { for (let i = 0; i < elt.obj.length; i++) {
for (var p in elt.prop) { for (let p in elt.prop) {
if ( p === "color" ) { elt.obj[i].style.color = elt.prop[p][i]; } if (p === "color") {
else if ( p === "bgColor" ) { elt.obj[i].style.backgroundColor = elt.prop[p][i]; } elt.obj[i].style.color = elt.prop[p][i];
else if ( p === "display" ) { elt.obj[i].style.display = elt.prop[p][i]; } }
else if (p === "bgColor") {
elt.obj[i].style.backgroundColor = elt.prop[p][i];
}
else if (p === "display") {
elt.obj[i].style.display = elt.prop[p][i];
}
} }
} }
}, },
@ -74,136 +98,255 @@ var Sapphire = function () {
alerts: { alerts: {
obj: undefined, obj: undefined,
prop: {bgColor: []}, prop: {bgColor: []},
get: function(main) { sapphire.getClass(this, main, "alert"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "alert");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
btns: { btns: {
obj: undefined, obj: undefined,
prop: {color: [], bgColor: []}, prop: {color: [], bgColor: []},
get: function(main) { sapphire.getClass(this, main, "btn"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "btn");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
body: { body: {
obj: undefined, obj: undefined,
prop: {color: []}, prop: {color: []},
get: function(main) { get: function () {
this.obj = document.body; this.obj = document.body;
for (var p in this.prop) { if ( p === "color" ) { this.prop[p] = this.obj.style.color; } } for (let p in this.prop) {
if (p === "color") {
this.prop[p] = this.obj.style.color;
}
}
}, },
alter: function() { for (var p in this.prop) { if ( p === "color" ) { this.obj.style.color = "white"; } } }, alter: function () {
revert: function() { for (var p in this.prop) { if ( p === "color" ) { this.obj.style.color = this.prop[p]; } } } for (let p in this.prop) {
if (p === "color") {
this.obj.style.color = "white";
}
}
},
revert: function () {
for (let p in this.prop) {
if (p === "color") {
this.obj.style.color = this.prop[p];
}
}
}
}, },
captions: { captions: {
obj: undefined, obj: undefined,
prop: {color: []}, prop: {color: []},
get: function(main) { sapphire.getClass(this, main, "caption"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "caption");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
helps: { helps: {
obj: undefined, obj: undefined,
prop: {color: []}, prop: {color: []},
get: function(main) { sapphire.getClass(this, main, "help-block"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "help-block");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
hrs: { hrs: {
obj: undefined, obj: undefined,
prop: {display: []}, prop: {display: []},
get: function(main) { sapphire.getTag(this, main, "hr"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getTag(this, main, "hr");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
inputs: { inputs: {
obj: undefined, obj: undefined,
prop: {color: [], bgColor: []}, prop: {color: [], bgColor: []},
get: function(main) { sapphire.getTag(this, main, "input"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getTag(this, main, "input");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
listGroups: { listGroups: {
obj: undefined, obj: undefined,
prop: {color: [], bgColor: []}, prop: {color: [], bgColor: []},
get: function(main) { sapphire.getClass(this, main, "list-group-item"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "list-group-item");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
paginations: { paginations: {
obj: [], obj: [],
prop: {bgColor: []}, prop: {bgColor: []},
get: function(main) { get: function (main) {
var a = main.getElementsByClassName("pagination"); let a = main.getElementsByClassName("pagination");
for (var i=0 ; i<a.length ; i++) { for (let i = 0; i < a.length; i++) {
this.obj[i] = []; this.prop.bgColor[i] = []; this.obj[i] = [];
for (var j=0 ; j<a[i].children.length ; j++) { this.prop.bgColor[i] = [];
for (let j = 0; j < a[i].children.length; j++) {
this.obj[i][j] = a[i].children[j].children[0]; this.obj[i][j] = a[i].children[j].children[0];
this.prop.bgColor[i][j] = this.obj[i][j].style.backgroundColor; this.prop.bgColor[i][j] = this.obj[i][j].style.backgroundColor;
} }
} }
}, },
alter: function () { alter: function () {
for (var i=0 ; i<this.obj.length ; i++) for (let i = 0; i < this.obj.length; i++)
for (var j=0 ; j<this.obj[i].length ; j++) for (let j = 0; j < this.obj[i].length; j++)
for (var p in this.prop) for (let p in this.prop)
if ( p === "bgColor" ) { this.obj[i][j].style.backgroundColor = "transparent"; } if (p === "bgColor") {
this.obj[i][j].style.backgroundColor = "transparent";
}
}, },
revert: function() { revert: function () {
for (var i=0 ; i<this.obj.length ; i++) for (let i = 0; i < this.obj.length; i++)
for (var j=0 ; j<this.obj[i].length ; j++) for (let j = 0; j < this.obj[i].length; j++)
for (var p in this.prop) for (let p in this.prop)
if ( p === "bgColor" ) { this.obj[i][j].style.backgroundColor = this.prop[p][i][j]; } if (p === "bgColor") {
this.obj[i][j].style.backgroundColor = this.prop[p][i][j];
}
} }
}, },
panelHeadings: { panelHeadings: {
obj: undefined, obj: undefined,
prop: {bgColor: [], color: []}, prop: {bgColor: [], color: []},
get: function(main) { sapphire.getClass(this, main, "panel-heading"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "panel-heading");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
panels: { panels: {
obj: undefined, obj: undefined,
prop: {bgColor: []}, prop: {bgColor: []},
get: function(main) { sapphire.getClass(this, main, "panel"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "panel");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
selects: { selects: {
obj: undefined, obj: undefined,
prop: {color: [], bgColor: []}, prop: {color: [], bgColor: []},
get: function(main) { sapphire.getTag(this, main, "select"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getTag(this, main, "select");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
sidenavs: { sidenavs: {
obj: undefined, obj: undefined,
prop: {bgColor: []}, prop: {bgColor: []},
get: function(main) { sapphire.getClass(this, main, "sidenav"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "sidenav");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
tds: { tds: {
obj: undefined, obj: undefined,
prop: {bgColor: []}, prop: {bgColor: []},
get: function(main) { sapphire.getTag(this, main, "td"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getTag(this, main, "td");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
thumbnails: { thumbnails: {
obj: undefined, obj: undefined,
prop: {bgColor: []}, prop: {bgColor: []},
get: function(main) { sapphire.getClass(this, main, "thumbnail"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getClass(this, main, "thumbnail");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
}, },
trs: { trs: {
obj: undefined, obj: undefined,
prop: {bgColor: []}, prop: {bgColor: []},
get: function(main) { sapphire.getTag(this, main, "tr"); sapphire.getProp(this); }, get: function (main) {
alter: function() { sapphire.alterProp(this); }, sapphire.getTag(this, main, "tr");
revert: function() { sapphire.revertProp(this); } sapphire.getProp(this);
},
alter: function () {
sapphire.alterProp(this);
},
revert: function () {
sapphire.revertProp(this);
}
} }
}, },
@ -212,35 +355,39 @@ var Sapphire = function () {
drops: undefined, drops: undefined,
canvas: undefined, canvas: undefined,
init: function() { init: function () {
var main = document.getElementById("main"); let main = document.getElementById("main");
for (var e in sapphire.elts) { sapphire.elts[e].get(main); } for (let e in sapphire.elts) {
sapphire.elts[e].get(main);
}
}, },
resize: function() { resize: function () {
var ctx = sapphire.canvas.getContext("2d"); let ctx = sapphire.canvas.getContext("2d");
var img = ctx.getImageData( 0, 0, sapphire.canvas.width, sapphire.canvas.height ); let img = ctx.getImageData(0, 0, sapphire.canvas.width, sapphire.canvas.height);
sapphire.canvas.width = window.innerWidth; sapphire.canvas.width = window.innerWidth;
sapphire.canvas.height = window.innerHeight; sapphire.canvas.height = window.innerHeight;
ctx.fillStyle = "rgba(0, 0, 0, 1)"; ctx.fillStyle = "rgba(0, 0, 0, 1)";
ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height); ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height);
ctx.putImageData( img, 0, 0 ); ctx.putImageData(img, 0, 0);
sapphire.columns = sapphire.canvas.width/FONT_SIZE; sapphire.columns = sapphire.canvas.width / FONT_SIZE;
sapphire.alpha = Math.max( 0, Math.min( 1, TRAIL_TIME / ( sapphire.canvas.height/FONT_SIZE ) ) ); sapphire.alpha = Math.max(0, Math.min(1, TRAIL_TIME / (sapphire.canvas.height / FONT_SIZE)));
var newDrops = []; let newDrops = [];
for(var x = 0; x < sapphire.columns; x++) { for (let x = 0; x < sapphire.columns; x++) {
if ( sapphire.drops && sapphire.drops[x] ) { newDrops[x] = sapphire.drops[x] } if (sapphire.drops && sapphire.drops[x]) {
newDrops[x] = sapphire.drops[x]
}
else { else {
newDrops[x] = []; newDrops[x] = [];
var nb = Math.floor(Math.random()*MAX_CHAR); let nb = Math.floor(Math.random() * MAX_CHAR);
for (var y = 0; y < nb; y++) for (let y = 0; y < nb; y++)
newDrops[x][y] = 0; newDrops[x][y] = 0;
} }
} }
sapphire.drops = newDrops; sapphire.drops = newDrops;
}, },
run: function() { run: function () {
sapphire.canvas = document.createElement("canvas"); sapphire.canvas = document.createElement("canvas");
document.body.appendChild(sapphire.canvas); document.body.appendChild(sapphire.canvas);
sapphire.canvas.style.position = "fixed"; sapphire.canvas.style.position = "fixed";
@ -248,23 +395,23 @@ var Sapphire = function () {
sapphire.canvas.style.left = 0; sapphire.canvas.style.left = 0;
sapphire.canvas.style.top = 0; sapphire.canvas.style.top = 0;
var ctx = sapphire.canvas.getContext("2d"); let ctx = sapphire.canvas.getContext("2d");
ctx.fillStyle = "rgba(0, 0, 0, 1)"; ctx.fillStyle = "rgba(0, 0, 0, 1)";
ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height); ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height);
function attenuateBackground() { function attenuateBackground() {
ctx.fillStyle = "rgba(0, 0, 0, "+sapphire.alpha+")"; ctx.fillStyle = "rgba(0, 0, 0, " + sapphire.alpha + ")";
ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height); ctx.fillRect(0, 0, sapphire.canvas.width, sapphire.canvas.height);
} }
function drawMatrixRainDrop() { function drawMatrixRainDrop() {
ctx.fillStyle = RAIN_COLOR; ctx.fillStyle = RAIN_COLOR;
ctx.font = FONT_SIZE + "px arial"; ctx.font = FONT_SIZE + "px arial";
for(var i = 0; i < sapphire.drops.length; i++) { for (let i = 0; i < sapphire.drops.length; i++) {
for (var j = 0; j < sapphire.drops[i].length; j++) { for (let j = 0; j < sapphire.drops[i].length; j++) {
var text = CHARACTERS[Math.floor(Math.random()*CHARACTERS.length)]; let text = CHARACTERS[Math.floor(Math.random() * CHARACTERS.length)];
ctx.fillText(text, i*FONT_SIZE, sapphire.drops[i][j]*FONT_SIZE); ctx.fillText(text, i * FONT_SIZE, sapphire.drops[i][j] * FONT_SIZE);
if(sapphire.drops[i][j]*FONT_SIZE > sapphire.canvas.height && Math.random() > 0.975) if (sapphire.drops[i][j] * FONT_SIZE > sapphire.canvas.height && Math.random() > 0.975)
sapphire.drops[i][j] = 0; sapphire.drops[i][j] = 0;
sapphire.drops[i][j]++; sapphire.drops[i][j]++;
} }
@ -278,19 +425,29 @@ var Sapphire = function () {
sapphire.resize(); sapphire.resize();
window.addEventListener('resize', sapphire.resize); window.addEventListener('resize', sapphire.resize);
sapphire.triggerHandle = setInterval(drawEverything, 1000/FPS); sapphire.triggerHandle = setInterval(drawEverything, 1000 / FPS);
}, },
stop: function() { stop: function () {
window.removeEventListener('resize', sapphire.resize); window.removeEventListener('resize', sapphire.resize);
clearInterval(sapphire.triggerHandle); clearInterval(sapphire.triggerHandle);
sapphire.canvas.parentNode.removeChild(sapphire.canvas); sapphire.canvas.parentNode.removeChild(sapphire.canvas);
}, },
alterElts: function() { for (var e in sapphire.elts) { sapphire.elts[e].alter(main); } }, alterElts: function () {
revertElts: function() { for (var e in sapphire.elts) { sapphire.elts[e].revert(main); } }, for (let e in sapphire.elts) {
let main = document.getElementById("main");
sapphire.elts[e].alter(main);
}
},
revertElts: function () {
for (let e in sapphire.elts) {
let main = document.getElementById("main");
sapphire.elts[e].revert(main);
}
},
activate: function() { activate: function () {
if (!sapphire.runOnce) { if (!sapphire.runOnce) {
sapphire.runOnce = true; sapphire.runOnce = true;
sapphire.init(); sapphire.init();
@ -306,11 +463,7 @@ var Sapphire = function () {
sapphire.revertElts(); sapphire.revertElts();
} }
} }
} };
return sapphire; return sapphire;
} };
var s = Sapphire();
Konami(s.activate);

View file

@ -40,28 +40,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<meta property="og:image:type" content="image/svg"/> <meta property="og:image:type" content="image/svg"/>
<meta property="og:image:alt" content="The Re2o logo"/> <meta property="og:image:alt" content="The Re2o logo"/>
<meta property="og:description" content="{% trans "Networking managing website endorsed by FedeRez." %}" /> <meta property="og:description" content="{% trans "Networking managing website endorsed by FedeRez." %}" />
<script defer src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"></script>
{# Load CSS and JavaScript #}
{% bootstrap_css %}
<link href="/static/css/typeaheadjs.css" rel="stylesheet">
<link href="/static/css/bootstrap-tokenfield.css" rel="stylesheet">
{% bootstrap_javascript %} {# Load CSS #}
<script src="/static/js/typeahead/typeahead.js"></script> {% bootstrap_css %}
<script src="/static/js/handlebars/handlebars.js"></script> <link href="{% static 'css/typeaheadjs.css' %}" rel="stylesheet">
<script src="/static/js/konami/konami.js"></script> <link href="{% static 'css/bootstrap-tokenfield.css' %}" rel="stylesheet">
<script src="/static/js/sapphire.js"> var s=Sapphire(); Konami(s.activate); </script> <link href="{% static 'css/font-awesome.min.css' %}" rel="stylesheet">
<script src="/static/js/bootstrap-tokenfield/bootstrap-tokenfield.js"></script> <link href="{% static 'css/base.css' %}" rel="stylesheet">
<script src="/static/js/shortcuts.js"></script>
<link rel="stylesheet" href="{% static 'css/base.css' %}">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/svg" href="{% static 'images/logo_re2o.svg' %}"> <link rel="shortcut icon" type="image/svg" href="{% static 'images/logo_re2o.svg' %}">
<title>{{ name_website }} : {% block title %}{% trans "Home" %}{% endblock %}</title> <title>{{ name_website }} : {% block title %}{% trans "Home" %}{% endblock %}</title>
</head> </head>
<body> <body id="main">
<div id="wrap"> <nav class="navbar navbar-inverse navbar-static-top">
<nav class="navbar navbar-inverse">
<div class="container-fluid"> <div class="container-fluid">
<div class="navbar-header"> <div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
@ -88,7 +81,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<li><a href="{% url 'machines:index' %}"><i class="fa fa-desktop"></i> {% trans "Manage the machines" %}</a></li> <li><a href="{% url 'machines:index' %}"><i class="fa fa-desktop"></i> {% trans "Manage the machines" %}</a></li>
{% acl_end %} {% acl_end %}
{% can_view_app cotisations %} {% can_view_app cotisations %}
<li><a href="{% url 'cotisations:index' %}"><i class="fa fa-dollar-sign"></i> {% trans "Manage the subscriptions" %}</a></li> <li><a href="{% url 'cotisations:index' %}"><i class="fa fa-eur"></i> {% trans "Manage the subscriptions" %}</a></li>
{% acl_end %} {% acl_end %}
</ul> </ul>
</li> </li>
@ -104,7 +97,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</li> </li>
{% acl_end %} {% acl_end %}
{% can_view_app logs %} {% can_view_app logs %}
<li><a href="{% url "logs:index" %}"><i class="fa fa-chart-area"></i> {% trans "Statistics" %}</a></li> <li><a href="{% url "logs:index" %}"><i class="fa fa-area-chart"></i> {% trans "Statistics" %}</a></li>
{% acl_end %} {% acl_end %}
{% can_view_app preferences %} {% can_view_app preferences %}
<li> <li>
@ -116,10 +109,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fas fa-info"></i> {% trans "More information" %}<span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-info"></i> {% trans "More information" %}<span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="{% url 'about' %}"><i class="fa fa-info-circle"></i> {% trans "About" %}</a></li> <li><a href="{% url 'about' %}"><i class="fa fa-info-circle"></i> {% trans "About" %}</a></li>
<li><a href="{% url 'contact' %}"><i class="fas fa-at"></i> {% trans "Contact" %}</a></li> <li><a href="{% url 'contact' %}"><i class="fa fa-at"></i> {% trans "Contact" %}</a></li>
</ul> </ul>
</li> </li>
{% if not request.user.is_authenticated %} {% if not request.user.is_authenticated %}
@ -132,7 +125,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endif %} {% endif %}
<li> <li>
<a id="toggle_login" href="{% url 'login' %}"> <a id="toggle_login" href="{% url 'login' %}">
<i class="fa fa-sign-in-alt"></i> {% trans "Log in" %} <i class="fa fa-sign-in"></i> {% trans "Log in" %}
</a> </a>
</li> </li>
{% else %} {% else %}
@ -155,7 +148,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-user-circle"></i> {{ request.user.pseudo|slice:":15" }} <span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-user-circle"></i> {{ request.user.pseudo|slice:":15" }} <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="{% url "users:mon-profil" %}"><i class="fa fa-user"></i> {% trans "My profile" %}</a></li> <li><a href="{% url "users:mon-profil" %}"><i class="fa fa-user"></i> {% trans "My profile" %}</a></li>
<li><a id="toggle_login" href="{% url 'logout' %}"><i class="fa fa-sign-out-alt"></i> {% trans "Log out" %}</a></li> <li><a id="toggle_login" href="{% url 'logout' %}"><i class="fa fa-sign-out"></i> {% trans "Log out" %}</a></li>
</ul> </ul>
</li> </li>
{% endif %} {% endif %}
@ -167,9 +160,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</div> </div>
</nav> </nav>
<div id="main" class="container-fluid text-center"> <div class="container-fluid text-center">
<div class="row content"> <div class="row content">
<div class="col-sm-2 sidenav"> <div class="col-sm-2 sidenav pt4">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="text-left list-group"> <div class="text-left list-group">
{% block sidebar %} {% block sidebar %}
@ -177,13 +170,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-8 text-left"> <div class="col-sm-8 text-left pt4">
{# Display django.contrib.messages as Bootstrap alerts #} {# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %} {% bootstrap_messages %}
<hr>
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
<div class="col-sm-2 sidenav"> <div class="col-sm-2 sidenav pt4">
<div class="panel panel-default"> <div class="panel panel-default">
{% if request_user.is_authenticated %} {% if request_user.is_authenticated %}
<div class="panel-heading"> <div class="panel-heading">
@ -250,13 +242,42 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</div> </div>
</div> </div>
</div> </div>
</div>
<footer class="navbar"> <footer class="text-muted">
<div class="containerfluid text-center"> <div class="container">
<p> <a href="\\{{request.get_host}}/about/">Re2o 2016-2018</a> </p> <p class="pull-right">
<a href="#">{% trans "Back to top" %}</a>
</p>
<p>{{ name_website }} {% trans "powered by" %} Re2o 2016&ndash;2018</p>
<p>
{% blocktrans trimmed %}
Brought to you with <i class="fa fa-heart text-danger"></i>.
{% endblocktrans %}
<a href="{{ request.scheme }}://{{ request.get_host }}/about/">{% trans "About this website" %}</a>.
</p>
<p>
{% blocktrans trimmed %}
This software is under the terms of the
<a href="http://www.gnu.org/licenses/gpl-2.0.txt" target="_blank" rel="nofollow">GPLv2</a> License.
{% endblocktrans %}
</p>
</div> </div>
</footer> </footer>
{# Load JavaScript #}
{% bootstrap_javascript %}
<script src="/static/js/typeahead/typeahead.js"></script>
<script src="/static/js/handlebars/handlebars.js"></script>
<script src="/static/js/konami/konami.js"></script>
<script src="/static/js/sapphire.js"></script>
<script>
// Konami activate sapphire
let s = Sapphire();
Konami(s.activate);
</script>
<script src="/static/js/bootstrap-tokenfield/bootstrap-tokenfield.js"></script>
<script src="/static/js/shortcuts.js"></script>
{# Read the documentation for more information #} {# Read the documentation for more information #}
</body> </body>
</html> </html>

View file

@ -26,6 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% trans "Edit" as tr_edit %} {% trans "Edit" as tr_edit %}
<a class="btn btn-primary btn-sm" role="button" title="{{ desc|default:tr_edit }}" href="{% url href id %}"> <a class="btn btn-primary btn-sm" role="button" title="{{ desc|default:tr_edit }}" href="{% url href id %}">
<i class="fa fa-pencil-alt"></i> <i class="fa fa-pencil"></i>
</a> </a>

View file

@ -82,11 +82,11 @@ msgstr "Statistiques"
msgid "Administration" msgid "Administration"
msgstr "Administration" msgstr "Administration"
#: base.html:119 #: base.html:112
msgid "More information" msgid "More information"
msgstr "Plus d'informations" msgstr "Plus d'informations"
#: base.html:121 #: base.html:114
msgid "About" msgid "About"
msgstr "À propos" msgstr "À propos"
@ -162,6 +162,30 @@ msgstr[1] "%(nb)s machines actives"
msgid "View my machines" msgid "View my machines"
msgstr "Voir mes machines" msgstr "Voir mes machines"
#: base.html:257
msgid "Back to top"
msgstr "Retour en haut"
#: base.html:259
msgid "powered by"
msgstr "propulsé par"
#: base.html:261
msgid "Brought to you with <i class=\"fa fa-heart text-danger\"></i>."
msgstr "Codé avec <i class=\"fa fa-heart text-danger\"></i>."
#: base.html:264
msgid "About this website"
msgstr "À propos de ce site"
#: base.html:267
msgid ""
"This software is under the terms of the "
"<a href=\"http://www.gnu.org/licenses/gpl-2.0.txt\" target=\"_blank\" rel=\"nofollow\">GPLv2</a> License."
msgstr ""
"Ce logiciel est sous les termes de la licence "
"<a href=\"http://www.gnu.org/licenses/gpl-2.0.txt\" target=\"_blank\" rel=\"nofollow\">GPLv2</a>."
#: buttons/add.html:27 #: buttons/add.html:27
msgid "Add" msgid "Add"
msgstr "Ajouter" msgstr "Ajouter"

View file

@ -24,33 +24,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load bootstrap3 %} {% load bootstrap3 %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Log in" %}{% endblock %} {% block title %}{% trans "Log in" %}{% endblock %}
{% block content %} {% block content %}
<form method="post" action="{% url 'login' %}">
{% if form.errors %}
<p>{% trans "Your username and password didn't match. Please try again." %}</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>{% trans "Your account doesn't have access to this page. To proceed,
please log in with an account that has access." %}</p>
{% else %}
<p>{% trans "Please log in to see this page." %}</p>
{% endif %}
{% endif %}
<p><form method="post" action="{% url 'login' %}">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form form %} {% bootstrap_form form %}
<button class="btn btn-success" type="submit"><span class="glyphicon glyphicon-log-in"></span> {% trans "Log in" %}</button> <button class="btn btn-success" type="submit"><span
<input type="hidden" name="next" value="{{ next }}" /> class="glyphicon glyphicon-log-in"></span> {% trans "Log in" %}</button>
</form></p> </form>
<p><a class="btn btn-warning btn-sm" role="button" href="{% url 'users:reset-password' %}"> {% trans "Forgotten password?" %}</a></p> <p><a class="btn btn-warning btn-sm" role="button"
href="{% url 'users:reset-password' %}"> {% trans "Forgotten password?" %}</a></p>
{% endblock %} {% endblock %}

View file

@ -55,7 +55,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel-body dashboard"> <div class="panel-body dashboard">
{% can_create Facture %} {% can_create Facture %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:new-facture' users.id %}"> <a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:new-facture' users.id %}">
<i class="fas fa-sign-in-alt"></i> {% trans "Pay for a connection" %} <i class="fa fa-sign-in"></i> {% trans "Pay for a connection" %}
</a> </a>
{% acl_else %} {% acl_else %}
{% trans "Ask for someone with the appropriate rights to pay for a connection." %} {% trans "Ask for someone with the appropriate rights to pay for a connection." %}
@ -68,7 +68,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel-body dashboard"> <div class="panel-body dashboard">
{% can_create Facture %} {% can_create Facture %}
<a class="btn btn-success btn-sm" role="button" href="{% url 'cotisations:new-facture' users.id %}"> <a class="btn btn-success btn-sm" role="button" href="{% url 'cotisations:new-facture' users.id %}">
<i class="fas fa-sign-in-alt"></i> {% trans "Extend the connection period" %} <i class="fa fa-sign-in"></i> {% trans "Extend the connection period" %}
</a> </a>
{% acl_end %} {% acl_end %}
</div> </div>
@ -79,11 +79,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="col-sm-6 col-md-4"> <div class="col-sm-6 col-md-4">
<div class="panel panel-info"> <div class="panel panel-info">
<div class="panel-heading dashboard" data-parent="#accordion" data-toggle="collapse" data-target="#collapse4"> <div class="panel-heading dashboard" data-parent="#accordion" data-toggle="collapse" data-target="#collapse4">
{{ users.solde }} <i class="fas fa-euro-sign"></i> {{ users.solde }} <i class="fa fa-eur"></i>
</div> </div>
<div class="panel-body dashboard"> <div class="panel-body dashboard">
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:credit-solde' users.id %}"> <a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:credit-solde' users.id %}">
<i class="fa fa-euro-sign"></i> {% trans "Refill the balance" %} <i class="fa fa-eur"></i> {% trans "Refill the balance" %}
</a> </a>
</div> </div>
</div> </div>
@ -240,7 +240,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td>{{ users.solde }} € <td>{{ users.solde }} €
{% if user_solde %} {% if user_solde %}
<a class="btn btn-primary btn-sm" style='float:right' role="button" href="{% url 'cotisations:credit-solde' users.pk%}"> <a class="btn btn-primary btn-sm" style='float:right' role="button" href="{% url 'cotisations:credit-solde' users.pk%}">
<i class="fa fa-euro-sign"></i> <i class="fa fa-eur"></i>
{% trans "Refill" %} {% trans "Refill" %}
</a> </a>
{% endif %} {% endif %}
@ -345,7 +345,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading clearfix profil" data-parent="#accordion" data-toggle="collapse" data-target="#collapse4"> <div class="panel-heading clearfix profil" data-parent="#accordion" data-toggle="collapse" data-target="#collapse4">
<h3 class="panel-title pull-left"> <h3 class="panel-title pull-left">
<i class="fa fa-euro-sign"></i> <i class="fa fa-eur"></i>
{% trans "Subscriptions" %} {% trans "Subscriptions" %}
</h3> </h3>
</div> </div>
@ -353,12 +353,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel-body"> <div class="panel-body">
{% can_create Facture %} {% can_create Facture %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:new-facture' users.id %}"> <a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:new-facture' users.id %}">
<i class="fa fa-euro-sign"></i> <i class="fa fa-eur"></i>
{% trans "Add as subscription" %} {% trans "Add as subscription" %}
</a> </a>
{% if user_solde %} {% if user_solde %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:credit-solde' users.id %}"> <a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:credit-solde' users.id %}">
<i class="fa fa-euro-sign"></i> <i class="fa fa-eur"></i>
{% trans "Edit the balance" %} {% trans "Edit the balance" %}
</a> </a>
{% endif%} {% endif%}
@ -433,7 +433,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel-body"> <div class="panel-body">
{% can_edit users %} {% can_edit users %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-email-settings' users.id %}"> <a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-email-settings' users.id %}">
<i class="fa fa-pencil-alt"></i>{% trans " Edit email settings" %} <i class="fa fa-pencil"></i>{% trans " Edit email settings" %}
</a> </a>
{% acl_end %} {% acl_end %}
</div> </div>