Compare commits

...

2 Commits

Author SHA1 Message Date
516fa107e5 Allow selecting single users to view 2024-02-16 00:18:55 +01:00
26acc22e84 Formatting 2024-02-16 00:18:45 +01:00
5 changed files with 102 additions and 44 deletions

View File

@ -17,10 +17,11 @@ db.init_app(app)
# - Sortable list to enter full race results (need 7 positions to calculate points),
# don't enter race result on guess page
# - Move guessed place to leftmost column and display actual finishing position of driver instead
# - Display selector to choose a single user on race guessing page
# - Display selector to choose a single user on season guessing page?
# - Choose place to guess late before the race?
# - Choose "place to guess" late before the race?
# - Already show coming race in table, to give better feedback once a user has locked in a guess
# - Set fixed sizes for left- and rightmost column in races table
# - Fix the weird sizing everywhere when selecting only a single user...
# - Replace ALL absolute pixel values inside the templates
@app.route("/")
@ -28,6 +29,12 @@ def index():
return redirect("/race")
@app.route("/saveall")
def savedynamic():
export_dynamic_data()
return redirect("/")
@app.route("/loadall")
def load():
reload_static_data(db)
@ -35,38 +42,34 @@ def load():
return redirect("/")
@app.route("/reloadall")
def reload():
export_dynamic_data()
reload_static_data(db)
reload_dynamic_data(db)
return redirect("/")
@app.route("/reloadstatic")
@app.route("/loadstatic")
def reloadstatic():
reload_static_data(db)
return redirect("/")
@app.route("/reloaddynamic")
@app.route("/loaddynamic")
def reloaddynamic():
reload_dynamic_data(db)
return redirect("/")
@app.route("/savedynamic")
def savedynamic():
export_dynamic_data()
return redirect("/")
@app.route("/race")
def guessraceresults():
def guessraceresult():
return redirect("/race/Everyone")
@app.route("/race/<username>")
def guessuserraceresults(username):
users: List[User] = User.query.all()
raceresults: List[RaceResult] = RaceResult.query.all()[::-1]
drivers: List[Driver] = Driver.query.all()
# Select User
chosenusers = users
if username != "Everyone":
chosenusers = [user for user in users if user.name == username]
pastguesses = dict() # The guesses for which raceresults exist
nextguesses = dict() # The guesses that are still open for modification
raceresult: RaceResult
@ -89,7 +92,9 @@ def guessraceresults():
raceresults=raceresults,
pastguesses=pastguesses,
currentselection=nextguesses,
nextrace=nextrace)
nextrace=nextrace,
chosenusername=username,
chosenusers=chosenusers)
@app.route("/guessrace/<raceid>/<username>", methods=["POST"])
@ -145,12 +150,21 @@ def enterresult(raceid):
@app.route("/season")
def guessseasonresults():
return redirect("/season/Everyone")
@app.route("/season/<username>")
def guessuserseasonresults(username):
users: List[User] = User.query.all()
teams: List[Team] = Team.query.all()
drivers: List[Driver] = Driver.query.all()
# Remove NONE driver
drivers = [driver for driver in drivers if driver.name != "NONE"]
# Select User
chosenusers = users
if username != "Everyone":
chosenusers = [user for user in users if user.name == username]
seasonguesses = dict()
guess: SeasonGuess
@ -170,7 +184,9 @@ def guessseasonresults():
teams=teams,
drivers=drivers,
driverpairs=driverpairs,
currentselection=seasonguesses)
currentselection=seasonguesses,
chosenusername=username,
chosenusers=chosenusers)
@app.route("/guessseason/<username>", methods=["POST"])

View File

@ -8,9 +8,9 @@ import json
db = SQLAlchemy()
#
# Static Data (Defined in Backend)
#
####################################
# Static Data (Defined in Backend) #
####################################
class Race(db.Model):
@ -60,9 +60,9 @@ class Driver(db.Model):
team: Mapped["Team"] = relationship("Team", foreign_keys=[team_id])
#
# Dynamic Data (Defined in Frontend)
#
######################################
# Dynamic Data (Defined in Frontend) #
######################################
class User(db.Model):

View File

@ -3,7 +3,7 @@
{# Easy nav-bar entries. When a page sets the active_page variable, the current entry will be underlined #}
{% macro nav_selector(page='', text='') %}
<a class="nav-link" href="/{{ page }}">{% if active_page == page %}<u>{% endif %} {{ text }}
<a class="nav-link text-nowrap" href="/{{ page }}">{% if active_page == page %}<u>{% endif %} {{ text }}
{% if active_page == page %}</u>{% endif %}</a>
{% endmacro %}
@ -110,18 +110,28 @@
<a class="navbar-brand" href="/">
<img src="../static/image/f1_logo.svg" alt="Logo" width="120" height="30"
class="d-inline-block align-text-top">
Formula <i>10</i> - 2024
Formula <i>10</i>
</a>
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#navbarCollapse">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<div class="navbar-nav">
<div class="navbar-nav me-2">
{{ nav_selector("race", "Guess Race") }}
{{ nav_selector("season", "Guess Season") }}
{{ nav_selector("graphs", "Statistics") }}
{{ nav_selector("rules", "Rules") }}
</div>
{% block navbar_center %}{% endblock navbar_center %}
<div class="flex-grow-1"></div>
<div class="navbar-nav">
{{ nav_selector("enter", "Enter Race Result") }}
{{ nav_selector("users", "Manage Users") }}
</div>
</div>
</div>
</nav>

View File

@ -2,7 +2,22 @@
{% set active_page = "race" %}
{% block title %}Formula 10{% endblock title %}
{% block title %}Formula 10 - Race{% endblock title %}
{% block navbar_center %}
<div class="dropdown">
<button class="btn btn-outline-danger dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ chosenusername }}
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/race/Everyone">Everyone</a></li>
<li><hr class="dropdown-divider"></li>
{% for user in users %}
<li><a class="dropdown-item" href="/race/{{ user.name }}">{{ user.name }}</a></li>
{% endfor %}
</ul>
</div>
{% endblock navbar_center %}
{% block body %}
@ -10,7 +25,7 @@
<thead>
<tr>
<th scope="col" rowspan="2" class="text-center">Race</th>
<th scope="col" colspan="{{ users | length }}" class="text-center">Call</th>
<th scope="col" colspan="{{ chosenusers | length }}" class="text-center">Call</th>
<th scope="col" rowspan="2" class="text-center">Result</th>
</tr>
</thead>
@ -21,7 +36,7 @@
<tr>
<td>&nbsp;</td>
{% for user in users %}
{% for user in chosenusers %}
<td class="text-center text-nowrap">{{ user.name }}</td>
{% endfor %}
@ -33,7 +48,7 @@
<tr class="table-light">
<td class="text-nowrap"><span class="fw-bold">{{ nextrace.id }}:</span> {{ nextrace.grandprix }}</td>
{% for user in users %}
{% for user in chosenusers %}
<td>
<form action="/guessrace/{{ nextrace.id }}/{{ user.name }}" method="post">
{# Driver PXX Select #}
@ -73,7 +88,7 @@
<td class="text-nowrap"><span
class="fw-bold">{{ raceresult.race.id }}:</span> {{ raceresult.race.grandprix }}</td>
{% for user in users %}
{% for user in chosenusers %}
<td class="text-center text-nowrap">
{% if (raceresult.race_id in pastguesses) and (user.name in pastguesses.get(raceresult.race_id)) %}
{% set pxx = pastguesses.get(raceresult.race_id).get(user.name).pxx.abbr %}

View File

@ -2,13 +2,30 @@
{% set active_page = "season" %}
{% block title %}Formula 10{% endblock title %}
{% block title %}Formula 10 - Season{% endblock title %}
{% block navbar_center %}
<div class="dropdown">
<button class="btn btn-outline-danger dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ chosenusername }}
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/season/Everyone">Everyone</a></li>
<li><hr class="dropdown-divider"></li>
{% for user in users %}
<li><a class="dropdown-item" href="/season/{{ user.name }}">{{ user.name }}</a></li>
{% endfor %}
</ul>
</div>
{% endblock navbar_center %}
{% block body %}
<h4 class="heading-text text-danger text-center">All fields (of a single user, excluding podiums) must be set or your inputs won't be saved!</h4>
<div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));">
{% for user in users %}
<div class="card mb-2 shadow-sm">
{% for user in chosenusers %}
<div class="card mb-2 shadow-sm" style="width: 450px;">
<div class="card-body">
<h5 class="card-title">{{ user.name }}</h5>
<form action="/guessseason/{{ user.name }}" method="post">
@ -24,31 +41,31 @@
{# P2 Constructor #}
<div class="mt-2">
{{ team_select_with_preselect(currentselection.get(user.name).p2_constructor.name if user.name in currentselection else "",
"p2select", "P2 Constructor:") }}
"p2select", "P2 Constructor:") }}
</div>
{# Most Overtakes #}
<div class="mt-2">
{{ driver_select_with_preselect(currentselection.get(user.name).most_overtakes.abbr if user.name in currentselection else "",
"overtakeselect", "Most Overtakes:") }}
"overtakeselect", "Most Overtakes:") }}
</div>
{# Most DNFs #}
<div class="mt-2">
{{ driver_select_with_preselect(currentselection.get(user.name).most_dnfs.abbr if user.name in currentselection else "",
"dnfselect", "Most DNFs:") }}
"dnfselect", "Most DNFs:") }}
</div>
{# Most Gained #}
<div class="mt-2">
{{ driver_select_with_preselect(currentselection.get(user.name).most_gained.abbr if user.name in currentselection else "",
"gainedselect", "Most Championship Positions gained:") }}
"gainedselect", "Most Championship Positions gained:") }}
</div>
{# Most Lost #}
<div class="mt-2">
{{ driver_select_with_preselect(currentselection.get(user.name).most_lost.abbr if user.name in currentselection else "",
"lostselect", "Most Championship Positions lost:") }}
"lostselect", "Most Championship Positions lost:") }}
</div>
{# Team-internal Winners #}