remake contest ui
This commit is contained in:
parent
6c64e42322
commit
eb9c155c26
3 changed files with 163 additions and 138 deletions
|
@ -134,7 +134,7 @@ class ContestList(
|
||||||
QueryStringSortMixin, DiggPaginatorMixin, TitleMixin, ContestListMixin, ListView
|
QueryStringSortMixin, DiggPaginatorMixin, TitleMixin, ContestListMixin, ListView
|
||||||
):
|
):
|
||||||
model = Contest
|
model = Contest
|
||||||
paginate_by = 20
|
paginate_by = 10
|
||||||
template_name = "contest/list.html"
|
template_name = "contest/list.html"
|
||||||
title = gettext_lazy("Contests")
|
title = gettext_lazy("Contests")
|
||||||
context_object_name = "past_contests"
|
context_object_name = "past_contests"
|
||||||
|
|
|
@ -326,11 +326,14 @@ input {
|
||||||
// Bootstrap-y pagination
|
// Bootstrap-y pagination
|
||||||
ul.pagination a:hover {
|
ul.pagination a:hover {
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
background: rgba(0, 0, 0, 0.55);
|
background: #0aa082;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.pagination {
|
ul.pagination {
|
||||||
display: inline-block;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-radius: $widget_border_radius;
|
border-radius: $widget_border_radius;
|
||||||
|
@ -339,33 +342,35 @@ ul.pagination {
|
||||||
li {
|
li {
|
||||||
display: inline;
|
display: inline;
|
||||||
|
|
||||||
&:first-child > {
|
// &:first-child > {
|
||||||
a, span {
|
// a, span {
|
||||||
margin-left: 0;
|
// margin-left: 0;
|
||||||
border-top-left-radius: $widget_border_radius;
|
// border-top-left-radius: $widget_border_radius;
|
||||||
border-bottom-left-radius: $widget_border_radius;
|
// border-bottom-left-radius: $widget_border_radius;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&:last-child > {
|
// &:last-child > {
|
||||||
a, span {
|
// a, span {
|
||||||
margin-left: 0;
|
// margin-left: 0;
|
||||||
border-top-right-radius: $widget_border_radius;
|
// border-top-right-radius: $widget_border_radius;
|
||||||
border-bottom-right-radius: $widget_border_radius;
|
// border-bottom-right-radius: $widget_border_radius;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
> {
|
> {
|
||||||
a, span {
|
a, span {
|
||||||
position: relative;
|
position: relative;
|
||||||
float: left;
|
float: left;
|
||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
|
margin-right: 5px;
|
||||||
|
font-weight: bold;
|
||||||
line-height: 1.42857;
|
line-height: 1.42857;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #FFF;
|
color: #045343;
|
||||||
background-color: $widget_black;
|
background-color: white;
|
||||||
border: 1px solid #505050;
|
border: 2px solid #045343;
|
||||||
margin-left: -1px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,22 +378,22 @@ ul.pagination {
|
||||||
.disabled-page > {
|
.disabled-page > {
|
||||||
a {
|
a {
|
||||||
color: #888;
|
color: #888;
|
||||||
background-color: $widget_black;
|
background-color: #04534380;
|
||||||
border-color: #282828;
|
border-color: #04534380;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: #888;
|
color: #888;
|
||||||
background-color: $widget_black;
|
background-color: #04534380;
|
||||||
border-color: #505050;
|
border-color: #04534380;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.active-page > {
|
.active-page > {
|
||||||
a {
|
a {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
color: black;
|
color: white;
|
||||||
background-color: #7dc7ff;
|
background-color: #045343;
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,33 @@
|
||||||
|
|
||||||
{% block two_col_media %}
|
{% block two_col_media %}
|
||||||
<style>
|
<style>
|
||||||
|
.list-contest {
|
||||||
|
box-shadow: 0px 4px 8px rgba(4, 83, 67, 0.2), 0px 6px 20px rgba(4, 83, 67, 0.19);
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contest {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.participate-button {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contest-title {
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 150%;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.content-description ul {
|
.content-description ul {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +136,7 @@
|
||||||
|
|
||||||
{% macro contest_head(contest) %}
|
{% macro contest_head(contest) %}
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<a href="{{ url('contest_view', contest.key) }}" class="contest-list-title">
|
<a href="{{ url('contest_view', contest.key) }}" class="contest-list-title" style="margin-right: 5px;">
|
||||||
{{- contest.name -}}
|
{{- contest.name -}}
|
||||||
</a>
|
</a>
|
||||||
<span class="contest-tags">
|
<span class="contest-tags">
|
||||||
|
@ -186,21 +213,19 @@
|
||||||
|
|
||||||
{% macro contest_join(contest, request) %}
|
{% macro contest_join(contest, request) %}
|
||||||
{% if not request.in_contest %}
|
{% if not request.in_contest %}
|
||||||
<td>
|
{% if request.profile in contest.authors.all() or request.profile in contest.curators.all() or request.profile in contest.testers.all() %}
|
||||||
{% if request.profile in contest.authors.all() or request.profile in contest.curators.all() or request.profile in contest.testers.all() %}
|
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||||
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
{% csrf_token %}
|
||||||
{% csrf_token %}
|
<input type="submit" class="unselectable button full small"
|
||||||
<input type="submit" class="unselectable button full small"
|
value="{{ _('Spectate') }}">
|
||||||
value="{{ _('Spectate') }}">
|
</form>
|
||||||
</form>
|
{% else %}
|
||||||
{% else %}
|
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||||
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
{% csrf_token %}
|
||||||
{% csrf_token %}
|
<input type="submit" class="unselectable button full small join-warning"
|
||||||
<input type="submit" class="unselectable button full small join-warning"
|
value="{{ _('Join') }}">
|
||||||
value="{{ _('Join') }}">
|
</form>
|
||||||
</form>
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
@ -284,39 +309,38 @@
|
||||||
</h3>
|
</h3>
|
||||||
{% if current_contests %}
|
{% if current_contests %}
|
||||||
<div id="ongoing-table" class="toggled">
|
<div id="ongoing-table" class="toggled">
|
||||||
<table class="contest-list table striped">
|
{% for contest in current_contests %}
|
||||||
<thead>
|
<div class="list-contest">
|
||||||
<tr>
|
<div class="info-contest" style="flex: 1.5">
|
||||||
<th style="width:90%">{{ _('Contest') }}</th>
|
<div class="contest-title">Kì thi:</div>
|
||||||
<th>{{ _('Users') }}</th>
|
{{ contest_head(contest) }}
|
||||||
{% if not request.in_contest %}
|
</div>
|
||||||
<th style="width:15%"></th>
|
<div class="info-contest" style="flex: 1.5">
|
||||||
|
<div class="contest-title">Thời gian:</div>
|
||||||
|
<div class="contest-block">
|
||||||
|
{% if contest.start_time %}
|
||||||
|
{% if contest.time_before_end %}
|
||||||
|
<span class="time">{% trans countdown=contest.end_time|as_countdown %}Ends in {{countdown}}{% endtrans %}</span>
|
||||||
|
{% endif %}
|
||||||
|
{{ time_left(contest) }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-contest">
|
||||||
|
<div class="contest-title">Định dạng:</div>
|
||||||
|
{% if contest.format_name == "default" %} IOI
|
||||||
|
{% else %} {{ contest.format_name|upper }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</div>
|
||||||
</thead>
|
<div class="info-contest">
|
||||||
<tbody>
|
<div class="contest-title">Người tham gia:</div>
|
||||||
{% for contest in current_contests %}
|
{{ user_count(contest, request.user) }}
|
||||||
<tr>
|
</div>
|
||||||
<td>
|
<div class="participate-button">
|
||||||
<div class="contest-block">
|
{{ contest_join(contest, request) }}
|
||||||
{{ contest_head(contest) }}
|
</div>
|
||||||
{% if contest.start_time %}
|
</div>
|
||||||
<br>
|
{% endfor %}
|
||||||
{% if contest.time_before_end %}
|
|
||||||
<span class="time">{% trans countdown=contest.end_time|as_countdown %}Ends in {{countdown}}{% endtrans %}</span>
|
|
||||||
{% endif %}
|
|
||||||
{{ time_left(contest) }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ user_count(contest, request.user) }}
|
|
||||||
</td>
|
|
||||||
{{ contest_join(contest, request) }}
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -332,31 +356,31 @@
|
||||||
</h3>
|
</h3>
|
||||||
{% if future_contests %}
|
{% if future_contests %}
|
||||||
<div class="toggled">
|
<div class="toggled">
|
||||||
<table class="contest-list table striped">
|
{% for contest in future_contests %}
|
||||||
<thead>
|
<div class="list-contest">
|
||||||
<tr>
|
<div class="info-contest" style="flex: 1.5">
|
||||||
<th>{{ _('Contest') }}</th>
|
<div class="contest-title">Kì thi:</div>
|
||||||
</tr>
|
{{ contest_head(contest) }}
|
||||||
</thead>
|
</div>
|
||||||
<tbody>
|
<div class="info-contest" style="flex: 1.5">
|
||||||
{% for contest in future_contests %}
|
<div class="contest-title">Thời gian:</div>
|
||||||
<tr>
|
<div class="contest-block">
|
||||||
<td>
|
{% if contest.start_time %}
|
||||||
<div class="contest-block">
|
{% if contest.time_before_start %}
|
||||||
{{ contest_head(contest) }}
|
<span class="time">{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}</span>
|
||||||
{% if contest.start_time %}
|
{% endif %}
|
||||||
<br>
|
{{ time_left(contest) }}
|
||||||
{% if contest.time_before_start %}
|
{% endif %}
|
||||||
<span class="time">{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}</span>
|
</div>
|
||||||
{% endif %}
|
</div>
|
||||||
{{ time_left(contest) }}
|
<div class="info-contest">
|
||||||
{% endif %}
|
<div class="contest-title">Định dạng:</div>
|
||||||
</div>
|
{% if contest.format_name == "default" %} IOI
|
||||||
</td>
|
{% else %} {{ contest.format_name|upper }}
|
||||||
</tr>
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
</tbody>
|
</div>
|
||||||
</table>
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="toggled">
|
<div class="toggled">
|
||||||
|
@ -371,48 +395,44 @@
|
||||||
</h3>
|
</h3>
|
||||||
{% if past_contests %}
|
{% if past_contests %}
|
||||||
{% if page_obj and page_obj.num_pages > 1 %}
|
{% if page_obj and page_obj.num_pages > 1 %}
|
||||||
<div style="margin-bottom: 4px;">
|
<div style="margin-bottom: 10px;">
|
||||||
{% include "list-pages.html" %}
|
{% include "list-pages.html" %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<table class="contest-list table striped">
|
|
||||||
<thead>
|
{% for contest in past_contests %}
|
||||||
<tr>
|
<div class="list-contest">
|
||||||
<th style="width:90%">
|
<div class="info-contest" style="flex: 1.5">
|
||||||
<a class="contest-list-sort" href="{{ sort_links.name }}">{{ _('Contest') }}{{ sort_order.name }}</a>
|
<div class="contest-title">Kì thi:</div>
|
||||||
</th>
|
{{ contest_head(contest) }}
|
||||||
<th>
|
</div>
|
||||||
<a class="contest-list-sort" href="{{ sort_links.user_count }}">{{ _('Users') }}{{ sort_order.user_count }}</a>
|
<div class="info-contest" style="flex: 1.5">
|
||||||
</th>
|
<div class="contest-title">Thời gian:</div>
|
||||||
{% if not request.in_contest %}
|
<div class="contest-block">
|
||||||
<th style="width:15%"></th>
|
{{ time_left(contest) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-contest">
|
||||||
|
<div class="contest-title">Định dạng:</div>
|
||||||
|
{% if contest.format_name == "default" %} IOI
|
||||||
|
{% else %} {{ contest.format_name|upper }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</div>
|
||||||
</thead>
|
<div class="info-contest">
|
||||||
<tbody>
|
<div class="contest-title">Người tham gia:</div>
|
||||||
{% for contest in past_contests %}
|
{{ user_count(contest, request.user) }}
|
||||||
<tr>
|
</div>
|
||||||
<td>
|
{% if not request.in_contest %}
|
||||||
<div class="contest-block">
|
<div class="participate-button">
|
||||||
{{ contest_head(contest) }}
|
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||||
{{ time_left(contest) }}
|
{% csrf_token %}
|
||||||
</div>
|
<input type="submit" class="unselectable button full small"
|
||||||
</td>
|
value="{{ _('Virtual join') }}">
|
||||||
<td>
|
</form>
|
||||||
{{ user_count(contest, request.user) }}
|
</div>
|
||||||
</td>
|
{% endif %}
|
||||||
{% if not request.in_contest %}
|
</div>
|
||||||
<td><form action="{{ url('contest_join', contest.key) }}" method="post">
|
{% endfor %}
|
||||||
{% csrf_token %}
|
|
||||||
<input type="submit" class="unselectable button full small"
|
|
||||||
value="{{ _('Virtual join') }}">
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
{% endif %}
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% if page_obj and page_obj.num_pages > 1 %}
|
{% if page_obj and page_obj.num_pages > 1 %}
|
||||||
<div style="margin-top: 10px;">
|
<div style="margin-top: 10px;">
|
||||||
{% include "list-pages.html" %}
|
{% include "list-pages.html" %}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue