templates: slightly restructure and improve design

This commit is contained in:
lephe 2019-02-09 11:32:08 +01:00
parent 07a685f3c4
commit 9faabea997
28 changed files with 72 additions and 89 deletions

View File

@ -127,7 +127,7 @@ class Member(User, db.Model):
def priv(self, priv):
"""Check whether the member has the specified privilege."""
if SpecialPrivilege.query.filter_by(mid=self.id, priv=priv):
if SpecialPrivilege.query.filter_by(mid=self.id, priv=priv).first():
return True
return False
# return db.session.query(User, Group, GroupPrivilege).filter(

View File

@ -10,7 +10,7 @@ from app.utils.render import render
from app import app, db
@app.route('/admin', methods=['GET', 'POST'])
@priv_required('panel-admin')
@priv_required('admin-panel')
def admin():
class AdminForm(FlaskForm):
submit = SubmitField('Régénérer groupes, privilèges, membres de test')
@ -38,7 +38,7 @@ def admin():
m = Member.query.filter_by(name=name).first()
if m is not None:
db.session.delete(m)
db.session.commit()
db.session.commit()
# Create template members
m = Member('PlanèteCasio','contact@planet-casio.com','v5-forever')

View File

@ -9,9 +9,9 @@ section {
section h1 {
margin-top: 0;
border-bottom: 1px solid #a0a0a0;
font-family: Raleway; font-size: 32px;
font-weight: 300; color: #242424;
border-bottom: 1px solid #d8d8d8;
font-family: Cantarell; font-weight: bold;
font-size: 26px; color: #101010;
}
section h2 {

View File

@ -6,8 +6,6 @@
@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); }
/*
ALL
*/

View File

@ -3,7 +3,7 @@
*/
header {
height: 50px; margin: 0; padding: 0 30px;
height: 50px; margin: 0; padding: 0 16px;
display: flex; align-items: center; justify-content: space-between;
background: #f4f4f6; border-bottom: 1px solid #d0d0d0;
}
@ -14,6 +14,10 @@ header h1 {
display: inline;
}
header .spacer {
flex: auto 1 0;
}
header svg {
width: 24px; height: 24px; vertical-align: middle;
transition: .15s ease;
@ -22,7 +26,7 @@ header a:hover > svg, header a:focus > svg {
fill: black;
}
header a {
fill: #484848;
fill: #363636;
cursor: pointer;
}

View File

@ -72,7 +72,6 @@ nav a:focus {
align-items: center; flex-grow: 1;
height: 100%;
text-align: center;
font-family: Raleway; font-size: 13px;
color: #ffffff;
}
#light-menu li {
@ -82,6 +81,7 @@ nav a:focus {
display: flex; flex-direction: column;
align-items: center; justify-content: center;
width: 100%; height: 100%;
cursor: pointer;
}
#light-menu li > a > div {
display: none;
@ -363,4 +363,4 @@ footer {
}
footer p {
margin: 3px 0;
}
}

View File

@ -1,6 +1,6 @@
nav a {
color: #ffffff;
opacity: .7;
opacity: 0.75;
cursor: pointer;
}
nav a:hover,

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section class="form">

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section class="form">

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section class="form">

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block title %}
Panneau d'administration » <h1>Utilisateurs et groupes</h1>

View File

@ -1,11 +1,19 @@
<!DOCTYPE html>
<html lang="fr-FR">
{% include "base/head.html" %}
<body>
{% include "base/navbar.html" %}
{% block container %}
{% endblock container %}
<div class="container">
<header>
<div>{% block title %}(page title){% endblock %}</div>
{% include "base/header.html" %}
</header>
{% block content %}
{% endblock %}
</div>
{% include "base/footer.html" %}
{% include "base/flash.html" %}

View File

@ -1,11 +0,0 @@
{% extends "base/base.html" %}
{% block container %}
<div class="container">
{% include "base/header.html" %}
{% block content %}
{% endblock %}
</div>
{% endblock container %}

View File

@ -1,29 +1,22 @@
<header>
<div>
{% block title %}
Test
{% endblock %}
</div>
<div style="flex: auto 1 0"></div>
<form action={{url_for('search')}} method="get">
<input type="search" name="q" id="q" placeholder="{{search_form.label}}" />
<a role="button" onclick="this.parentNode.submit();" href="#" class="light-hidden">
<svg viewBox="0 0 24 24">
<path fill="#adb0b4"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"></path>
</svg>
</a>
</form>
{% if current_user.is_authenticated %}
<a href="{{ url_for('user', username=current_user.name) }}" role=button title='Mon compte'>
<div class=spacer></div>
<form action={{url_for('search')}} method="get">
<input type="search" name="q" id="q" placeholder="{{search_form.label}}" />
<a role="button" onclick="this.parentNode.submit();" href="#" class="light-hidden">
<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>
<path fill="#adb0b4"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"></path>
</svg>
</a>
</form>
{% if current_user.is_authenticated %}
<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>
{% endif %}
<div id="spotlight">
<a href="#">Concours</a>
<a href="#">Jeu du mois : février 2019</a>
</div>
</header>
<div id="spotlight">
<a href="#">Concours</a>
<a href="#">Jeu du mois : février 2019</a>
</div>

View File

@ -59,7 +59,7 @@
</li>
<li>
<a href="#" label="Outils">
<a role="button" label="Outils" tabindex="0">
<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>

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section class="form">

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section>

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section>

View File

@ -1,4 +1,8 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block title %}
<h1>Planète Casio</h1>
{% endblock %}
{% block content %}
<section class="home-pinned-content">

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section class="form" style="width:40%;">

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section class="form" style="width:40%;">

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section class="form">

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section>

View File

@ -1,4 +1,4 @@
{% extends "base/container.html" %}
{% extends "base/base.html" %}
{% block content %}
<section>

View File

@ -1,17 +0,0 @@
from flask import redirect, url_for, flash
from flask import current_user
import functools
# Use only with @login_required.
def privilege_required(priv):
def privilege_decorator(f):
@functools.wraps(f)
def wrapper():
if not current_user.priv(priv):
flash(f'Cette page est protégée par le privilège <code>{priv}'+
'</code>', 'error')
return redirect(url_for('index'))
else:
f()
return wrapper
return privilege_decorator

View File

@ -6,19 +6,19 @@ from app import app
def priv_required(*perms):
"""
If you decorate a view with this, it will ensure that the current user is
authenticated and has required permissions before calling the actual view.
(If they are not, it calls the :attr:`LoginManager.unauthorized` callback.)
For example::
Requires the user to be an authenticated member with privileges [perms].
Calls :attr:`LoginManager.unauthorized` if the user is not authenticated,
and a 403 if some of the privileges are missing.
Example:
@app.route('/admin')
@priv_required('access-admin-board')
def admin_board():
pass
It can be convenient to globally turn off authentication when unit testing.
To enable this, if the application configuration variable `LOGIN_DISABLED`
is set to `True`, this decorator will be ignored.
Setting the `LOGIN_DISABLED` configuration variable to `True` will silence
this decorator.
"""
def decorated_view(func):
@wraps(func)
@ -32,6 +32,7 @@ def priv_required(*perms):
else:
for p in perms:
if not current_user.priv(p):
# TODO: Add error message and privilege name
abort(403)
return func(*args, **kwargs)
return wrapped

View File

@ -35,4 +35,7 @@ Miscellaenous:
footer-statistics View performance statistics in the page footer
community-login Automatically login as a community account
Administration panel...
Administration panel:
admin-panel Access administration panel (read-only as it is)
edt-account Edit details of any account
delete-account Remove member accounts

View File

@ -6,6 +6,7 @@ class Config(object):
'postgresql+psycopg2://' + os.environ.get('USER') + ':@/pcv5'
SQLALCHEMY_TRACK_MODIFICATIONS = False
UPLOAD_FOLDER = './app/static/avatars'
LOGIN_DISABLED=True
class V5Config(object):
# Length allocated to privilege names (slugs)
@ -14,4 +15,3 @@ class V5Config(object):
FORBIDDEN_USERNAMES = [ "admin", "root", "webmaster", "contact" ]
# Unauthorized message (@priv_required)
UNAUTHORIZED_MSG = "Vous n'avez pas l'autorisation d'effectuer cette action!"