Готов новый раздел сайта: SafeAppSchool
@ -1 +1 @@
|
|||||||
from . import users, diary_post, questions, answer_quest, like, popularity
|
from . import users, diary_post, questions, answer_quest, like, popularity, app_school_user_point
|
||||||
15
data/app_school_user_point.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import sqlalchemy
|
||||||
|
from flask_login import UserMixin
|
||||||
|
|
||||||
|
from .db_session import SqlAlchemyBase
|
||||||
|
|
||||||
|
|
||||||
|
class UserPoint(SqlAlchemyBase, UserMixin):
|
||||||
|
__tablename__ = 'user_point'
|
||||||
|
|
||||||
|
id = sqlalchemy.Column(sqlalchemy.Integer,
|
||||||
|
primary_key=True, autoincrement=True)
|
||||||
|
user = sqlalchemy.Column(sqlalchemy.Integer,
|
||||||
|
sqlalchemy.ForeignKey("users.id"), nullable=True)
|
||||||
|
home_address = sqlalchemy.Column(sqlalchemy.String, nullable=True)
|
||||||
|
school_address = sqlalchemy.Column(sqlalchemy.String, nullable=True)
|
||||||
8
forms/point_user.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import TextAreaField, SubmitField
|
||||||
|
|
||||||
|
|
||||||
|
class PointForm(FlaskForm):
|
||||||
|
home_address = TextAreaField('Адрес дома:')
|
||||||
|
school_address = TextAreaField('Адрес школы:')
|
||||||
|
submit = SubmitField('Сохранить')
|
||||||
@ -18,6 +18,7 @@ class RegisterForm(FlaskForm):
|
|||||||
del_photo = SubmitField('Удалить фотографию')
|
del_photo = SubmitField('Удалить фотографию')
|
||||||
submit2 = SubmitField('Сохранить')
|
submit2 = SubmitField('Сохранить')
|
||||||
simple = False
|
simple = False
|
||||||
|
back = False
|
||||||
|
|
||||||
|
|
||||||
class Confirmation(FlaskForm):
|
class Confirmation(FlaskForm):
|
||||||
|
|||||||
289
main.py
@ -1,20 +1,24 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
from random import randint, choices
|
from random import randint, choices
|
||||||
from waitress import serve
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from flask import Flask, render_template, request, jsonify, make_response
|
from flask import Flask, render_template, request, jsonify, make_response, session, url_for
|
||||||
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
|
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
|
||||||
from flask_restful import abort
|
from flask_restful import abort
|
||||||
|
from waitress import serve
|
||||||
from werkzeug.utils import redirect
|
from werkzeug.utils import redirect
|
||||||
|
from threading import Timer
|
||||||
|
|
||||||
from data import db_session
|
from data import db_session
|
||||||
|
from data.app_school_user_point import UserPoint
|
||||||
from data.answer_quest import Answer
|
from data.answer_quest import Answer
|
||||||
from data.diary_post import DiaryPost
|
from data.diary_post import DiaryPost
|
||||||
from data.like import Like
|
from data.like import Like
|
||||||
from data.popularity import Popularity
|
from data.popularity import Popularity
|
||||||
from data.questions import Quest
|
from data.questions import Quest
|
||||||
from data.users import User
|
from data.users import User
|
||||||
|
from forms.point_user import PointForm
|
||||||
from forms.add_question import AddQuest
|
from forms.add_question import AddQuest
|
||||||
from forms.answer_quest import AnswerQuest
|
from forms.answer_quest import AnswerQuest
|
||||||
from forms.login import LoginForm
|
from forms.login import LoginForm
|
||||||
@ -36,6 +40,10 @@ photo = None
|
|||||||
user_email = ""
|
user_email = ""
|
||||||
|
|
||||||
|
|
||||||
|
def remove_java():
|
||||||
|
os.remove('static/js/safe_app_school/mapbasics.js')
|
||||||
|
|
||||||
|
|
||||||
def norm_data(datatime, date_or_time, r=False):
|
def norm_data(datatime, date_or_time, r=False):
|
||||||
if date_or_time == 'date':
|
if date_or_time == 'date':
|
||||||
return '.'.join(str(datatime).split()[0].split('-')[::-1])
|
return '.'.join(str(datatime).split()[0].split('-')[::-1])
|
||||||
@ -69,28 +77,267 @@ def load_user(user_id):
|
|||||||
db_sess = db_session.create_session()
|
db_sess = db_session.create_session()
|
||||||
return db_sess.query(User).get(user_id)
|
return db_sess.query(User).get(user_id)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def main_page():
|
def main_page():
|
||||||
return render_template('/main/main.html')
|
return render_template('/main/main.html', title='Добро пожаловать')
|
||||||
|
|
||||||
@app.route('/safeappschool/login')
|
|
||||||
def safe_app_school_login():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/safeappschool/main')
|
@app.route('/login', methods=['GET', 'POST'])
|
||||||
|
def login():
|
||||||
|
form = LoginForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
db_sess = db_session.create_session()
|
||||||
|
user = db_sess.query(User).filter(User.email == form.email.data).first()
|
||||||
|
if user and user.check_password(form.password.data):
|
||||||
|
login_user(user, remember=form.remember_me.data)
|
||||||
|
return redirect('/')
|
||||||
|
return render_template('main/login.html',
|
||||||
|
message="Неправильный логин или пароль",
|
||||||
|
form=form)
|
||||||
|
return render_template('main/login.html', title='Авторизация', form=form, message='')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/register', methods=['GET', 'POST'])
|
||||||
|
def register():
|
||||||
|
form = RegisterForm()
|
||||||
|
form.simple = True
|
||||||
|
if form.validate_on_submit():
|
||||||
|
if form.password.data != form.password2.data:
|
||||||
|
return render_template('main/register.html', title='Регистрация',
|
||||||
|
form=form,
|
||||||
|
message="Пароли не совпадают")
|
||||||
|
data_session = db_session.create_session()
|
||||||
|
if data_session.query(User).filter(User.login == form.login.data).first():
|
||||||
|
return render_template('main/register.html', title='Регистрация',
|
||||||
|
form=form,
|
||||||
|
message="Такой пользователь уже есть")
|
||||||
|
if data_session.query(User).filter(User.email == form.email.data).first():
|
||||||
|
return render_template('main/register.html', title='Регистрация',
|
||||||
|
form=form,
|
||||||
|
message="Такая почта уже есть")
|
||||||
|
if form.photo.data:
|
||||||
|
photo = save_photo(form.photo.data, form.login.data)
|
||||||
|
else:
|
||||||
|
photo = False
|
||||||
|
session['ps'] = form.password.data
|
||||||
|
return redirect(
|
||||||
|
url_for('confirmation', photo=photo, name=form.name.data, surname=form.surname.data, login=form.login.data,
|
||||||
|
age=form.age.data, about=form.about.data, email=form.email.data, form=True))
|
||||||
|
return render_template('main/register.html', title='Регистрация', form=form, message='')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/confirmation', methods=['GET', 'POST'])
|
||||||
|
def confirmation():
|
||||||
|
if request.args.get('form'):
|
||||||
|
app_school = request.args.get('app_school') if request.args.get('app_school') else False
|
||||||
|
data_session = db_session.create_session()
|
||||||
|
form = RegisterForm(
|
||||||
|
name=request.args.get('name'),
|
||||||
|
surname=request.args.get('surname'),
|
||||||
|
login=request.args.get('login'),
|
||||||
|
age=request.args.get('age'),
|
||||||
|
about=request.args.get('about'),
|
||||||
|
email=request.args.get('email'),
|
||||||
|
password=session['ps']
|
||||||
|
)
|
||||||
|
session['photo'] = request.args.get('photo')
|
||||||
|
if 'send_msg' not in session:
|
||||||
|
session['secret_code'] = secret_key()
|
||||||
|
mail(f'Ваш секретный код: {session["secret_code"]}', form.email.data, 'Moona Код')
|
||||||
|
session['send_msg'] = True
|
||||||
|
else:
|
||||||
|
if not session['send_msg']:
|
||||||
|
if 'no_code' in session:
|
||||||
|
if not session['no_code']:
|
||||||
|
session['secret_code'] = secret_key()
|
||||||
|
mail(f'Ваш секретный код: {session["secret_code"]}', form.email.data, 'Moona Код')
|
||||||
|
session['send_msg'] = True
|
||||||
|
session['no_code'] = False
|
||||||
|
else:
|
||||||
|
session['secret_code'] = secret_key()
|
||||||
|
mail(f'Ваш секретный код: {session["secret_code"]}', form.email.data, 'Moona Код')
|
||||||
|
session['send_msg'] = True
|
||||||
|
session['send_msg'] = False
|
||||||
|
conf = Confirmation()
|
||||||
|
if conf.validate_on_submit():
|
||||||
|
if str(conf.code_key.data).strip() == str(session['secret_code']).strip():
|
||||||
|
if form.photo.data:
|
||||||
|
user = User(
|
||||||
|
name=form.name.data,
|
||||||
|
surname=form.surname.data,
|
||||||
|
login=form.login.data,
|
||||||
|
age=form.age.data,
|
||||||
|
about=form.about.data,
|
||||||
|
email=form.email.data,
|
||||||
|
photo=session['photo'],
|
||||||
|
role='user'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
user = User(
|
||||||
|
name=form.name.data,
|
||||||
|
surname=form.surname.data,
|
||||||
|
login=form.login.data,
|
||||||
|
age=form.age.data,
|
||||||
|
about=form.about.data,
|
||||||
|
email=form.email.data,
|
||||||
|
role='user',
|
||||||
|
photo='../../static/img/None_logo.png'
|
||||||
|
)
|
||||||
|
user.set_password(form.password.data)
|
||||||
|
data_session.add(user)
|
||||||
|
data_session.commit()
|
||||||
|
session['send_msg'] = False
|
||||||
|
if app_school:
|
||||||
|
return redirect('/safeappschool/login')
|
||||||
|
else:
|
||||||
|
return redirect('/login')
|
||||||
|
else:
|
||||||
|
session['no_code'] = True
|
||||||
|
if app_school:
|
||||||
|
return render_template('simple/simple_confirmation.html', title='Подтверждение', form=conf,
|
||||||
|
message='Коды не совпадают')
|
||||||
|
else:
|
||||||
|
return render_template('main/confirmation_reg.html', title='Подтверждение', form=conf,
|
||||||
|
message='Коды не совпадают')
|
||||||
|
else:
|
||||||
|
if app_school:
|
||||||
|
return render_template('simple/simple_confirmation.html', title='Подтверждение', form=conf, message='')
|
||||||
|
else:
|
||||||
|
return render_template('main/confirmation_reg.html', title='Подтверждение', form=conf, message='')
|
||||||
|
else:
|
||||||
|
return redirect('/')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/logout')
|
||||||
|
@login_required
|
||||||
|
def logout():
|
||||||
|
logout_user()
|
||||||
|
return redirect("/")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/safeappschool')
|
||||||
|
def safe_app_school():
|
||||||
|
return redirect('/safeappschool/main')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/safeappschool/main', methods=['GET', 'POST'])
|
||||||
def safe_app_school_main():
|
def safe_app_school_main():
|
||||||
pass
|
if current_user.is_authenticated:
|
||||||
|
return render_template('safe_app_school/main.html', title='SafeAppSchool')
|
||||||
|
else:
|
||||||
|
return redirect('/safeappschool/login')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/safeappschool/login', methods=['GET', 'POST'])
|
||||||
|
def safe_app_school_login():
|
||||||
|
form = LoginForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
db_sess = db_session.create_session()
|
||||||
|
user = db_sess.query(User).filter(User.email == form.email.data).first()
|
||||||
|
if user and user.check_password(form.password.data):
|
||||||
|
login_user(user, remember=form.remember_me.data)
|
||||||
|
return redirect('/safeappschool/main')
|
||||||
|
return render_template('/simple/simple_login.html',
|
||||||
|
message="Неправильный логин или пароль",
|
||||||
|
form=form)
|
||||||
|
return render_template('/simple/simple_login.html', title='Вход', form=form, message='')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/safeappschool/register', methods=['GET', 'POST'])
|
||||||
|
def safe_app_school_register():
|
||||||
|
form = RegisterForm()
|
||||||
|
form.simple = True
|
||||||
|
if form.validate_on_submit():
|
||||||
|
if form.password.data != form.password2.data:
|
||||||
|
return render_template('simple/simple_register.html', title='Регистрация',
|
||||||
|
form=form,
|
||||||
|
message="Пароли не совпадают")
|
||||||
|
data_session = db_session.create_session()
|
||||||
|
if data_session.query(User).filter(User.login == form.login.data).first():
|
||||||
|
return render_template('simple/simple_register.html', title='Регистрация',
|
||||||
|
form=form,
|
||||||
|
message="Такой пользователь уже есть")
|
||||||
|
if data_session.query(User).filter(User.email == form.email.data).first():
|
||||||
|
return render_template('simple/simple_register.html', title='Регистрация',
|
||||||
|
form=form,
|
||||||
|
message="Такая почта уже есть")
|
||||||
|
if form.photo.data:
|
||||||
|
photo = save_photo(form.photo.data, form.login.data)
|
||||||
|
else:
|
||||||
|
photo = False
|
||||||
|
session['ps'] = form.password.data
|
||||||
|
return redirect(
|
||||||
|
url_for('confirmation', photo=photo, name=form.name.data, surname=form.surname.data,
|
||||||
|
login=form.login.data,
|
||||||
|
age=form.age.data, about=form.about.data, email=form.email.data, form=True, app_school=True))
|
||||||
|
return render_template('simple/simple_register.html', title='Регистрация', form=form, message='')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/safeappschool/about')
|
@app.route('/safeappschool/about')
|
||||||
def safe_app_school_about():
|
def safe_app_school_about():
|
||||||
pass
|
if current_user.is_authenticated:
|
||||||
|
return render_template('safe_app_school/about.html')
|
||||||
|
else:
|
||||||
|
return redirect('/safe_app_school/login')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/safeappschool/go')
|
@app.route('/safeappschool/setting', methods=['GET', 'POST'])
|
||||||
def safe_app_school_go():
|
def safe_app_school_setting():
|
||||||
pass
|
if current_user.is_authenticated:
|
||||||
|
form = PointForm()
|
||||||
|
data_session = db_session.create_session()
|
||||||
|
point = data_session.query(UserPoint).filter(UserPoint.user == current_user.id).first()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
if point:
|
||||||
|
point.school_address = form.school_address.data
|
||||||
|
point.home_address = form.home_address.data
|
||||||
|
else:
|
||||||
|
point = UserPoint(
|
||||||
|
user=current_user.id,
|
||||||
|
home_address=form.home_address.data,
|
||||||
|
school_address=form.school_address.data
|
||||||
|
)
|
||||||
|
data_session.add(point)
|
||||||
|
data_session.commit()
|
||||||
|
data_session.close()
|
||||||
|
return redirect('/safeappschool/main')
|
||||||
|
if point:
|
||||||
|
form.school_address.data = point.school_address
|
||||||
|
form.home_address.data = point.home_address
|
||||||
|
return render_template('safe_app_school/setting.html', form=form, message='')
|
||||||
|
else:
|
||||||
|
return redirect('/safe_app_school/login')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/safeappschool/go/<string:point>')
|
||||||
|
def safe_app_school_go(point):
|
||||||
|
if current_user.is_authenticated:
|
||||||
|
data_session = db_session.create_session()
|
||||||
|
address = data_session.query(UserPoint).filter(UserPoint.user == current_user.id).first()
|
||||||
|
if address.school_address and address.home_address:
|
||||||
|
with open('static/js/safe_app_school/mapbasics_templates.js', 'r', encoding='utf-8') as file:
|
||||||
|
new_file = file.read().split('<point1>')
|
||||||
|
new_file = new_file[0] + f'\'{address.home_address if point == "home" else address.school_address}\'' \
|
||||||
|
+ new_file[1]
|
||||||
|
new_file = new_file.split('<point2>')
|
||||||
|
new_file = new_file[
|
||||||
|
0] + f'\'{address.school_address if point == "home" else address.home_address}\'' + \
|
||||||
|
new_file[1]
|
||||||
|
with open('static/js/safe_app_school/mapbasics.js', 'w', encoding='utf-8') as new_js:
|
||||||
|
new_js.write(new_file)
|
||||||
|
t = Timer(1, remove_java, args=None, kwargs=None)
|
||||||
|
t.start()
|
||||||
|
if point == 'home':
|
||||||
|
return render_template('safe_app_school/route.html', title='Маршрут домой', route='домой')
|
||||||
|
elif point == 'school':
|
||||||
|
return render_template('safe_app_school/route.html', title='Маршрут в школу', route='в школу')
|
||||||
|
else:
|
||||||
|
return redirect('/safe_app_school/main')
|
||||||
|
else:
|
||||||
|
return render_template('safe_app_school/route.html', title='Маршрут не указан', route=False)
|
||||||
|
else:
|
||||||
|
return redirect('/safe_app_school/login')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/diary/')
|
@app.route('/diary/')
|
||||||
@ -653,13 +900,13 @@ def diary():
|
|||||||
|
|
||||||
@app.route('/diary/logout')
|
@app.route('/diary/logout')
|
||||||
@login_required
|
@login_required
|
||||||
def logout():
|
def diary_logout():
|
||||||
logout_user()
|
logout_user()
|
||||||
return redirect("/diary/")
|
return redirect("/diary/")
|
||||||
|
|
||||||
|
|
||||||
@app.route('/diary/login', methods=['GET', 'POST'])
|
@app.route('/diary/login', methods=['GET', 'POST'])
|
||||||
def login():
|
def diary_login():
|
||||||
form = LoginForm()
|
form = LoginForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
db_sess = db_session.create_session()
|
db_sess = db_session.create_session()
|
||||||
@ -674,7 +921,7 @@ def login():
|
|||||||
|
|
||||||
|
|
||||||
@app.route('/diary/confirmation', methods=['GET', 'POST'])
|
@app.route('/diary/confirmation', methods=['GET', 'POST'])
|
||||||
def confirmation():
|
def diary_onfirmation():
|
||||||
global help_arg
|
global help_arg
|
||||||
if help_arg:
|
if help_arg:
|
||||||
global send_msg
|
global send_msg
|
||||||
@ -724,13 +971,13 @@ def confirmation():
|
|||||||
return redirect('/diary/login')
|
return redirect('/diary/login')
|
||||||
else:
|
else:
|
||||||
if form.simple:
|
if form.simple:
|
||||||
return render_template('simple_confimication.html', title='Подтверждение', form=conf,
|
return render_template('simple/simple_confirmation.html', title='Подтверждение', form=conf,
|
||||||
message='Коды не совпадают')
|
message='Коды не совпадают')
|
||||||
else:
|
else:
|
||||||
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf,
|
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf,
|
||||||
message='Коды не совпадают')
|
message='Коды не совпадают')
|
||||||
if form.simple:
|
if form.simple:
|
||||||
return render_template('simple_confimication.html', title='Подтверждение', form=conf,
|
return render_template('simple/simple_confirmation.html', title='Подтверждение', form=conf,
|
||||||
message='Коды не совпадают')
|
message='Коды не совпадают')
|
||||||
else:
|
else:
|
||||||
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf, message='')
|
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf, message='')
|
||||||
@ -751,7 +998,7 @@ def confirmation():
|
|||||||
return redirect('/diary/profile')
|
return redirect('/diary/profile')
|
||||||
|
|
||||||
if form.simple:
|
if form.simple:
|
||||||
return render_template('simple_confimication.html', title='Подтверждение', form=conf,
|
return render_template('simple_confirmation.html', title='Подтверждение', form=conf,
|
||||||
message='Коды не совпадают')
|
message='Коды не совпадают')
|
||||||
else:
|
else:
|
||||||
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf, message='')
|
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf, message='')
|
||||||
@ -760,7 +1007,7 @@ def confirmation():
|
|||||||
|
|
||||||
|
|
||||||
@app.route('/diary/register', methods=['GET', 'POST'])
|
@app.route('/diary/register', methods=['GET', 'POST'])
|
||||||
def register():
|
def diary_register():
|
||||||
global help_arg
|
global help_arg
|
||||||
global photo
|
global photo
|
||||||
form = RegisterForm()
|
form = RegisterForm()
|
||||||
|
|||||||
6
static/css/main/base.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
body {
|
||||||
|
background-image: url('../../img/big_back_moona.png');
|
||||||
|
font-family: 'Comfortaa', sans-serif;
|
||||||
|
background-color: #f0ffff;
|
||||||
|
margin-bottom: 200px;
|
||||||
|
}
|
||||||
43
static/css/main/confirmation_reg.css
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
.confirmation {
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
.confirmation {
|
||||||
|
width: 60%;
|
||||||
|
margin-left: 20%;
|
||||||
|
margin-right: 20%;
|
||||||
|
}
|
||||||
|
.confirmation_form {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column wrap;
|
||||||
|
}
|
||||||
|
.form_buttons {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
.header_title {
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
margin-left: 27%;
|
||||||
|
margin-right: 27%;
|
||||||
|
width: 46%;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: font-size 0.5s ease-in, text-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.header_title:hover {
|
||||||
|
font-size: 43;
|
||||||
|
text-shadow: 0px 0px 20px #ffffff;
|
||||||
|
}
|
||||||
|
.back {
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 19px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
width: 10%;
|
||||||
|
margin-left: 12px;
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
.back_text {
|
||||||
|
margin-top: 7%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
48
static/css/main/login.css
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
.login {
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
.header_title {
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
margin-left: 27%;
|
||||||
|
margin-right: 27%;
|
||||||
|
width: 46%;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: font-size 0.5s ease-in, text-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.header_title:hover {
|
||||||
|
font-size: 53;
|
||||||
|
text-shadow: 0px 0px 20px #ffffff;
|
||||||
|
}
|
||||||
|
.login {
|
||||||
|
width: 60%;
|
||||||
|
margin-left: 20%;
|
||||||
|
margin-right: 20%;
|
||||||
|
}
|
||||||
|
.login_form {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column wrap;
|
||||||
|
}
|
||||||
|
.form_buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.button_form {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
.back {
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 19px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
width: 10%;
|
||||||
|
margin-left: 12px;
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
.back_text {
|
||||||
|
margin-top: 7%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
@ -1,16 +1,8 @@
|
|||||||
body {
|
|
||||||
background-image: url('../../img/big_back_moona.png');
|
|
||||||
font-family: 'Comfortaa', sans-serif;
|
|
||||||
background-color: #f0ffff;
|
|
||||||
}
|
|
||||||
.header, .body {
|
.header, .body {
|
||||||
width: 70%;
|
width: 70%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
.body {
|
|
||||||
margin-top: 5%;
|
|
||||||
}
|
|
||||||
.header_logo {
|
.header_logo {
|
||||||
width: 60%;
|
width: 60%;
|
||||||
margin-left: 20%;
|
margin-left: 20%;
|
||||||
@ -58,7 +50,6 @@ body {
|
|||||||
margin-left: 3%;
|
margin-left: 3%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: justify;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
.article_one_image, .article_two_image {
|
.article_one_image, .article_two_image {
|
||||||
@ -73,3 +64,35 @@ body {
|
|||||||
border-radius: 22px;
|
border-radius: 22px;
|
||||||
box-shadow: 0px 0px 30px #ffffff;
|
box-shadow: 0px 0px 30px #ffffff;
|
||||||
}
|
}
|
||||||
|
.auth {
|
||||||
|
width: 28%;
|
||||||
|
margin-left: 12px;
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
.user {
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 19px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
width: 160px;
|
||||||
|
height: 50px;
|
||||||
|
margin-bottom: 30%;
|
||||||
|
border-radius: 15px;
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
transition: border-radius 0.5s ease-in, box-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
border-radius: 22px;
|
||||||
|
box-shadow: 0px 0px 30px #ffffff;
|
||||||
|
}
|
||||||
|
.btn_text {
|
||||||
|
margin-top: 7%;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.login {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|||||||
43
static/css/main/register.css
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
.register {
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
.header_title {
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
margin-left: 27%;
|
||||||
|
margin-right: 27%;
|
||||||
|
width: 46%;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: font-size 0.5s ease-in, text-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.header_title:hover {
|
||||||
|
font-size: 53;
|
||||||
|
text-shadow: 0px 0px 20px #ffffff;
|
||||||
|
}
|
||||||
|
.register {
|
||||||
|
width: 60%;
|
||||||
|
margin-left: 20%;
|
||||||
|
margin-right: 20%;
|
||||||
|
}
|
||||||
|
.register_form {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column wrap;
|
||||||
|
}
|
||||||
|
.form_buttons {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
.back {
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 19px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
width: 10%;
|
||||||
|
margin-left: 12px;
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
.back_text {
|
||||||
|
margin-top: 7%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
47
static/css/safe_app_school/about.css
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
.back {
|
||||||
|
margin-top: 5%;
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 22px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
width: 20%;
|
||||||
|
margin-left: 40%;
|
||||||
|
height: 8%;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
}
|
||||||
|
.back_text {
|
||||||
|
margin-top: 4%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.header_title {
|
||||||
|
font-size: 2.5vw;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: font-size 0.5s ease-in, text-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.header_title:hover {
|
||||||
|
font-size: 3vw;
|
||||||
|
text-shadow: 0px 0px 20px #ffffff;
|
||||||
|
}
|
||||||
|
.article {
|
||||||
|
width 60%;
|
||||||
|
margin-left: 20%;
|
||||||
|
margin-right: 20%;
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
border-radius: 22px;
|
||||||
|
}
|
||||||
|
.article_text_back {
|
||||||
|
margin-top: 5%;
|
||||||
|
margin-right: 5%;
|
||||||
|
margin-left: 5%;
|
||||||
|
margin-bottom: 5%;
|
||||||
|
}
|
||||||
|
.article_text {
|
||||||
|
font-size: 1.5vw;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
6
static/css/safe_app_school/base.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
body {
|
||||||
|
background-image: url('../../img/big_back_moona.png');
|
||||||
|
font-family: 'Comfortaa', sans-serif;
|
||||||
|
background-color: #f0ffff;
|
||||||
|
margin-bottom: 200px;
|
||||||
|
}
|
||||||
52
static/css/safe_app_school/main.css
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
.header {
|
||||||
|
width: 70%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.header_logo {
|
||||||
|
width:30%;
|
||||||
|
margin-left: 35%;
|
||||||
|
margin-right: 35%;
|
||||||
|
}
|
||||||
|
.header_title {
|
||||||
|
font-size: 2.5vw;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: font-size 0.5s ease-in, text-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.header_title:hover {
|
||||||
|
font-size: 3vw;
|
||||||
|
text-shadow: 0px 0px 20px #ffffff;
|
||||||
|
}
|
||||||
|
.page {
|
||||||
|
width: 70%;
|
||||||
|
margin-left: 15%;
|
||||||
|
margin-right: 15%;
|
||||||
|
}
|
||||||
|
.navigation {
|
||||||
|
margin-top: 50px;
|
||||||
|
margin-right: 20%;
|
||||||
|
margin-left: 20%;
|
||||||
|
width: 60%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-content: stretch;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
width: 100%;
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 10%;
|
||||||
|
margin-top: 5%;
|
||||||
|
transition: border-radius 0.5s ease-in, box-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
border-radius: 15%;
|
||||||
|
box-shadow: 0px 0px 30px #ffffff;
|
||||||
|
}
|
||||||
|
.button_block {
|
||||||
|
width: 35%;
|
||||||
|
}
|
||||||
46
static/css/safe_app_school/route.css
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
.back {
|
||||||
|
margin-top: 5%;
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 22px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
width: 20%;
|
||||||
|
margin-left: 40%;
|
||||||
|
height: 8%;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
}
|
||||||
|
.back_text {
|
||||||
|
margin-top: 4%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.page {
|
||||||
|
width: 70%;
|
||||||
|
margin-left: 15%;
|
||||||
|
margin-right: 15%;
|
||||||
|
}
|
||||||
|
.header_title {
|
||||||
|
font-size: 2.5vw;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: font-size 0.5s ease-in, text-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.header_title:hover {
|
||||||
|
font-size: 3vw;
|
||||||
|
text-shadow: 0px 0px 20px #ffffff;
|
||||||
|
}
|
||||||
|
.header_button {
|
||||||
|
margin-top: 10px;
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 19px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
width: 40%;
|
||||||
|
margin-left: 30%;
|
||||||
|
margin-right: 30%;
|
||||||
|
height: 10%;
|
||||||
|
}
|
||||||
|
.header_button_text {
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
43
static/css/safe_app_school/setting.css
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
.page {
|
||||||
|
width: 70%;
|
||||||
|
margin-left: 15%;
|
||||||
|
margin-right: 15%;
|
||||||
|
}
|
||||||
|
.header_title {
|
||||||
|
font-size: 2.5vw;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: font-size 0.5s ease-in, text-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.header_title:hover {
|
||||||
|
font-size: 3vw;
|
||||||
|
text-shadow: 0px 0px 20px #ffffff;
|
||||||
|
}
|
||||||
|
form {
|
||||||
|
width: 80%;
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
.button_form {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.form_label {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 2vw;
|
||||||
|
}
|
||||||
|
.back {
|
||||||
|
margin-top: 5%;
|
||||||
|
background: linear-gradient(45deg, #d1c3fc, #9bc4fc);
|
||||||
|
border-radius: 22px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
width: 20%;
|
||||||
|
margin-left: 40%;
|
||||||
|
height: 8%;
|
||||||
|
font-size: 1.5vw;
|
||||||
|
}
|
||||||
|
.back_text {
|
||||||
|
margin-top: 4%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
37
static/css/simple/login.css
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
body {
|
||||||
|
font-family: 'Comfortaa', sans-serif;
|
||||||
|
background-color: #f0ffff;
|
||||||
|
}
|
||||||
|
.header_title {
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 27%;
|
||||||
|
margin-right: 27%;
|
||||||
|
width: 46%;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 15px;
|
||||||
|
transition: font-size 0.5s ease-in, text-shadow 1s ease-in;
|
||||||
|
}
|
||||||
|
.header_title:hover {
|
||||||
|
font-size: 53;
|
||||||
|
text-shadow: 0px 0px 20px #ffffff;
|
||||||
|
}
|
||||||
|
.login {
|
||||||
|
width: 60%;
|
||||||
|
margin-left: 30%;
|
||||||
|
margin-right: 20%;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
}
|
||||||
|
form {
|
||||||
|
width: 80%;
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
.buttons_from {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 798 KiB |
|
Before Width: | Height: | Size: 4.5 MiB After Width: | Height: | Size: 2.7 MiB |
BIN
static/img/home.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
static/img/info.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
static/img/maps.ico
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
static/img/school.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
static/img/setting.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
static/img/strong_big_back_moona.png
Normal file
|
After Width: | Height: | Size: 4.5 MiB |
51
static/js/safe_app_school/mapbasics_templates.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
function init() {
|
||||||
|
// Задаём точки мультимаршрута.
|
||||||
|
var pointA = <point1>,
|
||||||
|
pointB = <point2>,
|
||||||
|
/**
|
||||||
|
* Создаем мультимаршрут.
|
||||||
|
* @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/multiRouter.MultiRoute.xml
|
||||||
|
*/
|
||||||
|
multiRoute = new ymaps.multiRouter.MultiRoute({
|
||||||
|
referencePoints: [
|
||||||
|
pointA,
|
||||||
|
pointB
|
||||||
|
],
|
||||||
|
params: {
|
||||||
|
//Тип маршрутизации - пешеходная маршрутизация.
|
||||||
|
routingMode: 'pedestrian'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
// Автоматически устанавливать границы карты так, чтобы маршрут был виден целиком.
|
||||||
|
boundsAutoApply: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Создаем кнопку.
|
||||||
|
var changePointsButton = new ymaps.control.Button({
|
||||||
|
data: {content: "Поменять местами точки А и В"},
|
||||||
|
options: {selectOnClick: false}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Объявляем обработчики для кнопки.
|
||||||
|
changePointsButton.events.add('select', function () {
|
||||||
|
multiRoute.model.setReferencePoints([pointB, pointA]);
|
||||||
|
});
|
||||||
|
|
||||||
|
changePointsButton.events.add('deselect', function () {
|
||||||
|
multiRoute.model.setReferencePoints([pointA, pointB]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Создаем карту с добавленной на нее кнопкой.
|
||||||
|
var myMap = new ymaps.Map('map', {
|
||||||
|
center: [55.739625, 37.54120],
|
||||||
|
zoom: 12,
|
||||||
|
controls: [changePointsButton]
|
||||||
|
}, {
|
||||||
|
buttonMaxWidth: 300
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем мультимаршрут на карту.
|
||||||
|
myMap.geoObjects.add(multiRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
ymaps.ready(init);
|
||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="divlog" id="divlog">
|
<div class="divlog" id="divlog">
|
||||||
<h1 class="zag_auth">Авторизация</h1>
|
<h1 class="header_title">Авторизация</h1>
|
||||||
<form class="row g-2" action="" method="post">
|
<form class="row g-2" action="" method="post">
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
|
|||||||
@ -46,8 +46,8 @@
|
|||||||
<div class="join_us">
|
<div class="join_us">
|
||||||
<h2 class="join_us_header">Присоединяйся к нам! Регистрируйся или авторизуйся :з</h2>
|
<h2 class="join_us_header">Присоединяйся к нам! Регистрируйся или авторизуйся :з</h2>
|
||||||
<div class="join_us_login_block">
|
<div class="join_us_login_block">
|
||||||
<a class="button" href="/register"><p class="btn_text">Регистрация</p></a>
|
<a class="button" href="/diary/register"><p class="btn_text">Регистрация</p></a>
|
||||||
<a class="button" href="/login"><p class="btn_text">Вход</p></a>
|
<a class="button" href="/diary/login"><p class="btn_text">Вход</p></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
27
templates/main/base.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
<link rel="icon" href="../static/img/MoonCcircl.ico" type="image/x-icon">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Montserrat+Alternates:wght@600&display=swap"
|
||||||
|
rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="../../static/css/main/base.css">
|
||||||
|
<title>{{title}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js"
|
||||||
|
integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<h4 style="text-align:center;">Сайт находится на доработке и может работать некорректно :)</h4>
|
||||||
|
</div>
|
||||||
|
<!-- Begin page content -->
|
||||||
|
<main role="main">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
31
templates/main/confirmation_reg.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<link rel="stylesheet" href="../../static/css/main/confirmation_reg.css">
|
||||||
|
{% extends "main/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="back">
|
||||||
|
<a href="/"><p class="back_text" style="color: #ffffff">Назад</p></a>
|
||||||
|
</div>
|
||||||
|
<div class="confirmation">
|
||||||
|
<h1 class="header_title">Подтверждение почты</h1>
|
||||||
|
<form action="" method="post">
|
||||||
|
<div class="confirmation_form">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
{{ form.csrf_token }}
|
||||||
|
<h3>Мы отправили секретный код вам на почту</h3>
|
||||||
|
<p>
|
||||||
|
{{ form.code_key.label }}<br>
|
||||||
|
{{ form.code_key(class="form-control") }}<br>
|
||||||
|
{% for error in form.code_key.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
<p>{{ form.submit(type="submit", class="btn btn-primary form_buttons") }}</p>
|
||||||
|
{% if message != '' %}
|
||||||
|
<div class="alert alert-danger" role="alert">{{ message }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
52
templates/main/login.html
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<link rel="stylesheet" href="../../static/css/main/login.css">
|
||||||
|
{% extends "main/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="back">
|
||||||
|
<a href="/"><p class="back_text" style="color: #ffffff">Назад</p></a>
|
||||||
|
</div>
|
||||||
|
<div class="login">
|
||||||
|
<h1 class="header_title">Авторизация</h1>
|
||||||
|
<form action="" method="post">
|
||||||
|
<div class="login_form">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
<div>
|
||||||
|
<label class="form-label">{{ form.email.label }}</label>
|
||||||
|
{{ form.email(class="form-control", type="email") }}
|
||||||
|
{% for error in form.email.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="form-label">{{ form.password.label }}</label>
|
||||||
|
{{ form.password(class="form-control", type="password") }}
|
||||||
|
{% for error in form.password.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="box">{{ form.remember_me(class="form-check-input")}} {{ form.remember_me.label }}<br></div>
|
||||||
|
{% for error in form.remember_me.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="form_buttons">
|
||||||
|
{{ form.submit(type="submit", class="btn btn-primary button_form") }}
|
||||||
|
<a class="btn btn-primary button_form" type="submit"
|
||||||
|
href="/register"><strong>Регистрация</strong></a>
|
||||||
|
<a class="btn btn-primary button_form" type="submit" href="/recovery"><strong>Забыли
|
||||||
|
пароль</strong></a>
|
||||||
|
</div>
|
||||||
|
{% if message != '' %}
|
||||||
|
<div class="alert alert-danger" role="alert">{{ message }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@ -1,23 +1,28 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link rel="stylesheet"
|
|
||||||
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
|
||||||
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
|
|
||||||
crossorigin="anonymous">
|
|
||||||
<link rel="icon" href="../static/img/MoonCcircl.ico" type="image/x-icon">
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Montserrat+Alternates:wght@600&display=swap"
|
|
||||||
rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="../../static/css/main/main.css">
|
<link rel="stylesheet" href="../../static/css/main/main.css">
|
||||||
<title>Добро пожаловать</title>
|
{% extends "main/base.html" %}
|
||||||
</head>
|
|
||||||
<body>
|
{% block content %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js"
|
<div class="auth">
|
||||||
integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8"
|
{% if current_user.is_authenticated %}
|
||||||
crossorigin="anonymous"></script>
|
<div class="dropdown">
|
||||||
<div class="alert alert-danger" role="alert">
|
<button class="btn btn-secondary dropdown-toggle user" type="button" data-bs-toggle="dropdown"
|
||||||
<h4 style="text-align:center;">Сайт находится на доработке и может работать некорректно :)</h4>
|
aria-expanded="false">
|
||||||
|
<img src="../../{{ current_user.photo }}" width="40" height="40"
|
||||||
|
style="border-radius: 22px">
|
||||||
|
<strong style="color: #ffffff">{{ current_user.name }}</strong>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a class="dropdown-item" href="/diary">Дневник</a></li>
|
||||||
|
<li><a class="dropdown-item" href="/safeappschool" aria-current="true">SafeAppSchool</a></li>
|
||||||
|
<li><a class="dropdown-item btn btn-danger active" href="/logout">Выйти</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="login">
|
||||||
|
<a class="button" href="/register"><p class="btn_text">Регистрация</p></a>
|
||||||
|
<a class="button" href="/login"><p class="btn_text">Вход</p></a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<img class="header_logo" src="../../static/img/string_moona_no_back.png" width="50%">
|
<img class="header_logo" src="../../static/img/string_moona_no_back.png" width="50%">
|
||||||
@ -33,7 +38,7 @@
|
|||||||
<img class="article_one_image img-thumbnail" src="../../static/img/MoonCcircl.png">
|
<img class="article_one_image img-thumbnail" src="../../static/img/MoonCcircl.png">
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a>
|
<a href="/safeappschool/main">
|
||||||
<div class="article_two">
|
<div class="article_two">
|
||||||
<img class="article_two_image img-thumbnail" src="../../static/img/maps.png">
|
<img class="article_two_image img-thumbnail" src="../../static/img/maps.png">
|
||||||
<div class="article_two_text_back">
|
<div class="article_two_text_back">
|
||||||
@ -45,5 +50,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</body>
|
{% endblock %}
|
||||||
</html>
|
|
||||||
77
templates/main/register.html
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<link rel="stylesheet" href="../../static/css/main/register.css">
|
||||||
|
{% extends "main/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="back">
|
||||||
|
<a href="/"><p class="back_text" style="color: #ffffff">Назад</p></a>
|
||||||
|
</div>
|
||||||
|
<div class="register">
|
||||||
|
<h1 class="header_title">Регистрация</h1>
|
||||||
|
<form action="" method="POST" enctype="multipart/form-data">
|
||||||
|
<div class="register_form">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
{{ form.csrf_token }}
|
||||||
|
<div>
|
||||||
|
<label class="form-label">{{ form.name.label }}</label>
|
||||||
|
{{ form.name(class="form-control", type="text") }}
|
||||||
|
{% for error in form.name.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="form-label">{{ form.surname.label }}</label>
|
||||||
|
{{ form.surname(class="form-control", type="text") }}
|
||||||
|
{% for error in form.surname.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="form-label">{{ form.email.label }}</label>
|
||||||
|
{{ form.email(class="form-control", type="email") }}
|
||||||
|
{% for error in form.email.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="form-label">{{ form.password.label }}</label>
|
||||||
|
{{ form.password(class="form-control", type="password") }}
|
||||||
|
{% for error in form.password.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="form-label">{{ form.password2.label }}</label>
|
||||||
|
{{ form.password2(class="form-control", type="password") }}
|
||||||
|
{% for error in form.password2.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="form-label">{{ form.login.label }}</label>
|
||||||
|
{{ form.login(class="form-control", type="text") }}
|
||||||
|
{% for error in form.login.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="form_buttons">
|
||||||
|
<p>{{ form.submit(type="submit", class="btn btn-primary", style="background-color:#38aaff") }}</p>
|
||||||
|
{% if message != '' %}
|
||||||
|
<div class="alert alert-danger" role="alert">{{ message }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
26
templates/safe_app_school/about.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<link rel="stylesheet" href="../../static/css/safe_app_school/about.css">
|
||||||
|
{% extends "safe_app_school/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="back">
|
||||||
|
<a href="/safeappschool/main"><p class="back_text" style="color: #ffffff">Назад</p></a>
|
||||||
|
</div>
|
||||||
|
<div class="header">
|
||||||
|
<h2 class="header_title">О SafeAppSchool</h2>
|
||||||
|
</div>
|
||||||
|
<div class="article">
|
||||||
|
<div class="article_text_back">
|
||||||
|
<p class="article_text">Построение безопасного маршрута для того, что бы ваш ребенок смог добраться от дома до
|
||||||
|
школы без проблем по пути.<br><br>
|
||||||
|
|
||||||
|
SafeAppSchool - приложение по городу. К тому, который прямо сейчас вокруг вас. Интерфейс приложения устроен
|
||||||
|
так, что бы ребенок интуитивно понимал как пользоваться им. Преимущество нашего приложения состоит в
|
||||||
|
минимизированном дизайне, без лишних функций.<br><br>
|
||||||
|
|
||||||
|
Для вопросов и предложений вы можете обращаться по адресу: <br><a href="mailto:andrei@duvakin.ru">andrei@duvakin.ru</a>
|
||||||
|
<br><a href="mailto:a.mikryukova119@mail.ru">a.mikryukova119@mail.ru</a><br><br>
|
||||||
|
|
||||||
|
Ссылка на Github.com: <a href="https://github.com/AndreiDuvakin/SafeAppShcool">https://github.com/AndreiDuvakin/SafeAppShcool</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
37
templates/safe_app_school/base.html
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
<link rel="icon" href="../static/img/maps.ico" type="image/x-icon">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Montserrat+Alternates:wght@600&display=swap"
|
||||||
|
rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="../../static/css/safe_app_school/base.css">
|
||||||
|
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
<!--
|
||||||
|
Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
|
||||||
|
Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
|
||||||
|
-->
|
||||||
|
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=d101001e-49f5-4a17-ac39-2d67f64b3f9b"
|
||||||
|
type="text/javascript"></script>
|
||||||
|
<script src="../../static/js/safe_app_school/mapbasics.js" type="text/javascript"></script>
|
||||||
|
<style>
|
||||||
|
html, body, #map {
|
||||||
|
width: 100%; height: 100%; padding: 0; margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<title>{{title}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Begin page content -->
|
||||||
|
<main role="main">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
25
templates/safe_app_school/main.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<link rel="stylesheet" href="../../static/css/safe_app_school/main.css">
|
||||||
|
{% extends "safe_app_school/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="page">
|
||||||
|
<div class="header">
|
||||||
|
<img class="header_logo" src="../../static/img/maps.png" width="200">
|
||||||
|
<h2 class="header_title">Здравствуйте, {{ current_user.name }}!</h2>
|
||||||
|
</div>
|
||||||
|
<div class="navigation">
|
||||||
|
<div class="button_block">
|
||||||
|
<a href="/safeappschool/go/school"><img class="button" src="../../static/img/school.png"></a>
|
||||||
|
</div>
|
||||||
|
<div class="button_block">
|
||||||
|
<a href="/safeappschool/go/home"><img class="button" src="../../static/img/home.png"></a>
|
||||||
|
</div>
|
||||||
|
<div class="button_block">
|
||||||
|
<a href="/safeappschool/setting"><img class="button" src="../../static/img/setting.png"></a>
|
||||||
|
</div>
|
||||||
|
<div class="button_block">
|
||||||
|
<a href="/safeappschool/about"><img class="button" src="../../static/img/info.png"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
26
templates/safe_app_school/map.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Построение пешеходного мультимаршрута</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
|
<!--
|
||||||
|
Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
|
||||||
|
Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
|
||||||
|
-->
|
||||||
|
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=d101001e-49f5-4a17-ac39-2d67f64b3f9b" type="text/javascript"></script>
|
||||||
|
<script src="../../static/js/safe_app_school/mapbasics.js" type="text/javascript"></script>
|
||||||
|
<style>
|
||||||
|
html, body, #map {
|
||||||
|
width: 100%; height: 100%; padding: 0; margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="map"></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
22
templates/safe_app_school/route.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<link rel="stylesheet" href="../../static/css/safe_app_school/route.css">
|
||||||
|
{% extends "safe_app_school/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="back">
|
||||||
|
<a href="/safeappschool/main"><p class="back_text" style="color: #ffffff">Назад</p></a>
|
||||||
|
</div>
|
||||||
|
<div class="page">
|
||||||
|
{% if route %}
|
||||||
|
<div class="header">
|
||||||
|
<h2 class="header_title">Пора {{ route }}</h2>
|
||||||
|
</div>
|
||||||
|
<div id="map" style="width: 70%; height: 100%; margin-left: 15%; margin-right: 15%;"></div>
|
||||||
|
{% else %}
|
||||||
|
<div class="header">
|
||||||
|
<h2 class="header_title">Вы не указали точки маршрута в настройках!</h2>
|
||||||
|
<div class="header_button"><a href="/safeappschool/setting"><h3 class="header_button_text">Перейти в
|
||||||
|
настройки</h3></a></div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
42
templates/safe_app_school/setting.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<link rel="stylesheet" href="../../static/css/safe_app_school/setting.css">
|
||||||
|
{% extends "safe_app_school/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="back">
|
||||||
|
<a href="/safeappschool/main"><p class="back_text" style="color: #ffffff">Назад</p></a>
|
||||||
|
</div>
|
||||||
|
<div class="page">
|
||||||
|
<div class="header">
|
||||||
|
<h2 class="header_title">Настройки</h2>
|
||||||
|
</div>
|
||||||
|
<form action="" method="post">
|
||||||
|
<div class="point_form">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
<div>
|
||||||
|
<label class="form_label">{{ form.home_address.label }}</label>
|
||||||
|
{{ form.home_address(class="form-control size_class") }}
|
||||||
|
{% for error in form.home_address.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="form_label">{{ form.school_address.label }}</label>
|
||||||
|
{{ form.school_address(class="form-control") }}
|
||||||
|
{% for error in form.school_address.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="form_buttons">
|
||||||
|
{{ form.submit(type="submit", class="btn btn-primary button_form") }}
|
||||||
|
</div>
|
||||||
|
{% if message != '' %}
|
||||||
|
<div class="alert alert-danger" role="alert">{{ message }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
58
templates/simple/simple_login.html
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
<link rel="icon" href="../static/img/MoonCcircl.ico" type="image/x-icon">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@700&family=Montserrat+Alternates:wght@600&display=swap"
|
||||||
|
rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="../../static/css/simple/login.css">
|
||||||
|
<title>{{title}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 class="header_title">Авторизация</h1>
|
||||||
|
<div class="login">
|
||||||
|
<form class="row g-2" action="" method="post">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label">{{ form.email.label }}</label>
|
||||||
|
{{ form.email(class="form-control", type="email") }}
|
||||||
|
{% for error in form.email.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label">{{ form.password.label }}</label>
|
||||||
|
{{ form.password(class="form-control", type="password") }}
|
||||||
|
{% for error in form.password.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="box">{{ form.remember_me(class="form-check-input")}} {{ form.remember_me.label }}<br></div>
|
||||||
|
{% for error in form.remember_me.errors %}
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-10 buttons_from">{{ form.submit(type="submit", class="btn btn-primary button") }}
|
||||||
|
<a class="btn btn-primary button" type="submit"
|
||||||
|
href="/safeappschool/register"><strong>Регистрация</strong></a>
|
||||||
|
<a class="btn btn-primary button" type="submit" href="/recovery"><strong>Забыли
|
||||||
|
пароль</strong></a>
|
||||||
|
</div>
|
||||||
|
{% if message != '' %}
|
||||||
|
<div class="alert alert-danger" role="alert">{{ message }}</div>
|
||||||
|
{% endif %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||