Skip to content

Commit

Permalink
Some dope shizz is going down. PERMISSION DENIED.
Browse files Browse the repository at this point in the history
  • Loading branch information
davepeck committed Apr 18, 2024
1 parent 8954d57 commit 19b682b
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 114 deletions.
238 changes: 126 additions & 112 deletions server/vb/templates/check.dhtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,143 +2,157 @@
{% load static %}

{% block title %}
Voter Bowl x {{ school.short_name }}
Voter Bowl x {{ school.short_name }}
{% endblock title %}

{% block head_extras %}
<script src="{% static 'js/fireworks.js' %}"></script>
<script src="https://cdn.voteamerica.com/embed/tools.js" async></script>
<script src="{% static 'js/fireworks.js' %}"></script>
<script src="https://cdn.voteamerica.com/embed/tools.js" async></script>
{% endblock head_extras %}

{% block body %}
<style>
me {
background-color: white;
}
</style>
<div>
<style>
me {
background-color: white;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
</style>
<div>
<style>
me {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}

me main {
width: 100%;
text-align: center;
padding: 2rem 0;
}
me main {
width: 100%;
text-align: center;
padding: 2rem 0;
}

me main img {
height: 150px;
margin: 1.5rem 0;
}
me main img {
height: 150px;
margin: 1.5rem 0;
}

me main p {
font-weight: 378;
font-size: 20px;
line-height: 130%;
}
me main p {
font-weight: 378;
font-size: 20px;
line-height: 130%;
}

me main h2 {
font-weight: 500;
font-size: 36px;
line-height: 120%;
text-transform: uppercase;
}
me main h2 {
font-weight: 500;
font-size: 36px;
line-height: 120%;
text-transform: uppercase;
}

me .faq {
width: 100%;
color: white;
padding: 2rem 0;
me .faq {
width: 100%;
color: white;
padding: 2rem 0;
}

me .button-holder {
display: flex;
justify-content: center;
margin: 1.5rem 0;
}

me .form {
width: 100%;
background-color: white;
padding: 2rem 0;
}
</style>
<main data-bg-color="{{ school.logo.bg_color }}" data-color="{{ school.logo.bg_text_color }}">
<style>
me {
--main-color: transparent;
--main-bg-color: transparent;
position: relative;
color: var(--main-color);
background-color: var(--main-bg-color);
}

me .button-holder {
me .urgency {
display: flex;
justify-content: center;
margin: 1.5rem 0;
align-items: center;
}

me .form {
width: 100%;
background-color: white;
padding: 2rem 0;
me .fireworks {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
overflow: hidden;
}
</style>
<main data-bg-color="{{ school.logo.bg_color }}"
data-color="{{ school.logo.bg_text_color }}">
<style>
me {
--main-color: transparent;
--main-bg-color: transparent;
position: relative;
color: var(--main-color);
background-color: var(--main-bg-color);
}
<script>
(function (self) {
onloadAdd(() => {
self.style.setProperty('--main-color', self.dataset.color);
self.style.setProperty('--main-bg-color', self.dataset.bgColor);
});
})(me());

me .urgency {
display: flex;
}
(function (self) {
/**
* Finalize a verify and, possibly, mint a new gift card if all is well.
*
* @param {string} firstName
* @param {string} lastName
* @param {string} email
*/
const finishVerify = (firstName, lastName, email) => {
htmx.ajax("POST", "./finish/", {
target: self.querySelector(".urgency"),
values: {
first_name: firstName,
last_name: lastName,
email: email
}
});
};

me .fireworks {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
overflow: hidden;
}
</style>
<script>
(function() {
const self = me();
onloadAdd(() => {
self.style.setProperty('--main-color', self.dataset.color);
self.style.setProperty('--main-bg-color', self.dataset.bgColor);
window.addEventListener('VoteAmericaEvent', (event) => {
const {
data
} = event.detail;
if (data?.tool === "verify" && data?.event === "action-finish") {
setTimeout(() => {
// scroll entire window back to top, smoothly
window.scrollTo({
top: 0,
behavior: 'smooth'
});
})();

(function() {
const self = me();
window.addEventListener('VoteAmericaEvent', (event) => {
const {
data
} = event.detail;
if (data?.tool === "verify" && data?.event === "action-finish") {
setTimeout(() => {
// scroll entire window back to top, smoothly
window.scrollTo({
top: 0,
behavior: 'smooth'
});
const fireworks = new Fireworks.default(self.querySelector('.fireworks'));
fireworks.start();
}, 500);
}
});
})();
</script>
<div class="container">
<div class="urgency">
<img src="{{ school.logo.url }}"
alt="{{ school.short_name }} {{ school.mascot }} logo" />
{% if current_contest %}
{% include "components/countdown.dhtml" with contest=current_contest %}
{% endif %}
</div>
</div>
<div class="fireworks"></div>
</main>
<div class="form">
<div class="container">
<!-- TODO replace data-subscriber -->
<div class="voteamerica-embed"
data-subscriber="countmore"
data-tool="verify"
data-edition="college"></div>
const fireworks = new Fireworks.default(self.querySelector('.fireworks'));
fireworks.start();
finishVerify(data.first_name, data.last_name, data.email);
}, 500);
}
});
})(me());
</script>
<div class="container">
<div class="urgency">
<img src="{{ school.logo.url }}" alt="{{ school.short_name }} {{ school.mascot }} logo" />
{% if current_contest %}
{% include "components/countdown.dhtml" with contest=current_contest %}
{% endif %}
</div>
</div>
<div class="fireworks"></div>
</main>
<div class="form">
<div class="container">
<!-- TODO replace data-subscriber -->
<div class="voteamerica-embed" data-subscriber="countmore" data-tool="verify" data-edition="college"></div>
</div>
</div>
{% endblock body %}
</div>
{% endblock body %}
3 changes: 3 additions & 0 deletions server/vb/templates/finish_check.dhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<img src="{{ school.logo.url }}"
alt="{{ school.short_name }} {{ school.mascot }} logo" />
<p>CONGRATS! Check your email {{ first_name }} AND {{ last_name }}, because some dope shizz is on its way.</p>
3 changes: 2 additions & 1 deletion server/vb/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from django.urls import path

from .views import check, home, school
from .views import check, finish_check, home, school

urlpatterns = [
path("<slug:slug>/check/finish/", finish_check, name="finish_check"),
path("<slug:slug>/check/", check, name="check"),
path("<slug:slug>/", school, name="school"),
path("", home),
Expand Down
38 changes: 37 additions & 1 deletion server/vb/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from django import forms
from django.core.exceptions import PermissionDenied
from django.http import HttpRequest, HttpResponse
from django.shortcuts import get_object_or_404, render
from django.views.decorators.http import require_GET
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_GET, require_POST

from .models import School

Expand Down Expand Up @@ -29,3 +32,36 @@ def check(request: HttpRequest, slug: str) -> HttpResponse:
return render(
request, "check.dhtml", {"school": school, "current_contest": current_contest}
)


class VerifyForm(forms.Form):
"""Form for verifying a check."""

first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
email = forms.EmailField()


@require_POST
@csrf_exempt # CONSIDER: maybe use Django's CSRF protection even here?
def finish_check(request: HttpRequest, slug: str) -> HttpResponse:
"""Handle a check registration form submission."""
school = get_object_or_404(School, slug=slug)
current_contest = school.contests.current()
if not current_contest:
raise ValueError("No active contest TODO")
form = VerifyForm(request.POST)
if not form.is_valid():
raise PermissionDenied("Invalid form")

return render(
request,
"finish_check.dhtml",
{
"school": school,
"current_contest": current_contest,
"first_name": form.cleaned_data["first_name"],
"last_name": form.cleaned_data["last_name"],
"email": form.cleaned_data["email"],
},
)

0 comments on commit 19b682b

Please sign in to comment.