forked from devs/PCv5
Merge branch 'master-fork'
This commit is contained in:
commit
183fb2d541
|
@ -6,7 +6,7 @@ from flask_wtf.file import FileField # Cuz' wtforms' FileField is shitty
|
|||
import app.utils.validators as vd
|
||||
|
||||
class RegistrationForm(FlaskForm):
|
||||
username = StringField('Pseudonyme', validators=[DataRequired(), vd.name])
|
||||
username = StringField('Pseudonyme', validators=[DataRequired(), vd.name_valid, vd.name_available])
|
||||
email = StringField('Adresse Email', validators=[DataRequired(), Email(), vd.email])
|
||||
password = PasswordField('Mot de passe', validators=[DataRequired(), vd.password])
|
||||
password2 = PasswordField('Répéter le mot de passe', validators=[DataRequired(), EqualTo('password')])
|
||||
|
@ -16,8 +16,8 @@ class RegistrationForm(FlaskForm):
|
|||
|
||||
class UpdateAccountForm(FlaskForm):
|
||||
avatar = FileField('Avatar', validators=[Optional(), vd.avatar])
|
||||
email = StringField('Adresse Email', validators=[Optional(), Email(), vd.email, vd.old_password])
|
||||
password = PasswordField('Mot de passe :', validators=[Optional(), vd.password, vd.old_password])
|
||||
email = StringField('Adresse email', validators=[Optional(), Email(), vd.email, vd.old_password])
|
||||
password = PasswordField('Mot de passe', validators=[Optional(), vd.password, vd.old_password])
|
||||
password2 = PasswordField('Répéter le mot de passe', validators=[Optional(), EqualTo('password')])
|
||||
old_password = PasswordField('Mot de passe actuel', validators=[Optional()])
|
||||
birthday = DateField('Anniversaire', validators=[Optional()])
|
||||
|
@ -33,10 +33,10 @@ class DeleteAccountForm(FlaskForm):
|
|||
|
||||
|
||||
class AdminUpdateAccountForm(FlaskForm):
|
||||
username = StringField('Pseudonyme', validators=[DataRequired(), vd.name])
|
||||
username = StringField('Pseudonyme', validators=[Optional(), vd.name_valid])
|
||||
avatar = FileField('Avatar', validators=[Optional(), vd.avatar])
|
||||
email = StringField('Adresse Email', validators=[Optional(), Email(), vd.email])
|
||||
password = PasswordField('Mot de passe :', validators=[Optional(), vd.password])
|
||||
email = StringField('Adresse email', validators=[Optional(), Email(), vd.email])
|
||||
password = PasswordField('Mot de passe', validators=[Optional(), vd.password])
|
||||
xp = DecimalField('XP', validators=[Optional()])
|
||||
innovation = DecimalField('Innovation', validators=[Optional()])
|
||||
birthday = DateField('Anniversaire', validators=[Optional()])
|
||||
|
@ -47,4 +47,4 @@ class AdminUpdateAccountForm(FlaskForm):
|
|||
|
||||
class AdminDeleteAccountForm(FlaskForm):
|
||||
delete = BooleanField('Confirmer la suppression', validators=[DataRequired()], description='Attention, cette opération est irréversible !')
|
||||
submit = SubmitField('Supprimer le compte')
|
||||
submit = SubmitField('Supprimer le compte')
|
||||
|
|
|
@ -3,7 +3,7 @@ from wtforms import StringField, PasswordField, BooleanField, SubmitField
|
|||
from wtforms.validators import DataRequired
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
username = StringField('Pseudonyme :', validators=[DataRequired()])
|
||||
password = PasswordField('Mot de passe :', validators=[DataRequired()])
|
||||
remember_me = BooleanField('Se souvenir de moi :')
|
||||
submit = SubmitField('Connexion')
|
||||
username = StringField('Identifiant', validators=[DataRequired()])
|
||||
password = PasswordField('Mot de passe', validators=[DataRequired()])
|
||||
remember_me = BooleanField('Se souvenir de moi')
|
||||
submit = SubmitField('Connexion')
|
||||
|
|
|
@ -73,21 +73,26 @@ def adm_groups():
|
|||
|
||||
users = Member.query.all()
|
||||
groups = Group.query.all()
|
||||
|
||||
return render('admin/groups_privileges.html', users=users, groups=groups,
|
||||
form=form)
|
||||
|
||||
@app.route('/admin/edit-account/<user_id>', methods=['GET', 'POST'])
|
||||
@priv_required('edit-account')
|
||||
def adm_edit_account(user_id):
|
||||
user = Member.query.filter_by(id=user_id).first()
|
||||
if not user:
|
||||
abort(404)
|
||||
user = Member.query.filter_by(id=user_id).first_or_404()
|
||||
|
||||
form = AdminUpdateAccountForm()
|
||||
if request.method == "POST":
|
||||
if form.validate_on_submit():
|
||||
if form.avatar.data:
|
||||
f = form.avatar.data
|
||||
f.save("./app/static/"+user.avatar)
|
||||
|
||||
newname = form.username.data
|
||||
names = list(Member.query.filter(Member.id != user.id).values(Member.name))
|
||||
if newname in names:
|
||||
raise Exception(f'{data["name"]} is not available')
|
||||
user.update(
|
||||
name = form.username.data or None,
|
||||
email = form.email.data or None,
|
||||
|
|
|
@ -24,6 +24,5 @@ section h2 {
|
|||
|
||||
section .avatar {
|
||||
display: block;
|
||||
border-radius: 100%;
|
||||
width: 150px; height: 150px;
|
||||
width: 128px; height: 128px;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
.form .avatar {
|
||||
display: inline-block; vertical-align: middle;
|
||||
border-radius: 100%;
|
||||
width: 150px; height: 150px;
|
||||
width: 128px; height: 128px;
|
||||
}
|
||||
|
||||
.form .avatar + input[type="file"] {
|
||||
display: inline-block; margin-left: 20px;
|
||||
margin: 16px 0 0 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
@ -26,17 +24,28 @@
|
|||
.form input[type='email'],
|
||||
.form input[type='date'],
|
||||
.form input[type='password'],
|
||||
.form input[type='search'],
|
||||
.form textarea {
|
||||
display: block;
|
||||
width: 100%; padding: 6px 2.5%;
|
||||
border: 1px solid #abcdef;
|
||||
width: 100%; padding: 6px 8px;
|
||||
border: 1px solid #c8c8c8;
|
||||
|
||||
/* Transitions when resizing with the mouse produces apparent lag */
|
||||
transition: all .15s ease, width 0s, height 0s;
|
||||
}
|
||||
.form input[type='text']:focus,
|
||||
.form input[type='email']:focus,
|
||||
.form input[type='date']:focus,
|
||||
.form input[type='password']:focus,
|
||||
.form input[type='search']:focus,
|
||||
.form textarea:focus {
|
||||
box-shadow: 0 0 4px rgba(0, 102, 255, .9);
|
||||
border-color: #91bfef;
|
||||
box-shadow: 0 0 0 3px rgba(87, 143, 228, 0.4);
|
||||
}
|
||||
|
||||
.form textarea {
|
||||
max-width: 100%;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.form input[type="submit"] {
|
||||
|
@ -47,4 +56,4 @@
|
|||
color: red;
|
||||
font-weight: 400;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* Fonts */
|
||||
|
||||
@font-face { font-family: NotoSans; src: url(../fonts/noto_sans.ttf); }
|
||||
@font-face { font-family: Raleway; font-weight: 200; src: url(../fonts/raleway_200.ttf); }
|
||||
@font-face { font-family: Raleway; font-weight: 300; src: url(../fonts/raleway_300.ttf); }
|
||||
@font-face { font-family: Cantarell; font-weight: normal; src: url(../fonts/Cantarell-Regular.otf); }
|
||||
@font-face { font-family: Cantarell; font-weight: bold; src: url(../fonts/Cantarell-Bold.otf); }
|
||||
|
||||
|
@ -10,6 +8,8 @@
|
|||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
/* This transition value is replicated everywhere transitions are customized,
|
||||
make sure to track them when editing */
|
||||
transition: .15s ease;
|
||||
}
|
||||
|
||||
|
@ -32,11 +32,11 @@ a:focus {
|
|||
outline: none;
|
||||
}
|
||||
|
||||
p {
|
||||
section p {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
ul {
|
||||
section ul {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,6 @@ input[type="submit"] {
|
|||
padding: 6px 10px; border-radius: 2px;
|
||||
cursor: pointer;
|
||||
font-family: 'DejaVu Sans', sans-serif; font-weight: 400;
|
||||
cursor: pointer;
|
||||
}
|
||||
input[type="button"]:hover,
|
||||
input[type="submit"]:hover,
|
||||
|
|
|
@ -8,14 +8,24 @@ header {
|
|||
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
flex-flow: row wrap;
|
||||
|
||||
/* When the search field occupies the rightmost position, the calculated
|
||||
position of the svg icon (on the right) might overflow from the header and
|
||||
induce horizontal scrolling. */
|
||||
overflow: hidden;
|
||||
}
|
||||
@media screen and (max-width: 1000px) {
|
||||
header {
|
||||
height: 75px;
|
||||
}
|
||||
header .title {
|
||||
page-break-after: always;
|
||||
}
|
||||
@media screen and (max-width: 1199px) {
|
||||
#spotlight {
|
||||
display: none;
|
||||
}
|
||||
header input[type="search"] {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 849px) {
|
||||
header .form {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
header .title a {
|
||||
|
@ -46,30 +56,25 @@ header a {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
header form {
|
||||
header .form {
|
||||
/* The search icon is draws inside the input field but its space is allocated
|
||||
on the right. Apply a negative margin to compensate this:
|
||||
-24px for the search icon
|
||||
-2px for the spacing between the search icon and the field */
|
||||
margin-right: -26px;
|
||||
}
|
||||
header input[type="search"] {
|
||||
header .form input[type="search"] {
|
||||
display: inline-block; width: 250px;
|
||||
padding: 5px 35px 5px 10px;
|
||||
border: 0; border-radius: 1px;
|
||||
font-family: "Segoe UI", Helvetica, "Droid Sans", Arial,sans-serif;
|
||||
box-shadow: 0 0 1px rgba(0, 0, 0, .4); transition: .15s ease;
|
||||
border-color: #d8d8d8;
|
||||
}
|
||||
header input[type="search"] ~ a {
|
||||
header .form input[type="search"] ~ a {
|
||||
position: relative; left: -33px;
|
||||
}
|
||||
header input[type="search"]:focus {
|
||||
box-shadow: 0 0 4px rgba(0, 102, 255, .9);
|
||||
}
|
||||
header input[type="search"] ~ a > svg > path {
|
||||
header .form input[type="search"] ~ a > svg > path {
|
||||
fill: #cccccc; transition: .15s ease;
|
||||
}
|
||||
header input[type="search"]:focus ~ a > svg > path {
|
||||
header .form input[type="search"]:focus ~ a > svg > path {
|
||||
fill: #333333;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
#menu {
|
||||
width: 100%; height: 0; overflow-x: hidden;
|
||||
font-family: NotoSans; font-size: 12px;
|
||||
background: #22292c; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
||||
transition: .1s ease;
|
||||
position: unset;
|
||||
left: unset;
|
||||
|
@ -81,35 +80,15 @@
|
|||
width: 100%;
|
||||
}
|
||||
#menu h2 {
|
||||
margin: 10px 0 10px 40px;
|
||||
font-family: Raleway; font-size: 15px;
|
||||
color: #ffffff;
|
||||
font-size: 15px;
|
||||
}
|
||||
#menu h2 > svg {
|
||||
width: 30px; vertical-align: middle;
|
||||
}
|
||||
#menu h2 > img {
|
||||
width: 64px; margin-right: 10px;
|
||||
vertical-align: middle; border-radius: 50%;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
#menu h3 {
|
||||
margin: 10px 0 10px 40px;
|
||||
font-family: Raleway; font-size: 13px;
|
||||
color: #ffffff;
|
||||
}
|
||||
#menu hr {
|
||||
margin: 10px 15px 0 15px;
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .15);
|
||||
}
|
||||
|
||||
#menu > div > a,
|
||||
#menu span {
|
||||
display: block; margin: 10px 15px;
|
||||
}
|
||||
#menu span {
|
||||
/*font-style: italic;*/ color: #b8b8b8;
|
||||
display: block;
|
||||
color: #b8b8b8;
|
||||
font-size: 10px;
|
||||
}
|
||||
#menu span > a {
|
||||
|
@ -117,24 +96,17 @@
|
|||
margin: 0; font-style: normal;
|
||||
font-size: 12px;
|
||||
}
|
||||
#menu a > img {
|
||||
vertical-align: middle;
|
||||
margin-right: 15px;
|
||||
}
|
||||
#menu a > svg {
|
||||
width: 20px; height: 20px; vertical-align: middle;
|
||||
margin-right: 10px;
|
||||
}
|
||||
#menu ul {
|
||||
list-style: none;
|
||||
margin: 10px 15px; padding: 0;
|
||||
margin: 10px 0; padding: 0;
|
||||
line-height: 20px;
|
||||
color: #b8b8b8;
|
||||
}
|
||||
#menu li {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
@media all and (max-width: 550px) {
|
||||
@media all and (max-width: 549px) {
|
||||
#light-menu, #spacer-menu {
|
||||
height: 40px;
|
||||
}
|
||||
|
@ -188,7 +160,8 @@ header {
|
|||
}
|
||||
|
||||
section {
|
||||
margin: 10px;
|
||||
width: unset;
|
||||
margin: 16px;
|
||||
}
|
||||
.home-title {
|
||||
padding: 10px;
|
||||
|
|
|
@ -94,8 +94,7 @@ nav a:focus {
|
|||
left: -240px; width: 300px; /* left-to-right animation */
|
||||
/*left: 60px; width: 0;*/ /* scroll animation */
|
||||
height: 100%; overflow-x: hidden; overflow-y: auto;
|
||||
font-family: NotoSans; font-size: 14px;
|
||||
background: #22292c; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
||||
background: #1c2124; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
||||
transition: .15s ease;
|
||||
}
|
||||
|
||||
|
@ -121,6 +120,7 @@ nav a:focus {
|
|||
|
||||
#menu > div {
|
||||
width: 300px;
|
||||
padding: 16px;
|
||||
display: none;
|
||||
}
|
||||
#menu > div.opened {
|
||||
|
@ -128,22 +128,20 @@ nav a:focus {
|
|||
}
|
||||
|
||||
#menu h2 {
|
||||
margin: 5% 0 20px 40px;
|
||||
font-family: Raleway; font-size: 18px;
|
||||
margin: 0 0 20px 0;
|
||||
font-family: Cantarell; font-weight: bold; font-size: 18px;
|
||||
color: #ffffff;
|
||||
display: flex; align-items: center;
|
||||
}
|
||||
#menu h2 a {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
font-size: inherit; opacity: inherit;
|
||||
}
|
||||
#menu h2 > svg {
|
||||
width: 42px; vertical-align: middle;
|
||||
width: 32px; vertical-align: middle; margin-right: 8px;
|
||||
}
|
||||
#menu h2 img {
|
||||
width: 64px; border-radius: 50%; vertical-align: middle; margin-right: 10px;
|
||||
height: 48px; vertical-align: middle; margin-right: 10px;
|
||||
}
|
||||
#menu h2 a:hover,
|
||||
#menu h2 a:focus {
|
||||
|
@ -151,14 +149,14 @@ nav a:focus {
|
|||
}
|
||||
|
||||
#menu h3 {
|
||||
margin: 20px 0 20px 40px;
|
||||
font-family: Raleway; font-size: 14px;
|
||||
margin: 16px 0;
|
||||
font-family: Cantarell; font-weight: bold; font-size: 15px;
|
||||
color: #ffffff;
|
||||
}
|
||||
#menu hr {
|
||||
margin: 15px;
|
||||
margin: 15px 0;
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .15);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
#menu ul {
|
||||
|
@ -166,7 +164,7 @@ nav a:focus {
|
|||
}
|
||||
#menu a,
|
||||
#menu li {
|
||||
display: block; margin: 10px 15px;
|
||||
display: block; margin: 10px 0;
|
||||
transition: opacity .15s ease;
|
||||
}
|
||||
#menu li {
|
||||
|
@ -175,6 +173,7 @@ nav a:focus {
|
|||
#menu li > a {
|
||||
display: inline;
|
||||
margin: 0; font-style: normal;
|
||||
font-size: 13px;
|
||||
}
|
||||
#menu a > img {
|
||||
vertical-align: middle;
|
||||
|
@ -186,32 +185,23 @@ nav a:focus {
|
|||
}
|
||||
|
||||
#menu form {
|
||||
padding: 0 5%;
|
||||
padding: 0 8%;
|
||||
}
|
||||
#menu form input[type="text"],
|
||||
#menu form input[type="password"] {
|
||||
display: block; width: 100%;
|
||||
margin: 0; padding: 5px 2%;
|
||||
margin: 3px 0 8px 0; padding: 5px 2%;
|
||||
font-size: 14px; color: inherit;
|
||||
background: #e8e8e8; transition: background .15s ease;
|
||||
border: none;
|
||||
border-color: #141719;
|
||||
}
|
||||
#menu form input[type="text"]:focus,
|
||||
#menu form input[type="password"]:focus {
|
||||
background: #ffffff;
|
||||
}
|
||||
#menu form input[type="text"] {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
#menu form input[type="password"] {
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
box-shadow: 0 0 0 3px rgba(87, 143, 228, 0.6);
|
||||
border-color: #2d4b5f;
|
||||
}
|
||||
#menu form input[type="submit"] {
|
||||
width: 100%;
|
||||
margin-top: 10px; margin-bottom: 5px;
|
||||
border-radius: 5px;
|
||||
margin: 16px 0 5px 0;
|
||||
}
|
||||
#menu form label {
|
||||
font-size: 13px; color: #FFFFFF; opacity: .7;
|
||||
|
|
|
@ -1,28 +1,20 @@
|
|||
/*
|
||||
Responsives rules
|
||||
*/
|
||||
|
||||
@media all and (max-width: 1399px) {
|
||||
body {
|
||||
body, input {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/*header form {
|
||||
border-bottom: 1px solid #adb0b4;
|
||||
}*/
|
||||
header input[type="search"] {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#menu li {
|
||||
font-size: 10px;
|
||||
font-size: 10px;
|
||||
}
|
||||
#menu a {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media all and (min-width: 1400px) {
|
||||
body, input {
|
||||
font-size: 13px;
|
||||
|
@ -35,18 +27,19 @@
|
|||
#menu li {
|
||||
font-size: 11px;
|
||||
}
|
||||
#menu a {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 1100px) {
|
||||
@media screen and (max-width: 1199px) {
|
||||
.home-pinned-content article:nth-child(5) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
section {
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
|
||||
@media screen and (max-width: 849px) {
|
||||
.home-pinned-content article:nth-child(4) {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ table th {
|
|||
border-color: #d0d0d0;
|
||||
border-style: solid;
|
||||
border-width: 1px 0;
|
||||
padding: 2px;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
table td {
|
||||
padding: 4px 6px;
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,9 +1,11 @@
|
|||
{% extends "base/base.html" %}
|
||||
|
||||
{% block title %}
|
||||
<h1>Gestion du compte</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="form">
|
||||
<h1>Gestion du compte</h1>
|
||||
|
||||
<form action="{{ url_for('edit_account') }}" method="post" enctype="multipart/form-data">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<footer>
|
||||
<p>Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.</p>
|
||||
<p>Planète Casio est un site communautaire non affilié à CASIO. Toute reproduction de Planète Casio, même partielle, est interdite.</p>
|
||||
<p>Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou des copyrights.</p>
|
||||
<p>CASIO est une marque déposée par CASIO Computer Co., Ltd.</p>
|
||||
</footer>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class=spacer></div>
|
||||
<form action={{url_for('search')}} method="get">
|
||||
<form action={{url_for('search')}} method="get" class=form>
|
||||
<input type="search" name="q" id="q" placeholder="{{search_form.label}}" />
|
||||
<a role=button onclick="this.parentNode.submit();" href=#>
|
||||
<svg viewBox="0 0 24 24">
|
||||
|
@ -8,16 +8,6 @@
|
|||
</a>
|
||||
</form>
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class=links>
|
||||
<a href="{{ url_for('user', username=current_user.name) }}" role=button title='Mon compte'>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="spotlight">
|
||||
<a href="#" class="button bg-red">Jeu du mois : février 2019</a>
|
||||
</div>
|
||||
|
|
|
@ -2,33 +2,29 @@
|
|||
<div>
|
||||
<h2>
|
||||
<a href="{{ url_for('user', username=current_user.name) }}">
|
||||
<img src="{{ url_for('static', filename=current_user.avatar) }}">
|
||||
<div>{{ current_user.name }}</div>
|
||||
</a>
|
||||
<img src="{{ url_for('static', filename=current_user.avatar) }}"></a>
|
||||
<a href="{{ url_for('user', username=current_user.name) }}">
|
||||
{{ current_user.name }}</a>
|
||||
</h2>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M20,2A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H6L2,22V4C2,2.89 2.9,2 4,2H20M4,4V17.17L5.17,16H20V4H4M6,7H18V9H6V7M6,11H15V13H6V11Z"></path>
|
||||
</svg>
|
||||
Notifications
|
||||
</svg>Notifications
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M2,2V11C2,12 3,13 4,13H6.2C6.6,15 7.9,16.7 11,17V19.1C8.8,19.3 8,20.4 8,21.7V22H16V21.7C16,20.4 15.2,19.3 13,19.1V17C16.1,16.7 17.4,15 17.8,13H20C21,13 22,12 22,11V2H18C17.1,2 16,3 16,4H8C8,3 6.9,2 6,2H2M4,4H6V6L6,11H4V4M18,4H20V11H18V6L18,4M8,6H16V11.5C16,13.43 15.42,15 12,15C8.59,15 8,13.43 8,11.5V6Z"></path>
|
||||
</svg>
|
||||
Trophées
|
||||
</svg>Trophées
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M12,15.39L8.24,17.66L9.23,13.38L5.91,10.5L10.29,10.13L12,6.09L13.71,10.13L18.09,10.5L14.77,13.38L15.76,17.66M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z"></path>
|
||||
</svg>
|
||||
Topics favoris
|
||||
</svg>Topics favoris
|
||||
</a>
|
||||
<a href="{{ url_for('adm') }}">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M3,1H19A1,1 0 0,1 20,2V6A1,1 0 0,1 19,7H3A1,1 0 0,1 2,6V2A1,1 0 0,1 3,1M3,9H19A1,1 0 0,1 20,10V10.67L17.5,9.56L11,12.44V15H3A1,1 0 0,1 2,14V10A1,1 0 0,1 3,9M3,17H11C11.06,19.25 12,21.4 13.46,23H3A1,1 0 0,1 2,22V18A1,1 0 0,1 3,17M8,5H9V3H8V5M8,13H9V11H8V13M8,21H9V19H8V21M4,3V5H6V3H4M4,11V13H6V11H4M4,19V21H6V19H4M17.5,12L22,14V17C22,19.78 20.08,22.37 17.5,23C14.92,22.37 13,19.78 13,17V14L17.5,12M17.5,13.94L15,15.06V17.72C15,19.26 16.07,20.7 17.5,21.06V13.94Z"></path>
|
||||
</svg>
|
||||
Panel d'administration
|
||||
</svg>Panel d'administration
|
||||
</a>
|
||||
|
||||
<hr />
|
||||
|
@ -36,24 +32,22 @@
|
|||
<a href="{{ url_for('edit_account') }}">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"></path>
|
||||
</svg>
|
||||
Paramètres
|
||||
</svg>Paramètres
|
||||
</a>
|
||||
<a href="{{ url_for('logout') }}">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M17,17.25V14H10V10H17V6.75L22.25,12L17,17.25M13,2A2,2 0 0,1 15,4V8H13V4H4V20H13V16H15V20A2,2 0 0,1 13,22H4A2,2 0 0,1 2,20V4A2,2 0 0,1 4,2H13Z"></path>
|
||||
</svg>
|
||||
Déconnexion
|
||||
</svg>Déconnexion
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div>
|
||||
<h2>
|
||||
Invité
|
||||
</h2>
|
||||
<form method="post" action="{{url_for('login')}}" class="login">
|
||||
<h2>Invité</h2>
|
||||
<form method="post" action="{{url_for('login')}}" class="login form">
|
||||
{{ login_form.hidden_tag() }}
|
||||
{{ login_form.username.label }}
|
||||
{{ login_form.username(size=32, placeholder="Identifiant") }}
|
||||
{{ login_form.password.label }}
|
||||
{{ login_form.password(size=32, placeholder="Mot de passe") }}
|
||||
{{ login_form.submit(class_="bg-green") }}
|
||||
{{ login_form.remember_me.label }} {{ login_form.remember_me() }}
|
||||
|
|
|
@ -2,32 +2,27 @@
|
|||
<h2>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M8,3A2,2 0 0,0 6,5V9A2,2 0 0,1 4,11H3V13H4A2,2 0 0,1 6,15V19A2,2 0 0,0 8,21H10V19H8V14A2,2 0 0,0 6,12A2,2 0 0,0 8,10V5H10V3M16,3A2,2 0 0,1 18,5V9A2,2 0 0,0 20,11H21V13H20A2,2 0 0,0 18,15V19A2,2 0 0,1 16,21H14V19H16V14A2,2 0 0,1 18,12A2,2 0 0,1 16,10V5H14V3H16Z"></path>
|
||||
</svg>
|
||||
Programmes
|
||||
</svg>Programmes
|
||||
</h2>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M7,6H17A6,6 0 0,1 23,12A6,6 0 0,1 17,18C15.22,18 13.63,17.23 12.53,16H11.47C10.37,17.23 8.78,18 7,18A6,6 0 0,1 1,12A6,6 0 0,1 7,6M6,9V11H4V13H6V15H8V13H10V11H8V9H6M15.5,12A1.5,1.5 0 0,0 14,13.5A1.5,1.5 0 0,0 15.5,15A1.5,1.5 0 0,0 17,13.5A1.5,1.5 0 0,0 15.5,12M18.5,9A1.5,1.5 0 0,0 17,10.5A1.5,1.5 0 0,0 18.5,12A1.5,1.5 0 0,0 20,10.5A1.5,1.5 0 0,0 18.5,9Z"></path>
|
||||
</svg>
|
||||
Jeux
|
||||
</svg>Jeux
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M19,19H5V8H19M19,3H18V1H16V3H8V1H6V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M16.53,11.06L15.47,10L10.59,14.88L8.47,12.76L7.41,13.82L10.59,17L16.53,11.06Z"></path>
|
||||
</svg>
|
||||
Utilitaires
|
||||
</svg>Utilitaires
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M21,16H3V4H21M21,2H3C1.89,2 1,2.89 1,4V16A2,2 0 0,0 3,18H10V20H8V22H16V20H14V18H21A2,2 0 0,0 23,16V4C23,2.89 22.1,2 21,2Z"></path>
|
||||
</svg>
|
||||
Logiciels
|
||||
</svg>Logiciels
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M12,15.39L8.24,17.66L9.23,13.38L5.91,10.5L10.29,10.13L12,6.09L13.71,10.13L18.09,10.5L14.77,13.38L15.76,17.66M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z"></path>
|
||||
</svg>
|
||||
Top 20
|
||||
</svg>Top 20
|
||||
</a>
|
||||
|
||||
<hr />
|
||||
|
@ -35,8 +30,7 @@
|
|||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" />
|
||||
</svg>
|
||||
Recherche avancée
|
||||
</svg>Recherche avancée
|
||||
</a>
|
||||
|
||||
<hr />
|
||||
|
@ -45,15 +39,11 @@
|
|||
<ul>
|
||||
<li><a href="#"><img src="{{ url_for('static', filename = 'images/fruit_ninja.gif') }}">Fruit Ninja</a></li>
|
||||
<li><a href="#"><img src="{{ url_for('static', filename = 'images/clonelab.gif') }}">Clonelab</a></li>
|
||||
<li><a href="#"><img src="{{ url_for('static', filename = 'images/gravity_duck.png') }}">Gravity Duck</a></li>
|
||||
<li><a href="#"><img src="{{ url_for('static', filename = 'images/calcraft.gif') }}">Calcraft</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
<h3>Coup de cœur</h3>
|
||||
<ul>
|
||||
<li><a href="#"><img src="{{ url_for('static', filename = 'images/fruit_ninja.gif') }}">Fruit Ninja</a></li>
|
||||
<li><a href="#"><img src="{{ url_for('static', filename = 'images/clonelab.gif') }}">Clonelab</a></li>
|
||||
<li><a href="#"><img src="{{ url_for('static', filename = 'images/gravity_duck.png') }}">Gravity Duck</a></li>
|
||||
<li><a href="#"><img src="{{ url_for('static', filename = 'images/calcraft.gif')}}">Calcraft</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -2,26 +2,22 @@
|
|||
<h2>
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M22.7,19L13.6,9.9C14.5,7.6 14,4.9 12.1,3C10.1,1 7.1,0.6 4.7,1.7L9,6L6,9L1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1C4.8,14 7.5,14.5 9.8,13.6L18.9,22.7C19.3,23.1 19.9,23.1 20.3,22.7L22.6,20.4C23.1,20 23.1,19.3 22.7,19Z"></path>
|
||||
</svg>
|
||||
Outils
|
||||
</svg>Outils
|
||||
</h2>
|
||||
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M2.6,10.59L8.38,4.8L10.07,6.5C9.83,7.35 10.22,8.28 11,8.73V14.27C10.4,14.61 10,15.26 10,16A2,2 0 0,0 12,18A2,2 0 0,0 14,16C14,15.26 13.6,14.61 13,14.27V9.41L15.07,11.5C15,11.65 15,11.82 15,12A2,2 0 0,0 17,14A2,2 0 0,0 19,12A2,2 0 0,0 17,10C16.82,10 16.65,10 16.5,10.07L13.93,7.5C14.19,6.57 13.71,5.55 12.78,5.16C12.35,5 11.9,4.96 11.5,5.07L9.8,3.38L10.59,2.6C11.37,1.81 12.63,1.81 13.41,2.6L21.4,10.59C22.19,11.37 22.19,12.63 21.4,13.41L13.41,21.4C12.63,22.19 11.37,22.19 10.59,21.4L2.6,13.41C1.81,12.63 1.81,11.37 2.6,10.59Z"></path>
|
||||
</svg>
|
||||
Forge GitLab
|
||||
</svg>Forge Gitea
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M14.97,18.95L12.41,12.92C11.39,14.91 10.27,17 9.31,18.95C9.3,18.96 8.84,18.95 8.84,18.95C7.37,15.5 5.85,12.1 4.37,8.68C4.03,7.84 2.83,6.5 2,6.5C2,6.4 2,6.18 2,6.05H7.06V6.5C6.46,6.5 5.44,6.9 5.7,7.55C6.42,9.09 8.94,15.06 9.63,16.58C10.1,15.64 11.43,13.16 12,12.11C11.55,11.23 10.13,7.93 9.71,7.11C9.39,6.57 8.58,6.5 7.96,6.5C7.96,6.35 7.97,6.25 7.96,6.06L12.42,6.07V6.47C11.81,6.5 11.24,6.71 11.5,7.29C12.1,8.53 12.45,9.42 13,10.57C13.17,10.23 14.07,8.38 14.5,7.41C14.76,6.76 14.37,6.5 13.29,6.5C13.3,6.38 13.3,6.17 13.3,6.07C14.69,6.06 16.78,6.06 17.15,6.05V6.47C16.44,6.5 15.71,6.88 15.33,7.46L13.5,11.3C13.68,11.81 15.46,15.76 15.65,16.2L19.5,7.37C19.2,6.65 18.34,6.5 18,6.5C18,6.37 18,6.2 18,6.05L22,6.08V6.1L22,6.5C21.12,6.5 20.57,7 20.25,7.75C19.45,9.54 17,15.24 15.4,18.95C15.4,18.95 14.97,18.95 14.97,18.95Z"></path>
|
||||
</svg>
|
||||
Casio Universal Wiki
|
||||
</svg>Casio Universal Wiki
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path fill="#ffffff" d="M19,8L15,12H18A6,6 0 0,1 12,18C11,18 10.03,17.75 9.2,17.3L7.74,18.76C8.97,19.54 10.43,20 12,20A8,8 0 0,0 20,12H23M6,12A6,6 0 0,1 12,6C13,6 13.97,6.25 14.8,6.7L16.26,5.24C15.03,4.46 13.57,4 12,4A8,8 0 0,0 4,12H1L5,16L9,12"></path>
|
||||
</svg>
|
||||
SH4 Compatibility Tool
|
||||
</svg>SH4 Compatibility Tool
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
{% extends "base/base.html" %}
|
||||
|
||||
{% block title %}
|
||||
<h1>Profil de '{{ user.name }}'</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<h1>
|
||||
<div>
|
||||
<img class="avatar" src="{{ url_for('static', filename=user.avatar) }}" alt="{{ user.name }}" style="display:inline; vertical-align:middle;"/>
|
||||
Profil de {{ user.name }}</h1>
|
||||
{{ user.name }}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,10 +2,11 @@ from flask_login import current_user
|
|||
from wtforms.validators import ValidationError
|
||||
from app.models.users import User, Member
|
||||
|
||||
def name(form, name):
|
||||
def name_valid(form, name):
|
||||
if not User.valid_name(name.data):
|
||||
raise ValidationError("Nom d'utilisateur invalide.")
|
||||
# last check: do not ask db if useless
|
||||
|
||||
def name_available(form, name):
|
||||
member = Member.query.filter_by(name=name.data).first()
|
||||
if member is not None:
|
||||
raise ValidationError('Pseudo indisponible.')
|
||||
|
|
Loading…
Reference in New Issue