Pārlūkot izejas kodu

Сделал страницу создания новой задачи, добавил на несколько страниц кнопки для перехода назад, начал делать страницу ответа на задачу

Andrei 3 gadi atpakaļ
vecāks
revīzija
d18352d166

+ 1 - 0
data/proof_to_quests.py

@@ -11,6 +11,7 @@ class Proofs(SqlAlchemyBase, UserMixin):
     id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True)
     quest = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.ForeignKey("quests.id"), nullable=True, default=None)
     file = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.ForeignKey("files.id"), nullable=True, default=None)
+    text = sqlalchemy.Column(sqlalchemy.Text, nullable=True, default=None)
     creator = sqlalchemy.Column(sqlalchemy.Integer, sqlalchemy.ForeignKey("users.id"), nullable=True,
                                 default=None)
     date_create = sqlalchemy.Column(sqlalchemy.DateTime, default=datetime.now())

+ 1 - 1
forms/register.py

@@ -8,4 +8,4 @@ class RegisterForm(FlaskForm):
     name = StringField('Имя', validators=[DataRequired()])
     login = StringField('Логин', validators=[DataRequired()])
     password = PasswordField('Пароль', validators=[DataRequired()])
-    submit = SubmitField('Регистрация')
+    submit = SubmitField('Регистрация')

+ 17 - 0
forms/task.py

@@ -0,0 +1,17 @@
+from flask_wtf import FlaskForm
+from wtforms import StringField, SubmitField, TextAreaField, DateField, TimeField, FileField
+from wtforms.validators import DataRequired
+
+
+class NewTask(FlaskForm):
+    name = StringField('Название', validators=[DataRequired()])
+    description = TextAreaField('Описание', validators=[DataRequired()])
+    deadline_date = DateField('Дедлайн', validators=[DataRequired()])
+    deadline_time = TimeField('', validators=[DataRequired()])
+    submit = SubmitField('Создать')
+
+
+class AnswerTask(FlaskForm):
+    text = TextAreaField('Письменный ответ')
+    file = FileField('Файловый ответ')
+    submit = SubmitField('Ответить')

+ 37 - 2
main.py

@@ -20,6 +20,7 @@ from forms.register import RegisterForm
 from forms.project import ProjectForm
 from forms.recovery import RecoveryForm, NewPasswordForm
 from forms.conf_delete_project import DeleteProjectForm
+from forms.task import NewTask, AnswerTask
 
 from data.users import User
 from data.quests import Quests
@@ -49,13 +50,47 @@ def base():
         return redirect('/projects')
 
 
-@app.route('/project/<int:id_project>/task/new')
+@app.route('/project/<int:id_project>/quest/<int:id_task>')
+def task_project(id_project, id_task):
+    if current_user.is_authenticated:
+        data_session = db_session.create_session()
+        current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
+        current_task = data_session.query(Quests).filter(Quests.id == id_task).first()
+        if current_project and current_task and current_task.project == current_project.id:
+            form = AnswerTask()
+            return render_template('decision.html', title='Решение', project=current_project, task=current_task,
+                                   form=form)
+        else:
+            abort(404)
+    else:
+        return redirect('/login')
+
+
+@app.route('/project/<int:id_project>/task/new', methods=['GET', 'POST'])
 def new_task_project(id_project):
     if current_user.is_authenticated:
         data_session = db_session.create_session()
         current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
         if current_project:
-            pass
+            form = NewTask()
+            if form.validate_on_submit():
+                if form.deadline_date.data and form.deadline_time.data:
+                    deadline = datetime.datetime.combine(form.deadline_date.data, form.deadline_time.data)
+                else:
+                    deadline = None
+                quest = Quests(
+                    project=current_project.id,
+                    creator=current_user.id,
+                    name=form.name.data if form.name.data else None,
+                    description=form.description.data if form.description.data else None,
+                    date_create=datetime.datetime.now(),
+                    deadline=deadline,
+                    realized=False
+                )
+                data_session.add(quest)
+                data_session.commit()
+                return redirect(f'/project/{str(current_project.id)}')
+            return render_template('new_task.html', title='Новая задача', form=form, porject=current_project)
         else:
             abort(404)
     else:

+ 124 - 0
static/css/decision.css

@@ -0,0 +1,124 @@
+.decision_page {
+    height: 90vw;
+    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;
+}
+.name_block {
+    margin-top: 3vw;
+    width: 90%;
+    height: 25vw;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+.title_block {
+    width: 90%;
+    display: flex;
+    justify-content: center;
+}
+.title_task {
+    text-align: center;
+    color: #000000;
+    font-size: 4vw;
+}
+.description_task {
+    width: 80%;
+    background-color: #EDCBB0;
+    height: auto;
+    max-height: 15vw;
+    border-radius: 2vw;
+    display: flex;
+    overflow-y: auto;
+}
+.description {
+    margin: 15px;
+}
+.description_text {
+    font-size: 1.5vw;
+    text-align: justify;
+}
+.data_block {
+    width: 90%;
+    display: flex;
+    align-items: flex-start;
+    justify-content: center
+}
+.bottom_data {
+    margin: 2vw;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+}
+.form_label {
+    margin-top: 10px;
+    font-size: 1.3vw;
+    color: #000000;
+    font-weight: bold;
+}
+.input_data {
+    color: #000000;
+    border: 0.1vw solid #595008;
+    height: 4.5vw;
+    min-height: 4.5vw;
+    width: 30vw;
+    background-color: #dbc3af;
+    border-radius: 5vw;
+    font-size: 1.3vw;
+    display: inline-flex;
+    align-items: center;
+}
+.input_button {
+    width: 10vw;
+    height: 5vw;
+    border-radius: 5vw;
+    vertical-align: middle;
+}
+.text_data {
+    border-radius: 2vw !important;
+    width: 35vw;
+}
+.form_data {
+    display: flex;
+    flex-direction: column;
+    margin-left: 2%;
+}
+.decision_block {
+    margin-top: 3vw;
+    width: 90%;
+    height: 25vw;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}

+ 29 - 0
static/css/new_project.css

@@ -130,4 +130,33 @@
     align-items: center;
     justify-content: flex-start;
     flex-direction: row;
+}
+.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;
 }

+ 100 - 0
static/css/new_task.css

@@ -0,0 +1,100 @@
+.new_task_page {
+    height: 50vw;
+    background-color: #dcb495;
+}
+.form_data {
+    display: flex;
+    flex-direction: column;
+    margin-left: 2%;
+}
+.form_block {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+.form_data_button {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+}
+.input_data {
+    color: #000000;
+    border: 0.1vw solid #595008;
+    height: 4.5vw;
+    min-height: 4.5vw;
+    width: 50vw;
+    background-color: #dbc3af;
+    border-radius: 4.5vw;
+    font-size: 1.3vw;
+    display: inline-flex;
+    align-items: center;
+}
+.form_label {
+    margin-top: 10px;
+    font-size: 1.3vw;
+    color: #ffffff;
+    font-weight: bold;
+}
+.description {
+    border-radius: 2vw !important;
+    width: 50vw;
+}
+.name_form_block {
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+.deadline {
+    width: 20vw;
+}
+.quest_button {
+    margin-top: 5vw;
+    margin-left: 5vw;
+    width: 20vw;
+    height: 5vw;
+    background-color: #000000;
+    color: #ffffff;
+    border-radius: 5vw;
+    vertical-align: middle;
+    font-size: 1.5vw;
+}
+.data_form_block {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+}
+.deadline {
+    margin: 5px;
+}
+.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;
+}

+ 35 - 1
static/css/project.css

@@ -1,6 +1,9 @@
 .projects_page {
     height: 120vw;
     background-color: #dcb495;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
 }
 .project_header {
     height: 25vw;
@@ -10,6 +13,7 @@
     justify-content: space-around;
 }
 .project_logo {
+    margin-right: 4vw;
     margin-top: 30px;
     width: 15vw;
     height: 15vw;
@@ -26,6 +30,7 @@
 }
 .name_project {
     font-size: 3vw !important;
+    margin-right: 4vw;
 }
 .edit_block {
     display: flex;
@@ -156,7 +161,7 @@
 .list_quests {
     width: 95%;
     margin-left: 2.5%;
-    margin-top: 2vw;
+    margin-top: 0.5vw;
     overflow-y: hidden;
     overflow-x: hidden;
 }
@@ -272,4 +277,33 @@
 }
 #quest_solve_link_id {
     display: none;
+}
+.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;
 }

+ 4 - 4
templates/base.html

@@ -2,14 +2,14 @@
 <html lang="ru">
   <head>
     <meta charset="UTF-8" />
-    <link rel="stylesheet" href="../../static/css/base.css" />
+    <link rel="stylesheet" href="../../../static/css/base.css" />
     <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/images/logo_b.ico" type="image/x-icon" />
+    <link rel="icon" href="../../../static/images/logo_b.ico" type="image/x-icon" />
     <title>{{title}}</title>
   </head>
   <body>
@@ -38,7 +38,7 @@
     <nav class="navbar" id="navbar">
       <div class="container-fluid">
         <a class="navbar-brand" href="/">
-          <img src="../../static/images/logo_b.png" class="nav_logo" />
+          <img src="../../../static/images/logo_b.png" class="nav_logo" />
         </a>
         <a class="auth_button" href="/login">Авторизация</a>
       </div>
@@ -49,7 +49,7 @@
     <footer class="footer">
       <div class="footer_block">
         <a href="/#header_block"
-          ><img class="footer_logo" src="../../static/images/logo_w.png"
+          ><img class="footer_logo" src="../../../static/images/logo_w.png"
         /></a>
         <strong class="footer_rights">© All rights reserved</strong>
       </div>

+ 41 - 0
templates/decision.html

@@ -0,0 +1,41 @@
+<link rel="stylesheet" href="../../../static/css/decision.css"/>
+{% extends "base.html" %} {% block content %}
+<div class="decision_page">
+    <div class="link_back_block">
+        <a class="link_back" href="../../../project/{{ project.id }}">
+            <p class="link_back_text">К проекту</p>
+        </a>
+    </div>
+    <div class="name_block">
+        <div class="title_block">
+            <h3 class="title_task">{{ task.name }}</h3>
+        </div>
+        <div class="description_task">
+            <div class="description">
+                <p class="description_text">{{ task.description }}</p>
+            </div>
+        </div>
+    </div>
+    <div class="decision_block">
+        <form action="" method="post" class="answer_form" enctype="multipart/form-data">
+            {{ form.hidden_tag() }}
+            <div class="data_block">
+                <div class="form_data bottom_data">
+                    <label class="form_label">{{ form.text.label }}</label>
+                    {{ form.text(class="input_data label_data text_data", type="text", placeholder='your answer') }}
+                    {% for error in form.text.errors %}
+                    <div class="alert alert-danger" role="alert">{{ error }}</div>
+                    {% endfor %}
+                </div>
+                <div class="form_data bottom_data">
+                    <label class="form_label">{{ form.file.label }}</label>
+                    {{ form.file(class="input_data padding_data", type="file") }}
+                    {% for error in form.file.errors %}
+                    <div class="alert alert-danger" role="alert">{{ error }}</div>
+                    {% endfor %}
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+{% endblock %}

+ 6 - 1
templates/new_project.html

@@ -1,8 +1,13 @@
 <link rel="stylesheet" href="../static/css/new_project.css"/>
 {% extends "base.html" %} {% block content %}
 <div class="new_project_page">
+    <div class="link_back_block">
+        <a class="link_back" href="../">
+            <p class="link_back_text">К проектам</p>
+        </a>
+    </div>
     <div class="form_block">
-        <form action="" method="post" class="register_form" enctype="multipart/form-data">
+        <form action="" method="post" class="new_project_form" enctype="multipart/form-data">
             {{ form.hidden_tag() }}
             <div class="name_form_block">
                 <div class="form_data">

+ 47 - 0
templates/new_task.html

@@ -0,0 +1,47 @@
+<link rel="stylesheet" href="../../../static/css/new_task.css"/>
+{% extends "base.html" %} {% block content %}
+<div class="new_task_page">
+    <div class="link_back_block">
+        <a class="link_back" href="../../../project/{{ porject.id }}">
+            <p class="link_back_text">К проекту</p>
+        </a>
+    </div>
+    <div class="form_block">
+        <form action="" method="post" class="new_task_form" enctype="multipart/form-data">
+            {{ form.hidden_tag() }}
+            <div class="name_form_block">
+                <div class="form_data">
+                    <label class="form_label">{{ form.name.label }}</label>
+                    {{ form.name(class="input_data label_data", type="name", placeholder='your project name') }}
+                    {% for error in form.name.errors %}
+                    <div class="alert alert-danger" role="alert">{{ error }}</div>
+                    {% endfor %}
+                </div>
+                <div class="form_data">
+                    <label class="form_label">{{ form.description.label }}</label>
+                    {{ form.description(class="input_data description padding_data", type="description", placeholder='your project description') }}
+                    {% for error in form.description.errors %}
+                    <div class="alert alert-danger" role="alert">{{ error }}</div>
+                    {% endfor %}
+                </div>
+            </div>
+            <div class="data_form_block">
+                <div class="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 %}
+                    <div class="alert alert-danger" role="alert">{{ error }}</div>
+                    {% endfor %}
+                    {{ form.deadline_time(class="input_data deadline padding_data", type="time") }}
+                    {% for error in form.deadline_time.errors %}
+                    <div class="alert alert-danger" role="alert">{{ error }}</div>
+                    {% endfor %}
+                </div>
+                <div class="form_data_button">
+                    {{ form.submit(type="submit", class="quest_button") }}
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+{% endblock %}

+ 5 - 0
templates/project.html

@@ -1,6 +1,11 @@
 <link rel="stylesheet" href="../static/css/project.css"/>
 {% extends "base.html" %} {% block content %}
 <div class="projects_page">
+    <div class="link_back_block">
+        <a class="link_back" href="../">
+            <p class="link_back_text">К проектам</p>
+        </a>
+    </div>
     <div class="project_header">
         <div class="edit_block">
             <a id="edit_button" class="edit_button" href="">