From 90112dfc560999aa7c89cc54e4fb4079d0aef681 Mon Sep 17 00:00:00 2001 From: Vladimir Velikovich Date: Sun, 15 Dec 2024 14:47:40 +0300 Subject: [PATCH 1/9] TS-86: Updated design for main page, and contest header --- source/web/main/views.py | 2 +- source/web/static/css/index.css | 199 ++++++++++++++++++ .../templates/contests/contest_wrapper.html | 4 + .../contests/includes/contest_subheader.html | 10 + source/web/templates/includes/header.html | 62 ++---- source/web/templates/includes/subheader.html | 10 + source/web/templates/main/index.html | 38 ++-- source/web/templates/wrapper.html | 32 +-- 8 files changed, 278 insertions(+), 79 deletions(-) create mode 100644 source/web/templates/contests/includes/contest_subheader.html create mode 100644 source/web/templates/includes/subheader.html diff --git a/source/web/main/views.py b/source/web/main/views.py index 805def8..94c63a2 100644 --- a/source/web/main/views.py +++ b/source/web/main/views.py @@ -23,7 +23,7 @@ class IndexView(TemplateView): template_name = 'main/index.html' def get(self, request): - opened_contests = Contest.objects.opened_contests() + opened_contests = Contest.objects.opened_contests()[:3] return render(request, self.template_name, { 'opened_contests': opened_contests, }) diff --git a/source/web/static/css/index.css b/source/web/static/css/index.css index ec56d2c..c0b25cd 100644 --- a/source/web/static/css/index.css +++ b/source/web/static/css/index.css @@ -1,8 +1,54 @@ +:root{ + --accent-color: #fe7373; + --color-dark: #252525; + --color-white: #ffffff; + --color-gray: #7d7d7d; + --color-primary: #6b6b6b; + --color-subheader: #3d3d3d; + --bg-color: #f1f1f1; + --default-radius: 15px; + --default-padding: 15px; +} body{ + background: var(--bg-color); + padding: 0; + margin: 0; display: flex; flex-direction: column; min-height: 100vh; justify-content: space-between; + + font-family: Ubuntu, serif; +} + +@media (min-width: 980px) { + .mobile-screen{ + display: none; + } +} + +@media (max-width: 980px) { + .mobile-screen{ + display: block; + position: fixed; + top: 0; + left: 0; + height: 100vh; + width: 100vw; + background: var(--color-subheader); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } +} + +.card-dark{ + background: var(--color-dark); + border-radius: var(--default-radius); + padding: var(--default-padding); + color: var(--color-white); + text-align: center; } main{ @@ -10,7 +56,160 @@ main{ min-height: 90vh; } +.container{ + width: 980px; + margin: auto; + height: 100%; +} + +header{ + background: var(--color-dark); + color: var(--color-white); + height: 50px; +} + +header > .container{ + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; +} + +header span.title{ + font-size: 20pt; +} + +header a{ + text-decoration: none; + color: var(--color-white); +} + +header a:visited, +header a:active{ + text-decoration: none; + color: var(--color-white); +} + +header a:hover{ + text-decoration: none; + color: var(--color-gray); +} + +header .nav-links{ + list-style-type: none; + display: flex; + flex-direction: row; +} + +.nav-links > li{ + margin: 0 10px; +} + +header .slogan{ + color: var(--color-primary); +} + +.active-link, +.active-link:visited, +.active-link:active +{ + color: var(--accent-color); +} + +.active-link:hover{ + color: var(--color-gray); +} + +.active-text{ + color: var(--accent-color); +} + +nav.subheader{ + height: 30px; + background: var(--color-subheader); +} + +nav.subheader ul{ + padding: 0; + margin: 0; + display: flex; + flex-direction: row; + list-style-type: none; + align-items: center; + height: 100%; +} + +nav.subheader ul>*{ + padding: 0 15px; + height: 100%; + display: flex; + align-items: center; +} + +nav.subheader ul>li:hover{ + background: var(--accent-color); +} + +nav.subheader ul>li>a{ + display: block; +} + +nav.subheader ul>:first-child{ + margin-left: 0; +} +nav.subheader ul>:last-child{ + margin-right: 0; +} + +nav a, +nav a:visited{ + color: var(--color-white); + text-decoration: none; +} + +nav li>a:hover, +nav li>a:active{ + background: var(--accent-color); + color: var(--color-white); +} + footer{ display: flex; justify-content: center; +} + +.contest-slider{ + z-index: 50; +} + +.contest-card{ + display: inline-block; + background: var(--color-white); + padding: 15px; + border-radius: 15px; + max-width: 270px; + min-width: 270px; + margin-right: 20px; + height: 150px; +} + +.contest-card > .contest-name{ + display: block; + font-size: 18pt; + text-overflow: ellipsis; + margin-bottom: 10px; +} + +.contest-card .contest-info{ + list-style-type: none; + margin: 0; + padding: 0; +} + +.contest-card > .contest-footer{ + margin-top: 10px; +} + +.contest-info > li{ + margin: 3px 0; } \ No newline at end of file diff --git a/source/web/templates/contests/contest_wrapper.html b/source/web/templates/contests/contest_wrapper.html index 31ef8d0..309cf6e 100644 --- a/source/web/templates/contests/contest_wrapper.html +++ b/source/web/templates/contests/contest_wrapper.html @@ -3,6 +3,10 @@ {% block title %} {% endblock title %} +{% block subheader %} + {% include "contests/includes/contest_subheader.html" %} +{% endblock %} + {% block content %}
diff --git a/source/web/templates/contests/includes/contest_subheader.html b/source/web/templates/contests/includes/contest_subheader.html new file mode 100644 index 0000000..46c17ed --- /dev/null +++ b/source/web/templates/contests/includes/contest_subheader.html @@ -0,0 +1,10 @@ +{% load i18n %} + \ No newline at end of file diff --git a/source/web/templates/includes/header.html b/source/web/templates/includes/header.html index d259bd2..f7aabd1 100644 --- a/source/web/templates/includes/header.html +++ b/source/web/templates/includes/header.html @@ -1,47 +1,19 @@ {% load i18n %} - + diff --git a/source/web/templates/includes/subheader.html b/source/web/templates/includes/subheader.html new file mode 100644 index 0000000..cc3e7f8 --- /dev/null +++ b/source/web/templates/includes/subheader.html @@ -0,0 +1,10 @@ +{% load i18n %} + \ No newline at end of file diff --git a/source/web/templates/main/index.html b/source/web/templates/main/index.html index e9db90e..cce1192 100644 --- a/source/web/templates/main/index.html +++ b/source/web/templates/main/index.html @@ -6,21 +6,35 @@ {% endblock %} {% block content %} -

{% trans "SysName" %}

-
-
-

{% trans "OpenedContests" %}

-
+

{% trans "OpenedContests" %}

+
{% if opened_contests %} {% for contest in opened_contests %} -
-
-
{{ contest.name }}
-

Authored by {{ contest.author.fullname }}

- {% if not request.user.isAuthenticated %} - Enter - {% endif %} +
+ {{ contest.name }} +
+
    +
  • + {% trans "Participants" %}: + {{ contest.participant_count }} +
  • +
  • + {% trans "StartTime" %}: + {{ contest.start_time|date:'Y-m-d H:i' }} +
  • +
  • + {% trans "TimeDuration" %}: + {{ contest.duration }} +
  • +
  • + {% trans "Author" %}: + {{ contest.author.user.username }} +
  • +
+
+
{% endfor %} diff --git a/source/web/templates/wrapper.html b/source/web/templates/wrapper.html index 0bb8e6b..1c67ce2 100644 --- a/source/web/templates/wrapper.html +++ b/source/web/templates/wrapper.html @@ -1,38 +1,28 @@ {% load static %} +{% load i18n %} {% block title %}{% endblock %} - + +
+
+

{% trans "SysName" %}

+

{% trans "MobileNotSupported" %}

+
+
{% include "includes/header.html" %} + {% block subheader %} + {% include "includes/subheader.html" %} + {% endblock %}
{% block content %}{% endblock %}
{% include "includes/footer.html" %} - - - \ No newline at end of file From 64efc8328af8f3df259a010a35a1a0eb674c8cf0 Mon Sep 17 00:00:00 2001 From: Vladimir Velikovich Date: Sun, 15 Dec 2024 22:16:10 +0300 Subject: [PATCH 2/9] TS-86: fixed code style --- source/web/main/admin.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/source/web/main/admin.py b/source/web/main/admin.py index 7bbd866..f869066 100644 --- a/source/web/main/admin.py +++ b/source/web/main/admin.py @@ -1,24 +1,24 @@ import json from django.contrib import admin from main.models import ( - Profile, - Achievment, - UserAchievments, - TaskType, - Task, - Test, - Verdict, - AnswerOption, - Compiler, - AnswerCode, - Answer, - Category, - ContestType, - Contest, - TaskOnContest, + Profile, + Achievment, + UserAchievments, + TaskType, + Task, + Test, + Verdict, + AnswerOption, + Compiler, + AnswerCode, + Answer, + Category, + ContestType, + Contest, + TaskOnContest, CategoryOnContest, - CompilerOnContest, - ContestRole, + CompilerOnContest, + ContestRole, UserToContest, Checker, ) From 09b37eb8eafea65df0fc2c688ba0e9a87a6c75f5 Mon Sep 17 00:00:00 2001 From: Vladimir Velikovich Date: Sun, 15 Dec 2024 22:21:03 +0300 Subject: [PATCH 3/9] TS-86: Updated styles for new design --- source/web/main/models.py | 8 + source/web/static/css/index.css | 143 +++++++++++++++++- .../templates/contests/contest_detail.html | 2 + .../web/templates/contests/contest_task.html | 11 +- .../templates/contests/contest_wrapper.html | 38 ++--- .../web/templates/contests/contests_list.html | 4 +- source/web/templates/tasks/task_detail.html | 13 +- source/web/templates/tasks/tasks_list.html | 4 +- source/web/templates/tasks/theta_code.html | 58 ++++--- source/web/templates/tasks/theta_quiz.html | 45 +++--- .../web/templates/tasks/theta_solutions.html | 20 ++- source/web/templates/wrapper.html | 5 + 12 files changed, 270 insertions(+), 81 deletions(-) diff --git a/source/web/main/models.py b/source/web/main/models.py index 0b117ba..07a3898 100644 --- a/source/web/main/models.py +++ b/source/web/main/models.py @@ -217,6 +217,14 @@ def ordered_tasks(self): res.append((item.order, item.task)) return res + @property + def participant_count(self): + users_to_contest = UserToContest.objects.filter( + contest=self, + role=ContestRole.objects.get(name="Participant") + ) + return users_to_contest.count() + class TaskOnContest(BaseModel): order = models.IntegerField() diff --git a/source/web/static/css/index.css b/source/web/static/css/index.css index c0b25cd..2a777da 100644 --- a/source/web/static/css/index.css +++ b/source/web/static/css/index.css @@ -6,9 +6,11 @@ --color-primary: #6b6b6b; --color-subheader: #3d3d3d; --bg-color: #f1f1f1; + --color-light-gray: #E7E7E7; --default-radius: 15px; - --default-padding: 15px; + --default-padding: 25px; } + body{ background: var(--bg-color); padding: 0; @@ -57,7 +59,7 @@ main{ } .container{ - width: 980px; + max-width: 980px; margin: auto; height: 100%; } @@ -212,4 +214,139 @@ footer{ .contest-info > li{ margin: 3px 0; -} \ No newline at end of file +} + +.contest-block > .container{ + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.contest-sidebar{ + width: 330px; +} + +.contest-content{ + width: 630px; +} + +.card{ + background: var(--color-white); + border-radius: var(--default-radius); + padding: var(--default-padding); + margin: 15px 0; +} + +.card-title{ + font-size: 18pt; + margin: 0; + font-weight: bold; +} + +.tasks-list ul{ + list-style-type: none; + padding: 0; +} + +table{ + width: 100%; + text-align: center; + border-collapse: collapse; +} + +table tr{ + height: 35px; +} + +table tbody tr:nth-child(2n + 1){ + background: #fe737333; +} + +table td{ + border: none; + padding: 0; + margin: 0; + border-spacing: 0; +} + +.submission-verdict{ + border: 1px solid black; + padding: 3px; + border-radius: 5px; +} + +.submission-verdict[type='ok']{ + background: #4c765850; + border-color: #295f38; +} + +.submission-verdict:not([type='ok']){ + background: #85404050; + border-color: #632727; +} + +.statement-block > h3{ + margin: 0; + margin-top: 30px; + padding: 0; +} + +.statement-block > p{ + margin: 0; + margin-top: 10px; +} + +.code-area{ + width: calc(100% - 24px); + min-height: 300px; + max-height: 500px; + resize: none; + padding: 0; + border: 0; + border: 2px solid var(--color-light-gray); + border-radius: 7px; + padding: 10px; +} + +.form-footer{ + margin-top: 15px; + display: flex; + flex-direction: row; + justify-content: space-between; +} + +select{ + width: 200px; + height: 40px; + border: none; + padding-left: 10px; + padding-right: 10px; + border: 2px solid var(--color-light-gray); + border-radius: 7px; + font-size: 12pt; +} + +hr{ + border-color: var(--color-light-gray); + border-style: solid; + margin: 0; +} + +.statement{ + margin-bottom: 25px; +} + +button{ + border: none; + color: white; + background: var(--accent-color); + height: 40px; + width: 120px; + border-radius: 10px; + font-size: 12pt; +} + +.answer-options{ + margin: 15px 0; +} + diff --git a/source/web/templates/contests/contest_detail.html b/source/web/templates/contests/contest_detail.html index f85cc57..0853ee7 100644 --- a/source/web/templates/contests/contest_detail.html +++ b/source/web/templates/contests/contest_detail.html @@ -6,6 +6,8 @@ {% endblock %} {% block contest_content %} +
{{contest.name}}
Contest description: ... +
{% endblock %} \ No newline at end of file diff --git a/source/web/templates/contests/contest_task.html b/source/web/templates/contests/contest_task.html index bf127db..5ba1440 100644 --- a/source/web/templates/contests/contest_task.html +++ b/source/web/templates/contests/contest_task.html @@ -2,10 +2,15 @@ {% load i18n %} {% block contest_content %} -
-
+
+
+

{{task.name}}

{% include task_template %}
- {% include "tasks/theta_solutions.html" %} +
+
+
+ {% include "tasks/theta_solutions.html" %} +
{% endblock %} \ No newline at end of file diff --git a/source/web/templates/contests/contest_wrapper.html b/source/web/templates/contests/contest_wrapper.html index 309cf6e..454fb53 100644 --- a/source/web/templates/contests/contest_wrapper.html +++ b/source/web/templates/contests/contest_wrapper.html @@ -1,4 +1,5 @@ {% extends "wrapper.html" %} +{% load i18n %} {% block title %} {% endblock title %} @@ -8,26 +9,29 @@ {% endblock %} {% block content %} -
-
-
+
+
+
+
+

{% trans "Tasks" %}

+ {% if contest.tasks %} +
    + {% for order, task in contest.ordered_tasks %} +
  • + {{order}}.  + + {{task.name}} + +
  • + {% endfor %} +
+ {% endif %} +
+
+
{% block contest_content %} {% endblock contest_content %}
-
- {% if contest.tasks %} - - {% endif %} -
diff --git a/source/web/templates/contests/contests_list.html b/source/web/templates/contests/contests_list.html index 33e272f..5fb42fd 100644 --- a/source/web/templates/contests/contests_list.html +++ b/source/web/templates/contests/contests_list.html @@ -7,8 +7,8 @@ {% block content %}
-
- +
+
diff --git a/source/web/templates/tasks/task_detail.html b/source/web/templates/tasks/task_detail.html index 093acc1..2b33341 100644 --- a/source/web/templates/tasks/task_detail.html +++ b/source/web/templates/tasks/task_detail.html @@ -3,9 +3,16 @@ {% block content %}
-
- {% include task_template %} +
+
+

{{task.name}}

+ {% include task_template %} +
+
+
+
+ {% include "tasks/theta_solutions.html" %} +
- {% include "tasks/theta_solutions.html" %}
{% endblock %} \ No newline at end of file diff --git a/source/web/templates/tasks/tasks_list.html b/source/web/templates/tasks/tasks_list.html index 0ec8012..5742175 100644 --- a/source/web/templates/tasks/tasks_list.html +++ b/source/web/templates/tasks/tasks_list.html @@ -7,8 +7,8 @@ {% block content %}
-
-
#
+
+
diff --git a/source/web/templates/tasks/theta_code.html b/source/web/templates/tasks/theta_code.html index 0570c9e..0cb27a2 100644 --- a/source/web/templates/tasks/theta_code.html +++ b/source/web/templates/tasks/theta_code.html @@ -1,27 +1,37 @@ {% load i18n %} -

{% trans "TaskStatement" %}

-

{{task.statement}}

-

{% trans "TaskInputFormat" %}

-

{{task.input}}

-

{% trans "TaskOutputFormat" %}

-

{{task.output}}

- - {% csrf_token %} -
- - +
+
+

{{task.statement | safe}}

- - - +
+

{% trans "TaskInputFormat" %}

+

{{task.input | safe}}

+
+
+

{% trans "TaskOutputFormat" %}

+

{{task.output | safe}}

+
+
+
+
+

{% trans "PasteCode" %}

+
+ {% csrf_token %} + + + +
diff --git a/source/web/templates/tasks/theta_quiz.html b/source/web/templates/tasks/theta_quiz.html index a040052..80c53c5 100644 --- a/source/web/templates/tasks/theta_quiz.html +++ b/source/web/templates/tasks/theta_quiz.html @@ -1,21 +1,28 @@ {% load i18n %} -

{% trans "TaskStatement" %}

-

{{task.statement}}

-
- {% csrf_token %} - {% for option in task.answer_options.all %} - - -
- {% endfor %} - - + +
+

{{task.statement}}

+
+
+
+
+ {% csrf_token %} +
+ {% for option in task.answer_options.all %} + + +
+ {% endfor %} +
+ + +
diff --git a/source/web/templates/tasks/theta_solutions.html b/source/web/templates/tasks/theta_solutions.html index 42ff1b3..9c73bd4 100644 --- a/source/web/templates/tasks/theta_solutions.html +++ b/source/web/templates/tasks/theta_solutions.html @@ -1,32 +1,36 @@ {% load i18n %} -

{% trans "Submissions" %}

+

{% trans "Submissions" %}


-
#
+
- + {% if not answers %} - No answers yet. + + + {% else %} {% for answer in answers %} - - + - {% endfor %} diff --git a/source/web/templates/wrapper.html b/source/web/templates/wrapper.html index 1c67ce2..f7d0f0b 100644 --- a/source/web/templates/wrapper.html +++ b/source/web/templates/wrapper.html @@ -24,5 +24,10 @@

{% trans "SysName" %}

{% include "includes/footer.html" %} + \ No newline at end of file From f167576d255c5246af3c82443f5fdb6a32416fb6 Mon Sep 17 00:00:00 2001 From: Vladimir Velikovich Date: Sun, 15 Dec 2024 22:22:04 +0300 Subject: [PATCH 4/9] TS-86: Added system messages displaying --- source/web/static/css/index.css | 47 +++++++++++++++++++++++++++++++ source/web/templates/wrapper.html | 9 ++++++ 2 files changed, 56 insertions(+) diff --git a/source/web/static/css/index.css b/source/web/static/css/index.css index 2a777da..0d41aa9 100644 --- a/source/web/static/css/index.css +++ b/source/web/static/css/index.css @@ -350,3 +350,50 @@ button{ margin: 15px 0; } +.system-messages{ + position: absolute; + bottom: 0; + right: 0; + list-style-type: none; + padding: 0; + margin: 0; + margin-right: 20px; +} + +.system-messages > li{ + border: 1px solid black; + background-color: var(--color-gray); + color: black; + border-radius: 7px; + min-width: 400px; + min-height: 20px; + padding: 15px; + margin: 5px 0; +} + +.system-messages>li[type='warning']{ + color: #ffda6a; + background: #332701e0; + border-color: #997404; + +} +.system-messages>li[type='error']{ + color: #ea868f; + background: #2c0b0ee0; + border-color: #842029; +} +.system-messages>li[type='info']{ + color: #6ea8fe; + background: #031633e0; + border-color: #084298; +} +.system-messages>li[type='success']{ + color: #75b798; + background: #051b11e0; + border-color: #0f5132; +} +.system-messages>li[type='debug']{ + color: #f8f9fa; + background: #343a40e0; + border-color: #495057; +} \ No newline at end of file diff --git a/source/web/templates/wrapper.html b/source/web/templates/wrapper.html index f7d0f0b..f585a84 100644 --- a/source/web/templates/wrapper.html +++ b/source/web/templates/wrapper.html @@ -22,6 +22,15 @@

{% trans "SysName" %}

{% block content %}{% endblock %}
+ {% if messages %} +
    + {% for message in messages %} +
  • + {{ message }} +
  • + {% endfor %} +
+ {% endif %} {% include "includes/footer.html" %}
# SolutionVerdict Submission timeVerdict Link
No answers yet.
{{forloop.counter}} {{answer.task.name}}{% if answer.verdict %} - {{answer.verdict.name}} + {{answer.created_at}} + {% if answer.verdict %} + + {{answer.verdict.short_name|upper}} + {% else %} Not tested yet. {% endif %} {{answer.created_at}} Link