Готов новый раздел сайта: SafeAppSchool

This commit is contained in:
Andrei 2022-10-31 22:23:36 +05:00
parent 7044e2ec8f
commit 123ff92d27
41 changed files with 1202 additions and 59 deletions

View File

@ -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

View 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
View 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('Сохранить')

View File

@ -18,6 +18,7 @@ class RegisterForm(FlaskForm):
del_photo = SubmitField('Удалить фотографию')
submit2 = SubmitField('Сохранить')
simple = False
back = False
class Confirmation(FlaskForm):

289
main.py
View File

@ -1,20 +1,24 @@
import datetime
import logging
import os
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_restful import abort
from waitress import serve
from werkzeug.utils import redirect
from threading import Timer
from data import db_session
from data.app_school_user_point import UserPoint
from data.answer_quest import Answer
from data.diary_post import DiaryPost
from data.like import Like
from data.popularity import Popularity
from data.questions import Quest
from data.users import User
from forms.point_user import PointForm
from forms.add_question import AddQuest
from forms.answer_quest import AnswerQuest
from forms.login import LoginForm
@ -36,6 +40,10 @@ photo = None
user_email = ""
def remove_java():
os.remove('static/js/safe_app_school/mapbasics.js')
def norm_data(datatime, date_or_time, r=False):
if date_or_time == 'date':
return '.'.join(str(datatime).split()[0].split('-')[::-1])
@ -69,28 +77,267 @@ def load_user(user_id):
db_sess = db_session.create_session()
return db_sess.query(User).get(user_id)
@app.route('/')
def main_page():
return render_template('/main/main.html')
@app.route('/safeappschool/login')
def safe_app_school_login():
pass
return render_template('/main/main.html', title='Добро пожаловать')
@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():
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')
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')
def safe_app_school_go():
pass
@app.route('/safeappschool/setting', methods=['GET', 'POST'])
def safe_app_school_setting():
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/')
@ -653,13 +900,13 @@ def diary():
@app.route('/diary/logout')
@login_required
def logout():
def diary_logout():
logout_user()
return redirect("/diary/")
@app.route('/diary/login', methods=['GET', 'POST'])
def login():
def diary_login():
form = LoginForm()
if form.validate_on_submit():
db_sess = db_session.create_session()
@ -674,7 +921,7 @@ def login():
@app.route('/diary/confirmation', methods=['GET', 'POST'])
def confirmation():
def diary_onfirmation():
global help_arg
if help_arg:
global send_msg
@ -724,13 +971,13 @@ def confirmation():
return redirect('/diary/login')
else:
if form.simple:
return render_template('simple_confimication.html', title='Подтверждение', form=conf,
return render_template('simple/simple_confirmation.html', title='Подтверждение', form=conf,
message='Коды не совпадают')
else:
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf,
message='Коды не совпадают')
if form.simple:
return render_template('simple_confimication.html', title='Подтверждение', form=conf,
return render_template('simple/simple_confirmation.html', title='Подтверждение', form=conf,
message='Коды не совпадают')
else:
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf, message='')
@ -751,7 +998,7 @@ def confirmation():
return redirect('/diary/profile')
if form.simple:
return render_template('simple_confimication.html', title='Подтверждение', form=conf,
return render_template('simple_confirmation.html', title='Подтверждение', form=conf,
message='Коды не совпадают')
else:
return render_template('diary/confirmation_reg.html', title='Подтверждение', form=conf, message='')
@ -760,7 +1007,7 @@ def confirmation():
@app.route('/diary/register', methods=['GET', 'POST'])
def register():
def diary_register():
global help_arg
global photo
form = RegisterForm()

View File

@ -6,7 +6,7 @@
margin-top: 35px;
}
.title {
text-align: center;
text-align: center;
}
input[type=text], input[type=email], input[type=password], input[type=file], input[type=number]{
padding:10px;

6
static/css/main/base.css Normal file
View 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;
}

View 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
View 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;
}

View File

@ -1,16 +1,8 @@
body {
background-image: url('../../img/big_back_moona.png');
font-family: 'Comfortaa', sans-serif;
background-color: #f0ffff;
}
.header, .body {
width: 70%;
margin-left: auto;
margin-right: auto;
}
.body {
margin-top: 5%;
}
.header_logo {
width: 60%;
margin-left: 20%;
@ -58,7 +50,6 @@ body {
margin-left: 3%;
overflow: auto;
color: white;
text-align: justify;
font-size: 20px;
}
.article_one_image, .article_two_image {
@ -72,4 +63,36 @@ body {
.article_one_image:hover, .article_two_image:hover {
border-radius: 22px;
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;
}

View 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;
}

View 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;
}

View 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;
}

View 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%;
}

View 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;
}

View 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;
}

View 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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 MiB

After

Width:  |  Height:  |  Size: 2.7 MiB

BIN
static/img/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
static/img/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
static/img/maps.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
static/img/school.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
static/img/setting.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

View 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);

View File

@ -3,7 +3,7 @@
{% block content %}
<div class="divlog" id="divlog">
<h1 class="zag_auth">Авторизация</h1>
<h1 class="header_title">Авторизация</h1>
<form class="row g-2" action="" method="post">
{{ form.hidden_tag() }}
<div class="col-md-4">

View File

@ -46,8 +46,8 @@
<div class="join_us">
<h2 class="join_us_header">Присоединяйся к нам! Регистрируйся или авторизуйся :з</h2>
<div class="join_us_login_block">
<a class="button" href="/register"><p class="btn_text">Регистрация</p></a>
<a class="button" href="/login"><p class="btn_text">Вход</p></a>
<a class="button" href="/diary/register"><p class="btn_text">Регистрация</p></a>
<a class="button" href="/diary/login"><p class="btn_text">Вход</p></a>
</div>
</div>
</div>

27
templates/main/base.html Normal file
View 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>

View 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
View 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 %}

View File

@ -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">
<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>
<link rel="stylesheet" href="../../static/css/main/main.css">
{% extends "main/base.html" %}
{% block content %}
<div class="auth">
{% if current_user.is_authenticated %}
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle user" type="button" data-bs-toggle="dropdown"
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 class="header">
<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">
</div>
</a>
<a>
<a href="/safeappschool/main">
<div class="article_two">
<img class="article_two_image img-thumbnail" src="../../static/img/maps.png">
<div class="article_two_text_back">
@ -45,5 +50,4 @@
</div>
</div>
</a>
</body>
</html>
{% endblock %}

View 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 %}

View 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 %}

View 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&amp;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>

View 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 %}

View 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&amp;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>

View 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 %}

View 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 %}

View 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>