Тестовая версия витрины
This commit is contained in:
parent
62ad4907db
commit
3617afce1b
@ -17,3 +17,5 @@ class Projects(SqlAlchemyBase, UserMixin):
|
||||
default=date.today())
|
||||
creator = sqlalchemy.Column(sqlalchemy.Integer,
|
||||
sqlalchemy.ForeignKey("users.id"), nullable=True, default=None)
|
||||
is_open = sqlalchemy.Column(sqlalchemy.Boolean, nullable=False, default=False)
|
||||
is_template = sqlalchemy.Column(sqlalchemy.Boolean, nullable=False, default=False)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from flask_wtf import FlaskForm
|
||||
from flask_wtf.file import FileAllowed
|
||||
from wtforms import StringField, SubmitField, TextAreaField, FileField, MultipleFileField
|
||||
from wtforms import StringField, SubmitField, TextAreaField, FileField, MultipleFileField, BooleanField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ class ProjectForm(FlaskForm):
|
||||
name = StringField('Название', validators=[DataRequired()])
|
||||
description = TextAreaField('Описание')
|
||||
logo = FileField('Логотип', validators=[FileAllowed(['jpg', 'png', 'bmp', 'ico', 'jpeg'], 'Только изображения')])
|
||||
is_template = BooleanField('Шаблон')
|
||||
submit = SubmitField('Создать')
|
||||
del_photo = SubmitField('Удалить фотографию')
|
||||
save = SubmitField('Сохранить')
|
||||
|
||||
@ -7,8 +7,8 @@ from wtforms.validators import DataRequired
|
||||
class Task(FlaskForm):
|
||||
name = StringField('Название', validators=[DataRequired()])
|
||||
description = TextAreaField('Описание', validators=[DataRequired()])
|
||||
deadline_date = DateField('Дедлайн', validators=[DataRequired()])
|
||||
deadline_time = TimeField('', validators=[DataRequired()])
|
||||
deadline_date = DateField('Дедлайн')
|
||||
deadline_time = TimeField('')
|
||||
submit = SubmitField('Создать')
|
||||
save = SubmitField('Сохранить')
|
||||
delete = SubmitField('Удалить')
|
||||
|
||||
41
functions.py
41
functions.py
@ -56,7 +56,7 @@ def mail(msg, to, topic='Подтверждение почты'):
|
||||
|
||||
def init_db_default():
|
||||
data_session = db_session.create_session()
|
||||
roles = [['admin', 2], ['moderator', 1], ['user', 0]]
|
||||
roles = [['admin', 90], ['moderator', 75], ['counselor', 45], ['user', 0]]
|
||||
for i in roles:
|
||||
role = Roles(
|
||||
name=i[0],
|
||||
@ -220,3 +220,42 @@ def delete_project_data(project, data_session):
|
||||
shutil.rmtree(f'static/app_files/all_projects/{str(project.id)}')
|
||||
data_session.delete(project)
|
||||
data_session.commit()
|
||||
|
||||
|
||||
def copy_file_from_template(file, new_project, data_session, current_user):
|
||||
path = f'static/app_files/all_projects/{str(new_project.id)}/{str(file.path).split("/")[-1]}'
|
||||
shutil.copy(file.path, path)
|
||||
new_file = Files(
|
||||
path=path,
|
||||
user=current_user.id,
|
||||
up_date=datetime.datetime.now()
|
||||
)
|
||||
data_session.add(new_file)
|
||||
|
||||
|
||||
def copy_quests_from_template(quest, new_project, data_session, current_user):
|
||||
new_quest = Quests(
|
||||
project=new_project.id,
|
||||
creator=current_user.id,
|
||||
name=quest.name,
|
||||
description=quest.description,
|
||||
date_create=datetime.datetime.now(),
|
||||
deadline=quest.deadline,
|
||||
realized=False
|
||||
)
|
||||
data_session.add(new_quest)
|
||||
|
||||
|
||||
def copy_template(template, new_project, data_session, current_user):
|
||||
os.mkdir(f'static/app_files/all_projects/{str(new_project.id)}')
|
||||
if 'none_project' not in template.photo:
|
||||
filename = f'static/app_files/project_logo/{uuid.uuid4()}.png'
|
||||
shutil.copy(template.photo, filename)
|
||||
new_project.photo = filename
|
||||
else:
|
||||
new_project.photo = 'static/images/none_project.png'
|
||||
list(map(lambda file: copy_file_from_template(file, new_project, data_session, current_user),
|
||||
data_session.query(Files).filter(Files.path.contains(f'all_projects/{str(template.id)}/')).all()))
|
||||
list(map(lambda quest: copy_quests_from_template(quest, new_project, data_session, current_user),
|
||||
data_session.query(Quests).filter(Quests.project == template.id).all()))
|
||||
data_session.commit()
|
||||
|
||||
59
main.py
59
main.py
@ -1,6 +1,7 @@
|
||||
import datetime
|
||||
import os
|
||||
import logging
|
||||
import shutil
|
||||
|
||||
from flask import Flask, render_template, request, url_for
|
||||
from flask_login import login_user, current_user, LoginManager, logout_user, login_required
|
||||
@ -13,7 +14,8 @@ from sqlalchemy import or_
|
||||
from json import loads
|
||||
|
||||
from functions import check_password, mail, init_db_default, get_projects_data, get_user_data, save_project_logo, \
|
||||
overdue_quest_project, save_proof_quest, find_files_answer, file_tree, delete_project_data, delete_quest_data
|
||||
overdue_quest_project, save_proof_quest, find_files_answer, file_tree, delete_project_data, delete_quest_data, \
|
||||
copy_template
|
||||
from forms.edit_profile import EditProfileForm
|
||||
from forms.login import LoginForm
|
||||
from forms.find_project import FindProjectForm
|
||||
@ -39,6 +41,7 @@ with open('incepted.config', 'r', encoding='utf-8') as file:
|
||||
file = loads(file)
|
||||
key = file["encrypt_key"]
|
||||
app.config['SECRET_KEY'] = key
|
||||
app.debug = True
|
||||
logging.basicConfig(level=logging.INFO, filename="logfiles/main.log", format="%(asctime)s %(levelname)s %(message)s",
|
||||
encoding='utf-8')
|
||||
csrf = CSRFProtect(app)
|
||||
@ -55,10 +58,55 @@ def base():
|
||||
return redirect('/projects')
|
||||
|
||||
|
||||
@app.route('/template/<int:id_template>/create')
|
||||
def create_by_template(id_template):
|
||||
if current_user.is_authenticated:
|
||||
data_session = db_session.create_session()
|
||||
current_template = data_session.query(Projects).filter(Projects.id == id_template).first()
|
||||
if current_template:
|
||||
new_project = Projects(
|
||||
name=current_template.name,
|
||||
description=current_template.description,
|
||||
date_create=datetime.datetime.now(),
|
||||
creator=current_user.id,
|
||||
is_open=False,
|
||||
is_template=False
|
||||
)
|
||||
data_session.add(new_project)
|
||||
data_session.flush()
|
||||
data_session.refresh(new_project)
|
||||
data_session.commit()
|
||||
copy_template(current_template, new_project, data_session, current_user)
|
||||
return redirect('/projects')
|
||||
else:
|
||||
abort(403)
|
||||
else:
|
||||
return redirect('/login')
|
||||
|
||||
|
||||
@app.route('/template/<int:id_template>')
|
||||
def template_project(id_template):
|
||||
if current_user.is_authenticated:
|
||||
data_session = db_session.create_session()
|
||||
current_project = data_session.query(Projects).filter(Projects.id == id_template).first()
|
||||
if current_project:
|
||||
quests = data_session.query(Quests).filter(Quests.project == current_project.id).all()
|
||||
files_list = file_tree(f'static/app_files/all_projects/{current_project.id}')
|
||||
return render_template('template_project.html', title=f'Шаблон {current_project.name}',
|
||||
project=current_project, quests=quests, file_tree=files_list)
|
||||
else:
|
||||
abort(404)
|
||||
else:
|
||||
return redirect('/login')
|
||||
|
||||
|
||||
@app.route('/showcase', methods=['GET', 'POST'])
|
||||
def showcase():
|
||||
if current_user.is_authenticated:
|
||||
return render_template('showcase.html', title='Витрина')
|
||||
data_session = db_session.create_session()
|
||||
list_template = list(map(lambda curr_project: get_projects_data(curr_project),
|
||||
data_session.query(Projects).filter(Projects.is_template == 1).all()))
|
||||
return render_template('showcase.html', title='Витрина', list_template=list_template)
|
||||
else:
|
||||
return redirect('/login')
|
||||
|
||||
@ -429,7 +477,8 @@ def new_project():
|
||||
name=form.name.data,
|
||||
description=form.description.data,
|
||||
date_create=datetime.datetime.now(),
|
||||
creator=current_user.id
|
||||
creator=current_user.id,
|
||||
is_template=form.is_template.data
|
||||
)
|
||||
current_project.photo = save_project_logo(
|
||||
form.logo.data) if form.logo.data else 'static/images/none_project.png'
|
||||
@ -595,7 +644,7 @@ def register():
|
||||
activity=datetime.datetime.now(),
|
||||
data_reg=datetime.date.today(),
|
||||
photo='static/images/none_logo.png',
|
||||
role=1
|
||||
role=3
|
||||
)
|
||||
user.set_password(form.password.data)
|
||||
data_session.add(user)
|
||||
@ -655,7 +704,7 @@ def main():
|
||||
db_session.global_init(db_path)
|
||||
if not db:
|
||||
init_db_default()
|
||||
serve(app, host='0.0.0.0', port=5000, threads=10)
|
||||
serve(app, host='0.0.0.0', port=5000, threads=100)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -62,6 +62,14 @@
|
||||
overflow-y: auto;
|
||||
padding-top: 2vw;
|
||||
}
|
||||
.list_project_block::-webkit-scrollbar {
|
||||
width: 0.8vw; /* ширина scrollbar */
|
||||
}
|
||||
.list_project_block::-webkit-scrollbar-thumb {
|
||||
background-color: #d49d51; /* цвет плашки */
|
||||
border-radius: 5vw; /* закругления плашки */
|
||||
border: 0.25vw solid #ffffff;
|
||||
}
|
||||
.list_project {
|
||||
width: 95%;
|
||||
margin-left: 2.5%;
|
||||
@ -133,6 +141,14 @@
|
||||
border-radius: 2vw;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.collaborator_block::-webkit-scrollbar {
|
||||
width: 0.8vw; /* ширина scrollbar */
|
||||
}
|
||||
.collaborator_block::-webkit-scrollbar-thumb {
|
||||
background-color: #d49d51; /* цвет плашки */
|
||||
border-radius: 5vw; /* закругления плашки */
|
||||
border: 0.25vw solid #ffffff;
|
||||
}
|
||||
.description_block {
|
||||
width: 48%;
|
||||
height: 90%;
|
||||
@ -145,12 +161,22 @@
|
||||
font-size: 2vw;
|
||||
}
|
||||
.description_block_text {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
width: 90% !important;
|
||||
height: 80% !important;
|
||||
width: 50%;
|
||||
background-color: #dcb495;
|
||||
border-radius: 2vw;
|
||||
}
|
||||
.description_block_text::-webkit-scrollbar {
|
||||
width: 0.8vw; /* ширина scrollbar */
|
||||
}
|
||||
.description_block_text::-webkit-scrollbar-thumb {
|
||||
background-color: #d49d51; /* цвет плашки */
|
||||
border-radius: 5vw; /* закругления плашки */
|
||||
border: 0.25vw solid #ffffff;
|
||||
}
|
||||
.description_text {
|
||||
width: 100% !important;
|
||||
height: 100%;
|
||||
|
||||
@ -1,4 +1,130 @@
|
||||
.showscale_page {
|
||||
height: 120vw;
|
||||
background-color: #dcb495;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.header_block {
|
||||
width: 100%;
|
||||
height: 20vw;
|
||||
background-position: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient( rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.85) ), url(../images/showcase.jpg);background-repeat: repeat; background-position: center;
|
||||
}
|
||||
.header_title {
|
||||
color: #ffffff;
|
||||
font-size: 7vw;
|
||||
}
|
||||
.header_title_2 {
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
font-size: 1.5vw;
|
||||
width: 50vw;
|
||||
}
|
||||
.templates_block {
|
||||
width: 95%;
|
||||
margin-top: 5vw;
|
||||
}
|
||||
.templates_title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 3.5vw;
|
||||
}
|
||||
.templates_list {
|
||||
height: 30vw;
|
||||
margin-top: 2vw;
|
||||
border: 0.2vw solid #694a2d;
|
||||
border-radius: 2vw;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.template {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-height: 28vw;
|
||||
min-width: 25vw;
|
||||
max-width: 25vw;
|
||||
background-color: #9E795A;
|
||||
margin: 1vw;
|
||||
border-radius: 2vw;
|
||||
}
|
||||
.template_title {
|
||||
margin-top: 1vw;
|
||||
max-width: 90%;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
font-size: 2vw;
|
||||
font-weight: 500;
|
||||
}
|
||||
.description {
|
||||
background-color: #EDCBB0;
|
||||
max-width: 90;
|
||||
height: auto;
|
||||
height: 15vw;
|
||||
min-width: 85%;
|
||||
max-width: 85%;
|
||||
border-radius: 0.5vw;
|
||||
}
|
||||
.description_text {
|
||||
margin: 0.8vw;
|
||||
overflow-wrap: normal; /* не поддерживает IE, Firefox; является копией word-wrap */
|
||||
word-wrap: normal;
|
||||
word-break: normal; /* не поддерживает Opera12.14, значение keep-all не поддерживается IE, Chrome */
|
||||
line-break: auto; /* нет поддержки для русского языка */
|
||||
hyphens: manual;
|
||||
}
|
||||
.description {
|
||||
overflow-y: auto;
|
||||
}
|
||||
.description::-webkit-scrollbar {
|
||||
width: 0.8vw; /* ширина scrollbar */
|
||||
}
|
||||
.description::-webkit-scrollbar-thumb {
|
||||
background-color: #d49d51; /* цвет плашки */
|
||||
border-radius: 5vw; /* закругления плашки */
|
||||
border: 0.25vw solid #ffffff;
|
||||
}
|
||||
.open_button {
|
||||
margin-top: 1vw;
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
width: 15vw;
|
||||
height: 4.5vw;
|
||||
vertical-align: middle;
|
||||
border-radius: 5vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.open_button:hover {
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
}
|
||||
.open_button_text {
|
||||
font-size: 1.5vw;
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.open_button, .open_button_link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 15vw;
|
||||
height: 4.5vw;
|
||||
color: #000000;
|
||||
}
|
||||
.open_button_link:hover {
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
}
|
||||
249
static/css/template_project.css
Normal file
249
static/css/template_project.css
Normal file
@ -0,0 +1,249 @@
|
||||
.template_page {
|
||||
height: 120vw;
|
||||
background-color: #dcb495;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.link_back_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.link_back {
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
width: 15vw;
|
||||
height: 4.5vw;
|
||||
vertical-align: middle;
|
||||
border-radius: 5vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.link_back:hover {
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
}
|
||||
.link_back_text {
|
||||
font-size: 1.5vw;
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.project_logo {
|
||||
margin-top: 30px;
|
||||
width: 15vw;
|
||||
height: 15vw;
|
||||
border: 0.2vw solid #ffffff;
|
||||
border-radius: 2vw;
|
||||
}
|
||||
.brand_block {
|
||||
height: 25vw;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: #000000;
|
||||
}
|
||||
.name_project {
|
||||
font-size: 3vw !important;
|
||||
}
|
||||
.header_task_block {
|
||||
width: 60vw;
|
||||
height: 30vw;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.task_block, .list_files_block {
|
||||
background-color: #EDCBB0;
|
||||
width: 95%;
|
||||
height: 25vw;
|
||||
border-radius: 2vw;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.task {
|
||||
margin: 20px;
|
||||
}
|
||||
.body_block {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.head_task {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
width: 60vw;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.list_quests {
|
||||
width: 95%;
|
||||
margin-left: 2.5%;
|
||||
margin-top: 0.5vw;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.quest_header_button {
|
||||
height: 4.5vw;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
border-radius: 5vw;
|
||||
background-color: #9E795A;
|
||||
border-color: #9E795A;
|
||||
border-bottom-color: #9E795A;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.quest_button_block_one {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.quest_title_block {
|
||||
width: 90%;
|
||||
height: 4vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.quest_title {
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
max-height: 1.5vw;
|
||||
font-size: 1.5vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 0.7vw;
|
||||
margin-left: 1.8vw;
|
||||
}
|
||||
.quest_body_block {
|
||||
background-color: #9E795A;
|
||||
width: 100%;
|
||||
height: 20vw;
|
||||
border-radius: 2vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.quest_body {
|
||||
width: 94%;
|
||||
height: 94%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.quest_description_block {
|
||||
width: 100%;
|
||||
height: 90%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.quest_description {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #dcb495;
|
||||
border-radius: 2vw;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.quest_description::-webkit-scrollbar, .task_block::-webkit-scrollbar-thumb {
|
||||
width: 0.8vw !important;
|
||||
}
|
||||
.quest_description::-webkit-scrollbar-thumb, .task_block::-webkit-scrollbar-thumb {
|
||||
background-color: #d49d51 !important; /* цвет плашки */
|
||||
border-radius: 5vw !important; /* закругления плашки */
|
||||
border: 0.25vw solid #ffffff !important;
|
||||
}
|
||||
.quest_description_text {
|
||||
margin: 20px;
|
||||
}
|
||||
.files_block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 35vw;
|
||||
}
|
||||
.list_files {
|
||||
margin: 2vw;
|
||||
}
|
||||
.files_title {
|
||||
text-align: center;
|
||||
color: #000000;
|
||||
font-size: 4vw;
|
||||
}
|
||||
.file {
|
||||
width: 98%;
|
||||
display: flex;
|
||||
background-color: #9E795A;
|
||||
margin: 0.5vw;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-direction: row;
|
||||
height: 4.5vw;
|
||||
border-radius: 2vw;
|
||||
}
|
||||
.file_head {
|
||||
width: 30vw;
|
||||
margin-left: 1vw;
|
||||
height: 4vw;
|
||||
background-color: #9E795A !important;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.file_head_path, .file_path {
|
||||
font-size: 1.5vw;
|
||||
color: #ffffff !important;
|
||||
font-weight: bold;
|
||||
height: 3vw;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
background-color: #9E795A !important;
|
||||
}
|
||||
.file_buttons {
|
||||
margin-right: 2vw;
|
||||
}
|
||||
.file_delete, .file_download, .upload_button {
|
||||
border-radius: 1vw !important;
|
||||
margin: 1vw;
|
||||
width: 8vw;
|
||||
height: 3vw;
|
||||
}
|
||||
.file_delete {
|
||||
background-color: hsla(0, 100%, 62%, 0.785) !important;
|
||||
border-color: hsla(0, 100%, 62%, 0.785) !important;
|
||||
}
|
||||
.button_text {
|
||||
font-size: 1.3vw;
|
||||
}
|
||||
.create_project_block {
|
||||
width: 13vw;
|
||||
height: 5vw;
|
||||
background-color: #000000;
|
||||
border: 2px solid #ffffff;
|
||||
border-radius: 3vw;
|
||||
margin-left: 2vw;
|
||||
}
|
||||
.create_link:hover {
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
}
|
||||
.create_text {
|
||||
width: 13vw;
|
||||
height: 5vw;
|
||||
text-align: center;
|
||||
font-size: 1.5vw;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
var edit_button = document.getElementById("edit_button"),
|
||||
new_task_link = document.getElementById("new_task_link"),
|
||||
quest_solve_link = document.getElementById("quest_solve_link"),
|
||||
quest_solve_link_id = document.getElementById("quest_solve_link_id");
|
||||
quest_solve_link_id = document.getElementById("quest_solve_link_id"),
|
||||
is_template = document.getElementById("is_template");
|
||||
|
||||
edit_button.href = String(window.location.href) + '/edit';
|
||||
new_task_link.href = String(window.location.href) + '/quest/new';
|
||||
|
||||
@ -51,6 +51,14 @@
|
||||
</div>
|
||||
<div class="form_data_button">
|
||||
{{ form.submit(type="submit", class="project_button") }}
|
||||
{% if current_user.role != 3 %}
|
||||
<div class="box">
|
||||
{{ form.is_template(class="is_template")}} {{form.is_template.label }}<br/>
|
||||
{% for error in form.is_template.errors %}
|
||||
<div class="alert alert-danger" role="alert">{{ error }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -26,7 +26,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="data_form_block">
|
||||
<div class="form_data">
|
||||
{% if not porject.is_template %}
|
||||
<div class="form_data" id="form_data">
|
||||
<label class="form_label">{{ form.deadline_date.label }}</label>
|
||||
{{ form.deadline_date(class="input_data deadline padding_data", type="date") }}
|
||||
{% for error in form.deadline_date.errors %}
|
||||
@ -37,8 +38,9 @@
|
||||
<div class="alert alert-danger" role="alert">{{ error }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="form_data_button">
|
||||
{{ form.submit(type="submit", class="quest_button") }}
|
||||
{% endif %}
|
||||
<div class="form_data_button" {% if porject.is_template %} style="margin-left: -2vw;"{% endif %}>
|
||||
{{ form.submit(type="submit", class="quest_button", id="quest_button") }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -65,6 +65,7 @@
|
||||
<div class="quest_title_block">
|
||||
<p class="quest_title">{{ quest.name }}</p>
|
||||
</div>
|
||||
{% if not project.is_template %}
|
||||
</div>
|
||||
{% if quest.overdue == 'yes' and quest.realized != 1 %}
|
||||
<div class="deadline_block alert alert-danger" role="alert">
|
||||
@ -87,6 +88,7 @@
|
||||
Задача выполнена
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</button>
|
||||
</h2>
|
||||
<div id="panelsStayOpen-collapse{{ quest.id }}"
|
||||
|
||||
@ -1,8 +1,32 @@
|
||||
<link rel="stylesheet" href="../static/css/showcase.css"/>
|
||||
{% extends "base.html" %} {% block content %}
|
||||
<div class="showscale_page">
|
||||
<div class="header">
|
||||
<div class="header_block">
|
||||
<h2 class="header_title">Витрина</h2>
|
||||
<strong class="header_title_2">Здесь вы можете находить макеты для своих проектов, а также подключатся к другим проектам</strong>
|
||||
</div>
|
||||
<div class="templates_block">
|
||||
<h2 class="templates_title">Шаблоны проектов</h2>
|
||||
<div class="templates_list">
|
||||
{% for template in list_template %}
|
||||
<div class="template">
|
||||
<p class="template_title">
|
||||
{{ template.name }}
|
||||
</p>
|
||||
<div class="description">
|
||||
<p class="description_text">{{ template.description }}</p>
|
||||
</div>
|
||||
<div class="open_button">
|
||||
<a class="open_button_link" href="/template/{{ template.id }}">
|
||||
<p class="open_button_text">Открыть</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="open_projects_block">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
107
templates/template_project.html
Normal file
107
templates/template_project.html
Normal file
@ -0,0 +1,107 @@
|
||||
<link rel="stylesheet" href="../static/css/template_project.css"/>
|
||||
{% extends "base.html" %} {% block content %}
|
||||
<div class="template_page">
|
||||
<div class="link_back_block">
|
||||
<a class="link_back" href="../showcase">
|
||||
<p class="link_back_text">К витрине</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="brand_block">
|
||||
<img class="project_logo" src="../{{project.photo}}"/>
|
||||
<p class="name_project header_title">{{ project.name }}</p>
|
||||
</div>
|
||||
<div class="body_block">
|
||||
<div class="header_task_block">
|
||||
<h3 class="header_title_2">Задачи</h3>
|
||||
<div class="task_block">
|
||||
<div class="task">
|
||||
{% for quest in quests %}
|
||||
<div class="accordion list_quests" id="accordionPanelsStayOpen{{ quest.id }}">
|
||||
<div class="accordion-item quest">
|
||||
<h2 class="accordion-header quest_header" id="panelsStayOpen-heading{{ quest.id }}">
|
||||
<button class="accordion-button quest_header_button" type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#panelsStayOpen-collapse{{ quest.id }}" aria-expanded="true"
|
||||
aria-controls="panelsStayOpen-collapse{{ quest.id }}">
|
||||
<div class="quest_button_block_one">
|
||||
<div class="quest_title_block">
|
||||
<p class="quest_title">{{ quest.name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="panelsStayOpen-collapse{{ quest.id }}"
|
||||
class="accordion-collapse collapse quest_body_block"
|
||||
aria-labelledby="panelsStayOpen-heading{{ quest.id }}">
|
||||
<div class="accordion-body quest_body">
|
||||
{% if quest.realized == 0 %}
|
||||
<div class="quest_body">
|
||||
<div class="quest_description_block">
|
||||
<p class="quest_description_title">Описание</p>
|
||||
<div class="quest_description">
|
||||
<p class="quest_description_text">{{ quest.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="quest_body">
|
||||
<div class="quest_description_block">
|
||||
<p class="quest_description_title">Описание</p>
|
||||
<div class="quest_description">
|
||||
<p class="quest_description_text">{{ quest.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quest_solve_button">
|
||||
<a class="quest_solve_link" href="{{ project.id }}/quest/{{ quest.id }}">
|
||||
<p class="quest_solve_text">Посмотреть</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="files_block">
|
||||
<h2 class="files_title">Файлы</h2>
|
||||
<div class="list_files_block">
|
||||
<div class="list_files">
|
||||
{% for item in file_tree %}
|
||||
{% if item['type'] == 'file' %}
|
||||
<div class="file">
|
||||
<div class="file_head">
|
||||
<nav class="file_head_group" style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb">
|
||||
<ol class="breadcrumb file_head_path">
|
||||
{% for path in item['current_path'] %}
|
||||
{% if loop.index != 1 %}
|
||||
<li class="breadcrumb-item active file_path" aria-current="page">{{ path }}</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="file_buttons">
|
||||
<div class="btn-group file_buttons_groud">
|
||||
<a href="../../../{{ item['path'] }}" download="" class="btn btn-primary file_download">
|
||||
<p class="button_text">Скачать</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="create_project_block">
|
||||
<a class="create_link" href="/template/{{project.id}}/create">
|
||||
<p class="create_text">Создать</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Loading…
x
Reference in New Issue
Block a user