PAOV 4 years ago
parent 46ee7ad545
commit 43d31a0e3f
  1. 117
      choose/templates/choose.html
  2. 91
      choose/templates/vote.html
  3. 24
      choose/views.py
  4. 18
      tea/urls.py

@ -2,11 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<title>Choose your set of tea</title>
</head>
<body>
<script async src="https://telegram.org/js/telegram-widget.js?21" data-telegram-login="PAOV_Tea_bot" data-size="large"
data-auth-url="https://tea.paov.ru/auth/complete/telegram" data-request-access="write"></script>
<table>
<tbody>
<tr>
@ -33,15 +31,20 @@
</td>
<td>
<label for="{{ type_name }}">{{ type_name }}</label>
{{ type_name }}
</td>
<td>{{ type.price }}</td>
<td>
<select name="{{ type_name }}" id="{{ type_name }}" onchange="change(value, '{{ type_name }}')">
<div class="select-wrapper">
<select class="selector" name="{{ type_name }}" id="{{ type_name }}"
onchange="change(value, '{{ type_name }}')">
{% for m in ms %}
<option value="{{ m }}">{{ m }}</option>
{% endfor %}
</select>
<div class="select-arrow"></div>
<div class="select-arrow"></div>
</div>
</td>
<td id="price {{ type_name }}">
0
@ -52,7 +55,7 @@
{% endfor %}
</table>
<h3 id="sum_h">0</h3>
<button onclick="confirm_choice()" id="confirm_button">Подтвердить</button>
<button class="btn" onclick="confirm_choice()" id="confirm_button">Подтвердить</button>
</body>
<script>
function getCookie(name) {
@ -126,8 +129,11 @@
);
fetch(request).then((response) => response.json())
.then((data) => {
if (data.response == 'ok'){window.location.replace("/");}
else {window.alert(data.response)}
if (data.response == 'ok') {
window.location.replace("/");
} else {
window.alert(data.response)
}
})
}
</script>
@ -159,8 +165,8 @@
text-align: left;
border: none;
padding: 10px 15px;
font-size: 14px;
vertical-align: top;
font-size: 16px;
vertical-align: center;
}
table tbody tr:nth-child(even) {
@ -184,5 +190,96 @@
margin-top: 0px;
margin-bottom: 0px;
}
.selector {
padding-left: 10px;
}
.select-wrapper {
width: 65px;
position: relative;
height: 38px;
color: #444;
background: transparent;
border: 1px solid #bcbcbc;
border-radius: 5px;
}
.select-wrapper > select {
width: 100%;
height: 37px;
background: transparent;
border: 0;
appearance: none;
z-index: 1;
-webkit-appearance: none;
-moz-appearance: none;
}
.select-wrapper > select::-ms-expand {
display: none;
}
.select-arrow {
position: absolute;
z-index: -1;
border: 8px solid transparent;
border-bottom: 0;
right: 11px;
}
.select-arrow:nth-child(2) {
top: 15px;
border-top-color: #bdbdbd;
}
.select-arrow:nth-child(3) {
top: 13px;
border-top-color: #FFF;
}
.btn {
display: inline-block;
box-sizing: border-box;
padding: 0 13px;
margin: 0 15px 15px 0;
outline: none;
border: 1px solid transparent;
border-radius: 3px;
height: 32px;
line-height: 32px;
font-size: 14px;
font-weight: 500;
text-decoration: none;
color: #fff;
background-color: #65a3be;
cursor: pointer;
user-select: none;
appearance: none;
touch-action: manipulation;
}
.btn:focus-visible {
box-shadow: 0 0 0 3px lightskyblue;
}
.btn:hover {
border-color: transparent;
background-color: #4986a1;
color: #fff;
}
.btn:active {
border-color: #6f9cbc !important;
background-color: #367089 !important;
}
.btn:disabled {
background-color: #afafaf;
color: #fff;
pointer-events: none;
}
</style>
</html>

@ -5,12 +5,16 @@
<title>Title</title>
</head>
<body>
{% if not voted %}
<button class="btn" onclick="location.href='/choose'">Проголосовать</button>
{% endif %}
<table>
<tbody>
<tr>
<th>Список чаев</th>
<th>Выбрали</th>
<th>Проголосовали</th>
<th>Всего голосов</th>
<th></th>
</tr>
{% for choice in choices %}
@ -37,11 +41,19 @@
</ul>
</td>
<td>
{{ choice.votes }}
</td>
<td style="text-align: center;">
{% if choice.class == 'choice' %}
<button onclick="vote({{ choice.id }})"{% if request.user.username in choice.voted %}disabled{% endif %}>+</button>
<button class="btn" onclick="vote({{ choice.id }})"
{% if request.user.username in choice.voted %}disabled{% endif %}>+
</button>
<button class="btn" onclick="cancel_vote({{ choice.id }})"
{% if request.user.username not in choice.voted %}disabled{% endif %}>-
</button>
{% endif %}
{% if choice.class == 'my_choice' %}
<button onclick="location.href='/choose'">Изменить выбор</button>
<button class="btn" style="width: 138px" onclick="location.href='/choose'">Изменить выбор</button>
{% endif %}
</td>
</tr>
@ -77,8 +89,8 @@
text-align: left;
border: none;
padding: 10px 15px;
font-size: 14px;
vertical-align: top;
font-size: 16px;
vertical-align: center;
}
table tbody tr:nth-child(even) {
@ -107,6 +119,48 @@
padding-inline-start: 10px;
}
.btn {
display: inline-block;
box-sizing: border-box;
padding: 0 13px;
margin: 0 15px 15px 0;
outline: none;
border: 1px solid transparent;
border-radius: 3px;
height: 32px;
line-height: 32px;
font-size: 14px;
font-weight: 500;
text-decoration: none;
color: #fff;
background-color: #65a3be;
cursor: pointer;
user-select: none;
appearance: none;
touch-action: manipulation;
}
.btn:focus-visible {
box-shadow: 0 0 0 3px lightskyblue;
}
.btn:hover {
border-color: transparent;
background-color: #4986a1;
color: #fff;
}
.btn:active {
border-color: #6f9cbc !important;
background-color: #367089 !important;
}
.btn:disabled {
background-color: #afafaf;
color: #fff;
pointer-events: none;
}
</style>
<script>
function getCookie(name) {
@ -126,6 +180,7 @@
}
const csrftoken = getCookie('csrftoken');
function vote(id) {
const request = new Request(
'confirm-vote',
@ -133,13 +188,35 @@
method: 'POST',
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin',
body: JSON.stringify({vote:id})
body: JSON.stringify({vote: id})
}
);
fetch(request).then((response) => response.json())
.then((data) => {
if (data.response == 'ok' || data.response == 'not found'){window.location.reload();}
else {window.alert(data.response)}
if (data.response == 'ok' || data.response == 'not found') {
window.location.reload();
} else {
window.alert(data.response)
}
})
}
function cancel_vote(id) {
const request = new Request(
'confirm-cancel-vote',
{
method: 'POST',
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin',
body: JSON.stringify({vote: id})
}
);
fetch(request).then((response) => response.json())
.then((data) => {
if (data.response == 'ok' || data.response == 'not found') {
window.location.reload();
} else {
window.alert(data.response)
}
})
}
</script>

@ -44,12 +44,14 @@ def list_of_teas():
def list_of_choices(request):
arr = []
voted = False
my_choice = Choice.objects.filter(users__in=[request.user]).first()
if my_choice is not None:
voted =True
json.loads(my_choice.choice)
arr.append({'voted': [user.username for user in my_choice.votes.all()],
'chosed': [user.username for user in my_choice.users.all()],
'votes': len(list(my_choice.votes.all())) + len(list(my_choice.users.all())),
'teas': sorted([Tea.objects.get(id=int(tea_id)).name + ':' + str(mass) for tea_id, mass in
json.loads(my_choice.choice).items()]),
'class': 'my_choice', 'id': my_choice.id})
@ -59,10 +61,11 @@ def list_of_choices(request):
for choice in choices:
arr.append({'voted': [user.username for user in choice.votes.all()],
'chosed': [user.username for user in choice.users.all()],
'votes': len(list(choice.votes.all())) + len(list(choice.users.all())),
'teas': sorted([Tea.objects.get(id=int(tea_id)).name + ':' + str(mass) for tea_id, mass in
json.loads(choice.choice).items()]),
'class': 'choice', 'id': choice.id})
return {'choices': arr}
return {'choices': arr, 'voted': voted}
@login_requiered
@ -72,6 +75,7 @@ def choose(request):
return HttpResponse(template.render(context, request))
@login_requiered
def home(request):
context = list_of_choices(request)
template = loader.get_template('vote.html')
@ -118,3 +122,19 @@ def confirm_vote(request):
return JsonResponse({'response': 'ok'})
else:
return JsonResponse({'response': 'unauthenticated'})
def confirm_cancel_vote(request):
if request.user.is_authenticated:
vote = json.loads(request.body.decode(encoding='UTF-8'))
choice = Choice.objects.filter(id=vote['vote']).first()
if choice is None:
return JsonResponse({'response': 'not found'})
my_choice = Choice.objects.filter(users__in=[request.user]).first()
if my_choice is not None:
if my_choice.id == choice.id:
return JsonResponse({'response': 'WAT'})
choice.votes.remove(request.user)
return JsonResponse({'response': 'ok'})
else:
return JsonResponse({'response': 'unauthenticated'})

@ -1,18 +1,3 @@
"""tea URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
@ -26,7 +11,8 @@ urlpatterns = [
path('choose', choose.views.choose, name='choose'),
path('vote', choose.views.home, name='home'),
path('confirm-choice', choose.views.confirm_choose),
path('confirm-vote', choose.views.confirm_choose),
path('confirm-vote', choose.views.confirm_vote),
path('confirm-cancel-vote', choose.views.confirm_cancel_vote),
path('login', choose.views.login_view, name='login_view')
]
if settings.DEBUG:

Loading…
Cancel
Save