Skip to content

Commit

Permalink
Merge branch 'staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
davepeck committed May 16, 2024
2 parents f31b4ea + d4a2a2d commit 712f148
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 9 deletions.
14 changes: 8 additions & 6 deletions server/vb/components/countdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from server.utils.components import style

from ..models import Contest
from .utils import remaining_time


def _describe_contest(contest: Contest) -> h.Node:
Expand Down Expand Up @@ -51,6 +52,7 @@ def _describe_contest(contest: Contest) -> h.Node:
def countdown(contest: Contest) -> h.Element:
"""Render a countdown timer for the given contest."""
logo = contest.school.logo
remaining = remaining_time(contest.end_at)
return h.div[
style(
__file__,
Expand All @@ -62,14 +64,14 @@ def countdown(contest: Contest) -> h.Element:
_describe_contest(contest),
h.big_countdown(data_end_at=contest.end_at.isoformat())[
h.div(".countdown")[
h.span(".number", data_number="h0"),
h.span(".number", data_number="h1"),
h.span(".number", data_number="h0")[f"{remaining.h0}"],
h.span(".number", data_number="h1")[f"{remaining.h1}"],
h.span(".colon")[":"],
h.span(".number", data_number="m0"),
h.span(".number", data_number="m1"),
h.span(".number", data_number="m0")[f"{remaining.m0}"],
h.span(".number", data_number="m1")[f"{remaining.m1}"],
h.span(".colon")[":"],
h.span(".number", data_number="s0"),
h.span(".number", data_number="s1"),
h.span(".number", data_number="s0")[f"{remaining.s0}"],
h.span(".number", data_number="s1")[f"{remaining.s1}"],
]
],
]
8 changes: 7 additions & 1 deletion server/vb/components/ongoing_contest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
from ..models import Contest
from .button import button
from .logo import school_logo
from .utils import small_countdown_str


def _ongoing_description(contest: Contest) -> list[str]:
"""Render a description of the given contest."""
if contest.is_no_prize:
school = contest.school
if school.mascot and school.percent_voted_2020:
return [
f"Join the {school.percent_voted_2020}% of the {school.mascot} who voted in the 2020 presidential election."
]
return [
"Check your voter registration now to avoid last-minute issues before the election."
]
Expand Down Expand Up @@ -61,6 +67,6 @@ def ongoing_contest(contest: Contest) -> h.Element:
],
],
h.small_countdown(data_end_at=contest.end_at.isoformat())[
h.div(".box countdown")[""]
h.div(".box countdown")[small_countdown_str(contest.end_at)]
],
]
18 changes: 16 additions & 2 deletions server/vb/components/school_page.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,17 @@ me main {
background-color: var(--bg-color);
}

me main>div {
display: flex;
flex-direction: column;
justify-content: space-evenly;
min-height: calc(100dvh - env(safe-area-inset-bottom) - 2rem);
}

@media screen and (min-width: 768px) {
me main {
me main>div {
padding: 2rem 0;
min-height: unset;
}
}

Expand Down Expand Up @@ -46,7 +54,13 @@ me .faq {
me .button-holder {
display: flex;
justify-content: center;
margin: 1.5rem 0;
margin: 0;
}

@media screen and (min-width: 768px) {
me .button-holder {
margin-top: 1.5rem;
}
}

me .faq {
Expand Down
4 changes: 4 additions & 0 deletions server/vb/components/school_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@


def _no_current_prize_contest(school: School) -> h.Node:
if school.mascot and school.percent_voted_2020:
return h.p[
f"Join the {school.percent_voted_2020}% of the {school.mascot} who voted in the 2020 presidential election."
]
return h.p[
school.short_name,
" ",
Expand Down
61 changes: 61 additions & 0 deletions server/vb/components/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import datetime
import typing as t
from dataclasses import dataclass, field, replace
from math import floor

import htpy as h
from htpy import _iter_children as _h_iter_children
Expand Down Expand Up @@ -70,3 +72,62 @@ def __iter__(self):


fragment = Fragment(None)


@dataclass(frozen=True)
class RemainingTime:
"""Render the remaining time until the given end time."""

h0: int
"""The tens digit of the hours."""

h1: int
"""The ones digit of the hours."""

m0: int
"""The tens digit of the minutes."""

m1: int
"""The ones digit of the minutes."""

s0: int
"""The tens digit of the seconds."""

s1: int
"""The ones digit of the seconds."""

@property
def ended(self) -> bool:
"""Return whether the remaining time has ended."""
return self.h0 == self.h1 == self.m0 == self.m1 == self.s0 == self.s1 == 0


def remaining_time(
end_at: datetime.datetime, when: datetime.datetime | None = None
) -> RemainingTime:
"""Render the remaining time until the given end time."""
now = when or datetime.datetime.now(datetime.UTC)
delta = end_at - now
if delta.total_seconds() <= 0:
return RemainingTime(0, 0, 0, 0, 0, 0)
hours, remainder = divmod(delta.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
hours, minutes, seconds = map(floor, (hours, minutes, seconds))
return RemainingTime(
h0=hours // 10,
h1=hours % 10,
m0=minutes // 10,
m1=minutes % 10,
s0=seconds // 10,
s1=seconds % 10,
)


def small_countdown_str(
end_at: datetime.datetime, when: datetime.datetime | None = None
) -> str:
"""Render the remaining time until the given end time."""
rt = remaining_time(end_at, when)
if rt.ended:
return "Just ended!"
return f"Ends in {rt.h0}{rt.h1}:{rt.m0}{rt.m1}:{rt.s0}{rt.s1}"
18 changes: 18 additions & 0 deletions server/vb/migrations/0012_add_percent_voted.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.3 on 2024-05-15 17:53

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('vb', '0011_complex_contest_additions'),
]

operations = [
migrations.AddField(
model_name='school',
name='percent_voted_2020',
field=models.IntegerField(blank=True, default=0, help_text='If known, the percentage of students who voted in 2020 (like 70).'),
),
]
5 changes: 5 additions & 0 deletions server/vb/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class School(models.Model):

short_name = models.CharField(max_length=255, blank=True)
mascot = models.CharField(max_length=255, blank=True)
percent_voted_2020 = models.IntegerField(
blank=True,
default=0,
help_text="If known, the percentage of students who voted in 2020 (like 70).",
)

# Fields that define how the school handles email addresses.
# This allows us both to validate that a school-matching email address is
Expand Down

0 comments on commit 712f148

Please sign in to comment.