@@ -1,7 +1,8 @@ | |||
from app import app, db | |||
from app.models import User, Post | |||
from app.models.users import User | |||
# from app.models.models import Post | |||
@app.shell_context_processor | |||
def make_shell_context(): | |||
return {'db': db, 'User': User, 'Post': Post} | |||
return {'db': db, 'User': User} |
@@ -1,7 +1,7 @@ | |||
from flask_wtf import FlaskForm | |||
from wtforms import StringField, PasswordField, BooleanField, SubmitField | |||
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo | |||
from app.models import User | |||
from app.models.users import Member | |||
class LoginForm(FlaskForm): | |||
@@ -16,14 +16,21 @@ class RegistrationForm(FlaskForm): | |||
email = StringField('Adresse Email :', validators=[DataRequired(), Email()]) | |||
password = PasswordField('Mot de passe :', validators=[DataRequired()]) | |||
password2 = PasswordField('Répéter le mot de passe', validators=[DataRequired(), EqualTo('password')]) | |||
guidelines = BooleanField('J’accepte les <a href="#">CGU</a>', validators=[DataRequired()]) | |||
newsletter = BooleanField('Inscription à la newsletter', description='Un mail par trimestre environ, pour être prévenu des concours, évènements et nouveautés.') | |||
submit = SubmitField('S\'enregistrer') | |||
def validate_username(self, username): | |||
user = User.query.filter_by(username=username.data).first() | |||
if user is not None: | |||
member = Member.query.filter_by(username=username.data).first() | |||
if member is not None: | |||
raise ValidationError('Pseudo indisponible.') | |||
def validate_email(self, email): | |||
user = User.query.filter_by(email=email.data).first() | |||
if user is not None: | |||
raise ValidationError('Adresse email déjà utilisé.') | |||
member = Member.query.filter_by(email=email.data).first() | |||
if member is not None: | |||
raise ValidationError('Adresse email déjà utilisée.') | |||
def validate_password(self, password): | |||
if len(password.data) < 10: | |||
raise ValidationError('Mot de passe est trop court (10 caractères minimum)') | |||
# TODO: add more rules >:] |
@@ -0,0 +1,19 @@ | |||
from datetime import datetime | |||
from app import db | |||
from app.models.users import * | |||
class Content(db.Model): | |||
__tablename__ = 'content' | |||
id = db.Column(db.Integer, primary_key=True) | |||
type = db.Column(db.String(20)) | |||
__mapper_args__ = { | |||
'polymorphic_identity':__tablename__, | |||
'polymorphic_on': type | |||
} | |||
# Standalone properties | |||
data = db.Column(db.Text(convert_unicode=True)) | |||
date_created = db.Column(db.DateTime, default=datetime.now) | |||
date_modified = db.Column(db.DateTime, default=datetime.now) | |||
# Relationships | |||
author_id = db.Column(db.ForeignKey('user.id')) | |||
author = db.relationship("User", back_populates="contents") |
@@ -0,0 +1,15 @@ | |||
from app import db | |||
class Parent(): | |||
__tablename__ = 'user' | |||
id = db.Column(db.Integer, primary_key=True) | |||
type = db.Column(db.String(20)) | |||
__mapper_args__ = { | |||
'polymorphic_identity': __tablename__, | |||
'polymorphic_on': type | |||
} | |||
class Children(Parent): | |||
__tablename__ = 'member' | |||
id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) | |||
__mapper_args__ = { 'polymorphic_identity': __tablename__ } |
@@ -3,53 +3,54 @@ from flask_login import login_user, logout_user, current_user, login_required | |||
from werkzeug.urls import url_parse | |||
from app import app, db | |||
from app.forms import LoginForm, RegistrationForm | |||
from app.models import User | |||
from app.models.users import Member | |||
@app.route('/', methods=['GET', 'POST']) | |||
def index(): | |||
form = LoginForm() | |||
flash('pseudo ou mot de passe invalide', 'error') | |||
flash('tout ça c\'est ok !', 'ok') | |||
flash('mais ça non', 'error') | |||
if form.validate_on_submit(): | |||
user = User.query.filter_by(username=form.username.data).first() | |||
if user is None or not user.check_password(form.password.data): | |||
flash('pseudo ou mot de passe invalide') | |||
return redirect(url_for('index')) | |||
login_user(user, remember=form.remember_me.data) | |||
return render_template('index.html', form=form) | |||
form = LoginForm() | |||
flash('pseudo ou mot de passe invalide', 'error') | |||
flash('tout ça c\'est ok !', 'ok') | |||
flash('mais ça bof', 'warning') | |||
flash('et une info', 'info') | |||
if form.validate_on_submit(): | |||
flash('test', 'ok') | |||
member = Member.query.filter_by(username=form.username.data).first() | |||
if member is None or not member.check_password(form.password.data): | |||
flash('pseudo ou mot de passe invalide') | |||
return redirect(url_for('index')) | |||
flash('Connexion réussie') | |||
login_user(member, remember=form.remember_me.data) | |||
return render_template('index.html', form=form) | |||
@app.route('/logout/') | |||
def logout(): | |||
logout_user() | |||
return redirect(url_for('index')) | |||
logout_user() | |||
return redirect(url_for('index')) | |||
@app.route('/register', methods=['GET', 'POST']) | |||
def register(): | |||
if current_user.is_authenticated: | |||
return redirect(url_for('index')) | |||
form = LoginForm() | |||
form2 = RegistrationForm() | |||
if form2.validate_on_submit(): | |||
user = User(username=form2.username.data, email=form2.email.data) | |||
user.set_password(form2.password.data) | |||
db.session.add(user) | |||
db.session.commit() | |||
flash('Congratulations, you are now a registered user!') | |||
return redirect(url_for('validation')) | |||
return render_template('register.html', title='Register', form=form, form2 = form2) | |||
if current_user.is_authenticated: | |||
return redirect(url_for('index')) | |||
form = LoginForm() | |||
form2 = RegistrationForm() | |||
if form2.validate_on_submit(): | |||
member = Member(form2.username.data, form2.email.data, form2.password.data) | |||
db.session.add(member) | |||
db.session.commit() | |||
flash('Congratulations, you are now a registered member!') | |||
return redirect(url_for('validation')) | |||
return render_template('register.html', title='Register', form=form, form2 = form2) | |||
@app.route('/register/validation/') | |||
def validation(): | |||
if current_user.is_authenticated : | |||
return redirect(url_for('index')) | |||
form = LoginForm() | |||
return render_template('validation.html', form = form) | |||
if current_user.is_authenticated : | |||
return redirect(url_for('index')) | |||
form = LoginForm() | |||
return render_template('validation.html', form = form) |
@@ -2,6 +2,16 @@ | |||
margin-left: 60px; | |||
} | |||
section { | |||
margin: 10px 5%; | |||
} | |||
section h1 { | |||
border-bottom: 1px solid #a0a0a0; | |||
font-family: Raleway; font-size: 32px; | |||
font-weight: 200; color: #242424; | |||
} | |||
/* #container h1 { | |||
margin-left: 5%; | |||
font-family: Raleway; font-size: 24px; |
@@ -0,0 +1,45 @@ | |||
/* | |||
flash overlay | |||
*/ | |||
.flash { | |||
position: fixed; left: 15%; | |||
display: flex; align-items: center; | |||
width: 70%; z-index: 10; | |||
font-family: NotoSans; font-size: 14px; color: #212121; | |||
background: #ffffff; | |||
border-bottom: 5px solid #4caf50; | |||
border-radius: 1px; box-shadow: 0 1px 12px rgba(0, 0, 0, 0.3); | |||
transition: opacity .15s ease; | |||
transition: top .2s ease; | |||
} | |||
.flash.info { | |||
border-color: #2e7aec; | |||
} | |||
.flash.ok { | |||
border-color: #4caf50; | |||
} | |||
.flash.warning { | |||
border-color: #fbbc26; | |||
} | |||
.flash.error { | |||
border-color: #f44336; | |||
} | |||
.flash span { | |||
flex-grow: 1; margin: 15px 10px 10px 0; | |||
} | |||
.flash input[type="button"] { | |||
margin: 3px 30px 0 0; padding: 10px 15px; | |||
border: none; | |||
background: rgba(0, 0, 0, 0); color: #727272; | |||
} | |||
.flash input[type="button"]:hover { | |||
background: rgba(0, 0, 0, .1); | |||
} | |||
.flash input[type="button"]:focus { | |||
background: rgba(0, 0, 0, .2); | |||
} | |||
.flash svg { | |||
margin: 15px 20px 10px 30px; | |||
} |
@@ -1,5 +1,5 @@ | |||
/* | |||
footer | |||
Footer | |||
*/ | |||
footer { | |||
@@ -10,4 +10,4 @@ footer { | |||
} | |||
footer p { | |||
margin: 3px 0; | |||
} | |||
} |
@@ -7,6 +7,14 @@ | |||
@font-face { font-family: Raleway; font-weight: 300; src: url(../fonts/raleway_300.ttf); } | |||
/* | |||
ALL | |||
*/ | |||
* { | |||
box-sizing: border-box; | |||
transition: .15s ease; | |||
} | |||
/* | |||
body | |||
@@ -19,69 +27,6 @@ body { | |||
} | |||
/* | |||
header | |||
*/ | |||
header { | |||
height: 50px; margin: 0; padding: 0 30px; | |||
display: flex; align-items: center; justify-content: space-between; | |||
background: #f8f8fa; border-bottom: 1px solid #d0d0d0; | |||
} | |||
header h1 { | |||
font-family: Raleway; font-weight: 200; | |||
} | |||
header svg { | |||
width: 24px; height: 24px; vertical-align: middle; | |||
transition: .15s ease; | |||
} | |||
header a:hover > svg, header a:focus > svg { | |||
filter: brightness(.5); | |||
} | |||
header input[type="search"] { | |||
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; | |||
} | |||
header 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 { | |||
fill: #cccccc; transition: .15s ease; | |||
} | |||
header input[type="search"]:focus ~ a > svg > path { | |||
fill: #333333; | |||
} | |||
#spotlight a { | |||
padding: 8px 18px 6px 18px; | |||
color: #727272; font-size: 15px; | |||
border-bottom: 2px solid rgba(93, 123, 141, 0); | |||
transition: border .15s ease; | |||
} | |||
#spotlight a:hover, header #spotlight a:focus { | |||
border-bottom: 2px solid rgba(93, 123, 141, 1); | |||
} | |||
footer { | |||
margin: 20px 10% 5px 10%; padding: 10px 0; | |||
text-align: center; font-size: 11px; font-style: italic; | |||
color: #a0a0a0; | |||
border-top: 1px solid rgba(0, 0, 0, .1); | |||
} | |||
footer p { | |||
margin: 3px 0; | |||
} | |||
/* | |||
links | |||
*/ | |||
@@ -95,75 +40,19 @@ a:focus { | |||
/* | |||
alert overlay | |||
*/ | |||
.alert { | |||
position: fixed; left: 15%; | |||
display: flex; align-items: center; | |||
width: 70%; z-index: 10; | |||
font-family: NotoSans; font-size: 14px; color: #212121; | |||
background: #ffffff; | |||
border-bottom: 5px solid #4caf50; | |||
border-radius: 1px; box-shadow: 0 1px 12px rgba(0, 0, 0, 0.3); | |||
transition: opacity .15s ease; | |||
/* Buttons */ | |||
input[type="button"], | |||
input[type="submit"] { | |||
padding: 6px 0; | |||
border-radius: 3px; | |||
font-size: 14px; | |||
font-weight: 400; | |||
border: 1px solid transparent; | |||
} | |||
.alert.ok { | |||
border-color: #4caf50; | |||
} | |||
.alert.error { | |||
border-color: #f44336; | |||
} | |||
.alert span { | |||
flex-grow: 1; margin: 15px 10px 10px 0; | |||
} | |||
.alert input[type="button"] { | |||
margin: 3px 30px 0 0; | |||
} | |||
.alert svg { | |||
margin: 15px 20px 10px 30px; | |||
} | |||
/* | |||
buttons | |||
*/ | |||
input[type="button"] { | |||
font-family: NotoSans; font-size: 14px; /*font-weight: bold;*/ | |||
text-align: center; | |||
padding: 5px 15px; | |||
transition: .1s ease; | |||
} | |||
/* flat */ | |||
input[type="button"].flat { | |||
border: none; | |||
background: rgba(0, 0, 0, 0); color: #727272; | |||
} | |||
input[type="button"].flat:hover { | |||
background: rgba(0, 0, 0, .1); | |||
} | |||
input[type="button"].flat:focus { | |||
background: rgba(0, 0, 0, .2); | |||
} | |||
/* raised */ | |||
input[type="button"].raised { | |||
border: none; | |||
background: #e0e0e0; color: #212121; | |||
box-shadow: 0 1px 2px rgba(0, 0, 0, .3); | |||
} | |||
input[type="button"].raised:hover, | |||
input[type="button"].raised:focus { | |||
background: #d5d5d5; | |||
} | |||
input[type="button"].raised:active { | |||
background: #d6d6d6; | |||
box-shadow: 0 1px 8px rgba(0, 0, 0, .3); | |||
/* Checkbox */ | |||
input[type="checkbox"] { | |||
vertical-align: middle; | |||
} | |||
/* Input text */ | |||
@@ -180,23 +69,20 @@ input[type="password"]:focus { | |||
} | |||
section { | |||
margin: 10px 5%; | |||
} | |||
section h1 { | |||
border-bottom: 1px solid #a0a0a0; | |||
font-family: Raleway; font-size: 24px; | |||
font-weight: 200; color: #242424; | |||
} | |||
section * { | |||
transition: .15s ease; | |||
} | |||
/* Bootstrap-style rules */ | |||
.flex { | |||
display: flex; | |||
} | |||
.bg-green, | |||
.bg-green { | |||
background-color: #149641; | |||
border-color: #0e692d; | |||
color: #ffffff; | |||
} | |||
.bg-green:hover, | |||
.bg-green:focus, | |||
.bg-green:active { | |||
background-color: #0f7331; | |||
border-color: #073617; | |||
} |
@@ -3,31 +3,29 @@ | |||
*/ | |||
header { | |||
margin: 0; padding: 10px 16px; | |||
display: flex; align-items: center; justify-content: flex-end; | |||
background: #ffffff; border-bottom: 1px solid #e0e0e0; | |||
height: 50px; margin: 0; padding: 0 30px; | |||
display: flex; align-items: center; justify-content: space-between; | |||
background: #f8f8fa; border-bottom: 1px solid #d0d0d0; | |||
} | |||
header h1 { | |||
font-family: Raleway; font-weight: 200; | |||
} | |||
header input + span { position: relative; left: -32px; cursor: pointer; } | |||
header span > svg { | |||
header svg { | |||
width: 24px; height: 24px; vertical-align: middle; | |||
transition: .15s ease; fill: #969696; | |||
transition: .15s ease; | |||
} | |||
header span:hover > svg, header span:focus > svg { | |||
border-color: rgba(32, 128, 255, .6); | |||
fill: #484848; | |||
header a:hover > svg, header a:focus > svg { | |||
filter: brightness(.5); | |||
} | |||
header form { | |||
flex-shrink: 0; margin-right: -23px; | |||
} | |||
header input[type="search"] { | |||
width: 220px; height: 30px; padding: 4px 30px 4px 8px; | |||
border: 1px solid rgba(0, 0, 0, .2); border-radius: 2px; | |||
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; | |||
} | |||
header input[type="search"] ~ a { | |||
position: relative; left: -33px; | |||
@@ -42,54 +40,13 @@ header input[type="search"]:focus ~ a > svg > path { | |||
fill: #333333; | |||
} | |||
#spotlight { | |||
flex-shrink: 0; | |||
} | |||
#spotlight a { | |||
display: inline-block; | |||
height: 24px; line-height: 24px; | |||
padding: 2px 10px; | |||
background: #728bf6; color: white; font-size: 12px; | |||
border-radius: 2px; border: 1px solid rgba(0, 0, 255, .05); | |||
} | |||
#spotlight a:hover { border-bottom: 1px solid rgba(128, 128, 255, .05); | |||
background: #7a93ff; border-color: rgba(128, 128, 255, .03); | |||
} | |||
/* | |||
subheader | |||
*/ | |||
#subheader { | |||
margin: 0; padding: 0 32px; | |||
flex-grow: 1; | |||
} | |||
#subheader * { | |||
margin: 0; padding: 0; | |||
} | |||
#subheader li { | |||
height: 30px; margin: 5px 0; | |||
display: inline; | |||
/*display: flex; align-items: center;*/ | |||
} | |||
#subheader li:after { | |||
content: " »"; | |||
opacity: 0.3; | |||
} | |||
#subheader li:last-child:after { | |||
content: none; | |||
} | |||
#subheader a { | |||
padding: 0 3px; | |||
/*border-bottom: 1px solid rgba(93, 123, 141, 0);*/ | |||
color: #727272; | |||
#spotlight a { | |||
padding: 8px 18px 6px 18px; | |||
color: #727272; font-size: 15px; | |||
border-bottom: 2px solid rgba(93, 123, 141, 0); | |||
transition: border .15s ease; | |||
} | |||
#subheader a:hover, #subheader a:focus { | |||
/*border-bottom: 1px solid rgba(93, 123, 141, 1);*/ | |||
color: #22292c; | |||
text-decoration: none | |||
#spotlight a:hover, header #spotlight a:focus { | |||
border-bottom: 2px solid rgba(93, 123, 141, 1); | |||
} | |||
@@ -183,34 +183,31 @@ nav a:focus { | |||
#menu form div { | |||
padding: 0 5%; | |||
} | |||
#menu form input[type="text"] { | |||
display: block; width: 96%; | |||
#menu form input[type="text"], | |||
#menu form input[type="password"] { | |||
display: block; width: 100%; | |||
margin: 0; padding: 5px 2%; | |||
font-size: 14px; color: inherit; | |||
background: #e8e8e8; transition: background .15s ease; | |||
border: none; | |||
} | |||
#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"]{ | |||
display: block; width: 96%; | |||
margin: 0; padding: 5px 2%; | |||
font-size: 14px; color: inherit; | |||
background: #e8e8e8; transition: background .15s ease; | |||
border: none; border-top: 1px solid #dddddd; | |||
#menu form input[type="password"] { | |||
border-bottom-left-radius: 5px; | |||
border-bottom-right-radius: 5px; | |||
} | |||
#menu form input[type="text"]:focus, | |||
#menu form input[type="password"]:focus { | |||
background: #ffffff; | |||
#menu form input[type="submit"] { | |||
width: 100%; | |||
margin-top: 10px; margin-bottom: 5px; | |||
border-radius: 5px; | |||
} | |||
#menu form label { | |||
font-size: 13px; color: #FFFFFF; opacity: .7; | |||
} | |||
#menu form input[type="checkbox"] { | |||
vertical-align: middle; | |||
} | |||
#menu form input[type="submit"] { | |||
width: 100%; padding: 5px; | |||
} |
@@ -1,50 +1,45 @@ | |||
#form { | |||
#register { | |||
width: 30%; min-width: 350px; | |||
margin: auto; | |||
} | |||
form > div { | |||
#register form > div { | |||
margin-bottom: 15px; | |||
} | |||
form > div > * { | |||
display: block; | |||
} | |||
form > div > label { | |||
#register form > div > label { | |||
display: inline-block; | |||
margin-bottom: 5px; | |||
} | |||
form > div > input[type='text'], | |||
form > div > input[type='email'], | |||
form > div > input[type='password'] { | |||
width: 96%; padding: 6px 2%; | |||
#register form > div > input[type='text'], | |||
#register form > div > input[type='email'], | |||
#register form > div > input[type='password'] { | |||
display: block; | |||
width: 100%; padding: 6px 2.5%; | |||
border: 1px solid #abcdef; | |||
} | |||
form > div > input[type='text']:focus, | |||
form > div > input[type='email']:focus, | |||
form > div > input[type='password']:focus { | |||
box-shadow: 0px 0px 3px 0px #0033ff; | |||
#register form > div > input[type='text']:focus, | |||
#register form > div > input[type='email']:focus, | |||
#register form > div > input[type='password']:focus { | |||
box-shadow: 0 0 4px rgba(0, 102, 255, .9); | |||
} | |||
form > div > input[type='submit'] { | |||
width: 100%; padding: 6px 0; | |||
background-color: #168f48; | |||
border-color: #12753a; | |||
color: #fff; | |||
border-radius: 3px; | |||
font-size: 14px; | |||
font-weight: 400; | |||
border: 1px solid transparent; | |||
#register input[type="submit"] { | |||
width: 100%; | |||
background-color: #149641; | |||
border-color: #0e692d; | |||
color: #ffffff; | |||
} | |||
form > div > input[type='submit']:hover { | |||
background-color: #168f48; | |||
border-color: #12753a; | |||
#register input[type="submit"]:hover, | |||
#register input[type="submit"]:focus, | |||
#register input[type="submit"]:active { | |||
background-color: #0f7331; | |||
border-color: #073617; | |||
} | |||
form .msgerror { | |||
#register form .msgerror { | |||
color: red; | |||
font-weight: 400; | |||
margin-top: 5px; |
@@ -12,9 +12,42 @@ function getCookie(name) { | |||
return unescape( document.cookie.substring( debut+name.length+1, end ) ); | |||
} | |||
function close_important(element) { | |||
/* | |||
Flash messages | |||
*/ | |||
function flash_add(type, message) { | |||
template = `<div class="flash {{ category }}" style="top: {{ top }}px;" onclick="flash_close(this)"> | |||
<svg style='width:24px;height:24px' viewBox='0 0 24 24'> | |||
{{ icon }} | |||
</svg> | |||
<span> | |||
{{ message }} | |||
</span> | |||
<input type="button" value="MASQUER"></input> | |||
</div>`; | |||
paths = { | |||
'error': '<path fill="#727272" d="M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z"></path>', | |||
'warning': '<path fill="#727272" d="M12,2L1,21H23M12,6L19.53,19H4.47M11,10V14H13V10M11,16V18H13V16"></path>', | |||
'ok': '<path fill="#727272" d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"></path>', | |||
'info': '<path fill="#727272" d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z"></path>' | |||
}; | |||
var top = (document.getElementsByClassName('flash').length + 1) * 70 - 45; | |||
template = template.replace("{{ category }}", type); | |||
template = template.replace("{{ top }}", top); | |||
template = template.replace("{{ icon }}", paths[type]); | |||
template = template.replace("{{ message }}", message); | |||
document.body.innerHTML += template; | |||
} | |||
function flash_close(element) { | |||
element.style.opacity = 0; | |||
setTimeout(function(){ element.parentNode.removeChild(element); }, 200); | |||
setTimeout(function(){ | |||
var parent = element.parentNode; | |||
parent.removeChild(element); | |||
var childs = parent.getElementsByClassName('flash'); | |||
for(var i = 0; i < childs.length; i++) { | |||
childs[i].style.top = ((i + 1) * 70 - 45) + 'px'; | |||
} | |||
}, 200); | |||
} | |||
/* |
@@ -1,15 +0,0 @@ | |||
{% with messages = get_flashed_messages(with_categories=true) %} | |||
{% if messages %} | |||
{% for category, message in messages %} | |||
<div class="alert {{ category }}" style="top: {{ loop.index * 70 - 45 }}px;" onclick="close_important(this)"> | |||
<svg style='width:24px;height:24px' viewBox='0 0 24 24'> | |||
<path fill="#727272" d="M12,2L1,21H23M12,6L19.53,19H4.47M11,10V14H13V10M11,16V18H13V16"></path> | |||
</svg> | |||
<span> | |||
{{ message }} | |||
</span> | |||
<input type="button" class="flat" value="MASQUER"></input> | |||
</div> | |||
{% endfor %} | |||
{% endif %} | |||
{% endwith %} |
@@ -9,7 +9,7 @@ | |||
{% include "base/footer.html" %} | |||
{% include "base/alerts.html" %} | |||
{% include "base/flash.html" %} | |||
{% include "base/scripts.html" %} | |||
</body> |
@@ -0,0 +1,18 @@ | |||
{% with messages = get_flashed_messages(with_categories=true) %} | |||
{% if messages %} | |||
{% for category, message in messages %} | |||
<div class="flash {{ category }}" style="top: {{ loop.index * 70 - 45 }}px;" onclick="flash_close(this)"> | |||
<svg style='width:24px;height:24px' viewBox='0 0 24 24'> | |||
{% if category=="error" %}<path fill="#727272" d="M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z"></path>{% endif %} | |||
{% if category=="warning" %}<path fill="#727272" d="M12,2L1,21H23M12,6L19.53,19H4.47M11,10V14H13V10M11,16V18H13V16"></path>{% endif %} | |||
{% if category=="ok" %}<path fill="#727272" d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M11,16.5L6.5,12L7.91,10.59L11,13.67L16.59,8.09L18,9.5L11,16.5Z"></path>{% endif %} | |||
{% if category=="info" %}<path fill="#727272" d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z"></path>{% endif %} | |||
</svg> | |||
<span> | |||
{{ message }} | |||
</span> | |||
<input type="button" value="MASQUER"></input> | |||
</div> | |||
{% endfor %} | |||
{% endif %} | |||
{% endwith %} |
@@ -6,7 +6,10 @@ | |||
<link rel="stylesheet" media="all and (min-width: 700px)" type="text/css" href={{url_for('static', filename = 'css/global.css')}}> | |||
<link rel="stylesheet" media="all and (min-width: 700px)" type="text/css" href={{url_for('static', filename = 'css/navbar.css')}}> | |||
<link rel="stylesheet" media="all and (min-width: 700px)" type="text/css" href={{url_for('static', filename = 'css/header.css')}}> | |||
<link rel="stylesheet" media="all and (min-width: 700px)" type="text/css" href={{url_for('static', filename = 'css/container.css')}}> | |||
<link rel="stylesheet" media="all and (min-width: 700px)" type="text/css" href={{url_for('static', filename = 'css/footer.css')}}> | |||
<link rel="stylesheet" media="all and (min-width: 700px)" type="text/css" href={{url_for('static', filename = 'css/flash.css')}}> | |||
<link rel="stylesheet" media="all and (min-width: 700px)" type="text/css" href={{url_for('static', filename = 'css/responsive.css')}}> | |||
<link rel="stylesheet" media="all and (max-width: 699px)" type="text/css" href={{url_for('static', filename = 'css/light.css')}}> | |||
@@ -55,7 +55,7 @@ | |||
{{ form.username(size=32, placeholder="Identifiant") }} | |||
{{ form.password(size=32, placeholder="Mot de passe") }} | |||
</div> | |||
<div>{{ form.submit() }}</div> | |||
<div>{{ form.submit(class_="bg-green") }}</div> | |||
<div>{{ form.remember_me.label }} {{ form.remember_me() }}</div> | |||
</form> | |||
<hr /> |
@@ -2,7 +2,7 @@ | |||
{% block content %} | |||
<section class="home-pinned-content flex"> | |||
<div id="form"> | |||
<div id="register"> | |||
<h1>Inscription :</h1> | |||
<form action="" method="post"> | |||
@@ -35,7 +35,22 @@ | |||
<span class="msgerror">{{ error }}</span> | |||
{% endfor %} | |||
</div> | |||
<div>{{ form2.submit() }}</div> | |||
<div> | |||
{{ form2.guidelines.label }} | |||
{{ form2.guidelines() }} | |||
{% for error in form2.guidelines.errors %} | |||
<span class="msgerror">{{ error }}</span> | |||
{% endfor %} | |||
</div> | |||
<div> | |||
{{ form2.newsletter.label }} | |||
{{ form2.newsletter() }} | |||
<div style="font-size:80%;color:rgba(0,0,0,.5)">{{ form2.newsletter.description }}</div> | |||
{% for error in form2.newsletter.errors %} | |||
<span class="msgerror">{{ error }}</span> | |||
{% endfor %} | |||
</div> | |||
<div>{{ form2.submit(class_="bg-green") }}</div> | |||
</form> | |||
</div> | |||
</section> |