diff options
Diffstat (limited to '')
| -rw-r--r-- | pysite/mixins.py | 3 | ||||
| -rw-r--r-- | pysite/tables.py | 8 | ||||
| -rw-r--r-- | pysite/views/main/jams/join.py | 180 | ||||
| -rw-r--r-- | pysite/views/main/jams/signup.py | 9 | ||||
| -rw-r--r-- | static/style.css | 11 | ||||
| -rw-r--r-- | templates/main/jams/already.html | 26 | ||||
| -rw-r--r-- | templates/main/jams/banned.html | 44 | ||||
| -rw-r--r-- | templates/main/jams/index.html | 2 | ||||
| -rw-r--r-- | templates/main/jams/join.html | 357 | ||||
| -rw-r--r-- | templates/main/jams/signup.html | 15 | ||||
| -rw-r--r-- | templates/main/jams/thanks.html | 25 | ||||
| -rw-r--r-- | templates/main/navigation.html | 6 | 
12 files changed, 651 insertions, 35 deletions
| diff --git a/pysite/mixins.py b/pysite/mixins.py index a3edc4f2..6e5032ab 100644 --- a/pysite/mixins.py +++ b/pysite/mixins.py @@ -4,6 +4,7 @@ from flask import Blueprint  from rethinkdb.ast import Table  from pysite.database import RethinkDB +from pysite.oauth import OauthBackend  class DBMixin: @@ -98,5 +99,5 @@ class OauthMixin:          return self.oauth.user_data()      @property -    def oauth(self): +    def oauth(self) -> OauthBackend:          return self._oauth() diff --git a/pysite/tables.py b/pysite/tables.py index c180e161..c68feba0 100644 --- a/pysite/tables.py +++ b/pysite/tables.py @@ -79,8 +79,9 @@ TABLES = {          primary_key="id",          keys=sorted([              "id",  # uuid +            "snowflake",  # str              "jam",  # int -            "answers",  # dict {question, answer, metadata} +            "answers",  # list [{question, answer, metadata}]              "approved"  # bool          ])      ), @@ -100,14 +101,15 @@ TABLES = {              "id",  # uuid              "participant",  # str              "reason",  # str -            "number"  # int (optionally -1 for permanent) +            "number",  # int (optionally -1 for permanent) +            "decremented_for"  # list[int]          ])      ),      "code_jam_participants": Table(  # Info for each participant          primary_key="id",          keys=sorted([ -            "snowflake",  # int +            "id",  # str              "skill_level",  # str              "age",  # str              "github_username",  # str diff --git a/pysite/views/main/jams/join.py b/pysite/views/main/jams/join.py new file mode 100644 index 00000000..87a2c4ca --- /dev/null +++ b/pysite/views/main/jams/join.py @@ -0,0 +1,180 @@ +from email.utils import parseaddr + +from flask import request, redirect, url_for +from werkzeug.exceptions import NotFound, BadRequest + +from pysite.base_route import RouteView +from pysite.decorators import csrf +from pysite.mixins import DBMixin, OauthMixin + + +class JamsJoinView(RouteView, DBMixin, OauthMixin): +    path = "/jams/join/<int:jam>" +    name = "jams.join" + +    table_name = "code_jams" +    forms_table = "code_jam_forms" +    questions_table = "code_jam_questions" +    responses_table = "code_jam_responses" +    participants_table = "code_jam_participants" +    infractions_table = "code_jam_infractions" + +    def get(self, jam): +        jam_obj = self.db.get(self.table_name, jam) + +        if not jam_obj: +            return NotFound() + +        if not self.user_data: +            return redirect(url_for("discord.login")) + +        if self.get_response(jam, self.user_data["user_id"]): +            return self.render("main/jams/already.html", jam=jam_obj) + +        infractions = self.get_infractions(self.user_data["user_id"]) + +        for infraction in infractions: +            if infraction["number"] == -1:  # Indefinite ban +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +            if infraction["number"]:  # Got some jams left +                if jam not in infraction["decremented_for"]: +                    # Make sure they haven't already tried to apply for this jam +                    infraction["number"] -= 1 +                    infraction["decremented_for"].append(jam) + +                    self.db.insert(self.infractions_table, infraction, conflict="replace") + +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +            if jam in infraction["decremented_for"]: +                # They already tried to apply for this jam +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +        form_obj = self.db.get(self.forms_table, jam) +        questions = [] + +        if form_obj: +            for question in form_obj["questions"]: +                questions.append(self.db.get(self.questions_table, question)) + +        return self.render( +            "main/jams/join.html", jam=jam_obj, form=form_obj, +            questions=questions, question_ids=[q["id"] for q in questions] +        ) + +    @csrf +    def post(self, jam): +        jam_obj = self.db.get(self.table_name, jam) + +        if not jam_obj: +            return NotFound() + +        if not self.user_data: +            return redirect(url_for("discord.login")) + +        if self.get_response(jam, self.user_data["user_id"]): +            return self.render("main/jams/already.html", jam=jam_obj) + +        infractions = self.get_infractions(self.user_data["user_id"]) + +        for infraction in infractions: +            if infraction["number"] == -1:  # Indefinite ban +                return self.render("main/jams/banned.html", infraction=infraction) + +            if infraction["number"]:  # Got some jams left +                if jam not in infraction["decremented_for"]: +                    # Make sure they haven't already tried to apply for this jam +                    infraction["number"] -= 1 +                    infraction["decremented_for"].append(jam) + +                    self.db.insert(self.infractions_table, infraction, conflict="replace") + +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +            if jam in infraction["decremented_for"]: +                # They already tried to apply for this jam +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +        form_obj = self.db.get(self.forms_table, jam) + +        if not form_obj: +            return NotFound() + +        questions = [] + +        for question in form_obj["questions"]: +            questions.append(self.db.get(self.questions_table, question)) + +        answers = [] + +        for question in questions: +            value = request.form.get(question["id"]) +            answer = {"question": question["id"]} + +            if not question["optional"] and value is None: +                return BadRequest() + +            if question["type"] == "checkbox": +                if value == "on": +                    answer["value"] = True +                elif not question["optional"]: +                    return BadRequest() +                else: +                    answer["value"] = False + +            elif question["type"] == "email": +                if value: +                    address = parseaddr(value) + +                    if address == ("", ""): +                        return BadRequest() + +                answer["value"] = value + +            elif question["type"] in ["number", "range", "slider"]: +                if value is not None: +                    value = int(value) + +                    if value > int(question["data"]["max"]) or value < int(question["data"]["min"]): +                        return BadRequest() + +                answer["value"] = value + +            elif question["type"] == "radio": +                if value: +                    if value not in question["data"]["options"]: +                        return BadRequest() + +                answer["value"] = value + +            elif question["type"] in ["text", "textarea"]: +                answer["value"] = value + +            answers.append(answer) + +        user_id = self.user_data["user_id"] + +        response = { +            "snowflake": user_id, +            "jam": jam, +            "approved": False, +            "answers": answers +        } + +        print(response) +        self.db.insert(self.responses_table, response) +        return self.render("main/jams/thanks.html", jam=jam_obj) + +    def get_response(self, jam, user_id): +        query = self.db.query(self.responses_table).filter({"jam": jam, "snowflake": user_id}) +        result = self.db.run(query, coerce=list) +        print(result) + +        if result: +            return result[0] +        return None + +    def get_infractions(self, user_id): +        query = self.db.query(self.infractions_table).filter({"participant": user_id}) +        return self.db.run(query, coerce=list) diff --git a/pysite/views/main/jams/signup.py b/pysite/views/main/jams/signup.py deleted file mode 100644 index 632da6d6..00000000 --- a/pysite/views/main/jams/signup.py +++ /dev/null @@ -1,9 +0,0 @@ -from pysite.base_route import RouteView - - -class JamsSignupView(RouteView): -    path = "/jams/signup" -    name = "jams.signup" - -    def get(self): -        return self.render("main/jams/signup.html") diff --git a/static/style.css b/static/style.css index 2b9b329c..1f3f9f58 100644 --- a/static/style.css +++ b/static/style.css @@ -179,4 +179,15 @@ select {      left: auto !important;      -webkit-appearance: unset !important;      opacity: 1 !important; +} + +div.danger-input * { +    /*border-radius: 5px;*/ +    /*padding: 0.8rem;*/ +    /*min-height: 3.5rem;*/ +    color: red; +    border-color: red !important; + +    transition: color 0.5s ease, +                border-color 0.5s ease;  }
\ No newline at end of file diff --git a/templates/main/jams/already.html b/templates/main/jams/already.html new file mode 100644 index 00000000..0baaf4a9 --- /dev/null +++ b/templates/main/jams/already.html @@ -0,0 +1,26 @@ +{% extends "main/base.html" %} +{% block title %}Code Jams | Banned{% endblock %} +{% block og_title %}Code Jams | Banned{% endblock %} + +{% block content %} +<div class="uk-section"> +    <div class="uk-container uk-container-small"> +        <h1 class="uk-header uk-article-title"> +            Code Jam {{ jam.number }}: {{ jam.title }} +        </h1> +        <p class="uk-article-meta"> +            Bring the thunder! +        </p> + +        <p class="uk-alert uk-alert-danger"> +            Thanks for your interest in this code jam! It looks like we already have an application here for you, +            so please just sit back, relax, and we'll let you know whether you've been selected for this code +            jam when the time comes. +        </p> + +        <a class="uk-button uk-button-secondary uk-align-center" href="{{ url_for("main.jams.index") }}"> +            <i class="uk-icon fa-fw far fa-arrow-left"></i>  Back to all code jams +        </a> +    </div> +</div> +{% endblock %} diff --git a/templates/main/jams/banned.html b/templates/main/jams/banned.html new file mode 100644 index 00000000..adc82fef --- /dev/null +++ b/templates/main/jams/banned.html @@ -0,0 +1,44 @@ +{% extends "main/base.html" %} +{% block title %}Code Jams | Banned{% endblock %} +{% block og_title %}Code Jams | Banned{% endblock %} + +{% block content %} +<div class="uk-section"> +    <div class="uk-container uk-container-small"> +        <h1 class="uk-header uk-article-title"> +            Code Jam {{ jam.number }}: {{ jam.title }} +        </h1> +        <p class="uk-article-meta"> +            Bring the thunder! +        </p> + +        {% if infraction.number == -1 %} +            <p class="uk-alert uk-alert-danger"> +                Thanks for your interest in this code jam! Unfortunately, due to your previous actions, you have been +                permanently banned from participating in our code jams. +                <br /> +                <br /> +                The reason given is: <span style="font-family: monospace">{{ infraction.reason }}</span> +                <br /> +                <br /> +                If you feel that this is a mistake, please feel free to contact one of the admins on Discord. +            </p> +        {% else %} +            <p class="uk-alert uk-alert-danger"> +                Thanks for your interest in this code jam! Unfortunately, due to your previous actions, you have been +                temporarily banned from participating in our code jams. +                <br /> +                <br /> +                The reason given is: <span style="font-family: monospace">{{ infraction.reason }}</span> +                <br /> +                <br /> +                If you feel that this is a mistake, please feel free to contact one of the admins on Discord. +            </p> +        {% endif + +        <a class="uk-button uk-button-secondary uk-align-center" href="{{ url_for("main.jams.index") }}"> +            <i class="uk-icon fa-fw far fa-arrow-left"></i>  Back to all code jams +        </a> +    </div> +</div> +{% endblock %} diff --git a/templates/main/jams/index.html b/templates/main/jams/index.html index a5d2a5d0..71bce999 100644 --- a/templates/main/jams/index.html +++ b/templates/main/jams/index.html @@ -61,7 +61,7 @@                          Code Jam {{ jam.number }}: {{ jam.title }}                          <span class="uk-float-right">                              {% if jam.state == "announced" %} -                                <a class="uk-button uk-button-primary" target="_blank" href="{{ jam.repo }}"> +                                <a class="uk-button uk-button-primary" href="{{ url_for("main.jams.join", jam=jam.number) }}">                                      <i class="uk-icon fa-fw far fa-plus"></i>  Join                                  </a>                              {% else %} diff --git a/templates/main/jams/join.html b/templates/main/jams/join.html new file mode 100644 index 00000000..ffa80cb5 --- /dev/null +++ b/templates/main/jams/join.html @@ -0,0 +1,357 @@ +{% extends "main/base.html" %} +{% block title %}Code Jams | Join{% endblock %} +{% block og_title %}Code Jams | Join{% endblock %} + +{% macro show_question(question) %} +    <div id="div-{{ question.id }}"> +        <div class="uk-form-label"> +            {% if question.optional %} +                <label class="uk-form-label" style="margin-top: 0" for="{{ question.id }}"> +                    <strong>{{ question.title }}</strong> +                    <br /> +                    <span class="uk-text-meta">You may skip this question</span> +                </label> +            {% else %} +                <label class="uk-form-label" style="margin-top: 0" for="{{ question.id }}"> +                    <strong>{{ question.title }}</strong> +                    <br /> +                    <span class="uk-text-meta">This question is required</span> +                </label> +            {% endif %} +        </div> +        <div class="uk-form-controls uk-form-controls-text"> +            {% if question.type == "checkbox" %} +                {% if question.optional %} +                    <input class="uk-checkbox" type="checkbox" name="{{ question.id }}" id="{{ question.id }}"> +                    <label for="{{ question.id }}" style="padding-left: 0.7rem;">Confirm</label> +                {% else %} +                    <input class="uk-checkbox" type="checkbox" name="{{ question.id }}" id="{{ question.id }}" required> +                    <label for="{{ question.id }}" style="padding-left: 0.7rem;">Confirm</label> +                {% endif %} + +            {% elif question.type == "email" %} +                {% if question.optional %} +                    <input class="uk-input" type="email" name="{{ question.id }}" id="{{ question.id }}" placeholder="[email protected]"> +                {% else %} +                    <input class="uk-input" type="email" name="{{ question.id }}" id="{{ question.id }}" placeholder="[email protected]" required> +                {% endif %} + +            {% elif question.type == "number" %} +                {% if question.optional %} +                    <input class="uk-input" type="number" max="{{ question.data.max }}" min="{{ question.data.min }}" name="{{ question.id }}" id="{{ question.id }}" value="{{ question.data.min }}"> +                {% else %} +                    <input class="uk-input" type="number" max="{{ question.data.max }}" min="{{ question.data.min }}" name="{{ question.id }}" id="{{ question.id }}" value="{{ question.data.min }}" required> +                {% endif %} + +            {% elif question.type == "radio" %} +                {% if question.optional %} +                    {% for option in question.data.options %} +                        <input class="uk-radio radio-{{ question.id }}" type="radio" name="{{ question.id }}" id="{{ question.id }}-{{ option }}" value="{{ option }}"> +                        <label style="padding-left: 0.7rem; padding-right: 1rem;" for="{{ question.id }}-{{ option }}">{{ option }}</label> +                    {% endfor %} +                {% else %} +                    {% for option in question.data.options %} +                        <input class="uk-radio radio-{{ question.id }}" type="radio" name="{{ question.id }}" id="{{ question.id }}-{{ option }}" value="{{ option }}" required> +                        <label style="padding-left: 0.7rem; padding-right: 1rem;" for="{{ question.id }}-{{ option }}">{{ option }}</label> +                    {% endfor %} +                {% endif %} + +            {% elif question.type == "range" %} +                <div class="uk-flex uk-flex-between"> +                    {% if question.optional %} +                        {% for num in range(question.data.min, question.data.max + 1) %} +                            <span> +                                <input class="uk-radio radio-{{ question.id }}" type="radio" name="{{ question.id }}" id="{{ question.id }}-{{ num }}" value="{{ num }}"> +                                <label style="padding-left: 0.3rem;" for="{{ question.id }}-{{ num }}">{{ num }}</label> +                            </span> +                        {% endfor %} +                    {% else %} +                        {% for num in range(question.data.min, question.data.max + 1) %} +                            <span> +                                <input class="uk-radio radio-{{ question.id }}" type="radio" name="{{ question.id }}" id="{{ question.id }}-{{ num }}" value="{{ num }}" required> +                                <label style="padding-left: 0.3rem;" for="{{ question.id }}-{{ num }}">{{ num }}</label> +                            </span> +                        {% endfor %} +                    {% endif %} +                </div> + +            {% elif question.type == "text" %} +                {% if question.optional %} +                    <input class="uk-input" type="text" name="{{ question.id }}" id="{{ question.id }}"> +                {% else %} +                    <input class="uk-input" type="text" name="{{ question.id }}" id="{{ question.id }}" required> +                {% endif %} + +            {% elif question.type == "textarea" %} +                {% if question.optional %} +                    <textarea class="uk-input uk-textarea" name="{{ question.id }}" id="{{ question.id }}" style="resize: vertical; min-height: 15rem; font-family: monospace;"></textarea> +                {% else %} +                    <textarea class="uk-input uk-textarea" name="{{ question.id }}" id="{{ question.id }}" style="resize: vertical; min-height: 15rem; font-family: monospace;" required></textarea> +                {% endif %} + +            {% elif question.type == "slider" %} +                <div class="uk-flex uk-flex-between"> +                    <label class="uk-label" style="margin-right: 1rem;" for="{{ question.id }}" id="{{ question.id }}-slider-value">{{ question.data.min }}</label> +                    <input class="uk-range range-slider" name="{{ question.id }}" id="{{ question.id }}" min="{{ question.data.min }}" max="{{ question.data.max }}" step="1" value="{{ question.data.min }}" type="range"> +                </div> + +            {% endif %} +        </div> +    </div> +{% endmacro %} + +{% block content %} +<div class="uk-section"> +    <div class="uk-container uk-container-small"> +        <h1 class="uk-header uk-article-title"> +            Code Jam {{ jam.number }}: {{ jam.title }} +        </h1> +        <p class="uk-article-meta"> +            Bring the thunder! +        </p> +        <p> +            Please fill out the form below to apply for this code jam. Once you've submitted your application and the +            application window has closed, we'll review it and let you know whether you've been entered! +        </p> +        <p> +            Please note that you will not be able to edit your application after you've submitted it. +        </p> +        <hr class="uk-divider-icon" /> + +        {% if jam.state != "announced" %} +            <p class="uk-alert uk-alert-primary"> +                Unfortunately, we're not accepting applications for this code jam right now - but we appreciate your +                interest. Keep an eye on <code>#announcements</code> on Discord for information on the next jam! +            </p> +        {% else %} +            <form action="{{ url_for("main.jams.join", jam=jam.number) }}" method="post" class="uk-form-horizontal"> +                {% for question in questions %} +                    {{ show_question(question) }} +                    <br /> +                {% endfor %} +                <br /> + +                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> + +                <div class="uk-text-center"> +                    <a class="uk-button uk-button-default" href="{{ url_for("main.jams.index") }}"> +                        <i class="uk-icon fa-fw far fa-arrow-left"></i>  Back +                    </a> +                    <button type="submit" class="uk-button uk-button-primary" name="submit" id="submit" disabled> +                        <i class="uk-icon fa-fw far fa-check"></i>  Apply +                    </button> +                </div> +            </form> + +        {% endif %} +    </div> +</div> + +<script type="application/javascript"> +    "use strict"; + +    // noinspection JSAnnotator (It thinks I'm not assigning this for some reason) +    const questions = {{ questions | tojson }}; +    const button = document.getElementById("submit"); + +    function validateEmail(email) { +        let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; +        return re.test(String(email).toLowerCase()); +    } + +    function isNum(value) { +        return !isNaN(parseInt(value)); +    } + +    function checkInputs() { +        let input, inputs, div; +        let disabled = false; + +        for (let question of questions) { +            div = document.getElementById("div-" + question.id); + +            switch (question.type) { +                case "checkbox": +                    if (!question.optional) { +                        let input = document.getElementById(question.id); + +                        if (!input.checked) { +                            disabled = true; +                            div.classList.add("danger-input"); +                        } else { +                            div.classList.remove("danger-input"); +                        } +                    } +                    break; +                case "email": +                    input = document.getElementById(question.id); + +                    if (!question.optional || input.value.length > 0) { +                        if (input.value.length < 5 || !validateEmail(input.value)) { +                            disabled = true; +                            div.classList.add("danger-input"); +                        } else { +                            div.classList.remove("danger-input"); +                        } +                    } else { +                        div.classList.remove("danger-input"); +                    } +                    break; +                case "number": +                    input = document.getElementById(question.id); + +                    if (!question.optional || input.value.length > 0) { +                        if (input.value.length < 1 || !isNum(input.value)) { +                            disabled = true; +                            div.classList.add("danger-input"); +                        } else { +                            let val = parseInt(input.value); + +                            if (val < question.data.min || val > question.data.max) { +                                disabled = true; +                                div.classList.add("danger-input"); +                            } else { +                                div.classList.remove("danger-input"); +                            } +                        } +                    } +                    break; +                case "radio": +                    if (! question.optional) { +                        inputs = document.getElementsByClassName("radio-" + question.id); +                        let selected = null; + +                        for (let inner of inputs) { +                            if (inner.checked) { +                                selected = inner; +                            } +                        } + +                        if (selected === null) { +                            disabled = true; +                            div.classList.add("danger-input"); +                        } else { +                            div.classList.remove("danger-input"); +                        } +                    } + +                    break; +                case "range": +                    if (! question.optional) { +                        inputs = document.getElementsByClassName("radio-" + question.id); +                        let selected = null; + +                        for (let inner of inputs) { +                            if (inner.checked) { +                                selected = inner; +                            } +                        } + +                        if (selected === null) { +                            disabled = true; + +                            div.classList.add("danger-input"); +                        } else { +                            div.classList.remove("danger-input"); +                        } +                    } + +                    break; +                case "text": +                    if (!question.optional) { +                        input = document.getElementById(question.id); + +                        if (input.value.length < 1) { +                            disabled = true; +                            div.classList.add("danger-input"); +                        } else { +                            div.classList.remove("danger-input"); +                        } +                    } + +                    break; +                case "textarea": +                    if (!question.optional) { +                        input = document.getElementById(question.id); + +                        if (input.value.length < 1) { +                            disabled = true; +                            div.classList.add("danger-input"); +                        } else { +                            div.classList.remove("danger-input"); +                        } +                    } + +                    break; +                case "slider": +                    break; +            } +        } + +        button.disabled = disabled; +    } + +    function setUpChecks() { +        let input, inputs, label; + +        for (let question of questions) { +            switch (question.type) { +                case "checkbox": +                    input = document.getElementById(question.id); +                    input.onchange = checkInputs; + +                    break; +                case "email": +                    input = document.getElementById(question.id); +                    input.oninput = checkInputs; + +                    break; +                case "number": +                    input = document.getElementById(question.id); +                    input.oninput = checkInputs; +                    input.onchange = checkInputs; + +                    break; +                case "radio": +                    inputs = document.getElementsByClassName("radio-" + question.id); + +                    for (let inner of inputs) { +                        inner.onchange = checkInputs; +                    } + +                    break; +                case "range": +                    inputs = document.getElementsByClassName("radio-" + question.id); + +                    for (let inner of inputs) { +                        inner.onchange = checkInputs; +                    } + +                    break; +                case "text": +                    input = document.getElementById(question.id); +                    input.oninput = checkInputs; + +                    break; +                case "textarea": +                    input = document.getElementById(question.id); +                    input.oninput = checkInputs; + +                    break; +                case "slider": +                    input = document.getElementById(question.id); +                    label = document.getElementById(question.id + "-slider-value"); + +                    input.oninput = function() { +                        label.textContent = this.value; +                        checkInputs(); +                    }; +                    break; +            } +        } +    } + +    setUpChecks(); +    checkInputs(); +</script> +{% endblock %} diff --git a/templates/main/jams/signup.html b/templates/main/jams/signup.html deleted file mode 100644 index ddb48733..00000000 --- a/templates/main/jams/signup.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "main/base.html" %} -{% block title %}Home{% endblock %} -{% block og_title %}Home{% endblock %} -{% block content %} -<div class="uk-section"> -    <div class="uk-container uk-container-small uk-text-center"> -        <h1 class="uk-header"> -            Sign Up -        </h1> -        <p class="uk-article-meta"> -            # TODO -        </p> -    </div> -</div> -{% endblock %} diff --git a/templates/main/jams/thanks.html b/templates/main/jams/thanks.html new file mode 100644 index 00000000..e6709485 --- /dev/null +++ b/templates/main/jams/thanks.html @@ -0,0 +1,25 @@ +{% extends "main/base.html" %} +{% block title %}Code Jams | Banned{% endblock %} +{% block og_title %}Code Jams | Banned{% endblock %} + +{% block content %} +<div class="uk-section"> +    <div class="uk-container uk-container-small"> +        <h1 class="uk-header uk-article-title"> +            Code Jam {{ jam.number }}: {{ jam.title }} +        </h1> +        <p class="uk-article-meta"> +            Bring the thunder! +        </p> + +        <p class="uk-alert uk-alert-success"> +            Thanks for your application! Just sit back, relax, and we'll let you know whether you've been selected +            for this code jam when the time comes. +        </p> + +        <a class="uk-button uk-button-secondary uk-align-center" href="{{ url_for("main.jams.index") }}"> +            <i class="uk-icon fa-fw far fa-arrow-left"></i>  Back to all code jams +        </a> +    </div> +</div> +{% endblock %} diff --git a/templates/main/navigation.html b/templates/main/navigation.html index 391bbcf5..4e2ed369 100644 --- a/templates/main/navigation.html +++ b/templates/main/navigation.html @@ -107,12 +107,6 @@                                  <li><a href="{{ url_for('main.jams.index') }}">Info</a></li>                              {% endif %} -                            {% if current_page == "main.jams.signup" %} -                                <li class="uk-active"><a href="{{ url_for('main.jams.signup') }}">Sign Up</a></li> -                            {% else %} -                                <li><a href="{{ url_for('main.jams.signup') }}">Sign Up</a></li> -                            {% endif %} -                              <li class="uk-nav-divider"></li>                              {% if current_page.startswith("main.about.privacy") %} | 
