diff --git a/alkator/urls.py b/alkator/urls.py index e20094a..b3ff6be 100644 --- a/alkator/urls.py +++ b/alkator/urls.py @@ -16,10 +16,11 @@ Including another URLconf """ from django.contrib import admin from django.urls import path -from alkatorapi.views import register, results +from alkatorapi.views import register, results, photos urlpatterns = [ path('admin/', admin.site.urls), path('api/register', register), path('api/results', results), + path('api/photos', photos), ] diff --git a/alkator_table.py b/alkator_table.py new file mode 100644 index 0000000..3ea434b --- /dev/null +++ b/alkator_table.py @@ -0,0 +1,8 @@ +from alkatorapi.models import ALKATOR_CHOICES, User +n = 1 +for user in User.objects.order_by('duration'): + if user.alkator_category == 1: + print(f'{n}. {user.duration} {ALKATOR_CHOICES[user.alkator_category-1][1]} {user.starting_number:02}') + n += 1 + else: + print(f'x. {user.duration} {ALKATOR_CHOICES[user.alkator_category-1][1]} {user.starting_number:02}') \ No newline at end of file diff --git a/alkatorapi/views.py b/alkatorapi/views.py index 5161c53..ca33e3f 100644 --- a/alkatorapi/views.py +++ b/alkatorapi/views.py @@ -3,6 +3,8 @@ from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt from datetime import date, datetime import json +import glob +import PIL.Image from .models import User, ALKATOR_CHOICES_DICT @@ -58,4 +60,17 @@ def results(request): 'alkator_category': ALKATOR_CHOICES_DICT[user.alkator_category], 'starting_number': user.starting_number, }) - return HttpResponse(json.dumps(results), content_type='application/json') \ No newline at end of file + return HttpResponse(json.dumps(results), content_type='application/json') + + +def photos(request): + files = glob.glob("photos/*.jpg") + rtn = [] + for file in files: + img = PIL.Image.open(file) + rtn.append({ + 'original': '/' + file, + 'original_width': img.width, + 'original_height': img.height, + }) + return HttpResponse(json.dumps(rtn), content_type='application/json') \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index fa2d782..aa9fe1d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -62,7 +62,11 @@ "@babel/preset-react": "^7.23.3", "bootstrap": "^5.3.2", "core-js": "^3.35.1", + "react": "^18.3.1", "react-data-table-component": "^7.6.2", - "sass": "^1.70.0" + "react-dom": "^18.3.1", + "react-photo-gallery": "^8.0.0", + "sass": "^1.70.0", + "styled-components": "^6.1.9" } } diff --git a/frontend/src/scripts/index.js b/frontend/src/scripts/index.js index c701c19..d154cd9 100644 --- a/frontend/src/scripts/index.js +++ b/frontend/src/scripts/index.js @@ -4,8 +4,10 @@ import DataTable from "react-data-table-component"; import React, { Component } from 'react'; import { createRoot } from 'react-dom/client'; +import Gallery from "react-photo-gallery"; -const addr_prefix = "" //"http://localhost:8000" + +const addr_prefix = "http://localhost:8000" class Main extends Component { @@ -16,10 +18,19 @@ class Main extends Component { status: "", faq: false, results: [], + page: window.location.hash, + photos: [], }; fetch(addr_prefix + "/api/results").then(resp => resp.json()).then(json => { this.setState({results: json}) }) + fetch(addr_prefix + "/api/photos").then(resp => resp.json()).then(json => { + this.setState({photos: json}) + }) + window.addEventListener("hashchange", (e) => {this.onHashChange(e)}) + } + onHashChange(event){ + this.setState({page: window.location.hash}) } onSubmit(event){ event.preventDefault(); @@ -46,191 +57,220 @@ class Main extends Component { this.setState({faq: !this.state.faq}); } render(){ + let photos = [] + for (let photo in this.state.photos){ + photos.push({ + src: photo.original, + width: photo.original_width, + height: photo.original_height, + }) + } return (
Vetšinu ceny dělá alkohol a nápoje, které se během závodu konzumují. Dostanete přívěšek s panákem, který Vám zůstává a pokud závod doběhnete, dostanete památeční medaili. Zbytek startovného tvoří výherní ceny, dále náklady spojené s organizací závodu. Výroba překážek, časovačů na čekárnách, náramky pro závodníký, tisk plakátů a jejich propagace, atd. Cenu jsme se snažili nastavit co nejnižší, zároveň takovou, abychom byli schopní Alkátor Race uskutečnit.
-V kontextu Alkátor Race by se to dalo spíše nazvat kontrolním bodem. Závodník doběhne na určité místo, kde tokken sebere a následně ho zanese na další stanoviště, kde ho předáte kontrolorovi. Tím dáte najevo, že jste běžel trasu správě. Je to pojistka, aby jsi byl podctivý Alkátor a nešvindloval!
-Jedná se o překážku, kde na daném místě vylosujete otázku a běžíte k dalšímu stanovišti ke kontrolorovi. Mezi tím si můžete promyslet jednu z ze tří odpovědí (formát A,B,C). Špatná odpopvěď znamená panáčka. Navíc to má obdobnou funkci, jako Tokken.
-Na stanovišti na Vás budou čekat panáčky. Obsah může být cokoliv alkoholického i nealkoholického, od dobrot po blééé. Nejlepší na tom je, že podle čichu a barvy nemáte šanci poznat, o co se jedná. Jelikož panáčky jsou uzavřené a dobarvené potravinářským barvivem.
-Strategii závodu si určím sám s pomocí mého osobního trenéra. Tudíž se zaměřím hlavně na alkohol a abych dorazil do cíle jako hrdina a ostřílený alko-veterán.
-Zatím je kapacita závodu 50 účastníků.
-Tak neváhej a kontaktuj nás na sociálních sítích nebo emailu, rádi pomůžeme.
-Vítej člověče! Momentálně se nacházíš na oficiální stránce závodu ALKÁTOR RACE.
- -A co že jsme si to zase vymysleli!?
- -Jedná se o překážkový závod u nás v Orlických horách. Celkem máme připravených kolem 30 překážek a trať měří kolem 4 km. V závodě tě čeká pěkných pár panáků, kdy počty se pohybují od 3-15 kousků podle toho jak dobře si na překážkách povedeš. Dále máme v závodě překážku zvanou "Čekárna" na které si deset minut odpočneš a dáš si oddychové pivínko na nejkrásnějších místech v okolí Sobkovic. Čekárny tě v závodě čekají hned čtyři.
- -Pokud v průběhu závodu dostaneš pocit, že je to nad tvé síly, vždy budeš mít tu možnost přestoupit do kategorie Alkátor Race LIGHT, kde sice ztratíš možnost stanout na stupních vítězů, ale budeš moci plně regulovat svou obtížnost závodu. - Takže když budeš mít špatný den, nikdo tě nebude do ničeho nutit a ty si užiješ atmosféru akce na plné pecky.
- -Našim smělým alkátorkám nebudeme nic extra zjednodušovat, pouze na čekárnách budou konzumovat poloviční dávky piva(pokud budou chtít). - Pravděpodobně bude otevřena i kategorie NEAlkátor Race - zaměřena na řidiče, abstinenty a nezletilé.
- -Pro alkátory/rky na stupních vítězů čekají úžasné ceny.
- -Start závodu je v 12:00, ale check-in se zahájením akce je již od 10:00.
- -Rozhodně se podívej na FAQ sekci, zde na stránce, kde najdeš důležité informace týkající se závodu ALKÁTOR RACE.
-Sportem ku chlastu!
+ {this.state.page == "" && +Vetšinu ceny dělá alkohol a nápoje, které se během závodu konzumují. Dostanete přívěšek s panákem, který Vám zůstává a pokud závod doběhnete, dostanete památeční medaili. Zbytek startovného tvoří výherní ceny, dále náklady spojené s organizací závodu. Výroba překážek, časovačů na čekárnách, náramky pro závodníký, tisk plakátů a jejich propagace, atd. Cenu jsme se snažili nastavit co nejnižší, zároveň takovou, abychom byli schopní Alkátor Race uskutečnit.
+V kontextu Alkátor Race by se to dalo spíše nazvat kontrolním bodem. Závodník doběhne na určité místo, kde tokken sebere a následně ho zanese na další stanoviště, kde ho předáte kontrolorovi. Tím dáte najevo, že jste běžel trasu správě. Je to pojistka, aby jsi byl podctivý Alkátor a nešvindloval!
+Jedná se o překážku, kde na daném místě vylosujete otázku a běžíte k dalšímu stanovišti ke kontrolorovi. Mezi tím si můžete promyslet jednu z ze tří odpovědí (formát A,B,C). Špatná odpopvěď znamená panáčka. Navíc to má obdobnou funkci, jako Tokken.
+Na stanovišti na Vás budou čekat panáčky. Obsah může být cokoliv alkoholického i nealkoholického, od dobrot po blééé. Nejlepší na tom je, že podle čichu a barvy nemáte šanci poznat, o co se jedná. Jelikož panáčky jsou uzavřené a dobarvené potravinářským barvivem.
+Strategii závodu si určím sám s pomocí mého osobního trenéra. Tudíž se zaměřím hlavně na alkohol a abych dorazil do cíle jako hrdina a ostřílený alko-veterán.
+Zatím je kapacita závodu 50 účastníků.
+Tak neváhej a kontaktuj nás na sociálních sítích nebo emailu, rádi pomůžeme.
+Umístění | -Čas | -Kategorie | -Startovní číslo | - - - {this.state.results.map(user => -
---|---|---|---|
{user.order} | -{user.duration} | -{user.alkator_category} | -{user.starting_number} | -