Skip to content

Commit

Permalink
Further refactoring of the frontend code, just because.
Browse files Browse the repository at this point in the history
  • Loading branch information
davepeck committed May 7, 2024
1 parent a97459a commit 1de3626
Show file tree
Hide file tree
Showing 24 changed files with 756 additions and 722 deletions.
26 changes: 14 additions & 12 deletions server/utils/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@
from pydantic.alias_generators import to_camel


def load_file(file_name: str | pathlib.Path, markup: bool) -> str:
def load_file(file_name: str | pathlib.Path) -> str:
"""Load a text file and return its contents."""
with open(file_name, "r") as f:
text = f.read()
return Markup(text) if markup else text
return f.read()


def load_sibling_file(
base_file_name: str | pathlib.Path, file_name: str, markup: bool
) -> str:
def load_sibling_file(base_file_name: str | pathlib.Path, file_name: str) -> str:
"""Load a file in the same directory as the base file."""
return load_file(pathlib.Path(base_file_name).resolve().parent / file_name, markup)
return load_file(pathlib.Path(base_file_name).resolve().parent / file_name)


def _css_vars(selector: str, /, **vars: str) -> str:
Expand All @@ -37,10 +34,10 @@ def style(base_file_name: str | pathlib.Path, file_name: str, **vars: str) -> h.
In addition to the file, you can pass in CSS variables to inject into the
stylesheet.
"""
text = load_sibling_file(base_file_name, file_name, markup=True)
text = load_sibling_file(base_file_name, file_name)
if vars:
text = _css_vars("me", **vars) + text
return h.style[text]
return h.style[Markup(text)]


def js(
Expand All @@ -65,18 +62,23 @@ def js(
CONSIDER: this still feels awkward to me, and I bet there's a cleaner
pattern -- our CSS pattern feels very clean to me, for instance.
"""
text = load_sibling_file(base_file_name, file_name, markup=True)
text = load_sibling_file(base_file_name, file_name)
element = h.script
if props:
as_camel = {to_camel(k): v for k, v in props.items()}
as_json = json.dumps(as_camel)
element = element(data_props=as_json)
if surreal:
text = f"({text})(me(), me('script').dataset.props && JSON.parse(me('script').dataset.props))" # noqa: E501
return element[text]
return element[Markup(text)]


def svg(base_file_name: str | pathlib.Path, file_name: str) -> Markup:
"""Load an SVG file in the same directory as the base file."""
return Markup(load_sibling_file(base_file_name, file_name))


def markdown_html(base_file_name: str | pathlib.Path, file_name: str) -> Markup:
"""Load a markdown file in the same directory as the base file."""
text = load_sibling_file(base_file_name, file_name, markup=False)
text = load_sibling_file(base_file_name, file_name)
return Markup(markdown.markdown(text))
10 changes: 10 additions & 0 deletions server/vb/components/base_page.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
html {
background-color: var(--bg-color);
}

.faq {
width: 100%;
color: white;
padding: 2rem 0;
background-color: black;
}
22 changes: 3 additions & 19 deletions server/vb/components/base_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.templatetags.static import static
from markupsafe import Markup

from server.utils.components import style

from .faq import faq
from .footer import footer
from .utils import with_children
Expand All @@ -28,24 +30,6 @@ def _gtag_scripts() -> h.Node:
]


_STYLE = """
html {
background-color: {bg_color};
}
.faq {
width: 100%;
color: white;
padding: 2rem 0;
background-color: black;
}
"""


def _style(bg_color: str) -> h.Element:
return h.style[_STYLE.replace("{bg_color}", bg_color)]


@with_children
def base_page(
children: h.Node = None,
Expand All @@ -72,7 +56,7 @@ def base_page(
h.script(src=static("js/htmx.min.js")),
h.script(src=static("js/css-scope-inline.js")),
h.script(src=static("/js/surreal.js")),
_style(bg_color),
style(__file__, "base_page.css", bg_color=bg_color),
extra_head,
],
h.body[
Expand Down
20 changes: 20 additions & 0 deletions server/vb/components/button.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
me {
cursor: pointer;
transition: opacity 0.2s ease-in-out;
text-transform: uppercase;
text-decoration: none;
font-weight: 600;
font-size: 18px;
line-height: 100%;
border: none;
text-align: center;
letter-spacing: 0.05em;
padding: 20px 24px;
background-color: var(--bg-color);
color: var(--color);
}

me:hover {
opacity: 0.7;
transition: opacity 0.2s ease-in-out;
}
33 changes: 5 additions & 28 deletions server/vb/components/button.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,13 @@
import htpy as h

from .utils import with_children

_STYLE = """
me {
cursor: pointer;
transition: opacity 0.2s ease-in-out;
text-transform: uppercase;
text-decoration: none;
font-weight: 600;
font-size: 18px;
line-height: 100%;
border: none;
text-align: center;
letter-spacing: 0.05em;
padding: 20px 24px;
background-color: {bg_color};
color: {color};
}
me:hover {
opacity: 0.7;
transition: opacity 0.2s ease-in-out;
}
"""
from server.utils.components import style


def _style(bg_color: str, color: str) -> h.Element:
return h.style[_STYLE.replace("{bg_color}", bg_color).replace("{color}", color)]
from .utils import with_children


@with_children
def button(children: h.Node, href: str, bg_color: str, color: str) -> h.Element:
"""Render a button with the given background and text color."""
return h.a(href=href)[_style(bg_color, color), children]
return h.a(href=href)[
style(__file__, "button.css", bg_color=bg_color, color=color), children
]
5 changes: 5 additions & 0 deletions server/vb/components/clipboard.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions server/vb/components/clipboard_check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 63 additions & 0 deletions server/vb/components/footer.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
me {
background-color: black;
color: #aaa;
padding-top: 4rem;
padding-bottom: 2rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
width: 100%;
}

@media screen and (min-width: 768px) {
me {
padding-left: 2em;
padding-right: 2rem;
}
}

me div.center {
margin-bottom: 2em;
display: flex;
justify-content: center;
color: #fff;
}

me div.center svg {
width: 120px !important;
}

me div.outer {
display: flex;
flex-direction: column-reverse;
justify-content: space-between;
align-items: center;
}

@media screen and (min-width: 768px) {
me div.outer {
flex-direction: row;
}
}

me div.inner {
display: flex;
flex-direction: row;
gap: 1em;
}

me a {
color: #aaa;
text-decoration: underline;
}

me a:hover {
color: white;
}

me .colophon {
text-align: center;
color: #888;
font-size: 0.8em;
padding-top: 1em;
padding-bottom: 3em;
}
70 changes: 3 additions & 67 deletions server/vb/components/footer.py
Original file line number Diff line number Diff line change
@@ -1,79 +1,15 @@
import htpy as h
from django.urls import reverse

from .logo import VOTER_BOWL_LOGO

_STYLE = """
me {
background-color: black;
color: #aaa;
padding-top: 4rem;
padding-bottom: 2rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
width: 100%;
}
@media screen and (min-width: 768px) {
me {
padding-left: 2em;
padding-right: 2rem;
}
}
me div.center {
margin-bottom: 2em;
display: flex;
justify-content: center;
color: #fff;
}
me div.center svg {
width: 120px !important;
}
me div.outer {
display: flex;
flex-direction: column-reverse;
justify-content: space-between;
align-items: center;
}
from server.utils.components import style

@media screen and (min-width: 768px) {
me div.outer {
flex-direction: row;
}
}
me div.inner {
display: flex;
flex-direction: row;
gap: 1em;
}
me a {
color: #aaa;
text-decoration: underline;
}
me a:hover {
color: white;
}
me .colophon {
text-align: center;
color: #888;
font-size: 0.8em;
padding-top: 1em;
padding-bottom: 3em;
}
"""
from .logo import VOTER_BOWL_LOGO


def footer() -> h.Element:
"""Render the site-wide footer."""
return h.footer[
h.style[_STYLE],
style(__file__, "footer.css"),
h.div(".center")[VOTER_BOWL_LOGO],
h.div(".outer")[
h.p(".copyright")["© 2024 The Voter Bowl"],
Expand Down
Loading

0 comments on commit 1de3626

Please sign in to comment.