"Firt release"
This commit is contained in:
parent
f1ec84ef16
commit
ec8b53c3e5
559
participate.py
559
participate.py
@ -7,8 +7,18 @@ import inspect
|
|||||||
import random
|
import random
|
||||||
import binascii
|
import binascii
|
||||||
import bcrypt
|
import bcrypt
|
||||||
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
|
import datetime
|
||||||
|
import ast
|
||||||
|
from reportlab.lib import colors
|
||||||
|
from reportlab.lib.enums import TA_LEFT, TA_CENTER
|
||||||
|
from reportlab.lib.pagesizes import A4, cm, portrait
|
||||||
|
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, PageBreak, Indenter
|
||||||
|
from reportlab.lib.colors import black, white, orange, bisque, lightsalmon
|
||||||
|
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||||
|
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash, send_file
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
import cStringIO
|
||||||
|
from flask_mail import Mail, Message
|
||||||
|
|
||||||
# Optionnal modules
|
# Optionnal modules
|
||||||
import psycopg2
|
import psycopg2
|
||||||
@ -18,6 +28,9 @@ from flask_sqlalchemy import SQLAlchemy
|
|||||||
# App settings
|
# App settings
|
||||||
########################################################################
|
########################################################################
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
mail = Mail(app)
|
||||||
|
# Jinja2 loopcontrols extension
|
||||||
|
app.jinja_env.add_extension('jinja2.ext.loopcontrols')
|
||||||
# Path to static files
|
# Path to static files
|
||||||
app.static_url_path='/static'
|
app.static_url_path='/static'
|
||||||
# Set debug mode to False for production
|
# Set debug mode to False for production
|
||||||
@ -30,6 +43,7 @@ app.secret_key = '9ac80548e3a8d8dfd1aefcd9a3a73473'
|
|||||||
db = SQLAlchemy(app)
|
db = SQLAlchemy(app)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Sample user database
|
# Sample user database
|
||||||
########################################################################
|
########################################################################
|
||||||
@ -42,6 +56,7 @@ class Tetawebapp_users(db.Model):
|
|||||||
phone = db.Column(db.Text, nullable=True)
|
phone = db.Column(db.Text, nullable=True)
|
||||||
diet = db.Column(db.Text, nullable=True)
|
diet = db.Column(db.Text, nullable=True)
|
||||||
is_admin = db.Column(db.Integer, nullable=False, default=0)
|
is_admin = db.Column(db.Integer, nullable=False, default=0)
|
||||||
|
link_id = db.Column(db.Text, nullable=True)
|
||||||
|
|
||||||
class Tetawebapp_roles(db.Model):
|
class Tetawebapp_roles(db.Model):
|
||||||
__tablename__ = 'participer_thsf_roles'
|
__tablename__ = 'participer_thsf_roles'
|
||||||
@ -53,10 +68,16 @@ class Tetawebapp_turns(db.Model):
|
|||||||
__tablename__ = 'participer_thsf_turns'
|
__tablename__ = 'participer_thsf_turns'
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
role_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_roles.id'), nullable=False)
|
role_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_roles.id'), nullable=False)
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_users.id'), nullable=True)
|
start_time = db.Column(db.DateTime, nullable=False)
|
||||||
wday = db.Column(db.Enum('Jeudi', 'Vendredi', 'Samedi', 'Dimanche'), nullable=False)
|
end_time = db.Column(db.DateTime, nullable=False)
|
||||||
start_time = db.Column(db.Time, nullable=False)
|
num_slot = db.Column(db.Integer, nullable=False, default=2)
|
||||||
end_time = db.Column(db.Time, nullable=False)
|
|
||||||
|
class Tetawebapp_staffs(db.Model):
|
||||||
|
__tablename__ = 'participer_thsf_staffs'
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
turn_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_turns.id'), nullable=False)
|
||||||
|
user_id = db.Column(db.Integer, db.ForeignKey('participer_thsf_users.id'), default=0, nullable=False)
|
||||||
|
slot_num = db.Column(db.Integer, nullable=False)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Menu and navigation management
|
# Menu and navigation management
|
||||||
@ -73,14 +94,13 @@ def get_menu(page):
|
|||||||
The value MUST be 0."""
|
The value MUST be 0."""
|
||||||
menu = [[u'Accueil', {u'/': [u'/']}, 0],
|
menu = [[u'Accueil', {u'/': [u'/']}, 0],
|
||||||
[u'Mon compte', {u'/account': [u'/account', u'/account/update']}, 0],
|
[u'Mon compte', {u'/account': [u'/account', u'/account/update']}, 0],
|
||||||
[u'Mes tours de staff', {u'/turns': [u'/turns']}, 0],
|
[u'Feuille de staff', {u'/staffsheet': [u'/staffsheet', u'/staffsheet/clear/<TURN_ID>/<SLOT_ID>', u'/staffsheet/update/<TURN_ID>/<SLOT_ID>']}, 0],
|
||||||
[u'Feuilles de staff', {u'/staff_sheets': [u'/staff_sheet']}, 0],
|
|
||||||
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
|
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
|
||||||
]
|
]
|
||||||
if session['is_admin']:
|
if session['is_admin']:
|
||||||
menu = [[u'Accueil', {u'/': [u'/']}, 0],
|
menu = [[u'Accueil', {u'/': [u'/']}, 0],
|
||||||
[u'Tours de staff', {u'/turns': [u'/turns', u'/turn/<ID>', u'/turn/new', u'/turn/add', u'/turn/delete/<ID>', u'/turn/update/<ID>']}, 0],
|
[u'Tours de staff', {u'/turns': [u'/turns', u'/turn/<ID>', u'/turn/new', u'/turn/add', u'/turn/delete/<ID>', u'/turn/update/<ID>']}, 0],
|
||||||
[u'Feuilles de staff', {u'/staff_sheets': [u'/staff_sheet']}, 0],
|
[u'Feuille de staff', {u'/staffsheet': [u'/staffsheet', u'/staffsheet/clear/<TURN_ID>/<SLOT_ID>', u'/staffsheet/update/<TURN_ID>/<SLOT_ID>', u'/staffsheet/pdf']}, 0],
|
||||||
[u'Liste des staffers', {u'/users': [u'/users', u'/account/<ID>', u'/account/delete/<ID>']}, 0],
|
[u'Liste des staffers', {u'/users': [u'/users', u'/account/<ID>', u'/account/delete/<ID>']}, 0],
|
||||||
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
|
[u'Déconnexion', {u'/logout': [u'/logout']}, 0],
|
||||||
]
|
]
|
||||||
@ -154,11 +174,27 @@ def check_session(func):
|
|||||||
def check_login(login, password):
|
def check_login(login, password):
|
||||||
""" Puts the login verification code here """
|
""" Puts the login verification code here """
|
||||||
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
|
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
|
||||||
stored_hash = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.password).first()
|
stored_hash = Tetawebapp_users.query.filter(Tetawebapp_users.mail==login, Tetawebapp_users.link_id==None).with_entities(Tetawebapp_users.password).first()
|
||||||
is_admin = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.is_admin).first()
|
|
||||||
if stored_hash:
|
if stored_hash:
|
||||||
if bcrypt.checkpw(password, stored_hash[0].encode('utf-8')):
|
if bcrypt.checkpw(password, stored_hash[0].encode('utf-8')):
|
||||||
|
is_admin = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.is_admin).first()
|
||||||
|
user_id = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.id).first()
|
||||||
session['is_admin'] = is_admin[0]
|
session['is_admin'] = is_admin[0]
|
||||||
|
session['user_id'] = user_id[0]
|
||||||
|
return True
|
||||||
|
print "[+] Login failed"
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_confirm(login, password, link_id):
|
||||||
|
""" Check identity when confirming email address """
|
||||||
|
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
|
||||||
|
stored_hash = Tetawebapp_users.query.filter(Tetawebapp_users.mail==login, Tetawebapp_users.link_id==link_id).with_entities(Tetawebapp_users.password).first()
|
||||||
|
if stored_hash:
|
||||||
|
if bcrypt.checkpw(password, stored_hash[0].encode('utf-8')):
|
||||||
|
is_admin = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.is_admin).first()
|
||||||
|
user_id = Tetawebapp_users.query.filter_by(mail=login).with_entities(Tetawebapp_users.id).first()
|
||||||
|
session['is_admin'] = is_admin[0]
|
||||||
|
session['user_id'] = user_id[0]
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -173,8 +209,9 @@ def register_user(login, password, confirm):
|
|||||||
# User already exists
|
# User already exists
|
||||||
print "[+] User already exists"
|
print "[+] User already exists"
|
||||||
return False
|
return False
|
||||||
|
link_id = gen_token(20)
|
||||||
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
|
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
|
||||||
user = Tetawebapp_users(mail=login.encode('utf8'), password=hashed_password)
|
user = Tetawebapp_users(mail=login.encode('utf8'), password=hashed_password, link_id=link_id)
|
||||||
try:
|
try:
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
commit = db.session.commit()
|
commit = db.session.commit()
|
||||||
@ -185,9 +222,31 @@ def register_user(login, password, confirm):
|
|||||||
print "%s" % e.message
|
print "%s" % e.message
|
||||||
print "------------------------------"
|
print "------------------------------"
|
||||||
return False
|
return False
|
||||||
|
if commit != None:
|
||||||
|
print "[+] Error at register_user: commit was not None"
|
||||||
|
return False
|
||||||
|
send_mail(login, link_id)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def confirm_user(login, password, link_id):
|
||||||
|
""" Confirm user """
|
||||||
|
if check_confirm(login, password, link_id):
|
||||||
|
user = Tetawebapp_users.query.filter_by(mail=login).first()
|
||||||
|
setattr(user, 'link_id', None)
|
||||||
|
try:
|
||||||
|
db.session.add(user)
|
||||||
|
commit = db.session.commit()
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
print "[+] Error at confirm_user:"
|
||||||
|
print "------------------------------"
|
||||||
|
print "%s" % e.message
|
||||||
|
print "------------------------------"
|
||||||
|
return False
|
||||||
if commit != None:
|
if commit != None:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def update_user(login, password, confirm, name, phone, diet):
|
def update_user(login, password, confirm, name, phone, diet):
|
||||||
""" Update user infos with provided data """
|
""" Update user infos with provided data """
|
||||||
@ -250,7 +309,7 @@ def update_user_by_id(user_id, login, password, confirm, name, phone, diet):
|
|||||||
commit = db.session.commit()
|
commit = db.session.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
print "[+] Error at update_user:"
|
print "[+] Error at update_user_by_id:"
|
||||||
print "------------------------------"
|
print "------------------------------"
|
||||||
print "%s" % e.message
|
print "%s" % e.message
|
||||||
print "------------------------------"
|
print "------------------------------"
|
||||||
@ -275,12 +334,22 @@ def delete_user(user_id):
|
|||||||
print "------------------------------"
|
print "------------------------------"
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def save_turn(role_id, day, start, end):
|
def save_turn(role_id, day, start, end, num_slot):
|
||||||
""" Save a new turn """
|
""" Save a new turn """
|
||||||
|
days = ['2018-05-08', '2018-05-09', '2018-05-10', '2018-05-11', '2018-05-12', '2018-05-13', '2018-05-14']
|
||||||
|
day_index = days.index(day)
|
||||||
|
sday = day
|
||||||
|
eday = day
|
||||||
|
if str(start[0]) == '0':
|
||||||
|
sday = days[day_index+1]
|
||||||
|
if str(end[0]) == '0':
|
||||||
|
eday = days[day_index+1]
|
||||||
|
start = '%s %s' % (sday, start)
|
||||||
|
end = '%s %s' % (eday, end)
|
||||||
turn = Tetawebapp_turns(role_id=role_id.encode('utf-8'),
|
turn = Tetawebapp_turns(role_id=role_id.encode('utf-8'),
|
||||||
wday=day.encode('utf-8'),
|
|
||||||
start_time=start.encode('utf-8'),
|
start_time=start.encode('utf-8'),
|
||||||
end_time=end.encode('utf-8'),
|
end_time=end.encode('utf-8'),
|
||||||
|
num_slot=num_slot.encode('utf-8'),
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
db.session.add(turn)
|
db.session.add(turn)
|
||||||
@ -296,18 +365,45 @@ def save_turn(role_id, day, start, end):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update_turn_by_id(turn_id, role_id, wday, start, end):
|
def get_turn_by_id(turn_id):
|
||||||
|
""" Get specified stafff turn """
|
||||||
|
days = {'2018-05-08': 'Mardi',
|
||||||
|
'2018-05-09': 'Mercredi',
|
||||||
|
'2018-05-10': 'Jeudi',
|
||||||
|
'2018-05-11': 'Vendredi',
|
||||||
|
'2018-05-12': 'Samedi',
|
||||||
|
'2018-05-13': 'Dimanche',
|
||||||
|
'2018-05-14': 'Lundi'}
|
||||||
|
turn = Tetawebapp_turns.query.filter_by(id=turn_id).first()
|
||||||
|
s_day, s_time = str(turn.start_time).split(' ')
|
||||||
|
e_day, e_time = str(turn.end_time).split(' ')
|
||||||
|
if s_time[0] == '0':
|
||||||
|
s_day = (datetime.datetime.strptime(s_day, '%Y-%m-%d')-datetime.timedelta(1)).strftime("%Y-%m-%d")
|
||||||
|
day = days[s_day]
|
||||||
|
return {'id': turn_id, 'role_id': turn.role_id, 'day': day, 'start_time': s_time, 'end_time': e_time, 'num_slot': turn.num_slot}
|
||||||
|
|
||||||
|
def update_turn_by_id(turn_id, role_id, day, start, end, num_slot):
|
||||||
""" Update turn with provided data """
|
""" Update turn with provided data """
|
||||||
check_turn = Tetawebapp_turns.query.filter_by(id=turn_id).count()
|
check_turn = Tetawebapp_turns.query.filter_by(id=turn_id).count()
|
||||||
if check_turn == 0:
|
if check_turn == 0:
|
||||||
# User does not exist
|
# User does not exist
|
||||||
print "[+] User does not exist"
|
print "[+] Turn does not exist"
|
||||||
return False
|
return False
|
||||||
|
days = ['2018-05-08', '2018-05-09', '2018-05-10', '2018-05-11', '2018-05-12', '2018-05-13', '2018-05-14']
|
||||||
|
day_index = days.index(day)
|
||||||
|
sday = day
|
||||||
|
eday = day
|
||||||
|
if str(start[0]) == '0':
|
||||||
|
sday = days[day_index +1]
|
||||||
|
if str(end[0]) == '0':
|
||||||
|
eday = days[day_index +1]
|
||||||
|
start = '%s %s' % (sday, start)
|
||||||
|
end = '%s %s' % (eday, end)
|
||||||
turn = Tetawebapp_turns.query.filter_by(id=turn_id).first()
|
turn = Tetawebapp_turns.query.filter_by(id=turn_id).first()
|
||||||
setattr(turn, 'role_id', role_id)
|
setattr(turn, 'role_id', role_id)
|
||||||
setattr(turn, 'wday', wday)
|
|
||||||
setattr(turn, 'start_time', start)
|
setattr(turn, 'start_time', start)
|
||||||
setattr(turn, 'end_time', end)
|
setattr(turn, 'end_time', end)
|
||||||
|
setattr(turn, 'num_slot', num_slot)
|
||||||
try:
|
try:
|
||||||
db.session.add(turn)
|
db.session.add(turn)
|
||||||
commit = db.session.commit()
|
commit = db.session.commit()
|
||||||
@ -339,6 +435,104 @@ def drop_turn(turn_id):
|
|||||||
print "------------------------------"
|
print "------------------------------"
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def turns_list():
|
||||||
|
""" List staff turns """
|
||||||
|
turns = []
|
||||||
|
tuesday = '2018-05-08 06:00:00'
|
||||||
|
wenesday = '2018-05-09 06:00:00'
|
||||||
|
thirsday = '2018-05-10 06:00:00'
|
||||||
|
friday = '2018-05-11 06:00:00'
|
||||||
|
saturday = '2018-05-12 06:00:00'
|
||||||
|
sunday = '2018-05-13 06:00:00'
|
||||||
|
monday = '2018-05-14 06:00:00'
|
||||||
|
tuesday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > tuesday, Tetawebapp_turns.start_time < wenesday)
|
||||||
|
tuesday_turns = tuesday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||||
|
tuesday_turns = tuesday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||||
|
wenesday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > wenesday, Tetawebapp_turns.start_time < thirsday)
|
||||||
|
wenesday_turns = wenesday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||||
|
wenesday_turns = wenesday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||||
|
thirsday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > thirsday, Tetawebapp_turns.start_time < friday)
|
||||||
|
thirsday_turns = thirsday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||||
|
thirsday_turns = thirsday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||||
|
friday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > friday, Tetawebapp_turns.start_time < saturday)
|
||||||
|
friday_turns = friday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||||
|
friday_turns = friday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||||
|
saturday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > saturday, Tetawebapp_turns.start_time < sunday)
|
||||||
|
saturday_turns = saturday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||||
|
saturday_turns = saturday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||||
|
sunday_turns = Tetawebapp_turns.query.filter(Tetawebapp_turns.start_time > sunday, Tetawebapp_turns.start_time < monday)
|
||||||
|
sunday_turns = sunday_turns.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id)
|
||||||
|
sunday_turns = sunday_turns.add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id, Tetawebapp_turns.start_time).all()
|
||||||
|
turns.append(('Mardi', tuesday_turns))
|
||||||
|
turns.append(('Mercredi', wenesday_turns))
|
||||||
|
turns.append(('Jeudi', thirsday_turns))
|
||||||
|
turns.append(('Vendredi', friday_turns))
|
||||||
|
turns.append(('Samedi', saturday_turns))
|
||||||
|
turns.append(('Dimanche', sunday_turns))
|
||||||
|
return turns
|
||||||
|
|
||||||
|
def get_staffs():
|
||||||
|
""" """
|
||||||
|
try:
|
||||||
|
staffs = Tetawebapp_staffs.query.join(Tetawebapp_users, Tetawebapp_staffs.user_id==Tetawebapp_users.id)
|
||||||
|
staffs = staffs.add_columns(Tetawebapp_users.name).all()
|
||||||
|
return staffs
|
||||||
|
except Exception as e:
|
||||||
|
print "[+] Error at get_staffs:"
|
||||||
|
print "------------------------------"
|
||||||
|
print "%s" % e.message
|
||||||
|
print "------------------------------"
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def drop_staff_slot(turn_id, slot_num, user_id):
|
||||||
|
""" Drop staff given slot """
|
||||||
|
slot = Tetawebapp_staffs.query.filter_by(turn_id=turn_id, slot_num=slot_num).first()
|
||||||
|
if slot.user_id == user_id:
|
||||||
|
try:
|
||||||
|
Tetawebapp_staffs.query.filter_by(turn_id=turn_id, slot_num=slot_num).delete()
|
||||||
|
db.session.commit()
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
print "[+] Error at drop_staff_slot:"
|
||||||
|
print "------------------------------"
|
||||||
|
print "%s" % e.message
|
||||||
|
print "------------------------------"
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def save_staff_slot(turn_id, slot_id, user_id):
|
||||||
|
""" Save staff given slot """
|
||||||
|
slot = Tetawebapp_staffs(user_id=user_id,
|
||||||
|
turn_id=turn_id,
|
||||||
|
slot_num=slot_id)
|
||||||
|
try:
|
||||||
|
db.session.add(slot)
|
||||||
|
commit = db.session.commit()
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
print "[+] Error at save_staff_slot:"
|
||||||
|
print "------------------------------"
|
||||||
|
print "%s" % e.message
|
||||||
|
print "------------------------------"
|
||||||
|
return False
|
||||||
|
if commit != None:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_roles():
|
||||||
|
""" Get full roles list """
|
||||||
|
try:
|
||||||
|
roles = Tetawebapp_roles.query.filter(Tetawebapp_roles.id > 3).all()
|
||||||
|
return roles
|
||||||
|
except Exception as e:
|
||||||
|
print "[+] Error at get_staffs:"
|
||||||
|
print "------------------------------"
|
||||||
|
print "%s" % e.message
|
||||||
|
print "------------------------------"
|
||||||
|
return False
|
||||||
|
|
||||||
def check_user_info():
|
def check_user_info():
|
||||||
""" Check user info and send appropriate message if info are not complete"""
|
""" Check user info and send appropriate message if info are not complete"""
|
||||||
message = ''
|
message = ''
|
||||||
@ -351,11 +545,28 @@ def check_user_info():
|
|||||||
message = "Vos informations personnelles ne sont pas complètement renseignées. N'oubliez pas de remplir votre fiche située dans la section 'Mon compte'"
|
message = "Vos informations personnelles ne sont pas complètement renseignées. N'oubliez pas de remplir votre fiche située dans la section 'Mon compte'"
|
||||||
return message.decode('utf-8')
|
return message.decode('utf-8')
|
||||||
|
|
||||||
def gen_token():
|
def gen_token(size=42):
|
||||||
""" Generate a random token to be stored in session and cookie """
|
""" Generate a random token to be stored in session and cookie """
|
||||||
token = binascii.hexlify(os.urandom(42))
|
token = binascii.hexlify(os.urandom(size))
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
def send_mail(email, link_id):
|
||||||
|
msg = Message("Confirmation d'inscription au staff THSF",
|
||||||
|
sender="dave.null@tetalab.org",
|
||||||
|
recipients=[email])
|
||||||
|
msg.body = "Bonjour,\nVous recevez ce courriel car vous avez souhaité faire partie de l'équipe du staff du THSF.\n\n"
|
||||||
|
msg.body += "Pour confirmer votre inscription, rendez vous à la page suivante:\n"
|
||||||
|
msg.body += "https://wemake.thsf.net/confirm/%s\n\n" % str(link_id)
|
||||||
|
msg.body += "Si vous n'êtes pas à l'origine de cette inscription, ignorez simplement ce courriel.\n"
|
||||||
|
msg.body += "Votre compte sera automatiquement supprimé dans les 24 heures.\n\n"
|
||||||
|
msg.body += "Si vous désirez vous désinscrire, faites simplement une demande sur https://bofh.tetalab.org\n\n"
|
||||||
|
msg.body += "Dans tous les cas la base de données sera totalement réinitialisée à la fin du THSF.\n\n"
|
||||||
|
msg.body += "Votre aide nous est précieuse.\nMerci et bravo à vous.\n"
|
||||||
|
msg.body += "-- \n"
|
||||||
|
msg.body += "L'équipe d'organisation du THSF\n"
|
||||||
|
msg.body += "(Ce mail vous est envoyé par un robot qui n' a pas réussi le test de Turing, inutile de lui répondre)"
|
||||||
|
mail.send(msg)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Routes:
|
# Routes:
|
||||||
# -------
|
# -------
|
||||||
@ -388,11 +599,50 @@ def login():
|
|||||||
# Credentials are not valid
|
# Credentials are not valid
|
||||||
response = app.make_response(render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide"))
|
response = app.make_response(render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide"))
|
||||||
session['token'] = ''
|
session['token'] = ''
|
||||||
|
session['login'] = ''
|
||||||
|
session['is_admin'] = 0
|
||||||
sync_cookies(response, session)
|
sync_cookies(response, session)
|
||||||
return response
|
return response
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||||
|
|
||||||
|
@app.route("/confirm/<LINK_ID>", methods=['GET', 'POST'])
|
||||||
|
def confirm(LINK_ID):
|
||||||
|
""" Index page """
|
||||||
|
link_id = LINK_ID.encode('utf-8')
|
||||||
|
return render_template('confirm.html', message="Merci de confirmer votre enregistrement", link_id=link_id)
|
||||||
|
|
||||||
|
@app.route("/confirm/link/<LINK_ID>", methods=['GET', 'POST'])
|
||||||
|
def confirm_link(LINK_ID):
|
||||||
|
""" Index page """
|
||||||
|
try:
|
||||||
|
link_id = LINK_ID.encode('utf-8')
|
||||||
|
login = request.form.get('login').encode('utf-8')
|
||||||
|
password = request.form.get('password').encode('utf-8')
|
||||||
|
if check_confirm(login, password, link_id) and confirm_user(login, password, link_id):
|
||||||
|
# Generate and store a token in session
|
||||||
|
session['token'] = gen_token()
|
||||||
|
session['login'] = login
|
||||||
|
# Return user to index page
|
||||||
|
page = '/'
|
||||||
|
menu = get_menu(page)
|
||||||
|
message = check_user_info()
|
||||||
|
response = app.make_response(render_template('index.html', menu=menu, message=message, login=login))
|
||||||
|
# Push token to cookie
|
||||||
|
sync_cookies(response, session)
|
||||||
|
return response
|
||||||
|
# Credentials are not valid
|
||||||
|
response = app.make_response(render_template('confirm.html', message="Utilisateur ou mot de passe invalide", link_id=link_id))
|
||||||
|
session['token'] = ''
|
||||||
|
session['login'] = ''
|
||||||
|
session['is_admin'] = 0
|
||||||
|
sync_cookies(response, session)
|
||||||
|
return response
|
||||||
|
except AttributeError:
|
||||||
|
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||||
|
link_id = LINK_ID.encode('utf-8')
|
||||||
|
return render_template('confirm.html', message="Merci de confirmer votre enregistrement", link_id=link_id)
|
||||||
|
|
||||||
@app.route("/register", methods=['GET', 'POST'])
|
@app.route("/register", methods=['GET', 'POST'])
|
||||||
def register():
|
def register():
|
||||||
""" Allow self registration """
|
""" Allow self registration """
|
||||||
@ -400,24 +650,11 @@ def register():
|
|||||||
login = request.form.get('login').encode('utf-8')
|
login = request.form.get('login').encode('utf-8')
|
||||||
password = request.form.get('password').encode('utf-8')
|
password = request.form.get('password').encode('utf-8')
|
||||||
confirm = request.form.get('confirm').encode('utf-8')
|
confirm = request.form.get('confirm').encode('utf-8')
|
||||||
if register_user(login, password, confirm):
|
|
||||||
# Generate and store a token in session
|
|
||||||
session['token'] = gen_token()
|
|
||||||
session['login'] = login
|
|
||||||
# Return user to index page
|
|
||||||
page = '/'
|
|
||||||
menu = get_menu(page)
|
|
||||||
message = check_user_info()
|
|
||||||
response = app.make_response(render_template('index.html', menu=menu, login=login, message=message))
|
|
||||||
# Push token to cookie
|
|
||||||
sync_cookies(response, session)
|
|
||||||
return response
|
|
||||||
# Error while registering user
|
|
||||||
message = "Erreur lors de l'enregsitrement: L'utilisateur existe t-il déjà ?".decode('utf-8')
|
message = "Erreur lors de l'enregsitrement: L'utilisateur existe t-il déjà ?".decode('utf-8')
|
||||||
response = app.make_response(render_template('login_or_register.html', message=message))
|
if register_user(login, password, confirm):
|
||||||
session['token'] = ''
|
message = "Merci de votre engagement. Un courriel contenant les instructions de confirmation votre inscription vient de vous être envoyé."
|
||||||
sync_cookies(response, session)
|
# Error while registering user
|
||||||
return response
|
return render_template('login_or_register.html', message=message.decode('utf-8'))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||||
|
|
||||||
@ -578,15 +815,20 @@ def delete_account(ID):
|
|||||||
|
|
||||||
@app.route("/turns", methods=['GET', 'POST'])
|
@app.route("/turns", methods=['GET', 'POST'])
|
||||||
@check_session
|
@check_session
|
||||||
def list_turn():
|
def list_turns():
|
||||||
""" List staff turns """
|
""" List staff turns """
|
||||||
try:
|
try:
|
||||||
|
page = str(request.url_rule)
|
||||||
|
menu = get_menu(page)
|
||||||
|
message = ''
|
||||||
if session['is_admin']:
|
if session['is_admin']:
|
||||||
page = str(request.url_rule)
|
page = str(request.url_rule)
|
||||||
menu = get_menu(page)
|
menu = get_menu(page)
|
||||||
turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all()
|
turns = turns_list()
|
||||||
message = ''
|
message = ''
|
||||||
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
||||||
|
# TODO:
|
||||||
|
# Here comes the list_turns_by_user_id code
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# User is not logged in
|
# User is not logged in
|
||||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||||
@ -595,12 +837,19 @@ def list_turn():
|
|||||||
@check_session
|
@check_session
|
||||||
def new_turn():
|
def new_turn():
|
||||||
""" New turn form """
|
""" New turn form """
|
||||||
|
tuesday = '2018-05-08'
|
||||||
|
wenesday = '2018-05-09'
|
||||||
|
thirsday = '2018-05-10'
|
||||||
|
friday = '2018-05-11'
|
||||||
|
saturday = '2018-05-12'
|
||||||
|
sunday = '2018-05-13'
|
||||||
|
monday = '2018-05-14'
|
||||||
try:
|
try:
|
||||||
if session['is_admin']:
|
if session['is_admin']:
|
||||||
page = str(request.url_rule)
|
page = str(request.url_rule)
|
||||||
menu = get_menu(page)
|
menu = get_menu(page)
|
||||||
roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all()
|
roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all()
|
||||||
days = ['Jeudi', 'Vendredi', 'Samedi', 'Dimanche']
|
days = [('Mardi', tuesday), ('Mercredi', wenesday), ('Jeudi', thirsday), ('Vendredi', friday), ('Samedi', saturday), ('Dimanche', sunday)]
|
||||||
return render_template('new_turn.html', menu=menu, page=page, roles=roles, days=days)
|
return render_template('new_turn.html', menu=menu, page=page, roles=roles, days=days)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# User is not logged in
|
# User is not logged in
|
||||||
@ -616,18 +865,15 @@ def add_turn():
|
|||||||
day = request.form.get('day').encode('utf-8')
|
day = request.form.get('day').encode('utf-8')
|
||||||
start = request.form.get('start').encode('utf-8')
|
start = request.form.get('start').encode('utf-8')
|
||||||
end = request.form.get('end').encode('utf-8')
|
end = request.form.get('end').encode('utf-8')
|
||||||
|
num_slot = request.form.get('num_slot').encode('utf-8')
|
||||||
page = str(request.url_rule)
|
page = str(request.url_rule)
|
||||||
menu = get_menu(page)
|
menu = get_menu(page)
|
||||||
turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all()
|
turns = turns_list()
|
||||||
message = "Erreur lors de l'enregistrement.".decode('utf-8')
|
message = "Erreur lors de l'enregistrement.".decode('utf-8')
|
||||||
if save_turn(role_id, day, start, end):
|
if save_turn(role_id, day, start, end, num_slot):
|
||||||
turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all()
|
turns = turns_list()
|
||||||
message=''
|
message=''
|
||||||
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
||||||
# Error while saving turn
|
|
||||||
roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all()
|
|
||||||
days = ['Jeudi', 'Vendredi', 'Samedi', 'Dimanche']
|
|
||||||
return render_template('new_turn.html', menu=menu, page=page, roles=roles, days=days, message=message)
|
|
||||||
# User is not admin
|
# User is not admin
|
||||||
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
@ -639,14 +885,21 @@ def add_turn():
|
|||||||
def turn_by_id(ID):
|
def turn_by_id(ID):
|
||||||
try:
|
try:
|
||||||
if session['is_admin']:
|
if session['is_admin']:
|
||||||
|
tuesday = '2018-05-08'
|
||||||
|
wenesday = '2018-05-09'
|
||||||
|
thirsday = '2018-05-10'
|
||||||
|
friday = '2018-05-11'
|
||||||
|
saturday = '2018-05-12'
|
||||||
|
sunday = '2018-05-13'
|
||||||
|
monday = '2018-05-14'
|
||||||
|
days = [('Mardi', tuesday), ('Mercredi', wenesday), ('Jeudi', thirsday), ('Vendredi', friday), ('Samedi', saturday), ('Dimanche', sunday)]
|
||||||
page = str(request.url_rule)
|
page = str(request.url_rule)
|
||||||
menu = get_menu(page)
|
menu = get_menu(page)
|
||||||
roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all()
|
roles = Tetawebapp_roles.query.order_by(Tetawebapp_roles.id).all()
|
||||||
days = ['Jeudi', 'Vendredi', 'Samedi', 'Dimanche']
|
|
||||||
message = 'ID du tour de staff non conforme'
|
message = 'ID du tour de staff non conforme'
|
||||||
turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all()
|
turns = turns_list()
|
||||||
turn_id = int(ID.encode('utf-8'))
|
turn_id = int(ID.encode('utf-8'))
|
||||||
turn = Tetawebapp_turns.query.filter_by(id=ID).first()
|
turn = get_turn_by_id(turn_id)
|
||||||
return render_template('turn_by_id.html', menu=menu, page=page, turn=turn, roles=roles, days=days)
|
return render_template('turn_by_id.html', menu=menu, page=page, turn=turn, roles=roles, days=days)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# User is not logged in
|
# User is not logged in
|
||||||
@ -661,17 +914,18 @@ def update_turn(ID):
|
|||||||
""" Update given staff turn """
|
""" Update given staff turn """
|
||||||
try:
|
try:
|
||||||
role_id = request.form.get('role_id').encode('utf-8')
|
role_id = request.form.get('role_id').encode('utf-8')
|
||||||
day = request.form.get('day').encode('utf-8')
|
|
||||||
start = request.form.get('start').encode('utf-8')
|
start = request.form.get('start').encode('utf-8')
|
||||||
end = request.form.get('end').encode('utf-8')
|
end = request.form.get('end').encode('utf-8')
|
||||||
|
num_slot = request.form.get('num_slot').encode('utf-8')
|
||||||
|
day = request.form.get('day').encode('utf-8')
|
||||||
if session['is_admin']:
|
if session['is_admin']:
|
||||||
page = str(request.url_rule)
|
page = str(request.url_rule)
|
||||||
menu = get_menu(page)
|
menu = get_menu(page)
|
||||||
turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all()
|
turns = turns_list()
|
||||||
message = "Erreur lors de l'enregistrement.".decode('utf-8')
|
message = "Erreur lors de l'enregistrement.".decode('utf-8')
|
||||||
turn_id = int(ID.encode('utf-8'))
|
turn_id = int(ID.encode('utf-8'))
|
||||||
if update_turn_by_id(turn_id, role_id, day, start, end):
|
if update_turn_by_id(turn_id, role_id, day, start, end, num_slot):
|
||||||
turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all()
|
turns = turns_list()
|
||||||
message = ''
|
message = ''
|
||||||
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
||||||
# User is not admin
|
# User is not admin
|
||||||
@ -692,11 +946,11 @@ def delete_turn(ID):
|
|||||||
message = 'Erreur lors de la suppression.'
|
message = 'Erreur lors de la suppression.'
|
||||||
page = str(request.url_rule)
|
page = str(request.url_rule)
|
||||||
menu = get_menu(page)
|
menu = get_menu(page)
|
||||||
turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all()
|
turns = turns_list()
|
||||||
turn_id = int(ID.encode('utf-8'))
|
turn_id = int(ID.encode('utf-8'))
|
||||||
if drop_turn(turn_id):
|
if drop_turn(turn_id):
|
||||||
message = ''
|
message = ''
|
||||||
turns = Tetawebapp_turns.query.join(Tetawebapp_roles, Tetawebapp_turns.role_id==Tetawebapp_roles.id).add_columns(Tetawebapp_roles.role).order_by(Tetawebapp_turns.role_id).all()
|
turns = turns_list()
|
||||||
return render_template('list_turns.html', menu=menu, turns=turns, message=message)
|
return render_template('list_turns.html', menu=menu, turns=turns, message=message)
|
||||||
return render_template('list_turns.html', menu=menu, turns=turns, message=message)
|
return render_template('list_turns.html', menu=menu, turns=turns, message=message)
|
||||||
# User is not admin
|
# User is not admin
|
||||||
@ -708,6 +962,201 @@ def delete_turn(ID):
|
|||||||
# ID is not an integer
|
# ID is not an integer
|
||||||
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
return render_template('list_turns.html', menu=menu, page=page, turns=turns, message=message)
|
||||||
|
|
||||||
|
@app.route("/staffsheet", methods=['GET', 'POST'])
|
||||||
|
@check_session
|
||||||
|
def staffsheet():
|
||||||
|
try:
|
||||||
|
user_id = session['user_id']
|
||||||
|
if len(check_user_info()) == 0:
|
||||||
|
page = str(request.url_rule)
|
||||||
|
menu = get_menu(page)
|
||||||
|
turns = turns_list()
|
||||||
|
staffs = get_staffs()
|
||||||
|
roles = get_roles()
|
||||||
|
return render_template('staffsheet.html', menu=menu, turns=turns, staffs=staffs, user_id=user_id, roles=roles, message='')
|
||||||
|
else:
|
||||||
|
return account()
|
||||||
|
except AttributeError as e:
|
||||||
|
# User is not logged in
|
||||||
|
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||||
|
|
||||||
|
@app.route("/staffsheet/pdf", methods=['GET', 'POST'])
|
||||||
|
def staffsheet_pdf():
|
||||||
|
turns = turns_list()
|
||||||
|
staffs = get_staffs()
|
||||||
|
roles = get_roles()
|
||||||
|
data = render_template('staffsheet_txt.html', turns=turns, staffs=staffs, roles=roles)
|
||||||
|
data = [line for line in data.split('\n') if len(line) > 0]
|
||||||
|
data = '\n'.join(data)
|
||||||
|
data = [line for line in data.split('",\n') if len(line) > 0]
|
||||||
|
data = '", '.join(data)
|
||||||
|
ddata = [ast.literal_eval(line) for line in data.split('\n')]
|
||||||
|
pdf = cStringIO.StringIO()
|
||||||
|
doc = SimpleDocTemplate(pdf, pagesize=A4, rightMargin=3,leftMargin=3, topMargin=3,bottomMargin=3)
|
||||||
|
elements = []
|
||||||
|
styles = getSampleStyleSheet()
|
||||||
|
styles.add(ParagraphStyle(name='master_title',
|
||||||
|
alignment=TA_LEFT,
|
||||||
|
fontSize=20,
|
||||||
|
leading=25,
|
||||||
|
spaceBefore=10,
|
||||||
|
spaceAfter=10,
|
||||||
|
))
|
||||||
|
styles.add(ParagraphStyle(name='day_title',
|
||||||
|
alignment=TA_LEFT,
|
||||||
|
backColor=orange,
|
||||||
|
borderWidth=1,
|
||||||
|
borderColor=black,
|
||||||
|
borderPadding=5,
|
||||||
|
spaceBefore=10,
|
||||||
|
spaceAfter=10
|
||||||
|
))
|
||||||
|
styles.add(ParagraphStyle(name='role_title',
|
||||||
|
alignment=TA_LEFT,
|
||||||
|
backColor=lightsalmon,
|
||||||
|
borderWidth=1,
|
||||||
|
borderColor=black,
|
||||||
|
borderPadding=5,
|
||||||
|
spaceBefore=10,
|
||||||
|
spaceAfter=10
|
||||||
|
))
|
||||||
|
styles.add(ParagraphStyle(name='turn',
|
||||||
|
alignment=TA_LEFT,
|
||||||
|
backColor=white,
|
||||||
|
borderWidth=1,
|
||||||
|
borderColor=black,
|
||||||
|
borderPadding=5,
|
||||||
|
spaceBefore=10,
|
||||||
|
spaceAfter=0
|
||||||
|
))
|
||||||
|
styles.add(ParagraphStyle(name='basic_text',
|
||||||
|
alignment=TA_LEFT,
|
||||||
|
spaceBefore=5,
|
||||||
|
spaceAfter=5
|
||||||
|
))
|
||||||
|
styles.add(ParagraphStyle(name='row1',
|
||||||
|
alignment=TA_LEFT,
|
||||||
|
backColor=white,
|
||||||
|
spaceBefore=10,
|
||||||
|
spaceAfter=10
|
||||||
|
))
|
||||||
|
styles.add(ParagraphStyle(name='row2',
|
||||||
|
alignment=TA_CENTER,
|
||||||
|
backColor=white,
|
||||||
|
spaceBefore=10,
|
||||||
|
spaceAfter=10
|
||||||
|
))
|
||||||
|
|
||||||
|
elements.append(Paragraph("<b>Fiches de poste</b>", styles['master_title']))
|
||||||
|
elements.append(Paragraph("Les postes de référents (référent staff, référent bar, référent run) sont réservés à des personnes ayant une bonne connaissance du lieu et de l'évènement.",
|
||||||
|
styles['basic_text']))
|
||||||
|
for role in roles:
|
||||||
|
elements.append(Paragraph("<b>%s</b>" % role.role, styles['day_title']))
|
||||||
|
desc = role.description.split('|')
|
||||||
|
for point in desc:
|
||||||
|
elements.append(Paragraph(point, styles['basic_text'], bulletText='-'))
|
||||||
|
elements.append(PageBreak())
|
||||||
|
elements.append(Paragraph("<b>Feuilles de staff</b>", styles['master_title']))
|
||||||
|
elements.append(Paragraph("<b>Ménage le soir même pour tous les derniers créneaux du jour</b>", styles['basic_text'], bulletText='-'))
|
||||||
|
elements.append(Paragraph("Tâches dévolues <b>à tous et à tous moments</b>:", styles['basic_text'], bulletText='-'))
|
||||||
|
elements.append(Indenter(left=20, right=0) )
|
||||||
|
elements.append(Paragraph("Veiller à la sécurité générale du lieu", styles['basic_text'], bulletText='-'))
|
||||||
|
elements.append(Paragraph("Ramassage bouteilles ou objets en verre", styles['basic_text'], bulletText='-'))
|
||||||
|
elements.append(Paragraph("Séparation des bagarres (rarissime)", styles['basic_text'], bulletText='-'))
|
||||||
|
elements.append(Paragraph("Sécurisation des personnes en difficulté (ou trop alcoolisées), etc...", styles['basic_text'], bulletText='-'))
|
||||||
|
elements.append(Paragraph("<b>Sourire et bonne humeur</b> quel que soit le niveau de fatigue ;)", styles['basic_text'], bulletText='-'))
|
||||||
|
elements.append(Indenter(left=-20, right=0) )
|
||||||
|
for day in turns:
|
||||||
|
wday = day[0]
|
||||||
|
day_turns = day[1]
|
||||||
|
cur_role = ''
|
||||||
|
if wday not in ['Mardi', 'Mercredi']:
|
||||||
|
elements.append(PageBreak())
|
||||||
|
elements.append(Paragraph("<b>%s</b>" % wday, styles['day_title']))
|
||||||
|
for turn in day_turns:
|
||||||
|
rows = []
|
||||||
|
role = turn[1]
|
||||||
|
start_time = turn[0].start_time
|
||||||
|
end_time = turn[0].end_time
|
||||||
|
num_slot = turn[0].num_slot
|
||||||
|
role_id = turn[0].role_id
|
||||||
|
turn_id = turn[0].id
|
||||||
|
if role != cur_role:
|
||||||
|
cur_role = role
|
||||||
|
elements.append(Paragraph("<b>%s</b>" % role, styles['role_title']))
|
||||||
|
row = (Paragraph("<b>%s / %s</b>" % (start_time.strftime('%HH%M'), end_time.strftime('%HH%M')), styles['row1']),)
|
||||||
|
for slot in range(0, num_slot):
|
||||||
|
cols_width = [100] + [485/num_slot] * num_slot
|
||||||
|
allocated_slot = []
|
||||||
|
for sslot in staffs:
|
||||||
|
if sslot[0].turn_id == turn_id and sslot[0].slot_num == slot:
|
||||||
|
allocated_slot.append(sslot[0].slot_num)
|
||||||
|
row += (Paragraph(sslot[1], styles['row2']),)
|
||||||
|
if slot not in allocated_slot:
|
||||||
|
row += (Paragraph(" ", styles['row2']),)
|
||||||
|
rows.append(row)
|
||||||
|
table = Table(rows, colWidths=cols_width, rowHeights=23)
|
||||||
|
table.setStyle(TableStyle( [('GRID', (0,0), (-1,-1), 0.25, colors.black),
|
||||||
|
('ALIGN', (1,1), (-1,-1), 'RIGHT')]))
|
||||||
|
elements.append(table)
|
||||||
|
styles.wordWrap = 'CJK'
|
||||||
|
doc.build(elements)
|
||||||
|
pdf_out = pdf.getvalue()
|
||||||
|
pdf.close()
|
||||||
|
response = app.make_response(pdf_out)
|
||||||
|
response.headers['Content-Disposition'] = "attachment; filename=feuille_staff_thsf.pdf"
|
||||||
|
response.mimetype = 'application/pdf'
|
||||||
|
return response
|
||||||
|
|
||||||
|
@app.route("/staffsheet/clear/<TURN_ID>/<SLOT_ID>", methods=['GET', 'POST'])
|
||||||
|
@check_session
|
||||||
|
def clear_staff_slot(TURN_ID, SLOT_ID):
|
||||||
|
try:
|
||||||
|
turn_id = int(TURN_ID.encode('utf-8'))
|
||||||
|
slot_id = int(SLOT_ID.encode('utf-8'))
|
||||||
|
user_id = session['user_id']
|
||||||
|
message = "Erreur lors de l'enregistrement des données"
|
||||||
|
if (drop_staff_slot(turn_id, slot_id, user_id)):
|
||||||
|
message = ''
|
||||||
|
page = str(request.url_rule)
|
||||||
|
menu = get_menu(page)
|
||||||
|
turns = turns_list()
|
||||||
|
staffs = get_staffs()
|
||||||
|
roles = get_roles()
|
||||||
|
user_id = session['user_id']
|
||||||
|
return render_template('staffsheet.html', menu=menu, turns=turns, staffs=staffs, user_id=user_id, roles=roles, message=message.decode('utf-8'))
|
||||||
|
except AttributeError:
|
||||||
|
# User is not logged in
|
||||||
|
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||||
|
except ValueError:
|
||||||
|
# At least one ID is not integer
|
||||||
|
return render_template('login_or_register.html', message="Identifiants non conformes")
|
||||||
|
|
||||||
|
@app.route("/staffsheet/update/<TURN_ID>/<SLOT_ID>", methods=['GET', 'POST'])
|
||||||
|
@check_session
|
||||||
|
def update_staff_slot(TURN_ID, SLOT_ID):
|
||||||
|
try:
|
||||||
|
turn_id = int(TURN_ID.encode('utf-8'))
|
||||||
|
slot_id = int(SLOT_ID.encode('utf-8'))
|
||||||
|
user_id = session['user_id']
|
||||||
|
message = "Erreur lors de l'enregistrement des données"
|
||||||
|
if (save_staff_slot(turn_id, slot_id, user_id)):
|
||||||
|
message = ''
|
||||||
|
page = str(request.url_rule)
|
||||||
|
menu = get_menu(page)
|
||||||
|
turns = turns_list()
|
||||||
|
staffs = get_staffs()
|
||||||
|
roles = get_roles()
|
||||||
|
user_id = session['user_id']
|
||||||
|
return render_template('staffsheet.html', menu=menu, turns=turns, staffs=staffs, user_id=user_id, roles=roles, message=message.decode('utf-8'))
|
||||||
|
except AttributeError as e:
|
||||||
|
# User is not logged in
|
||||||
|
print e
|
||||||
|
return render_template('login_or_register.html', message="Utilisateur ou mot de passe invalide")
|
||||||
|
except ValueError:
|
||||||
|
# At least one ID is not integer
|
||||||
|
return render_template('login_or_register.html', message="Identifiants non conformes")
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Main
|
# Main
|
||||||
########################################################################
|
########################################################################
|
||||||
|
139
participate.sql
139
participate.sql
@ -37,7 +37,8 @@ CREATE TABLE participer_thsf_users (
|
|||||||
name text,
|
name text,
|
||||||
phone text,
|
phone text,
|
||||||
diet text,
|
diet text,
|
||||||
is_admin integer not NULL
|
is_admin integer not NULL,
|
||||||
|
link_id text
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -48,24 +49,37 @@ CREATE TABLE participer_thsf_users (
|
|||||||
CREATE TABLE participer_thsf_roles (
|
CREATE TABLE participer_thsf_roles (
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
role text not NULL,
|
role text not NULL,
|
||||||
description text not NULL
|
description text not NULL,
|
||||||
|
num_slot integer not null default 2
|
||||||
);
|
);
|
||||||
|
|
||||||
\echo *********************************
|
\echo *********************************
|
||||||
\echo * Creating participer_thsf_turns table
|
\echo * Creating participer_thsf_turns table
|
||||||
\echo *********************************
|
\echo *********************************
|
||||||
CREATE TYPE dow AS ENUM ('Jeudi', 'Vendredi', 'Samedi', 'Dimanche');
|
|
||||||
CREATE TABLE participer_thsf_turns (
|
CREATE TABLE participer_thsf_turns (
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
role_id integer not NULL,
|
role_id integer not NULL,
|
||||||
user_id integer,
|
start_time timestamp not NULL,
|
||||||
wday dow not NULL,
|
end_time timestamp not NULL,
|
||||||
start_time time not NULL,
|
num_slot integer not NULL default 2,
|
||||||
end_time time not NULL,
|
|
||||||
constraint fk_turns_role
|
constraint fk_turns_role
|
||||||
foreign key (role_id)
|
foreign key (role_id)
|
||||||
REFERENCES participer_thsf_roles (id),
|
REFERENCES participer_thsf_roles (id)
|
||||||
constraint fk_turns_user
|
);
|
||||||
|
|
||||||
|
|
||||||
|
\echo *********************************
|
||||||
|
\echo * Creating participer_thsf_staffs table
|
||||||
|
\echo *********************************
|
||||||
|
CREATE TABLE participer_thsf_staffs (
|
||||||
|
id serial primary key,
|
||||||
|
user_id integer not NULL,
|
||||||
|
turn_id integer not NULL,
|
||||||
|
slot_num integer not NULL,
|
||||||
|
constraint fk_turns_turn_id
|
||||||
|
foreign key (turn_id)
|
||||||
|
REFERENCES participer_thsf_turns(id),
|
||||||
|
constraint fk_turns_staff_user_id
|
||||||
foreign key (user_id)
|
foreign key (user_id)
|
||||||
REFERENCES participer_thsf_users (id)
|
REFERENCES participer_thsf_users (id)
|
||||||
);
|
);
|
||||||
@ -85,6 +99,11 @@ alter table participer_thsf_roles owner to participer_thsf;
|
|||||||
\echo *************************************************
|
\echo *************************************************
|
||||||
alter table participer_thsf_turns owner to participer_thsf;
|
alter table participer_thsf_turns owner to participer_thsf;
|
||||||
|
|
||||||
|
\echo *************************************************
|
||||||
|
\echo * Giving participer_thsf_staffs ownership to participer_thsf
|
||||||
|
\echo *************************************************
|
||||||
|
alter table participer_thsf_staffs owner to participer_thsf;
|
||||||
|
|
||||||
\echo *********************************************************************
|
\echo *********************************************************************
|
||||||
\echo * Inserting user demo identified by password demo to participer_thsf_users
|
\echo * Inserting user demo identified by password demo to participer_thsf_users
|
||||||
\echo *********************************************************************
|
\echo *********************************************************************
|
||||||
@ -98,10 +117,108 @@ insert into participer_thsf_users (mail, password, name, phone, diet, is_admin)
|
|||||||
\echo *********************************************************************
|
\echo *********************************************************************
|
||||||
\echo * Inserting roles to participer_thsf_roles
|
\echo * Inserting roles to participer_thsf_roles
|
||||||
\echo *********************************************************************
|
\echo *********************************************************************
|
||||||
|
insert into participer_thsf_roles (role, description) values ('Référent staff', '');
|
||||||
|
insert into participer_thsf_roles (role, description) values ('Référent run', '');
|
||||||
|
insert into participer_thsf_roles (role, description) values ('Référent bar', '');
|
||||||
insert into participer_thsf_roles (role, description) values ('Préparation/Installation/signalétique', 'Fermeture des zones inaccessibles au public|Prépa buvette : allumage tireuses et frigos 4h avant ouverture + approvisionnement des bars en produits destinés à la vente|Préparation des différents postes / stands selon besoins : PLN, billetterie, T-Shirts...|Prépa toilettes public : aspiration/pompage, nettoyage à grandes eaux, remplissage du produit, changement poubelles, approvisionnement PQ|Nettoyage lieu, réapprovisionnement poubelles aux endroits stratégiques');
|
insert into participer_thsf_roles (role, description) values ('Préparation/Installation/signalétique', 'Fermeture des zones inaccessibles au public|Prépa buvette : allumage tireuses et frigos 4h avant ouverture + approvisionnement des bars en produits destinés à la vente|Préparation des différents postes / stands selon besoins : PLN, billetterie, T-Shirts...|Prépa toilettes public : aspiration/pompage, nettoyage à grandes eaux, remplissage du produit, changement poubelles, approvisionnement PQ|Nettoyage lieu, réapprovisionnement poubelles aux endroits stratégiques');
|
||||||
insert into participer_thsf_roles (role, description) values ('Volante', 'veille à la sécurité du lieu : rondes, surveillance accès, gestion de crises, messager, remplaçant, etc... (collaboration avec référent staff)|Ramassage verre, check PQ, ménage ponctuel|Sur le dernier créneau horaire, nettoyage de deux blocs WC|Au moins une personne connaissant bien Myrys sur chaque créneau horaire');
|
insert into participer_thsf_roles (role, description) values ('Volante', 'Veiller à la sécurité du lieu : rondes, surveillance accès, gestion de crises, messager, remplaçant, etc... (collaboration avec référent staff)|Ramassage verre, check PQ, ménage ponctuel|Sur le dernier créneau horaire, nettoyage de deux blocs WC|Au moins une personne connaissant bien Myrys sur chaque créneau horaire');
|
||||||
insert into participer_thsf_roles (role, description) values ('P.L.N', 'Accueil public, explication du concept de PLN, tampons (si besoin)|Informer et guider le public (prog, espaces, toilettes,...)|Comptage du public');
|
insert into participer_thsf_roles (role, description) values ('P.L.N', 'Accueil public, explication du concept de PLN, tampons (si besoin)|Informer et guider le public (prog, espaces, toilettes,...)|Comptage du public');
|
||||||
insert into participer_thsf_roles (role, description) values ('Buvette','Service au bar et encaissement (caisse ou tickets boisson selon besoins)|Nettoyage régulier : bar, tireuses, cendriers, verres abandonnés...');
|
insert into participer_thsf_roles (role, description) values ('Buvette ''bulle''','Service au bar et encaissement (caisse ou tickets boisson selon besoins)|Nettoyage régulier : bar, tireuses, cendriers, verres abandonnés...');
|
||||||
|
insert into participer_thsf_roles (role, description) values ('Bar ''concert''','Service au bar et encaissement (caisse ou tickets boisson selon besoins)|Nettoyage régulier : bar, tireuses, cendriers, verres abandonnés...');
|
||||||
insert into participer_thsf_roles (role, description) values ('Billeterie','Vente de tickets boisson / 1 ticket = 2,50 €|Poinçonnage des cartes VIP. 1 poinçon = 1 ticket = 1 euros|Tickets valables sur les 4 jours mais NON REMBOURSABLES');
|
insert into participer_thsf_roles (role, description) values ('Billeterie','Vente de tickets boisson / 1 ticket = 2,50 €|Poinçonnage des cartes VIP. 1 poinçon = 1 ticket = 1 euros|Tickets valables sur les 4 jours mais NON REMBOURSABLES');
|
||||||
insert into participer_thsf_roles (role, description) values ('Catering', 'Vérification de l''accès au catering (badge)|Service à l''assiette si besoin, gestion des quantités, réapprovisionnement du buffet|Maintenir la propreté des espaces catering (cuisine, buffet, tables, salle d''AG, tables extérieures, jardins)|Informer / rappeler le principe d''autogestion pour la vaisselle');
|
insert into participer_thsf_roles (role, description) values ('Catering', 'Vérification de l''accès au catering (badge)|Service à l''assiette si besoin, gestion des quantités, réapprovisionnement du buffet|Maintenir la propreté des espaces catering (cuisine, buffet, tables, salle d''AG, tables extérieures, jardins)|Informer / rappeler le principe d''autogestion pour la vaisselle');
|
||||||
insert into participer_thsf_roles (role, description) values ('Ménage', 'Nettoyage général à la fermeture du lieu : ramasser verres / déchets / cendriers, sortir poubelles, cleaner surfaces (bar, stand,...) + balai');
|
insert into participer_thsf_roles (role, description) values ('Ménage', 'Nettoyage général à la fermeture du lieu : ramasser verres / déchets / cendriers, sortir poubelles, cleaner surfaces (bar, stand,...) + balai');
|
||||||
|
|
||||||
|
|
||||||
|
\echo *********************************************************************
|
||||||
|
\echo * Inserting turns to participer_thsf_turns
|
||||||
|
\echo *********************************************************************
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (1, '2018-05-10 20:00:00', '2018-05-11 02:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (1, '2018-05-10 12:00:00', '2018-05-10 20:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (1, '2018-05-11 12:00:00', '2018-05-11 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (1, '2018-05-12 12:00:00', '2018-05-12 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (1, '2018-05-11 21:00:00', '2018-05-12 04:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (1, '2018-05-12 21:00:00', '2018-05-13 05:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (1, '2018-05-13 12:00:00', '2018-05-13 18:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (1, '2018-05-13 18:00:00', '2018-05-13 23:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (2, '2018-05-10 12:00:00', '2018-05-10 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (2, '2018-05-11 12:00:00', '2018-05-11 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (2, '2018-05-12 12:00:00', '2018-05-12 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (2, '2018-05-13 12:00:00', '2018-05-13 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (3, '2018-05-10 12:00:00', '2018-05-10 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (3, '2018-05-11 12:00:00', '2018-05-11 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (3, '2018-05-12 12:00:00', '2018-05-12 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (3, '2018-05-13 12:00:00', '2018-05-13 21:00:00', 1);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (4, '2018-05-08 14:00:00', '2018-05-08 18:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (4, '2018-05-09 14:00:00', '2018-05-09 18:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (4, '2018-05-10 13:00:00', '2018-05-10 15:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-10 14:00:00', '2018-05-10 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-10 17:00:00', '2018-05-10 20:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-10 20:00:00', '2018-05-10 23:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-10 23:00:00', '2018-05-11 02:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-10 14:00:00', '2018-05-10 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-10 17:00:00', '2018-05-10 20:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-10 20:00:00', '2018-05-10 23:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-10 23:00:00', '2018-05-11 02:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (9, '2018-05-10 20:00:00', '2018-05-10 23:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (9, '2018-05-10 23:00:00', '2018-05-11 02:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-10 14:00:00', '2018-05-10 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-10 17:00:00', '2018-05-10 21:00:00', 3);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (10, '2018-05-10 12:00:00', '2018-05-10 14:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (10, '2018-05-10 19:30:00', '2018-05-10 22:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (4, '2018-05-11 13:00:00', '2018-05-11 14:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-11 14:00:00', '2018-05-11 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-11 17:00:00', '2018-05-11 20:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-11 20:00:00', '2018-05-11 23:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-11 23:00:00', '2018-05-12 01:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-12 01:30:00', '2018-05-12 03:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-11 14:00:00', '2018-05-11 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-11 17:00:00', '2018-05-11 20:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-11 20:00:00', '2018-05-11 23:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-11 23:00:00', '2018-05-12 01:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-12 01:30:00', '2018-05-12 03:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (9, '2018-05-11 20:00:00', '2018-05-11 23:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (9, '2018-05-11 23:00:00', '2018-05-12 01:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (9, '2018-05-12 01:30:00', '2018-05-12 03:15:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-11 14:00:00', '2018-05-11 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-11 17:00:00', '2018-05-11 20:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-11 20:00:00', '2018-05-11 22:00:00', 3);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (8, '2018-05-11 20:00:00', '2018-05-11 23:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (8, '2018-05-11 23:00:00', '2018-05-12 01:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (8, '2018-05-12 01:30:00', '2018-05-12 03:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (10, '2018-05-11 12:00:00', '2018-05-11 14:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (10, '2018-05-11 19:30:00', '2018-05-11 22:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (4, '2018-05-12 12:00:00', '2018-05-12 13:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-12 13:30:00', '2018-05-12 16:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-12 16:30:00', '2018-05-12 19:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-12 19:30:00', '2018-05-12 22:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-12 22:30:00', '2018-05-13 01:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-13 01:30:00', '2018-05-13 04:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-12 13:30:00', '2018-05-12 16:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-12 16:30:00', '2018-05-12 19:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-12 19:30:00', '2018-05-12 22:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-12 22:30:00', '2018-05-13 01:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-13 01:30:00', '2018-05-13 04:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (9, '2018-05-12 19:30:00', '2018-05-12 22:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (9, '2018-05-12 22:30:00', '2018-05-13 01:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (9, '2018-05-13 01:30:00', '2018-05-13 04:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-12 13:30:00', '2018-05-12 16:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-12 16:30:00', '2018-05-12 19:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (8, '2018-05-12 19:30:00', '2018-05-12 22:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (8, '2018-05-12 22:30:00', '2018-05-13 01:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-12 19:30:00', '2018-05-12 22:00:00', 3);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (8, '2018-05-13 01:30:00', '2018-05-13 04:30:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (10, '2018-05-12 12:00:00', '2018-05-12 14:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (10, '2018-05-12 19:30:00', '2018-05-12 22:30:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (4, '2018-05-13 13:00:00', '2018-05-13 14:00:00', 4);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-13 14:00:00', '2018-05-13 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-13 17:00:00', '2018-05-13 20:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (5, '2018-05-13 20:00:00', '2018-05-13 22:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-13 14:00:00', '2018-05-13 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-13 17:00:00', '2018-05-13 20:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (6, '2018-05-13 20:00:00', '2018-05-13 22:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-13 14:00:00', '2018-05-13 17:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (7, '2018-05-13 17:00:00', '2018-05-13 19:00:00', 3);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (8, '2018-05-13 19:00:00', '2018-05-13 22:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (10, '2018-05-13 12:00:00', '2018-05-13 14:00:00', 2);
|
||||||
|
INSERT INTO participer_thsf_turns (role_id, start_time, end_time, num_slot) VALUES (10, '2018-05-13 19:30:00', '2018-05-13 21:30:00', 2);
|
||||||
|
213
pdf
Normal file
213
pdf
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
%PDF-1.4
|
||||||
|
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
||||||
|
1 0 obj
|
||||||
|
<<
|
||||||
|
/F1 2 0 R /F2 3 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<<
|
||||||
|
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<<
|
||||||
|
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<<
|
||||||
|
/Contents 15 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||||
|
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||||
|
>> /Rotate 0 /Trans <<
|
||||||
|
|
||||||
|
>>
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<<
|
||||||
|
/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||||
|
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||||
|
>> /Rotate 0 /Trans <<
|
||||||
|
|
||||||
|
>>
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
<<
|
||||||
|
/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||||
|
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||||
|
>> /Rotate 0 /Trans <<
|
||||||
|
|
||||||
|
>>
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<<
|
||||||
|
/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||||
|
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||||
|
>> /Rotate 0 /Trans <<
|
||||||
|
|
||||||
|
>>
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
8 0 obj
|
||||||
|
<<
|
||||||
|
/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||||
|
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||||
|
>> /Rotate 0 /Trans <<
|
||||||
|
|
||||||
|
>>
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
9 0 obj
|
||||||
|
<<
|
||||||
|
/Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||||
|
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||||
|
>> /Rotate 0 /Trans <<
|
||||||
|
|
||||||
|
>>
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
10 0 obj
|
||||||
|
<<
|
||||||
|
/Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||||
|
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||||
|
>> /Rotate 0 /Trans <<
|
||||||
|
|
||||||
|
>>
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
11 0 obj
|
||||||
|
<<
|
||||||
|
/Contents 22 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources <<
|
||||||
|
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||||
|
>> /Rotate 0 /Trans <<
|
||||||
|
|
||||||
|
>>
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
12 0 obj
|
||||||
|
<<
|
||||||
|
/Outlines 23 0 R /PageMode /UseNone /Pages 14 0 R /Type /Catalog
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
13 0 obj
|
||||||
|
<<
|
||||||
|
/Author (\(anonymous\)) /CreationDate (D:20180305200013-01'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20180305200013-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
||||||
|
/Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
14 0 obj
|
||||||
|
<<
|
||||||
|
/Count 8 /Kids [ 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R ] /Type /Pages
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
15 0 obj
|
||||||
|
<<
|
||||||
|
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1895
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
Gau`U?!#c?&:N_CbT!o.P1]Tu3VuX!g7Fl<PX:[aac!5K7]g14P*IWrlh?G+KVX:&qp>+'"3@dD);ViEB,XS_?\/6A9;7=nFZopBKJZt2cu8YmH:dS'-f7^OC?C2hh,/M]SrE1@`k-]T`$]defW7!(kn5M#'R"buE5:e0IF.ON=dgk`1L$eZ2#U%qf=_)!Hu8=,)YO)RO.]itK&c]%ps@[S&j,mMrC1DM)[$QJ0IeY*c-CK&a;/6iB`0cK,%7(&)4/WTOj3Z&*jj(kr(idSqH[olI?hY?'YfJpJU&kJ'_)/pHjX_m8EIkZZali!.n?VtUF)nO)DBc<eIjsP%ln;74EJm:7ni[_s4YBiW&pB25"k-f^u'e7W#^m&6OH19MCr64(&,<u>[QBKB5bH9\M0c)=k`\9_KSRLraBr>MM.T<qR\h6[GbZ^jSQCA^!QEYl0R3/MBrcSHM?eu]@Xs,koAncAuQ+Bg\IlKc1m`L.\p%pl6tUaF-O9bd;j[5o;C47=V?D4=L,XHMVLf=Kq^MZMf;<$.k7o'cGCEKC124S=mA55=>:dO9K1f1Iuq`mPHD4B$r9?^pBkl#2cIT"\^L_;O=bRc"nP./$F<_q(C_aEAmJAFe_<"6M_--O.&+T^ONoF\Q!dpoCo1,=LYc9B[j]Zr_@AJ-[:jl8pRk5hg[0/Yj+kO=N8Mre[B8?dqEBQHRJ%EK$J>h&S*MPWo5'fs1bD<S-[TD%pe-VVI)6^5mK[u5/b=Y+$]dSV'fK5@+%.$6fZ>oc.JV&op:08O3S&)^*+4S2^EJ?AhKXTc\OlkJ&&0h7K^f/l1,g)+MCmadINrG/Zo'QN5#8&jS&b!(7&1(:mpORZ$G#ngA'So3`j/+21YTI,eg^2"R>`<C,4!I1hr2dO?usVc(lk#oI,pJJg@EIanea8"U'7tB_%A7qV*n-I)orHR6s2qs@\rd0K"VM#p?I`$7kYLkmfi?c=GekO62X2la=?upd0F=Rq,;a,B;mGP9'QG#0PDjon!p))F14^un0.`^UgPTs^kHL/_d[]d7W:gg-8#2pY,6(7L(a>e7n]Iu=>6mHjHaD2+P"QU=-)Lk1>nRH_(g;,:t*dqH[PM=^2.-u#a50tglV-(F<HYp6%TPp+PY"12`SMTWH,2h]d>/G&eW$HK[l>oGRFGfDXWX=Ak`,e/i&5i_kJi.)DT1(<%3FP)%p0_]59/GoAi@s[(qR,D&`2<Z0`Pg9X0m1^S'H\42HB9(q?O:qJ##PjA$4S_bPk+P@d\BC<iW8MZF$@8gUf?WI9jQr?%sa:hn'i$Gn150S3]cOjLLUdsY).*)#XD&rg26C#r&lqQHqJA5(QuG_0:N%Ya,)+HAb4^*p!e%.qQ[0A%psJZ#*S9Q:>S]uG*hOhoUa.`!2GC^oJ"$XYE*WI+\[@8fbsSpM6C_gf['#HsJ(oI#?p6'l1l[p.2'@8m""L.)?I(D_gHg!>huE0YqQl)'Fdo$%;>[:N`2b*f>CD&P<td\kV9XTYXYY-Y7^rg*EQ206dc'!spUT<IMQrRJmM^M`Ms?<k4ZX(bQ9H2jGn^e!KQOjR.F^\<G`?>Ll?GG<]31c)J>%M(U\`&q(CaYmrbZ`g]-fg7Ye"g#E&g?A4smXV/&%L#nd?Ec*VHlt$d[ofT'T'aA(To/kBBFnIL%JNV*6uGuS38o$eWURB8<'"-LU38/kj77pLY!lA:>]$+IrO<n9@8rIn!Jg0/YJSM5+o)>[L/c0iqWX*Xc)RQhJ)CC-F#Hq+,$RDYc^]49b"E7)Tr)u2j#?P3eifN*]Fk@,[ITnW:[AVW_'>+;CN&b8+#6Vt4l<N]"]bDs6Z_,bI,KD!fbR+:1D!;cSS++B&h.-U[TIdE1LZ]b*GOF'0?[Sr""Gi6qBmB5aaYZg2qn~>endstream
|
||||||
|
endobj
|
||||||
|
16 0 obj
|
||||||
|
<<
|
||||||
|
/Filter [ /ASCII85Decode /FlateDecode ] /Length 955
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
Gb"/%>>O!-'RoMS30+*"?p",M%;G/QO9S+"lAM.C`DnP0:1-;9a%k?aPbOmh'MTumS/`UmJ"MeJk>3:G;1$UrJ?oqbcRDZpkmXNZqN,%!kB(f)U7Gou0o=[F:1>2nG%0iR5/O"8*A)fK^dnkN0p,RGi]-+qOa/Q99EjXKcXo\//g*;81L/lrS0a&F_(6PA=W8>hg>E2%"fuZnF(1nRaJY`:'sur``:Z7Z9;g]QNkKt/HnHO3Pa,3ETS4*^Q;s]QXr7a$#?=Bi1h=ah&A7fBdfpTO[Gl>Wa*ihS)#l&(m6U]0m@ZX65<Ks550IgQ#m:.?ar>`:1&HZEd##,O71K2g;&,h,Fm$FFmX3fF1IKRkrMOq;]CPesR(]D$-92<JW+V*Q[<[;59qo0INeteEk#+&5P4JOgOLjQXf@k&l8_)=bXfe[TC9eC.-E`#KTp42r#)s*[j2S1tOt0k^Wl3'.0]@)5^bq&k`KeqV(1MZu0+UAZaM[?nh(r3.7T<qJCc8/22Nq:-[sN#Z@&dsA/V3(f<TVZs8YO0p+0al_f6-g5*6-iN-jeX+OrG)sWJ"-)M'3279d)Rr)i+UO2'Ot<,H/!^el(A"@%)^UL.aDESko6[(WhDRlhn<mJdr=dG=+S=6.4nuKTj4LJiIdR'SO7=+P=#1)t=*PK6,/b<'GA,KjO<i-5QEEDV'qYhkPZ;fafsAS^VL'*isYD^1]M[H#EIoM2T+^J)H&f'I<d5,[Ae8Jp=qX2SKG`n64Q0"!'JP'?A*3=j:9uMY^ZdJQ&3r[QAJ-Z>4>MOr$g+8M9L;9"T\0op-S"[k!P/DZY^Wa);$7+!q64nK%Xf^(+HH!.D'_Qj3dqSSoQi\ERD/-F.&']h@,UBH/>#T4unH`i(b`G&>0Y/Sd31g?=<`24Cs04r+m'me)9/W(`%\[4Va<s.FK89A[)E?0g@TmU03'UYkMbV=F~>endstream
|
||||||
|
endobj
|
||||||
|
17 0 obj
|
||||||
|
<<
|
||||||
|
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1197
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
Gb"/)>B?5u'RodXS@>;^$/,3mX)6<BPA-N9ku1q_7E:@ML1'oQHPR0s$7]$.UeIMPS6an\c?HEA"bJrqIfD,-kRZV2Oof2K(]tM5JAD]-+7u.N1gT?sbD>2iSr4DXSAb!1&%LOV^)SFUOWKCs8M>U8BmunZ*N#Y7`ZXoIJ(D6VY/Fn].Euhic?$q>J<C`O1C-aZrP`IH"pPSl3&>esj%m`NC!Wou`3bUc$LJ0qs"1Ogmp+;GGmjQnK'-f,*gZqn%cpl@'"!f>hVrGC__6E8b+i%RPP`6TOPY_[EF#mhiK*_g:Y?I+DukpU=GiT2ZFttSHYgEBF,WZ1j#B+;_.hsp7kjLBmY<$:$08b/Uk%_K?Os]9*@=Y2"q]fK8#8iL`sf\Z+;5>iOcXr^1ATOEPU,S=QjV#Y.@;-eN-0rf,ch/TEdSobeKs;Q.u5e++$,Br7s7"m&MA\&/jnU#<mWC=)760l/i6K1?f*?XmYBa21ujmHZW:f6U*C=LNje'&^4_5Y5DS2ORQ^ol*s52mB!^QjkNO6/cHLYmI9QC\>Z;"GV7+A)nUug"f&Ir#?>V;%ii&]ol[QX]ar"6J=G+JX[KR!SmK&tO^*sO+Uh_rCnlj&<br:H$h]SqHK?+g.q1\mk5\$K*1EdPc(7Hrk$H6MK),"4mP\ijqDi_55&FJI8Qn9ITUi&QOEuU(%g;Ke?k0.'bf&Fmpf%LB<jgjQqc(lbr^eQeT6j^bak?5YUh5l!BiqaMLRNq>s.FK@a<&74'#uqBSVG8kZHX'6$B%fZ8JF_qL`N36n?:")'buZDWb]haF@Joo_]71$-(mEbt8!d)e8u'=/[)4;;ZSlQ2Pd\O%",5'iQsP?KH@T"$>Fd)'`qd!Tpu@'l_#Ln=gT02r._jdi5H\i`\8>@DFnDu&?IG"f<R]*dUR.8<@[?YgRc`6C]e#lo-J:erPSNm.^\fMNiT,GBS,"Gdo0^H*LC(>U+1f<$eKmmt`K?+Q/gbAY67orM_'HFAEk9q*.]B:Q2=$5B"^T[3:o0_BUZ)id['O`t*8;mef.#"G.*f.f><3!=m2W&kk<Q8)pLYr_#HX#!*'#!40a^<t38NP\R!RR;5hBuA:'#0E/ETF$]2O7*-p+32_'nh>agSeZDhfZs#Ep1F345UAT713/0'p0@`lmdaAG#HPI_SqNe'#A_EL+[bm-+*Tklnab-2,Qo~>endstream
|
||||||
|
endobj
|
||||||
|
18 0 obj
|
||||||
|
<<
|
||||||
|
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1099
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
Gb"/*>u03/'RfGR\8O&HJpmT_]N3b+-8b6)n[+V_.4P[5KQR+gZ]gK(PpC47)QU8ZCUeBLPMC4sI'3t_U46kHH2@k$%H6@U"c<l:J9$]<GQseXan(0d4Tk29GeP9pq?1X_L&LSCmdN`]4inENJMq*6P8'%2GmRi'W.Y:AaC:MX9eP]eFZ2H3X`<Qe+#O6*8dYu?&0,#sl!5(^bs+Mh!9'&kFA[EW"%rfH+"UArka!`k1\uU;?2eAdcHJcoV`DENd;7A?<-XWV'aRW6e9K`C(&,K9ol'94"BJj$mK;!NQm9=`H>E;^p#/h3,m6sCWGXe;;pmN]=)<l4hd.9XI6Ys'n.#reFn"G"\V9+VIQoZloh]>b)A(!J;*.[C?P9lKJ<_JP`^6+HjhZGlUSR6hg</(05E9p^YOJ%T+5tLp_uA,9U-F*D02Q2;F>urb4fT5RF(&N@R`STX+-gFs;76PNQmL/(d;2OGdBTG!H"JJu/'=T6rfj"%9D-4N8]j8(k4`SSR,e#?GnKf?:R:nlb*Fa%9)d3IT;IhU)tQk0pZU570&]&p<o@B@[fQf$_8nTjU&n\^$G8#An@DP*<(Jk[BON`7D.FUoUM4KgQ`Mm0[Nh^V1"N\sqC.9LI$K55[QLd='en-L!<X4mR$a*n:G+H0D-fT0gI!`^8D_`]#JG?n=@+Z@c%h+Mf+-2$8NZ-9d)s^n\`o-Dmd0%WV\,c>6p!e>jWK5J1+,[Ab.SQ:,BemK&>Kg`F/!cNge1KK^r]]:XQSH.pLC]a^m$FOWidnWK6\CL[T&f&=^W'1KpG]/5$A_@oWjWd`0RFP#8:?40,s/0^*WH9O/?ZP?5Cp=!0hT$Ugq"2*Tq\V#<.PdM%>?i%n,:b$+TV;LEt6nMqF3K](BKVkTsRp!E.g<m']YRE5P[I^3NFK]j&raIC3,/=_lhC%Z[*feh,htU,ZAS3:!>!X#gd?3+Z+MPcYiOa--1om?h$Q3S*?7Bp?HMm8J<MBDDo+$At-cO*(7&ga^C:YC\U*,hs#0]);\*PYRHs./fl@T]G=2FSc63./-u2!JmCGj-D(Fo-B1a31I,@^B>r:M&C2Sm:+(A`XJ74"heu=!W~>endstream
|
||||||
|
endobj
|
||||||
|
19 0 obj
|
||||||
|
<<
|
||||||
|
/Filter [ /ASCII85Decode /FlateDecode ] /Length 484
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
Gb"/%gJ.f)&:O"KbbL=tAu><(N(T$^BRdfG&;cK69`0=nm]s&@&+C^28G4g.1RF[kF4qqUFA[=u/c^V<#'U3g&>qcsC5@pi)oYEG*GM<Lc34:kKChA&PUE[pf/'\Ra-+bqfbRPIcTo3B`j0j%cdD%b9RC6=gq*`hiL&m^;LNH5^LB&eKE33T'OF.s6gWo3a/.32S++eWK].a'gQOEc;Kg&=\:VuXr>g!@#IE_!&#F\%G\A&Abi9j0o=F_G]o['gX&*1-$SYoMNt6K<BiP_Q&DW">c6%=b<EusAa@lc][K2ZU!bU2;g8Y3d>D)<3CddO#m=m$I(pbX@Ls/;P(K(/r;$Lu?2elT7-UVSt"OaU)-<]`K<qR+"9tlU2P+Ak77:,6;naa;;q4+PDQa;=eg[5o9]!5`V=3!;bA5Ci43:/Z&Fs`?7G/#nYi?P`+G>-;YP$\?3W4gQ%UqK*;+>KM^Q[!5JZaUa,DeX0S&H~>endstream
|
||||||
|
endobj
|
||||||
|
20 0 obj
|
||||||
|
<<
|
||||||
|
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1099
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
Gb"/*>u03/'RfGR\8O&HJpmS4^K0(.-8b6)m:e3S;H/m8&^p(8cV@)qY,#DuNRq@@2;C1a8U\m`mu=#+bRZ:4mj8%P#gPV2TErpN-kA:*([s-t4:gYWVhPaS&;E5&-^ZkBj4BntLYq538?Rcq-Bp_'1,p$B+[Qp:&eYa!:LJE&\>mk3h9;P!`aM?.(^p\7PShak3514sao1u:7#qnM=?osL>;W";%[V`5`J&$:$9=m](>AEl-KrObj@NCf9+d4SSNoV/R8R4=P+otN*j,A4>Alb#fh5`'opIut]*s$3$uKnbJ$_4`MW]Z.)'CeR-Z2Pf`o`.q0_kRb+Z#aG4W<.o0t\!Fg((TRHo96jAnhD^Ao]I/A2#_O.I8]:grt:K+YjiW9pb/'?ft9aos=$:fJS-uh3brthTYm0iTG.Pr#)83mU!L]ML:kp[L$Y;Fb45^-8qWeD#&F]1qSb=2/'uLEALCs%;A</EjNsE;XA%da2Rg&48Y2/Khn.<J%U^^Z8f84Mt-Bq=i*C+nP:RRClYggpd^1tRX]q&7DDlF!=,?>!XIbZ'0*MO4l]Z+$@L59pbGq/Ff/fRO;TCl12,E'a>fJOgX\YC=W+S`LT(R,f6>j@V_l\VFUS@Xq8-V(X>C?"g+<^8c.UhaP>W1;7:s!G)b>*q8GWt@)g^_@(Y@@QHH@&<[&;Lsd7[&$kbTeU+`9e'^YJA&Sc=)JdtlFWU(a7P`FpcJe;Mb5o"[]9L`<'>`Fq]^]dUQB%oSW139f`UlXb#IHs9kl@*4bHWkL$gLNsgPY#Ls>=^W?9Ks"CGhH:W`oQ$+$`0%(KHP9X[0,Nl,Td05opSM\s?4P@U"%q9GdP79k8r=gDUYBLO-:b,c&&cg($2F.&O!N*!Mn"r+qXe9IkTsRp!Rf>[m']JM[bHJS\$,%q2f!_S=fk\Ielm9TK4APrF[nDl;4K49S1UKqX#mG^EQVFD;mpG2*%Tn#[UWl7ARCoSLN*eoG>HmtOr%o8.k&!74jrd8n97/.q^tDa9#BBqV;Era7Hm6DM)$Vt"\SJ@9#"`KMt4YPWBo`;NB:HSO4,p7P'jp^rt:uH`&%>Vg3^h*H3OfW!.i^^Sc~>endstream
|
||||||
|
endobj
|
||||||
|
21 0 obj
|
||||||
|
<<
|
||||||
|
/Filter [ /ASCII85Decode /FlateDecode ] /Length 480
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
Gb"/%9htgF&A@P9Qm7bj3n*OJ7O?%^g-8sZLdXcV-N8ETh.:$64hsA78.%H>bsu-1H*\X7ZnO^OQ2mZc_cm6hLbh:J1rKX/M8d'A.aeU'S-oP6%)Vo";dLWRF#,JXq(h-^6+-s9nI4nZ)6<,oSte5CR.ZA/Epjg_RU`A,9_GA^^IL+]&r%M`fdhjdLje-&Ot1CU;7>kO1*!QEo5I/*A7p:D*c1Qlm%FYHLg2<P..'+46ecQl*r"p2W/<gr'nQjAAdY>A$-$c[nIA>0XV-d+7.*B6kI3R<AK9GC,f0tqX[/d4K5>=">EqL_("g1;>*R=eDMU'+O[Z6&U:c<Q?]$UhZas2tH?U3"7mR]PS2SK(kI%=mG[U;V]G'@b9e?(:8&rgAqY=X4H!ANtQ+*5"$G/#ION*G2#3o_pQl)(Mc)I7jW.[<Mc$f?mXo9B*F/e4*6+"%doGqYL:qi%^^VrimrPeJ^iX9_/P7[~>endstream
|
||||||
|
endobj
|
||||||
|
22 0 obj
|
||||||
|
<<
|
||||||
|
/Filter [ /ASCII85Decode /FlateDecode ] /Length 981
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
Gb"/i>u03/'Sc)R/'].DM-qET`OFY>S'Wuo[&`#9/nIIg(a7`7rp1o+@3nVeTuL%I["]6lIM4qpm2h#a0gE$iT.Bu^&Y+9B5S9_>:`aS30&V.7\f]>"VM5XR&;E5&-^ZkBi`@3rKtlab8?Rcq-C!>F;E,Eb=+i%g,pXU"QGE9+FBP5MWgQ=jXi%NY0H(KN.5[\tE;XU^LssJLj:+Md&=lopQc4`]A18O:P(ec$;fWUn7UK3OeIO"je@oKcR_qK6:T(<]76m8=>(Dd1f%Y#C\GqPLIrb90Yk%Wa*N1U.*XP2<gW6#T/t_,`+`IWB1hE_*9%r"]MXAdcdu-S*mY<qDrIe[*D#CXXDCG<s?FQu<%8`G;[3C^K_K;TXJ'?kU-*.N;-P<Ya;BGc)4A*bB[]G'trQ!<JrX6pK6g"9L]DmgeD"b(2)+Cu-]59m'<o(QmZ3d<JZY_C[%=]H6Zg0U*!]/trRsE5$_i,)eAm[?Pf^CeXo@[Dqp*hj,TD?.tk@&Ot`cHJhTA;0TQYdq.-%A7l@WSVS%InoF;5/F/-eNM8254kI&=!ni(_<1a_5/2T8!baqF][Lj>_1Ll2Ru.h8>&DuQ?A://:t=3K3Y]+BZh/i&Rq]LlhfL#:@i<2"'q>!G\%_lT4&ie]tpM/"`g0XApB*)\j%K.%?bAD6OR4*CIdkleU!$r]FG3#-/HA;^rkYj*j8Y+QNf);:u;J/Mr78&[*=`E!PY27%g`(O0@nbYnC+hdl_X,LNpPHoC&<GMd_Gu)B\FL\s!2l]^sVgq5#73M-ZIYh4n02q*s+)O"Q\T,"DV$/^srQ_FjE0(n"4MtcfQ1sVED)!bldE7#KPCXn=F`D+jSXNB:BHFFet,rX/tlqZB9Xu=E8?'(@+IJ<2t'\B5f]<9.*;sDdiS-bju=uYC-o#prrdUlu@unELp^IoVS++lInTBI<R&%q[TmG_Fno>nC$L$HME);]Numj0_u#;V"F<~>endstream
|
||||||
|
endobj
|
||||||
|
23 0 obj
|
||||||
|
<<
|
||||||
|
/Count 0 /Type /Outlines
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 24
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000073 00000 n
|
||||||
|
0000000114 00000 n
|
||||||
|
0000000221 00000 n
|
||||||
|
0000000333 00000 n
|
||||||
|
0000000538 00000 n
|
||||||
|
0000000743 00000 n
|
||||||
|
0000000948 00000 n
|
||||||
|
0000001153 00000 n
|
||||||
|
0000001358 00000 n
|
||||||
|
0000001563 00000 n
|
||||||
|
0000001769 00000 n
|
||||||
|
0000001975 00000 n
|
||||||
|
0000002062 00000 n
|
||||||
|
0000002346 00000 n
|
||||||
|
0000002450 00000 n
|
||||||
|
0000004437 00000 n
|
||||||
|
0000005483 00000 n
|
||||||
|
0000006772 00000 n
|
||||||
|
0000007963 00000 n
|
||||||
|
0000008538 00000 n
|
||||||
|
0000009729 00000 n
|
||||||
|
0000010300 00000 n
|
||||||
|
0000011372 00000 n
|
||||||
|
trailer
|
||||||
|
<<
|
||||||
|
/ID
|
||||||
|
[<daed391e39bf0175680b4a859bbc42f7><daed391e39bf0175680b4a859bbc42f7>]
|
||||||
|
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
||||||
|
|
||||||
|
/Info 13 0 R
|
||||||
|
/Root 12 0 R
|
||||||
|
/Size 24
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
11419
|
||||||
|
%%EOF
|
5411
reportlab-userguide.pdf
Normal file
5411
reportlab-userguide.pdf
Normal file
File diff suppressed because one or more lines are too long
BIN
static/images/print.png
Normal file
BIN
static/images/print.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 347 B |
@ -59,3 +59,15 @@ function save_turn() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function update_sheet(turn, slot) {
|
||||||
|
document.location = '/staffsheet/update/'+turn+'/'+slot;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear_sheet(turn, slot) {
|
||||||
|
if (confirm("Voulez-vous vraiment libérer ce créneau ? \n\n Confirmer ?")) {
|
||||||
|
document.location = '/staffsheet/clear/'+turn+'/'+slot;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -247,3 +247,10 @@ function upload_file_from_ajax(obj, url, err_code) {
|
|||||||
}
|
}
|
||||||
xhttp.send(formData);
|
xhttp.send(formData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* **************************************************************************************
|
||||||
|
* Printing
|
||||||
|
* **************************************************************************************/
|
||||||
|
function print_page() {
|
||||||
|
document.location = '/staffsheet/pdf';
|
||||||
|
}
|
||||||
|
@ -24,4 +24,5 @@
|
|||||||
--search_icon: url(/static/images/search.png);
|
--search_icon: url(/static/images/search.png);
|
||||||
--trash_icon: url(/static/images/trash.png);
|
--trash_icon: url(/static/images/trash.png);
|
||||||
--upload_icon: url(/static/images/upload.png);
|
--upload_icon: url(/static/images/upload.png);
|
||||||
|
--print_icon: url(/static/images/print.png);
|
||||||
}
|
}
|
||||||
|
@ -3,3 +3,65 @@ main > article > p.note {
|
|||||||
display: block;
|
display: block;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
article > div.table_header > div.sheet_day {
|
||||||
|
background-color: var(--coloured-bg);
|
||||||
|
width: 100%;
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--white);
|
||||||
|
text-align: left;
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_header > div.sheet_role {
|
||||||
|
background-color: var(--light-coloured-bg);
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 5px 5px 5px 10px;
|
||||||
|
border-color: var(--coloured-bg);
|
||||||
|
border-style: none none solid none;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > border_right {
|
||||||
|
border-right-style: solid;
|
||||||
|
border-right-color: var(--coloured-bg);
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_time,
|
||||||
|
article > div.table_row > div.sheet_user1,
|
||||||
|
article > div.table_row > div.sheet_user2,
|
||||||
|
article > div.table_row > div.sheet_user3,
|
||||||
|
article > div.table_row > div.sheet_user4 {
|
||||||
|
width: 125px;
|
||||||
|
text-align: left;
|
||||||
|
padding: 5px 5px 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user1:hover,
|
||||||
|
article > div.table_row > div.sheet_user2:hover,
|
||||||
|
article > div.table_row > div.sheet_user3:hover,
|
||||||
|
article > div.table_row > div.sheet_user4:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user1 {
|
||||||
|
text-align: center;
|
||||||
|
width: 780px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user2 {
|
||||||
|
text-align: center;
|
||||||
|
width: 388px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user3 {
|
||||||
|
text-align: center;
|
||||||
|
width: 257px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user4 {
|
||||||
|
text-align: center;
|
||||||
|
width: 192px;
|
||||||
|
}
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
* HTML header section of the index.html template file.
|
* HTML header section of the index.html template file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@page {
|
||||||
|
size: 21cm 29.7cm;
|
||||||
|
margin: 30mm 45mm 30mm 45mm;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@ -169,11 +174,13 @@ main > article > img {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
main > article > p > a {
|
main > article > p > a,
|
||||||
|
main > article > ul > li > a {
|
||||||
color: var(--coloured-bg);
|
color: var(--coloured-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
main > article > p > a:hover {
|
main > article > p > a:hover,
|
||||||
|
main > article > ul > li > a:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,6 +233,9 @@ footer {
|
|||||||
|
|
||||||
input[type='text'],
|
input[type='text'],
|
||||||
input[type='password'],
|
input[type='password'],
|
||||||
|
input[type='number'],
|
||||||
|
input[type='email'],
|
||||||
|
input[type='url'],
|
||||||
textarea,
|
textarea,
|
||||||
select,
|
select,
|
||||||
pre {
|
pre {
|
||||||
@ -298,7 +308,8 @@ input.refresh,
|
|||||||
input.save,
|
input.save,
|
||||||
input.search,
|
input.search,
|
||||||
input.trash,
|
input.trash,
|
||||||
input.upload {
|
input.upload,
|
||||||
|
input.print {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -315,7 +326,8 @@ input.refresh:hover,
|
|||||||
input.save:hover,
|
input.save:hover,
|
||||||
input.search:hover,
|
input.search:hover,
|
||||||
input.trash:hover,
|
input.trash:hover,
|
||||||
input.upload:hover {
|
input.upload:hover,
|
||||||
|
input.print:hover {
|
||||||
border-color: var(--text-color);
|
border-color: var(--text-color);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -369,6 +381,12 @@ input.upload {
|
|||||||
background-position: center center;
|
background-position: center center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.print {
|
||||||
|
background: var(--print_icon);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
width: 450px;
|
width: 450px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -379,7 +397,12 @@ form > label {
|
|||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
form > input[type='text'], form > input[type='password'], form > select {
|
form > input[type='text'],
|
||||||
|
form > input[type='password'],
|
||||||
|
form > input[type='number'],
|
||||||
|
form > input[type='email'],
|
||||||
|
form > input[type='url'],
|
||||||
|
form > select {
|
||||||
float: right;
|
float: right;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
534
static/styles/tetawebapp_pdf.css
Normal file
534
static/styles/tetawebapp_pdf.css
Normal file
@ -0,0 +1,534 @@
|
|||||||
|
/*
|
||||||
|
* Do NOT modify this file:
|
||||||
|
* ------------------------
|
||||||
|
* If you want to add or modify classes, create a new
|
||||||
|
* CSS files and make it loaded after this one in the
|
||||||
|
* HTML header section of the index.html template file.
|
||||||
|
*/
|
||||||
|
@page {
|
||||||
|
size: 21cm 29.7cm;
|
||||||
|
margin: 3mm 5mm 3mm 5mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto Condensed';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(http://participer.redatomik.org/static/fonts/RobotoCondensed-Regular.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto Condensed';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(http://participer.redatomik.org/static/fonts/RobotoCondensed-Bold.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 10px;
|
||||||
|
font-family: 'Roboto Condensed';
|
||||||
|
background-color: #2B2B2B;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content {
|
||||||
|
display: flex;
|
||||||
|
min-height: calc(100vh - 110px);
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article {
|
||||||
|
flex: 1;
|
||||||
|
background-color: #E5E5E5;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > section.inline {
|
||||||
|
display: flex;
|
||||||
|
background-color: #E5E5E5;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > section.inline > article.left {
|
||||||
|
flex: 0 0 50%;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > section.inline > article.right {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav.vertical {
|
||||||
|
flex: 0 0 200px;
|
||||||
|
background-color: #E5E5E5;
|
||||||
|
border-right-color: #BBBBBB;
|
||||||
|
border-right-style: solid;
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav.vertical {
|
||||||
|
order: -1;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav.vertical > a {
|
||||||
|
display: block;
|
||||||
|
background-color: #E5E5E5;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #555555;
|
||||||
|
padding: 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav.vertical > a:hover {
|
||||||
|
background-color: #FF5D00;
|
||||||
|
color: #FFFFFF;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav.vertical > a.selected {
|
||||||
|
background-color: #FFB387;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
color: #555555;
|
||||||
|
background-color: #E5E5E5;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > div.navbar_container {
|
||||||
|
text-align: center;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > div.navbar_container > ul.horizontal {
|
||||||
|
display: inline-block;
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border-color: #FF5D00;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
color: #555555;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > div.navbar_container > ul.horizontal > li {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > div.navbar_container > ul.horizontal > li > a {
|
||||||
|
display: block;
|
||||||
|
color: #555555;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > div.navbar_container > ul.horizontal > li > a:hover {
|
||||||
|
background-color: #FF5D00;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > div.navbar_container > ul.horizontal > li > a.right_border {
|
||||||
|
border-right-color: #FF5D00;
|
||||||
|
border-right-style: solid;
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > div.navbar_container > ul.horizontal > li > a.selected {
|
||||||
|
background-color: #FFB387;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article {
|
||||||
|
padding: 10px;
|
||||||
|
color: #555555;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article.error,
|
||||||
|
main > article.error > p {
|
||||||
|
padding: 10px;
|
||||||
|
color: #555555;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > h3,
|
||||||
|
main > section.inline > article > h3 {
|
||||||
|
font-size: 30px;
|
||||||
|
color: #555555;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > p,
|
||||||
|
main > article > ul,
|
||||||
|
main > article > ol {
|
||||||
|
color: #555555;
|
||||||
|
text-align: justify;
|
||||||
|
text-justify: distribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > hr {
|
||||||
|
border-color: #BBBBBB;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > img {
|
||||||
|
display:inline-block;
|
||||||
|
border-color: #BBBBBB;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > p > a,
|
||||||
|
main > article > ul > li > a {
|
||||||
|
color: #FF5D00;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > p > a:hover,
|
||||||
|
main > article > ul > li > a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article.right > img {
|
||||||
|
float: right;
|
||||||
|
margin: 0 0 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article.left > img {
|
||||||
|
float: left;
|
||||||
|
margin: 0 10px 0px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
height: 65px;
|
||||||
|
font-size: 34px;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: right;
|
||||||
|
color: #FFFFFF;
|
||||||
|
background: url(http://participer.redatomik.org/static/images/logo.png);;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 10px;
|
||||||
|
text-shadow: 0 0 1px #000000;
|
||||||
|
border-bottom-color: #888888;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-top-color: #FFFFFF;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
height: 35px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1em;
|
||||||
|
border-bottom-color: #FFFFFF;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-top-color: #888888;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header,
|
||||||
|
footer {
|
||||||
|
background-color: #FF5D00;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='text'],
|
||||||
|
input[type='password'],
|
||||||
|
input[type='number'],
|
||||||
|
input[type='email'],
|
||||||
|
input[type='url'],
|
||||||
|
textarea,
|
||||||
|
select,
|
||||||
|
pre {
|
||||||
|
border-color: #888888;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
color: #555555;
|
||||||
|
padding: 5px;
|
||||||
|
font-family: 'Roboto Condensed';
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
border-color: #FF5D00;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
input[type='button'],
|
||||||
|
input[type='submit'] {
|
||||||
|
border-color: #888888;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
background-color: #FF5D00;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 5px;
|
||||||
|
font-family: 'Roboto Condensed';
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover,
|
||||||
|
input[type='button']:hover,
|
||||||
|
input[type='submit']:hover,
|
||||||
|
input[type='file']:hover {
|
||||||
|
background-color: #FFB387;
|
||||||
|
color: #555555;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.file_upload {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 2px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #E5E5E5;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='file'] {
|
||||||
|
position: absolute;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
left: 0;
|
||||||
|
top: 1px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input.add,
|
||||||
|
input.edit,
|
||||||
|
input.login,
|
||||||
|
input.logout,
|
||||||
|
input.refresh,
|
||||||
|
input.save,
|
||||||
|
input.search,
|
||||||
|
input.trash,
|
||||||
|
input.upload,
|
||||||
|
input.print {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 2px;
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.add:hover,
|
||||||
|
input.edit:hover,
|
||||||
|
input.login:hover,
|
||||||
|
input.logout:hover,
|
||||||
|
input.refresh:hover,
|
||||||
|
input.save:hover,
|
||||||
|
input.search:hover,
|
||||||
|
input.trash:hover,
|
||||||
|
input.upload:hover,
|
||||||
|
input.print:hover {
|
||||||
|
border-color: #555555;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
background-color: #FF5D00;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.add {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/add.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.edit {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/edit.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.login {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/login.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.logout {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/logout.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.refresh {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/refresh.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.save {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/save.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.search {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/search.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.trash {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/trash.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.upload {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/upload.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
input.print {
|
||||||
|
background: url(http://participer.redatomik.org/static/images/print.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
width: 450px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form > label {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
form > input[type='text'],
|
||||||
|
form > input[type='password'],
|
||||||
|
form > input[type='number'],
|
||||||
|
form > input[type='email'],
|
||||||
|
form > input[type='url'],
|
||||||
|
form > select {
|
||||||
|
float: right;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_header {
|
||||||
|
background-color: #FF5D00;
|
||||||
|
text-align: left;
|
||||||
|
width: 910px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_row {
|
||||||
|
text-align: left;
|
||||||
|
width: 910px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_header > div, div.table_row > div {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_row > div {
|
||||||
|
border-color: #FF5D00;
|
||||||
|
border-width: 1px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.even {
|
||||||
|
background-color: #FFB387;
|
||||||
|
border-color: #FF5D00;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: none none solid none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.odd {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border-color: #FF5D00;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: none none solid none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_row > div.border_left {
|
||||||
|
border-style: none none none solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_row > div.border_right {
|
||||||
|
border-style: none solid none none;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > p.note {
|
||||||
|
color: #555555;
|
||||||
|
display: block;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_header > div.sheet_day {
|
||||||
|
background-color: #FF5D00;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-align: left;
|
||||||
|
padding: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_header > div.sheet_role {
|
||||||
|
background-color: #FFB387;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 5px 5px 5px 10px;
|
||||||
|
border-color: #FF5D00;
|
||||||
|
border-style: none none solid none;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > border_right {
|
||||||
|
border-right-style: solid;
|
||||||
|
border-right-color: #FF5D00;
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_time,
|
||||||
|
article > div.table_row > div.sheet_user1,
|
||||||
|
article > div.table_row > div.sheet_user2,
|
||||||
|
article > div.table_row > div.sheet_user3,
|
||||||
|
article > div.table_row > div.sheet_user4 {
|
||||||
|
width: 125px;
|
||||||
|
text-align: left;
|
||||||
|
padding: 5px 5px 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user1:hover,
|
||||||
|
article > div.table_row > div.sheet_user2:hover,
|
||||||
|
article > div.table_row > div.sheet_user3:hover,
|
||||||
|
article > div.table_row > div.sheet_user4:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user1 {
|
||||||
|
text-align: center;
|
||||||
|
width: 780px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user2 {
|
||||||
|
text-align: center;
|
||||||
|
width: 388px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user3 {
|
||||||
|
text-align: center;
|
||||||
|
width: 257px;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > div.table_row > div.sheet_user4 {
|
||||||
|
text-align: center;
|
||||||
|
width: 192px;
|
||||||
|
}
|
@ -9,16 +9,17 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Notez que:
|
Notez que:
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Votre adresse mail doit être valide et consultée régulièrement si vous ne voulez pas manquez des informations importantes telels que les dates de réunions de staff</li>
|
<li>Votre adresse mail doit être <strong>valide et consultée</strong> régulièrement si vous ne voulez pas manquez des informations importantes telels que les dates de réunions de staff</li>
|
||||||
|
<li>Un nom ou psedonyme est nécessaire pour pouvoir s'enregistrer sur <a href='/staffsheet'>la feuille de staff</a></li>
|
||||||
<li>Votre numéro de téléphone nous permettra de vous contacter pendant l'évènement</li>
|
<li>Votre numéro de téléphone nous permettra de vous contacter pendant l'évènement</li>
|
||||||
<li>Si vous avez un régime alimentaire particulier (intolérences, veganisme, religieux), merci de le préciser dans le champs prévu à cet effet</li>
|
<li>Si vous avez un régime alimentaire particulier (intolérences, veganisme, religieux), merci de le préciser dans le champs prévu à cet effet</li>
|
||||||
<li>Aucune des données que vous nous transmettrez ne sera fournie à un tiers</li>
|
<li>Hormis votre pseudonyme aucune des données que vous nous transmettrez ne sera exposée au public ou fournie à un tiers</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
|
||||||
<form method='POST' action='/account/update'>
|
<form method='POST' action='/account/update'>
|
||||||
<label>Adresse email: </label><input id='login' name='login' type='text' value='{{ mail }}' disabled='disabled'/><br/>
|
<label>Adresse email: </label><input id='login' name='login' type='text' value='{{ mail }}' disabled='disabled'/><br/>
|
||||||
<label>Prénom ou pseudo: </label><input id='name' name='name' type='text' value='{{ name }}'/><br/>
|
<label>Pseudonyme: </label><input id='name' name='name' type='text' value='{{ name }}' required maxlength=20/><br/>
|
||||||
<label>Nouveau mot de passe: </label><input id='password' name='password' type='password'/><br/>
|
<label>Nouveau mot de passe: </label><input id='password' name='password' type='password'/><br/>
|
||||||
<label>Confirmation mot de passe: </label><input id='confirm' name='confirm' type='password'/><br/>
|
<label>Confirmation mot de passe: </label><input id='confirm' name='confirm' type='password'/><br/>
|
||||||
<label>Numéro de téléphone: </label><input id='phone' name='phone' type='text' value='{{ phone }}'/><br/>
|
<label>Numéro de téléphone: </label><input id='phone' name='phone' type='text' value='{{ phone }}'/><br/>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<article>
|
<article>
|
||||||
<h3>Informations du compte</h3>
|
<h3>Informations du compte</h3>
|
||||||
<form method='POST' action='/account/update/{{ user.id }}'>
|
<form method='POST' action='/account/update/{{ user.id }}'>
|
||||||
<label>Adresse email: </label><input id='login' name='login' type='text' value='{{ user.mail }}' disabled='disabled'/><br/>
|
<label>Adresse email: </label><input id='login' name='login' type='text' value='{{ user.mail }}' disabled='disabled' required/><br/>
|
||||||
<label>Prénom ou pseudo: </label><input id='name' name='name' type='text' value='{{ user.name }}'/><br/>
|
<label>Prénom ou pseudo: </label><input id='name' name='name' type='text' value='{{ user.name }}'/><br/>
|
||||||
<label>Nouveau mot de passe: </label><input id='password' name='password' type='password'/><br/>
|
<label>Nouveau mot de passe: </label><input id='password' name='password' type='password'/><br/>
|
||||||
<label>Confirmation mot de passe: </label><input id='confirm' name='confirm' type='password'/><br/>
|
<label>Confirmation mot de passe: </label><input id='confirm' name='confirm' type='password'/><br/>
|
||||||
|
19
templates/confirm.html
Normal file
19
templates/confirm.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{% extends "index.html" %}
|
||||||
|
{% block title %}Login{% endblock %}
|
||||||
|
{% block nav %}{% endblock %}
|
||||||
|
{% block main %}
|
||||||
|
<article class='login'>
|
||||||
|
<h3>Confirmation de votre inscription</h3>
|
||||||
|
<p>Merci de confirmer l'adresse de courriel et le mot de passe avec lesquels vous vous êtes enregistré.</p>
|
||||||
|
</article>
|
||||||
|
<article class='left'>
|
||||||
|
<form method='POST' action='/confirm/link/{{ link_id }}'>
|
||||||
|
<label>Adresse mail: </label><input id='login' name='login' type='text' /><br/>
|
||||||
|
<label>Mot de passe: </label><input id='password' name='password' type='password' /><br/>
|
||||||
|
<input type='submit' value='Log me in'>
|
||||||
|
</form>
|
||||||
|
<p class='note'>
|
||||||
|
Mot de passe oublié ? Envoyez une <a href='https://bofh.tetalab.org/?do=newtask&project=2'>demande de réinitialisation de votre mot de passe</a>.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
{% endblock %}
|
@ -32,7 +32,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
</nav>
|
</nav>
|
||||||
{% endblock%}
|
{% endblock%}
|
||||||
<main>
|
<main id='main'>
|
||||||
{% if navbar %}
|
{% if navbar %}
|
||||||
<div class='navbar_container'>
|
<div class='navbar_container'>
|
||||||
<ul class='horizontal'>
|
<ul class='horizontal'>
|
||||||
@ -62,19 +62,10 @@
|
|||||||
est précieuse.
|
est précieuse.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Ce site vous permettra:
|
Une fois vos <a href='/account'>informations personnelles</a> duement renseignées vous pourrez <a href='/staffsheet'>sélectionner les postes et les créneaux horaires</a> pendant lesquels vous souhaitez vous rendre disponible.
|
||||||
<ul>
|
</p>
|
||||||
<li>
|
<p>
|
||||||
de vous enregistrer afin de faire partie du "Staff", cette équipe de super-héros sans qui le THSF ne
|
Le <a href='https://www.tetalab.org'>Tetal@b</a> et l'ensemble de l'équipe d'organisation du THSF vous remercie pour votre aide.
|
||||||
saurait être un moment agréable, sûr et convivial.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
de sélectionner le poste et les créneaux horaires pendant lesquels vous souhaitez vous rendre disponible.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
de poser vos questions, obtenir des réponses et être tenu informé des évolutions de l'organisation et du déroulement du THSF via la mailing list du staff.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,29 +1,34 @@
|
|||||||
{% extends "index.html" %}
|
{% extends "index.html" %}
|
||||||
{% block title %}Liste des tours de staff{% endblock %}
|
{% block title %}Liste des tours de staff{% endblock %}
|
||||||
{% block main %}
|
{% block main %}
|
||||||
|
{{ A }}
|
||||||
<article>
|
<article>
|
||||||
<h3>Liste des tours de staff enregistrés <input class='add' value='' title='Ajouter un tour de staff' onclick='javascript:document.location="/turn/new"'/></h3>
|
<h3>Liste des tours de staff enregistrés <input class='add' value='' title='Ajouter un tour de staff' onclick='javascript:document.location="/turn/new"'/></h3>
|
||||||
<div class='table_header'>
|
<div class='table_header'>
|
||||||
<div class='border_right' style='width: 40px;'>ID</div>
|
<div class='border_right' style='width: 40px;'>ID</div>
|
||||||
<div class='border_right'>Role</div>
|
<div class='border_right' style='width: 240px;'>Role</div>
|
||||||
<div class='border_right'>Jour</div>
|
<div class='border_right' style='width: 150px;'>Jour</div>
|
||||||
<div class='border_right'>Début</div>
|
<div class='border_right' style='width: 150px;'>Début</div>
|
||||||
<div class='border_right'>Fin</div>
|
<div class='border_right' style='width: 150px;'>Fin</div>
|
||||||
<div style='width: 50px;'>Action</div>
|
<div class='border_right' style='width: 100px;'>Slots</div>
|
||||||
|
<div style='width: 50px;' style='width: 50px;'>Action</div>
|
||||||
</div>
|
</div>
|
||||||
{% set row_class = cycler('odd', 'even') %}
|
{% set row_class = cycler('odd', 'even') %}
|
||||||
{% for turn in turns %}
|
{% for day in turns %}
|
||||||
|
{% for turn in day[1] %}
|
||||||
<div class='table_row {{ row_class.next() }}'>
|
<div class='table_row {{ row_class.next() }}'>
|
||||||
<div class='border_right' style='width: 40px;'>{{ turn[0].id }}</div>
|
<div class='border_right' style='width: 40px;'>{{ turn[0].id }}</div>
|
||||||
<div class='border_right'>{{ turn[1] }}</div>
|
<div class='border_right' style='width: 240px;'>{{ turn[1] }}</div>
|
||||||
<div class='border_right'>{{ turn[0].wday }}</div>
|
<div class='border_right' style='width: 150px;'>{{ day[0] }}</div>
|
||||||
<div class='border_right'>{{ turn[0].start_time }}</div>
|
<div class='border_right' style='width: 150px;'>{{ turn[0].start_time }}</div>
|
||||||
<div class='border_right'>{{ turn[0].end_time }}</div>
|
<div class='border_right' style='width: 150px;'>{{ turn[0].end_time }}</div>
|
||||||
|
<div class='border_right' style='width: 100px;'>{{ turn[0].num_slot }}</div>
|
||||||
<div style='width: 50px;'>
|
<div style='width: 50px;'>
|
||||||
<input class='edit' value='' onclick='javascript:document.location="/turn/{{ turn[0].id }}"' title='Éditer'/>
|
<input class='edit' value='' onclick='javascript:document.location="/turn/{{ turn[0].id }}"' title='Éditer'/>
|
||||||
<input class='trash' value='' onclick='javascript:delete_turn({{ turn[0].id }});' title='Supprimer'/>
|
<input class='trash' value='' onclick='javascript:delete_turn({{ turn[0].id }});' title='Supprimer'/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
</article>
|
</article>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Ce site vous permettra:
|
Ce site vous permettra:
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
de vous enregistrer afin de faire partie du "Staff", cette équipe de super-héros sans qui le THSF ne
|
de vous enregistrer afin de faire partie du "Staff", cette équipe de super-héros sans qui le THSF ne
|
||||||
@ -26,13 +27,12 @@
|
|||||||
d'être tenu informé des évolutions de l'organisation et du déroulement du THSF via la mailing list du staff.
|
d'être tenu informé des évolutions de l'organisation et du déroulement du THSF via la mailing list du staff.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
Nul besoin de compétences particulières pour rejoindre notre équipe sinon votre meilleure volonté et votre bonne humeur
|
Nul besoin de compétences particulières pour rejoindre notre équipe sinon votre meilleure volonté et votre bonne humeur
|
||||||
qui feront du THSF un moment unique de partage.
|
qui feront du THSF un moment unique de partage.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Pour vous enregistrer, munissez vous de votre adresse email et renseignez les champs de la section "<strong>Inscription</strong>".
|
Pour vous enregistrer, munissez vous de <strong>votre plus belle adresse email</strong> et renseignez les champs de la section "<strong>Inscription</strong>".
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Si vous vous être préalablement enregistré, renseignez uniquement les champs de la section "<strong>Connexion</strong>"
|
Si vous vous être préalablement enregistré, renseignez uniquement les champs de la section "<strong>Connexion</strong>"
|
||||||
@ -48,7 +48,7 @@
|
|||||||
<form method='POST' action='/login'>
|
<form method='POST' action='/login'>
|
||||||
<label>Adresse mail: </label><input id='login' name='login' type='text' /><br/>
|
<label>Adresse mail: </label><input id='login' name='login' type='text' /><br/>
|
||||||
<label>Mot de passe: </label><input id='password' name='password' type='password' /><br/>
|
<label>Mot de passe: </label><input id='password' name='password' type='password' /><br/>
|
||||||
<input type='submit' value='Log me in' onclick='javascript:return verify_login();'>
|
<input type='submit' value='Log me in'>
|
||||||
</form>
|
</form>
|
||||||
<p class='note'>
|
<p class='note'>
|
||||||
Mot de passe oublié ? Envoyez une <a href='https://bofh.tetalab.org/?do=newtask&project=2'>demande de réinitialisation de votre mot de passe</a>.
|
Mot de passe oublié ? Envoyez une <a href='https://bofh.tetalab.org/?do=newtask&project=2'>demande de réinitialisation de votre mot de passe</a>.
|
||||||
@ -59,12 +59,13 @@
|
|||||||
<h3>Inscription</h3>
|
<h3>Inscription</h3>
|
||||||
</article>
|
</article>
|
||||||
<article class='left'>
|
<article class='left'>
|
||||||
<form method='POST' action='/register'>
|
<form method='POST' action='/register' onsubmit='return register();'>
|
||||||
<label>Adresse mail: </label><input id='reg_mail' name='login' type='text' /><br/>
|
<label>Adresse mail: </label><input id='reg_mail' name='login' type='text' required /><br/>
|
||||||
<label>Mot de passe (8 char min.): </label><input id='reg_password' name='password' type='password' /><br/>
|
<label>Mot de passe (8 char min.): </label><input id='reg_password' name='password' type='password' required /><br/>
|
||||||
<label>Confirmation: </label><input id='reg_confirm' name='confirm' type='password' /><br/>
|
<label>Confirmation: </label><input id='reg_confirm' name='confirm' type='password' required /><br/>
|
||||||
<input type='submit' value='Register me NOW !' onclick='javascript:return register();'>
|
<input type='submit' value='Register me NOW !'>
|
||||||
</form>
|
</form>
|
||||||
|
<p class='note'>En vous inscrivant vous déclarez être prèt à découvrir l'insondabilité de l'improbable</p>
|
||||||
</article>
|
</article>
|
||||||
<hr/>
|
<hr/>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -11,11 +11,12 @@
|
|||||||
</select><br/>
|
</select><br/>
|
||||||
<label>Jour de la semaine: </label><select id='day' name='day'>
|
<label>Jour de la semaine: </label><select id='day' name='day'>
|
||||||
{% for day in days %}
|
{% for day in days %}
|
||||||
<option value='{{ day }}'>{{ day }}</option>
|
<option value='{{ day[1] }}'>{{ day[0] }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select><br/>
|
</select><br/>
|
||||||
<label>Début (HH:MM:SS) </label><input id='start' name='start' type='text' maxlength=8/><br/>
|
<label>Début (HH:MM:SS) </label><input id='start' name='start' type='text' maxlength=8/><br/>
|
||||||
<label>Fin: (HH:MM:SS) </label><input id='end' name='end' type='text' maxlength=8/><br/>
|
<label>Fin: (HH:MM:SS) </label><input id='end' name='end' type='text' maxlength=8/><br/>
|
||||||
|
<label>Nombre de slots (max. 4) </label><input id='num_slot' name='num_slot' type='number' min='1' max='4'/><br/>
|
||||||
<input type='submit' value='Enregistrer' onclick='javascript:return save_turn();'/>
|
<input type='submit' value='Enregistrer' onclick='javascript:return save_turn();'/>
|
||||||
</form>
|
</form>
|
||||||
</article>
|
</article>
|
||||||
|
84
templates/staffsheet.html
Normal file
84
templates/staffsheet.html
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{% extends "index.html" %}
|
||||||
|
{% block title %}Feuille de staff{% endblock %}
|
||||||
|
{% block main %}
|
||||||
|
<article id='roles'>
|
||||||
|
<h3>Fiches de poste<input class='print' value='' title='Imprimer' onclick='javascript:print_page();'/></h3>
|
||||||
|
<p>Les postes de référents (référent staff, référent bar, référent run) sont réservés à des personnes ayant une bonne connaissance du lieu et de l'évènement.</p>
|
||||||
|
{% for role in roles %}
|
||||||
|
<div class='table_header'><div class='sheet_day'>{{ role.role }}</div></div>
|
||||||
|
<div class='table_row'>
|
||||||
|
<ul>
|
||||||
|
{% set desc = role.description.split('|') %}
|
||||||
|
{% for point in desc %}
|
||||||
|
<li>{{ point }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</article>
|
||||||
|
<hr/>
|
||||||
|
<article id='staff_sheet'>
|
||||||
|
<h3>Feuille de staff</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Ménage le soir même pour tous les derniers créneaux du jour</strong></li>
|
||||||
|
<li><strong>Tâches dévolues à tous:</strong>
|
||||||
|
<ul>
|
||||||
|
<li>Veiller à la sécurité générale du lieu</li>
|
||||||
|
<li>Ramassage bouteilles ou objets en verre</li>
|
||||||
|
<li>Séparation des bagarres (rarissime)</li>
|
||||||
|
<li>Sécurisation des personnes en difficulté (ou trop alcoolisées), etc...</li>
|
||||||
|
<li>Sourire et bonne humeur quel que soit le niveau de fatigue ;)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Mode d'emploi:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Cliquez sur l'un des créneaux vacants pour le réserver</li>
|
||||||
|
<li>Cliquez sur l'un des créneaux que vous occupez pour le libérez</li>
|
||||||
|
</ul>
|
||||||
|
{% for day in turns %}
|
||||||
|
{% set wday = day[0] %}
|
||||||
|
{% set day_turns = day[1] %}
|
||||||
|
{% set cur_role = '' %}
|
||||||
|
<div class='table_header'><div class='sheet_day' style='page-break-before: always;'>{{ wday }}</div></div>
|
||||||
|
{% for turn in day_turns %}
|
||||||
|
{% set role = turn[1] %}
|
||||||
|
{% set start_time = turn[0].start_time %}
|
||||||
|
{% set end_time = turn[0].end_time %}
|
||||||
|
{% set num_slot = turn[0].num_slot %}
|
||||||
|
{% set role_id = turn[0].role_id %}
|
||||||
|
{% set turn_id = turn[0].id %}
|
||||||
|
{% if role != cur_role %}
|
||||||
|
{% set cur_role = role %}
|
||||||
|
<div class='table_header'>
|
||||||
|
<div class='sheet_role'>{{ role }}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class='table_row' style='border-bottom-color: #FF5D00; border-bottom-width: 1px; border-bottom-style: solid;'>
|
||||||
|
<div class='sheet_time border_right'>{{ start_time.strftime('%HH%M') }} / {{ end_time.strftime('%HH%M') }}</div>
|
||||||
|
{% for slot in range(0, num_slot) %}
|
||||||
|
{% set allocated_slot = [] %}
|
||||||
|
{% set border = '' %}
|
||||||
|
{% if slot != num_slot - 1 %}
|
||||||
|
{% set border = 'border_right' %}
|
||||||
|
{% endif %}
|
||||||
|
{% for sslot in staffs %}
|
||||||
|
{% if sslot[0].turn_id == turn_id and sslot[0].slot_num == slot %}
|
||||||
|
{% if allocated_slot.append(sslot[0].slot_num) %}
|
||||||
|
{% endif %}
|
||||||
|
{% if user_id == sslot[0].user_id %}
|
||||||
|
<div class='sheet_user{{ num_slot }} {{ border }}' onclick='javascript:clear_sheet({{ turn_id }}, {{ slot }})'>{{ sslot[1] }}</div>
|
||||||
|
{% else %}
|
||||||
|
<div class='sheet_user{{ num_slot }} {{ border }}' style='cursor: text;'>{{ sslot[1] }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if slot not in allocated_slot %}
|
||||||
|
<div class='sheet_user{{ num_slot }} {{ border }}' onclick='javascript:update_sheet({{ turn_id }}, {{ slot }})'> </div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</article>
|
||||||
|
{% endblock %}
|
87
templates/staffsheet_pdf.html
Normal file
87
templates/staffsheet_pdf.html
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang='zxx'>
|
||||||
|
<head>
|
||||||
|
<title>We Make THSF - {% block title %}Feuille de staff{% endblock %}</title>
|
||||||
|
<meta name="viewport" content="initial-scale=1.0" />
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/styles/tetawebapp_pdf.css" />
|
||||||
|
<link rel="icon" type="image/png" href="/static/images/favicon.png" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class='content'>
|
||||||
|
<main id='main'>
|
||||||
|
<article id='roles'>
|
||||||
|
<h3>Fiches de poste</h3>
|
||||||
|
<p>Les postes de référents (référent staff, référent bar, référent run) sont réservés à des personnes ayant une bonne connaissance du lieu et de l'évènement.</p>
|
||||||
|
{% for role in roles %}
|
||||||
|
<div class='table_header'><div class='sheet_day'>{{ role.role }}</div></div>
|
||||||
|
<div class='table_row'>
|
||||||
|
<ul>
|
||||||
|
{% set desc = role.description.split('|') %}
|
||||||
|
{% for point in desc %}
|
||||||
|
<li>{{ point }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</article>
|
||||||
|
<hr/>
|
||||||
|
<article id='staff_sheet'>
|
||||||
|
<h3>Feuille de staff</h3>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Ménage le soir même pour tous les derniers créneaux du jour</strong></li>
|
||||||
|
<li><strong>Tâches dévolues à tous:</strong>
|
||||||
|
<ul>
|
||||||
|
<li>Veiller à la sécurité générale du lieu</li>
|
||||||
|
<li>Ramassage bouteilles ou objets en verre</li>
|
||||||
|
<li>Séparation des bagarres (rarissime)</li>
|
||||||
|
<li>Sécurisation des personnes en difficulté (ou trop alcoolisées), etc...</li>
|
||||||
|
<li>Sourire et bonne humeur quel que soit le niveau de fatigue ;)</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% for day in turns %}
|
||||||
|
{% set wday = day[0] %}
|
||||||
|
{% set day_turns = day[1] %}
|
||||||
|
{% set cur_role = '' %}
|
||||||
|
<div class='table_header'><div class='sheet_day'>{{ wday }}</div></div>
|
||||||
|
{% for turn in day_turns %}
|
||||||
|
{% set role = turn[1] %}
|
||||||
|
{% set start_time = turn[0].start_time %}
|
||||||
|
{% set end_time = turn[0].end_time %}
|
||||||
|
{% set num_slot = turn[0].num_slot %}
|
||||||
|
{% set role_id = turn[0].role_id %}
|
||||||
|
{% set turn_id = turn[0].id %}
|
||||||
|
{% if role != cur_role %}
|
||||||
|
{% set cur_role = role %}
|
||||||
|
<div class='table_header'>
|
||||||
|
<div class='sheet_role'>{{ role }}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class='table_row' style='border-bottom-color: #FF5D00; border-bottom-width: 1px; border-bottom-style: solid;'>
|
||||||
|
<div class='sheet_time border_right'>{{ start_time.strftime('%HH%M') }} / {{ end_time.strftime('%HH%M') }}</div>
|
||||||
|
{% for slot in range(0, num_slot) %}
|
||||||
|
{% set allocated_slot = [] %}
|
||||||
|
{% set border = '' %}
|
||||||
|
{% if slot != num_slot - 1 %}
|
||||||
|
{% set border = 'border_right' %}
|
||||||
|
{% endif %}
|
||||||
|
{% for sslot in staffs %}
|
||||||
|
{% if sslot[0].turn_id == turn_id and sslot[0].slot_num == slot %}
|
||||||
|
{% if allocated_slot.append(sslot[0].slot_num) %}
|
||||||
|
{% endif %}
|
||||||
|
<div class='sheet_user{{ num_slot }} {{ border }}' style='cursor: text;' id='staff_{{ staff }}'>{{ sslot[1] }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if slot not in allocated_slot %}
|
||||||
|
<div class='sheet_user{{ num_slot }} {{ border }}' id='staff_{{ staff }}' onclick='javascript:update_sheet({{ turn_id }}, {{ slot }})'> </div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
58
templates/staffsheet_txt.html
Normal file
58
templates/staffsheet_txt.html
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
("Fiches de poste",)
|
||||||
|
("Les postes de référents (référent staff, référent bar, référent run) sont réservés à des personnes ayant une bonne connaissance du lieu et de l'évènement.",)
|
||||||
|
{% for role in roles %}
|
||||||
|
(" ",)
|
||||||
|
("{{ role.role }}",)
|
||||||
|
{% set desc = role.description.split('|') %}
|
||||||
|
{% for point in desc %}
|
||||||
|
("{{ point }}",)
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
(" ",)
|
||||||
|
("Feuille de staff",)
|
||||||
|
("Ménage le soir même pour tous les derniers créneaux du jour",)
|
||||||
|
("",)
|
||||||
|
("Tâches dévolues à tous:",)
|
||||||
|
("Veiller à la sécurité générale du lieu",)
|
||||||
|
("Ramassage bouteilles ou objets en verre",)
|
||||||
|
("Séparation des bagarres (rarissime)",)
|
||||||
|
("Sécurisation des personnes en difficulté (ou trop alcoolisées), etc...",)
|
||||||
|
("Sourire et bonne humeur quel que soit le niveau de fatigue ;)",)
|
||||||
|
(" ",)
|
||||||
|
{% for day in turns %}
|
||||||
|
{% set wday = day[0] %}
|
||||||
|
{% set day_turns = day[1] %}
|
||||||
|
{% set cur_role = '' %}
|
||||||
|
("{{ wday }}",)
|
||||||
|
{% for turn in day_turns %}
|
||||||
|
{% set role = turn[1] %}
|
||||||
|
{% set start_time = turn[0].start_time %}
|
||||||
|
{% set end_time = turn[0].end_time %}
|
||||||
|
{% set num_slot = turn[0].num_slot %}
|
||||||
|
{% set role_id = turn[0].role_id %}
|
||||||
|
{% set turn_id = turn[0].id %}
|
||||||
|
{% if role != cur_role %}
|
||||||
|
{% set cur_role = role %}
|
||||||
|
("{{ role }}",)
|
||||||
|
{% endif %}
|
||||||
|
("{{ start_time.strftime('%HH%M') }} / {{ end_time.strftime('%HH%M') }}",
|
||||||
|
{% for slot in range(0, num_slot) %}
|
||||||
|
{% set allocated_slot = [] %}
|
||||||
|
{% set border = '' %}
|
||||||
|
{% if slot != num_slot - 1 %}
|
||||||
|
{% set border = 'border_right' %}
|
||||||
|
{% endif %}
|
||||||
|
{% for sslot in staffs %}
|
||||||
|
{% if sslot[0].turn_id == turn_id and sslot[0].slot_num == slot %}
|
||||||
|
{% if allocated_slot.append(sslot[0].slot_num) %}
|
||||||
|
{% endif %}
|
||||||
|
"{{ sslot[1] }}",
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if slot not in allocated_slot %}
|
||||||
|
" ",
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
)
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
@ -3,7 +3,7 @@
|
|||||||
{% block main %}
|
{% block main %}
|
||||||
<article>
|
<article>
|
||||||
<h3>Tour de staff:</h3>
|
<h3>Tour de staff:</h3>
|
||||||
<form method='POST' action='/turn/update/{{ turn.id }}'>
|
<form method='POST' action="/turn/update/{{ turn.id }}">
|
||||||
<label>Role: </label><select id='role_id' name='role_id'>
|
<label>Role: </label><select id='role_id' name='role_id'>
|
||||||
{% for role in roles %}
|
{% for role in roles %}
|
||||||
{% set selected = '' %}
|
{% set selected = '' %}
|
||||||
@ -16,14 +16,15 @@
|
|||||||
<label>Jour de la semaine: </label><select id='day' name='day'>
|
<label>Jour de la semaine: </label><select id='day' name='day'>
|
||||||
{% for day in days %}
|
{% for day in days %}
|
||||||
{% set selected = '' %}
|
{% set selected = '' %}
|
||||||
{% if turn.wday == day %}
|
{% if turn.day == day[0] %}
|
||||||
{% set selected="selected" %}
|
{% set selected="selected" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<option {{ selected }} value='{{ day }}'>{{ day }}</option>
|
<option {{ selected }} value='{{ day[1] }}'>{{ day[0] }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select><br/>
|
</select><br/>
|
||||||
<label>Début (HH:MM:SS) </label><input id='start' name='start' type='text' maxlength=8 value='{{ turn.start_time }}'/><br/>
|
<label>Début (HH:MM:SS) </label><input id='start' name='start' type='text' maxlength=8 value='{{ turn.start_time }}'/><br/>
|
||||||
<label>Fin: (HH:MM:SS) </label><input id='end' name='end' type='text' maxlength=8 value='{{ turn.end_time }}'/><br/>
|
<label>Fin: (HH:MM:SS) </label><input id='end' name='end' type='text' maxlength=8 value='{{ turn.end_time }}'/><br/>
|
||||||
|
<label>Nombre de slots (max. 4) </label><input id='num_slot' name='num_slot' type='number' min='1' max='4' value='{{ turn.num_slot }}'/><br/>
|
||||||
<input type='submit' value='Enregistrer' onclick='javascript:return save_turn();'/>
|
<input type='submit' value='Enregistrer' onclick='javascript:return save_turn();'/>
|
||||||
</form>
|
</form>
|
||||||
</article>
|
</article>
|
||||||
|
Loading…
Reference in New Issue
Block a user