UI rewrite #25

Merged
Muirrum merged 9 commits from rewrite into master 2024-03-17 18:01:16 -04:00
29 changed files with 458 additions and 1247 deletions

View file

@ -5,15 +5,20 @@ from flask_login import LoginManager
from flask_assets import Bundle, Environment
from flask_cors import CORS
from flask_mail import Mail, email_dispatched
from flask_bootstrap import Bootstrap5
from flask_font_awesome import FontAwesome
from flask_qrcode import QRcode
db = SQLAlchemy()
migrate = Migrate()
login = LoginManager()
environment = Environment()
cors = CORS()
mail = Mail()
bootstrap = Bootstrap5()
font_awesome = FontAwesome()
qrcode = QRcode()
def create_app():
@ -27,7 +32,9 @@ def create_app():
environment.init_app(app)
cors.init_app(app)
mail.init_app(app)
bootstrap.init_app(app)
qrcode.init_app(app)
font_awesome.init_app(app)
scss = Bundle('css/style.scss', filters='scss',
output='css/style.css')

View file

@ -1,4 +1,4 @@
from flask import Blueprint, jsonify, redirect, render_template, request, url_for
from flask import Blueprint, current_app, jsonify, redirect, render_template, request, url_for
from flask_login import current_user, login_required
from flask_mail import Message
@ -62,8 +62,20 @@ def mail():
return redirect(url_for("dashboard.home"))
total_count = len(db.session.execute(db.select(User)).scalars().all())
api_key = current_app.config["MCE_API_KEY"]
return render_template("mail.html", NUM_HACKERS=total_count)
return render_template("mail.html", NUM_HACKERS=total_count,
MCE_API_KEY=api_key)
@bp.route("/users")
@login_required
def users():
if not current_user.is_admin:
return redirect(url_for("dashboard.home"))
users = User.query.all()
return render_template("users.html", users=users)
@bp.route("/send", methods=["POST"])
@login_required

View file

@ -19,6 +19,8 @@ def home():
current_user.accomodations = request.form.get('accomodations')
db.session.commit()
flash("Updated successfully")
else:
form = forms.ShirtAndAccomForm(obj=current_user)
return render_template("dashboard.html", form=form, resform=resform)
@bp.route("/resume", methods=["POST"])

View file

@ -1,16 +1,19 @@
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileRequired, FileAllowed
from wtforms import RadioField, TextAreaField
from wtforms import SelectField, TextAreaField, SubmitField
from wtforms.validators import DataRequired
class ShirtAndAccomForm(FlaskForm):
shirt_size = RadioField("Shirt size", choices=["XS", "S", "M", "L", "XL",
shirt_size = SelectField("Shirt size", choices=["XS", "S", "M", "L", "XL",
"None"],
validators=[DataRequired()])
accomodations = TextAreaField("Special needs and/or Accomodations")
submit = SubmitField("Save")
class ResumeForm(FlaskForm):
resume = FileField("Resume", validators=[FileRequired(),
FileAllowed(['pdf', 'docx', 'doc',
'txt', 'rtf'],
"Documents only!")])
submit = SubmitField("Submit")

View file

@ -1,7 +1,7 @@
from datetime import datetime, timedelta
from flask import Blueprint, abort, config, current_app, flash, redirect, render_template, request, url_for
import flask_login
from flask_login import current_user
from flask_login import current_user, login_required
from goathacks.registration.forms import LoginForm, PwResetForm, RegisterForm, ResetForm
from werkzeug.security import check_password_hash, generate_password_hash
from flask_mail import Message
@ -97,6 +97,13 @@ def login():
return render_template("login.html", form=form)
@bp.route("/logout")
@login_required
def logout():
flask_login.logout_user()
flash("See you later!")
return redirect(url_for("registration.login"))
@bp.route("/reset", methods=["GET", "POST"])
def reset():
form = ResetForm(request.form)

View file

@ -1,185 +1,18 @@
@font-face {
font-family: "Krungthep";
src: url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.eot");
src: url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.eot?#iefix") format("embedded-opentype"), url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.woff2") format("woff2"), url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.woff") format("woff"), url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.ttf") format("truetype"), url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.svg#Krungthep") format("svg");
.navbar-dark, .modal-header, .table-header {
background-color: #974355;
color: #FFFFFF;
}
html {
height: 100%;
.modal-header, .table-header {
color: #FFFFFF;
}
.container {
min-height: 100vh;
position: relative;
}
body {
min-height: 100vh;
background-color: #003049;
font-family: 'Montserrat', sans-serif;
font-size: 1.1rem;
color: #eee;
position: relative;
min-height: 100%;
}
p {
line-height: 2rem;
}
#logo-container {
display: flex;
justify-content: center;
flex-direction: row;
padding-top: 5px;
padding-bottom: 5px;
height: 100%;
width: 100%;
}
#goat {
height: 100%;
}
.button-collapse {
color: #26a69a;
}
.parallax-container {
min-height: 380px;
line-height: 0;
height: auto;
color: rgba(255, 255, 255, 0.9);
}
.parallax-container .section {
width: 100%;
}
label {
color: white !important;
}
@media only screen and (max-width: 992px) {
.parallax-container .section {
top: 40%;
}
#index-banner .section {
top: 10%;
}
}
@media only screen and (max-width: 600px) {
.parallax-container .section {
height: auto;
overflow: auto;
}
.container {
height: auto;
}
#index-banner .section {
top: 0;
}
}
#tagline {
font-weight: 600;
}
#event-info {
font-weight: 400;
}
#registration-banner {
min-height: 100px;
max-height: 150px;
}
#registration-banner .section {
top: auto;
}
.icon-block {
padding: 0 15px;
}
.icon-block .material-icons {
font-size: inherit;
}
.parallax img {
display: inherit;
max-width: 200%;
}
#mlh-trust-badge {
display: block;
max-width: 100px;
min-width: 60px;
position: fixed;
right: 50px;
top: 0;
width: 10%;
z-index: 10000;
}
nav {
line-height: normal !important;
font-family: "Jost", sans-serif;
font-weight: 700;
}
/*
.navbar-brand {
} */
.footer-nav {
position: absolute;
bottom: 0;
width: 100%;
}
label {
padding-bottom: 0.5rem;
}
form input {
border-radius: 5px;
}
form input[type="submit"] {
background: #26a69a;
border-radius: 10px;
border-color: #26a69a;
}
form input[type="radio"] {
padding-right: 5px;
}
form input[type="checkbox"]:checked {
visibility: visible;
left: unset;
position: unset;
}
form label {
font-size: 1.1rem;
padding-right: 10px;
padding-left: 25px !important;
}
form select {
display: unset;
background: #974355;
max-width: 11rem;
}
.flashes {
list-style-type: none;
display: flex;
justify-content: center;
}
.message {
width: 80%;
justify-content: center;
border: 1px solid #eee;
background-color: #26a69a;
padding: 0.2rem;
font-size: large;
color: #eee;
}

View file

@ -1,184 +1,21 @@
$color-nav-bg: #974355;
$color-bg: #003049;
$color-fg: #eee;
$color-section-bg: #974355;
$color-accent: #26a69a;
@font-face {font-family: "Krungthep"; src: url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.eot"); src: url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.eot?#iefix") format("embedded-opentype"), url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.woff2") format("woff2"), url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.woff") format("woff"), url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.ttf") format("truetype"), url("//db.onlinewebfonts.com/t/736cf5b08b01082a3645e14038868e20.svg#Krungthep") format("svg"); }
html {
height: 100%;
.navbar-dark, .modal-header, .table-header {
background-color: $color-nav-bg;
color: #FFFFFF;
}
.modal-header, .table-header {
color: #FFFFFF;
}
.container {
min-height: 100vh;
position: relative;
}
body {
min-height: 100vh;
background-color: $color-bg;
font-family: 'Montserrat', sans-serif;
font-size: 1.1rem;
color: $color-fg;
position: relative;
min-height: 100%;
}
p {
line-height: 2rem;
}
#logo-container {
display: flex;
justify-content: center;
flex-direction: row;
padding-top: 5px;
padding-bottom: 5px;
height: 100%;
width: 100%;
}
#goat {
height: 100%;
}
.button-collapse {
color: $color-accent;
}
.parallax-container {
min-height: 380px;
line-height: 0;
height: auto;
color: rgba(255,255,255,.9);
}
.parallax-container .section {
width: 100%;
}
label {
color: white !important;
}
@media only screen and (max-width : 992px) {
.parallax-container .section {
top: 40%;
}
#index-banner .section {
top: 10%;
}
}
@media only screen and (max-width : 600px) {
.parallax-container .section {
height: auto;
overflow: auto;
}
.container {
height: auto;
}
#index-banner .section {
top: 0;
}
}
#tagline {
font-weight: 600;
}
#event-info {
font-weight: 400;
}
#registration-banner {
min-height: 100px;
max-height: 150px;
}
#registration-banner .section{
top: auto;
}
.icon-block {
padding: 0 15px;
}
.icon-block .material-icons {
font-size: inherit;
}
.parallax img {
display: inherit;
max-width: 200%;
}
#mlh-trust-badge {
display: block;
max-width: 100px;
min-width: 60px;
position: fixed;
right: 50px;
top: 0;
width: 10%;
z-index: 10000;
}
nav {
line-height: normal !important;
font-family: "Jost", sans-serif;
font-weight: 700;
}
/*
.navbar-brand {
} */
.footer-nav {
position: absolute;
bottom: 0;
width: 100%;
}
// Forms
label {
padding-bottom: 0.5rem;
}
form {
input {
border-radius: 5px;
}
input[type="submit"] {
background: $color-accent;
border-radius: 10px;
border-color: $color-accent;
}
input[type="radio"] {
padding-right: 5px;
}
input[type="checkbox"]:checked {
visibility: visible;
left: unset;
position: unset;
}
label {
font-size: 1.1rem;
padding-right: 10px;
padding-left: 25px !important;
}
select {
display: unset;
background: $color-section-bg;
max-width: 11rem;
}
}
// Flashed messages
.flashes {
list-style-type: none;
display: flex;
justify-content: center;
}
.message {
width: 80%;
justify-content: center;
border: 1px solid $color-fg;
background-color: $color-accent;
padding: 0.2rem;
font-size: large;
color: $color-fg;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View file

@ -0,0 +1,38 @@
{% extends 'layout.html' %}
{% block navbar %}
<nav class="navbar navbar-dark mb-4 navbar-expand-lg">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="true"
aria-label="Toggle
navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-header">
<a class="navbar-brand" href="{{ url_for('admin.home') }}">
<img src="{{url_for('static', filename='img/logo.png')}}"
alt="Logo" width="35" height="35" class="d-inline-block
align-text-middle mx-2">GoatHacks Admin</a>
</div>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="nav navbar-nav me-auto mb-2 mb-lg-0">
{{ render_nav_item('admin.home', 'User List')}}
{{ render_nav_item('admin.list_events', 'Event List')}}
{{ render_nav_item('admin.mail', 'Bulk Mail Tool')}}
</ul>
<ul class="nav navbar-nav">
{% if current_user.is_authenticated %}
{{ render_nav_item('dashboard.home', '<- Back To Site') }}
{{ render_nav_item('registration.logout', 'Logout') }}
{% else %}
{{ render_nav_item('registration.register', 'Registration') }}
{{ render_nav_item('registration.login', 'Login') }}
{% endif %}
</ul>
</div>
</div>
</nav>
{% endblock %}

View file

@ -1,213 +1,29 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hack @ WPI</title>
<link rel="icon" href="../static/favicon.png" type="image/png">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://opensource.keycdn.com/fontawesome/4.7.0/font-awesome.min.css" integrity="sha384-dNpIIXE8U05kAbPhy3G1cz+yZmTzA6CY8Vg/u2L9xRnHjJiAK76m2BIEaSEV+/aU" crossorigin="anonymous">
<!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script><![endif]--><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
{% extends 'admin-layout.html' %}
{% block head %}
{{super()}}
<script src="http://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>
<script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.4.3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="{{url_for('static', filename='js/admin.js')}}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
</head>
{% endblock %}
<style>
.table-striped > tbody > tr:nth-of-type(odd) {
background-color: rgba(255, 255, 255, 0.15);
}
.table-hover > tbody > tr:hover {
background-color: rgba(255, 255, 255, 0.25);
}
table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sorttable_nosort):after {
content: " \25B4\25BE"
}
canvas {
max-width: 500px;
max-height: 500px;
}
</style>
<div class="contact-section" style="height: auto; background-repeat: repeat; background-size: contain;">
<div class="container-fluid" style="margin-left: 3%; margin-right: 3%;">
<div class="row" style="margin-top: 10%;">
<h5>JSON object of users from MLH (Including dropped applications):</h5>
<p><a href="{{ mlh_url }}"><b>Do NOT share this URL.</b></a></p>
<h5>Get registered hackers only:</h5>
<p><a href="{{url_for('admin.hackers')}}">JSON</a> <a
href="{{url_for('admin.hackers_csv')}}">CSV</a></p>
</div>
<div class="row">
<div class="col-md-4">
<h2 style="">Gender:</h2>
<canvas id="genderCanvas" width="400" height="400"></canvas>
<script>
let genderCtx = document.getElementById('genderCanvas')
let genderChart = new Chart(genderCtx, {
type: 'doughnut',
data: {
labels: ['Female', 'Male', 'Non-Binary/Other'],
datasets: [
{
data: [{{ female_count }}, {{ male_count }}, {{ nb_count }}]
}
]
},
options: {
title: {
display: false
},
legend: {
display: false
},
labels: {
display: false
}
}
})
</script>
</div>
<div class="col-md-4">
<h2 style="">Schools:</h2>
<canvas id="schoolCanvas" width="400" height="400"></canvas>
<script>
let schoolNames = []
let schoolNums = []
{% for school in schools %}
schoolNames.push('{{ school }}')
schoolNums.push({{ schools[school] }})
{% endfor %}
let schoolCtx = document.getElementById('schoolCanvas')
let schoolChart = new Chart(schoolCtx, {
type: 'doughnut',
data: {
labels: schoolNames,
datasets: [
{
data: schoolNums
}
]
},
options: {
title: {
display: false
},
legend: {
display: false
},
labels: {
display: false
}
}
})
</script>
</div>
<div class="col-md-4">
<h2 style="">Majors:</h2>
<canvas id="majorCanvas" width="400" height="400"></canvas>
<script>
let majorNames = []
let majorNums = []
{% for major in majors %}
majorNames.push('{{ major }}')
majorNums.push({{ majors[major] }})
{% endfor %}
let majorCtx = document.getElementById('majorCanvas')
let majorChart = new Chart(majorCtx, {
type: 'doughnut',
data: {
labels: majorNames,
datasets: [
{
data: majorNums
}
]
},
options: {
title: {
display: false
},
legend: {
display: false
},
labels: {
display: false
}
}
})
</script>
</div>
</div>
<div class="row" style="">
<h2 style="">Counts:</h2>
<table id="counts" class="table table-striped table-hover table-condensed sortable">
<thead>
<tr>
<th>Total</th>
<th>Attendees</th>
<th>Waitlist</th>
<th>Checked In</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ total_count }}</td>
<td>{{ (total_count - waitlist_count) }}</td>
<td>{{ waitlist_count }}</td>
<td>{{ check_in_count }}</td>
</tr>
</tbody>
</table>
<h2 style="margin-top: 2%;">Shirts:</h2>
<table id="shirts" class="table table-striped table-hover table-condensed sortable">
<thead>
<tr>
<th>XXS</th>
<th>XS</th>
<th>S</th>
<th>M</th>
<th>L</th>
<th>XL</th>
<th>XXL</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ shirt_count['XXS'] }}</td>
<td>{{ shirt_count['XS'] }}</td>
<td>{{ shirt_count['S'] }}</td>
<td>{{ shirt_count['M'] }}</td>
<td>{{ shirt_count['L'] }}</td>
<td>{{ shirt_count['XL'] }}</td>
<td>{{ shirt_count['XXL'] }}</td>
</tr>
</tbody>
</table>
<h2 style="margin-top: 2%;">Hackers:</h2>
<table id="hackers" class="table table-striped table-hover table-condensed sortable">
{% block app_content %}
<div class="card text-center">
<div class="card-body">
<h1 class="h3 mb-3 fw-normal">Registered Users</h1>
<table id="hackers" class="table table-striped">
<thead>
<tr>
<th>Options</th>
<th>Checked In?</th>
<th>Waitlisted?</th>
<th>Admin</th>
<th>MLH ID</th>
<th>Time Registered</th>
<th>User ID</th>
<th>Registration Time</th>
<th>Email</th>
<th>Name</th>
<th>Phone</th>
@ -220,61 +36,59 @@
{% for hacker in hackers %}
<tr id="{{hacker.id}}-row">
<td>
<div class="btn-group">
<a href="#" class="btn btn-primary dropdown-toggle" data-toggle="dropdown"><span
<div class="dropdown">
<a href="#" class="btn btn-primary dropdown-toggle"
data-bs-toggle="dropdown"><span
class="caret"></span></a>
<ul class="dropdown-menu">
{% if not hacker.checked_in %}
<li><a class="check_in" id="{{ hacker.id }}-check_in" href="#">Check In</a>
</li>
<li><a class="dropdown-item check_in" id="{{
hacker.id}}-check_in"
href="#">Check
In</a></li>
{% endif %}
{% if hacker.waitlisted and not hacker.checked_in %}
<li><a class="promote_from_waitlist"
id="{{ hacker['id'] }}-promote_from_waitlist"
href="#">Promote From Waitlist</a></li>
{% if hacker.waitlisted and not
hacker.checked_in %}
<li><a class="dropdown-item
promote_from_waitlist" id="{{
hacker.id}}-promote_from_waitlist"
href="#">Promote From
Waitlist</a></li>
{% endif %}
<li class="divider"></li>
<li><hr class="dropdown-divider"></li>
{% if not hacker.checked_in %}
<li><a class="drop" id="{{ hacker['id'] }}-drop" href="#">Drop Application</a>
</li>
<li><a class="dropdown-item drop"
id="{{hacker.id}}-drop"
href="#">Drop Registration</a></li>
{% endif %}
{% if hacker.is_admin %}
<li><a class="demote_admin" id="{{ hacker['id'] }}-demote_admin" href="#">Demote
Admin</a>
</li>
<li><a class="dropdown-item demote_admin"
id="{{hacker.id}}-demote_admin"
href="#">Demote Admin</a></li>
{% else %}
<li><a class="promote_admin" id="{{ hacker['id'] }}-promote_admin" href="#">Promote
Admin</a>
</li>
<li><a class="dropdown-item promote_admin"
id="{{hacker.id}}-promote_admin"
href="#">Promote Admin</a></li>
{% endif %}
</ul>
</div>
</td>
<td id="{{ hacker['id'] }}-checked_in">{{ hacker['checked_in'] }}</td>
<td id="{{ hacker['id'] }}-waitlisted">{{ hacker['waitlisted'] }}</td>
<td id="{{hacker.id}}-checked_in">{{ hacker.checked_in }}</td>
<td id="{{hacker.id}}-waitlisted">{{ hacker.waitlisted }}</td>
<td>{{ hacker.is_admin }}</td>
<td>{{ hacker['id'] }}</td>
<td>{{ hacker['last_login'] }}</td>
<td>{{ hacker['email'] }}</td>
<td>{{ hacker['first_name'] + ' ' + hacker['last_name'] }}</td>
<td>{{ hacker['phone'] }}</td>
<td>{{ hacker['shirt_size'] }}</td>
<td>{{ hacker['accomodations'] }}</td>
<td>{{ hacker['school'] }}</td>
<td>{{ hacker.id }}</td>
<td>{{ hacker.last_login }}</td>
<td>{{ hacker.email }}</td>
<td>{{ hacker.first_name + ' ' + hacker.last_name }}</td>
<td>{{ hacker.phone }}</td>
<td>{{ hacker.shirt_size }}</td>
<td>{{ hacker.accomodations }}</td>
<td>{{ hacker.school }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
<script>
$(document).ready(() => {
setTimeout('let myTh = document.getElementsByTagName("th")[14]; sorttable.innerSortFunction.apply(myTh, []); sorttable.innerSortFunction.apply(myTh, []);', 50)
})
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="../static/js/jquery.easing.min.js"></script>
</body>
</html>

View file

@ -1,20 +0,0 @@
{% include 'header.html' %}
<div class="container">
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class="flashed-content">
{% for m in messages %}
<li class="message">{{ m }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block content %}
This content block is still being worked on!
{% endblock %}
</div>
{% include 'footer.html' %}

View file

@ -0,0 +1,44 @@
{% from 'bootstrap5/nav.html' import render_nav_item %}
{% from 'bootstrap5/utils.html' import render_messages %}
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
{% if title %}
<title>{{ title }} - GoatHacks</title>
{% else %}
<title>GoatHacks</title>
{% endif %}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% block styles %}
<!-- Bootstrap CSS -->
{{ bootstrap.load_css() }}
{% endblock %}
{% endblock %}
</head>
<body>
<!-- Your page content -->
{% block navbar %}{% endblock %}
<!-- Your page content -->
<div class="container">
<div id="outerAlerts">
{{ render_messages(container=False, dismissible=True, dismiss_animate=True) }}
</div>
{% block app_content %}{% endblock %}
</div>
{% block scripts %}
<!-- Optional JavaScript -->
{{ bootstrap.load_js() }}
{% endblock %}
</body>
</html>

View file

@ -1,104 +1,50 @@
{% extends 'base.html' %}
{% extends 'layout.html' %}
{% from 'bootstrap5/form.html' import render_field %}
{% block content %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
<script>
function drop(id) {
if(window.confirm("Are you sure you wish to drop your application? This cannot be undone. (patiently wait after clicking the button)")) {
window.location.href = "/admin/drop/" + id;
}
}
function resumeChange() {
let val = document.getElementById('resume').value;
val = val.split(/\\|\//gi).slice(-1)[0]
document.getElementById('filename').setAttribute('value', val);
}
</script>
<div class="contact-section" style="height: 100%;">
<div class="container">
<div class="row center justify-content-center" style="margin-top: 10%;">
<h1>Hi {{ current_user.first_name }}!</h1>
{% block app_content %}
<div class="card text-center">
<div class="card-body">
<h1 class="h2 mb-3 fw-normal">Hi {{current_user.first_name}}!</h1>
{% if current_user.waitlisted %}
<h2>You are waitlisted, if space opens up we will let you know</h2>
<h4 class="h3 mb-3 fw-normal">You're currently waitlisted. If space
opens up, we'll let you know!</h4>
{% else %}
<h2>You are fully registered! We look forward to seeing you!</h2>
Let us know if you have any questions by sending them to <a href="mailto:hack@wpi.edu">hack@wpi.edu</a>
<br>
<br>
Forgot to upload your resume while registering? No worries, submit it below.
</div>
<div class="row center justify-content-center">
{% if config['DISCORD_LINK'] is defined %}
<h5>Make sure to join the Discord and enter your shirt size below!</h5>
<a href="{{ config['DISCORD_LINK'] }}" style="margin: 5px;"
class="btn btn-lg btn-primary btn-invert">Discord</a>
{% else %}
<h5>Our discord is still under construction! We'll send out an email when it's ready.</h5>
<h4>You are fully registered! We look forward to seeing you!</h4>
{% endif %}
</div>
<div class="row center justify-content-center" style="background-color: #974355; padding: 20; margin-left: 20; margin-right: 20; border-radius: 5px;">
<p class="card-text">Let us know if you have any questions by sending
them to <a href="mailto:hack@wpi.edu">hack@wpi.edu</a></p>
<div class="row center justify-content-center">
<form method="post">
{{ form.csrf_token }}
<br>
<p><b>Optional Info:</b></p>
<div>
<p>Shirt Size (Currently selected: {{current_user.shirt_size}})</p>
{% for subfield in form.shirt_size %}
{{subfield}}{{subfield.label}}
{% endfor %}
<p>Special Needs/Accommodations:</p>
<input type="text" name="accomodations"
id="special_needs" value="{{ current_user.accomodations }}">
{{ form.csrf_token() }}
<p><b>Optional Info</b></p>
<div class="form-floating mb-3 required">
{{ form.shirt_size(class="form-control", selected=current_user.shirt_size) }}
{{ form.shirt_size.label() }}
</div>
<br><br>
<input name="save" class="btn btn-lg btn-primary btn-invert" type="submit" value="Save"/>
<br><br><br>
<div class="form-floating mb-3 required">
{{ form.accomodations(class="form-control") }}
{{ form.accomodations.label() }}
</div>
{{ render_field(form.submit) }}
</form>
</div>
<hr/>
<div class="row center justify-content-center">
<form method="post" action="{{url_for('dashboard.resume')}}" enctype="multipart/form-data">
{{ resform.csrf_token }}
<p><b>If you'd like, add your resume to send to sponsors... </b></p>
<div class="file-field input-field">
<div class="btn">
<span>File</span>
<input id="resume" name="resume" type="file" oninput="resumeChange()"/>
<form method="post" action={{url_for('dashboard.resume')}}"
enctype="multipart/form-data">
{{ resform.csrf_token() }}
<p><b>If you'd like, add your resume to send to
sponsors...</b></p>
<div class="form mb-3 required">
{{ resform.resume(class="form-control") }}
</div>
<div class="file-path-wrapper white-text">
<input disabled id="filename" class="file-path validate white-text" type="text">
</div>
</div>
<input name="submit" class="btn btn-lg btn-primary btn-invert" type="submit" value="Submit"/>
{{ render_field(resform.submit) }}
</form>
{% endif %}
<br>
</div>
{% if current_user.is_admin %}
<br>
<div class="row justify-content-center">
<a href="/admin"><p class="btn">Admin Dashboard</p></a>
</div>
{% endif %}
<br>
</div>
<br>
<br>
<center><a onclick="drop('{{current_user.id}}')" id="drop-link"><p class="btn">Drop Application if you can't make it :(</p></a></center>
</div>
<script>
let errColor = '#E74C3C'
$(document).ready(() => {
$('#drop-link').click((e) => {
e.preventDefault()
let id = {{ id }}
drop(id)
})
})
</script>
</div>
</div>
{% endblock %}

View file

@ -1,8 +1,9 @@
{% extends 'base.html' %}
{% extends 'admin-layout.html' %}
{% block content %}
{% block app_content %}
<div class="card text-center">
<div style="height: 100%; color: white;">
<div style="height: 100%;">
<h2>Events</h2>
Get a JSON readout of events <a href="{{ url_for('admin.events_json')
}}">here</a>
@ -39,5 +40,5 @@
</tbody>
</table>
</div>
</div>
{% endblock %}

View file

@ -1,6 +1,7 @@
{% extends 'base.html' %}
{% extends 'admin-layout.html' %}
{% block content %}
{% block app_content %}
<div class="card text-center">
<div style="height: 100%;">
<div id="registration-banner" class="parallax-container valign-wrapper">
<div class="section">
@ -9,30 +10,39 @@
</div>
</div>
<div class="container">
<div class="section" style="background-color: #974355; padding: 20px;">
<form method="post">
{{ form.csrf_token }}
<div>
{{ form.name}}<br/> {{ form.name.label }}
<div class="form-floating mb-3 required">
{{ form.name(class="form-control") }}
{{ form.name.label }}
</div>
<div>
{{ form.description}}<br/>{{form.description.label}}
<div class="form-floating mb-3">
{{ form.description(class="form-control") }}
{{form.description.label}}
</div>
<div>
{{ form.location}}<br/>{{form.location.label}}
<div class="form-floating mb-3 required">
{{ form.location(class="form-control")}}
{{form.location.label}}
</div>
<div>
{{form.start_time}}<br/>{{form.start_time.label}}
<div class="row">
<div class="col">
<div class="form mb-3 required">
{{form.start_time(class="form-control")}}
{{form.start_time.label}}
</div>
<div>
{{form.end_time}}<br/>{{form.end_time.label}}
</div>
<div>
{{form.category}}<br/>{{form.category.label}}
<div class="col">
<div class="form mb-3 required">
{{form.end_time(class="form-control")}}
{{form.end_time.label}}
</div>
</div>
</div>
<div class="form-floating mb-3 required">
{{form.category(class="form-control")}}
{{form.category.label}}
</div>
<div>
{{form.submit}}
</div>
</form>
</div>
</div>

View file

@ -1,16 +0,0 @@
<!-- A hack to make sure the footer bar shows-->
<div style="height: 100px"></div>
<nav class="navbar navbar-inverse footer-nav" style= "margin-top: 30px">
<div class="container-fluid">
<div class="navbar-header">
</div>
<ul class="nav justify-content-end">
<li class="nav-item">
<a class="nav-link" href="mailto:hack@wpi.edu?subject=[Hackathon]">Contact Us</a>
</li>
</ul>
</div>
</nav>
</body>
</html>

View file

@ -1,45 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="../static/css/materialize.min.css" rel="stylesheet">
{% assets 'scss' %}
<link rel="stylesheet" type="text/css" href="{{ ASSET_URL }}">
{% endassets %}
</head>
<style>
nav {
background-color: #F5665B;
border-color: #E7E4C6;
color: white;
}
</style>
<body>
<nav class="navbar navbar-inverse sticky-top navbar-expand">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">Goathacks</a>
</div>
<ul class="nav justify-content-end">
<!-- <li class="nav-item">
{% if registration_open or registration_open is not defined %}
<a class="nav-link active" href="/register">Register</a>
{% else %}
<a class="nav-link active disabled" href="#">Registration is closed</a>
{% endif %}
</li>
<li class="nav-item">
<a class="nav-link" href="../static/assets/Hack@WPI-SponsorshipInformation-2020.pdf">Sponsorship Packet</a>
</li> -->
<li class="nav-item">
<a class="nav-link" href="https://hack.wpi.edu/conduct/conduct.pdf">Code of Conduct</a>
</li>
</ul>
</div>
</nav>

@ -1 +1 @@
Subproject commit e0fb69c0be54c6cce7391ccb86a9bf14b80f432b
Subproject commit 8d8a691aad1cea4037bb9d33ddf7230d8d272597

View file

@ -1,195 +0,0 @@
{% include 'header.html' %}
<div>
<style>
hr {
margin-top: 2rem;
margin-bottom: 2rem;
width: 70%;
border-width: 10px;
border-color: #F5665B;
}
h2 {
text-align: center;
}
h3 {
text-align: center;
}
h4 {
text-align: center;
}
h5 {
text-align: center;
}
h6 {
text-align: center;
margin-right: 100px;
margin-left: 100px;
}
div.main-logo {
margin-top: 16px;
}
.sponsors {
text-align: center;
display: block;
padding: 20px;
}
.sponsors > div {
margin-bottom: 40px;
}
.sponsors > div:last-child {
margin-bottom: 0;
}
.sponsors img {
display: inline-block;
margin-right: 40px;
/* Hack to fix overflow of bose logo*/
max-width: calc(100% - 10px);
}
.title-sponsors img{
max-height: 90px;
}
.silver-sponsors img {
max-height: 25px;
}
a {
color: black;
}
.x{
background-color: #E7E4C6;
margin-right: 100px;
margin-left: 100px;
color: black;
border-radius: 50px 50px 50px 50px;
padding-bottom: 10px;
padding-top:10px;
}
.snow-banner {
background-color: red;
width: 100%;
padding: 10px;
text-align: center;
}
</style>
<div class="snow-banner">
<b>Attention!</b> Due to the road conditions, we have delayed the schedule by an hour. We will still have live presentations, but submissions have been extended until 9am, and judging will take place at 10am.
</div>
<!--Logo + Date+ Hosted By -->
<div class="container">
<div class="row center main-logo">
<img src="../static/img/hackwpilogo.png" alt="logo" style='height: 100%; width: 100%; object-fit: contain'/>
</div>
</div>
<!--"Hackathon for all students" -->
<hr/>
<h2> A HACKATHON FOR ALL COLLEGE STUDENTS </h2>
<hr/>
<!--Location -->
<h3> WPI Campus Center </h3>
<h4>100 Institute Road</h4>
<h4> Worcester, MA 01609</h4>
<hr/>
<!-- Sponsors for 2020 -->
<h2> OUR SPONSORS FOR 2020 </h2>
<div class="container">
<div class="row center sponsors">
<div class="title-sponsors">
<img class="logo" src="../static/img/logos/bose.png"></div>
<div class="platinum-sponsors">
<h1>WPI Computer Science Department</h1>
</div>
<div class="gold-sponsors">
<img class="logo" src="../static/img/logos/iboss.png" style = "height: 150px">
<img class="logo" src="../static/img/logos/kronos.png" style = "height: 75px">
<img class="logo" src="../static/img/logos/paytronix.png" style = "height: 30px">
<img class="logo" src="../static/img/logos/abbvie.png" style = "height: 60px">
</div>
<div class="silver-sponsors">
<img class="logo" src="../static/img/logos/carbonblack.png" >
</div>
<div class="bronze-sponsors">
<img class="logo" src="../static/img/logos/wakefly.png" style = "height: 70px">
<img class="logo" src="../static/img/logos/amazon.png" style = "height: 70px">
<img class="logo" src="../static/img/logos/everquote.png" style = "height: 35px">
<img class="logo" src="../static/img/logos/synopses.png" style = "height: 20px">
<img class="logo" src="../static/img/logos/boozallenhamilton.png" style = "height: 35px">
</div>
</div>
</div>
<!--FAQs -->
<hr/>
<div class = "x">
<h2> FAQs </h2>
<div class = "FAQ">
<h4>Who can attend?</h4>
<h6> Our event is open to any college student! You dont need any experience to participate. However, due to legal issues, anyone under 18 must have a legal guardian present and cannot win prizes </h6>
</div>
<div class = "FAQ">
<h4>What is the max team size?</h4>
<h6>The maximum is 5 people per team. Minimum is 1 :P</h6>
</div>
<div class = "FAQ">
<h4>What are the awards for?</h4>
<h6>The categories this year are: </h6>
<h6>Best Overall Project
<h6>Best Game </h6>
<h6>Best Software </h6>
<h6>Best Hardware </h6>
<h6>Company Favorite </h6>
<h6>Best Use of the Bose API/SDK </h6>
<h6>Best Meme </h6>
<h6>Best Rookie </h6>
</div>
<div class = "FAQ">
<h4>What should I bring?</h4>
<h6>Bring devices, chargers, sleeping bags, toiletries, basically anything you need to be comfortable. We will provide showers at certain time slots during the weekend. Food will also be provided.</h6>
</div>
<div class = "FAQ">
<h4>What if I don't have a team?</h4>
<h6>You dont need a team to register! We will have a team formation session right after the opening ceremony for those who would like to work with a team. If you prefer to stay solo, thats also great. </h6>
</div>
<div class = "FAQ">
<h4>How should I prepare beforehand?</h4>
<h6>Make sure you have travel plans in place, especially in case of random snowfalls. Unfortunately, we do not provide travel reimbursements.
Its also nice to have an idea in mind beforehand. However, we ask that you do not bring any pre-made materials to keep the competition fair. </h6>
</div>
<div class = "FAQ">
<h4>What is the schedule?</h4>
<h6><a href = 'https://docs.google.com/spreadsheets/d/1FSh2UfZwoMwXlgrKnKjnQg2okEcLDVCP30khnPdM1H0/edit?usp=sharing' style= "color: blue">Here it is!</a> Keep in mind that this is tentative. </h6>
</div>
</div>
</div>
{% include 'footer.html' %}

View file

@ -0,0 +1,56 @@
{% extends 'bootstrap-base.html' %}
{% block html_attribs %} lang="en"{% endblock %}
{% block title %}{% if title %}{{ title }} - GoatHacks{% else %}GoatHacks{%
endif %}{% endblock %}
{% block head %}
{{super()}}
{{ font_awesome.load_css() }}
{% endblock %}
{% block styles %}
{{super()}}
{% assets 'scss' %}
<link rel="stylesheet" type="text/css" href="{{ ASSET_URL }}">
{% endassets %}
{% endblock %}
{% block navbar %}
<nav class="navbar navbar-dark mb-4 navbar-expand-lg">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="true"
aria-label="Toggle
navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-header">
<a class="navbar-brand" href="{{ url_for('registration.register') }}">
<img src="{{url_for('static', filename='img/logo.png')}}"
alt="Logo" width="35" height="35" class="d-inline-block
align-text-middle mx-2">GoatHacks</a>
</div>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="nav navbar-nav me-auto mb-2 mb-lg-0">
{{ render_nav_item('registration.register', 'Home')}}
</ul>
<ul class="nav navbar-nav">
{% if current_user.is_authenticated %}
{{ render_nav_item('dashboard.home', 'Dashboard') }}
{% if current_user.is_admin %}
{{ render_nav_item('admin.home', 'Admin Dash') }}
{% endif %}
{{ render_nav_item('registration.logout', 'Logout') }}
{% else %}
{{ render_nav_item('registration.register', 'Registration') }}
{{ render_nav_item('registration.login', 'Login') }}
{% endif %}
</ul>
</div>
</div>
</nav>
{% endblock %}

View file

@ -1,34 +1,34 @@
{% extends 'base.html' %}
{% extends 'layout.html' %}
{% from 'bootstrap5/form.html' import render_field %}
{% block content %}
<div style="height: 100%;">
<div id="registration-banner" class="parallax-container valign-wrapper">
<div class="section">
<h3 class="header-center text-darken-2">Login</h3>
{% block app_content %}
<div class="card text-center">
<div class="card-body">
<img class="mb-4" src="{{ url_for('static', filename='img/banner.png')
}}" alt="GoatHacks 2024 Banner">
<h1 class="h3 mb-3 fw-normal">Welcome back to GoatHacks!</h1>
<p class="card-text">If you've already registered, please use this page
to access your participant dashboard. Otherwise, please use the <a
href="{{
url_for('registration.register')
}}"
>
registration</a> page to register!</p>
<div class="text-center">
<form action="" method="post" class="form" role="form">
{{ form.csrf_token() }}
<div class="form-floating mb-3 required">
{{ form.email(class="form-control") }}
{{ form.email.label() }}
</div>
<div class="form-floating mb-3 required">
{{ form.password(class="form-control") }}
{{ form.password.label() }}
</div>
</div>
<div class="container">
<div class="section" style="background-color: #974355; padding: 20px;">
<form method="post">
{{ form.csrf_token }}
<div>
{{form.email}}<br/>{{ form.email.label}}
</div>
<div>
{{form.password}}<br/>{{form.password.label}}
</div>
<div>
{{form.submit}}
</div>
{{ render_field(form.submit) }}
</form>
<span><p><em>Don't have an account? <a
href="{{url_for('registration.register')}}">Register
here</a>.</em></p></span>
<span><p><em>Forgot your password? Head over <a
href="{{url_for('registration.reset')}}">here</a>
to reset it.</em></p></span>
</div>
</div>
</div>
{% endblock %}

View file

@ -1,23 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>🍪CookieMailer</title>
{% extends 'admin-layout.html' %}
{% block head %}
{{super()}}
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="description" content="" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<meta name="theme-color" content="">
<link rel="stylesheet" type="text/css" href="/static/css/mail.css" />
<script src="https://cdn.tiny.cloud/1/{{MCE_API_KEY}}/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script></head>
<body>
<div id="loader"></div>
<div class="container">
<div class="row">
<div id="root" class="col">
<h2>🍪CookieMailer</h2>
{% endblock %}
{% block app_content %}
<div class="card">
<div class="card-body">
<h1 class="h3 mb-3 fw-normal">🍪CookieMailer</h1>
<label for="recipients">To: </label>
<br/>
<select id="recipients" name="recipients">
<select class="form-control" id="recipients" name="recipients">
<option value="admin">Test Email (SysAdmin)</option>
<option value="org">Test Email (Organizers)</option>
<!-- <option value="wpi">WPI Only</option> -->
@ -26,7 +23,8 @@
<br/>
<label for="subject">Subject: </label>
<br/>
<input id="subject" name="subject" width="100%" type="text" value="Hack@WPI" />
<input class="form-control" id="subject" name="subject" width="100%"
type="text" value="GoatHacks -- " />
<br/>
<br/>
<textarea id="content" name="content">
@ -40,7 +38,7 @@
</textarea>
<br/>
<br/>
<input type="button" onClick="send()" value="Send"/>
<input class="btn btn-primary" type="button" onClick="send()" value="Send"/>
</div>
</div>
</div>
@ -77,6 +75,7 @@
];
if((rec != "all" && window.confirm("Send test email?")) || (rec == "all" && window.confirm("Send email to {{NUM_HACKERS}} recipients?"))) {
console.log(`Sending email to ${rec}`)
fetch('/admin/send', {method: 'POST', body: JSON.stringify(body), headers: headers}).then(async (res) => {
window.alert(await res.text());
}).catch((err) => {
@ -96,6 +95,7 @@
// })
}
</script>
</body>
</div>
</div>
{% endblock %}
</html>

View file

@ -1,27 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<div style="height: 100%;">
<div id="registration-banner" class="parallax-container valign-wrapper">
<div class="section">
<h3 class="header-center text-darken-2">Reset Password</h3>
</div>
</div>
</div>
<div class="container">
<div class="section" style="background-color: #974355; padding: 20px;">
<form method="post">
{{ form.csrf_token }}
<div>
{{form.password}}<br/>{{form.password.label}}
</div>
<div>
{{form.password_confirm}}<br/>{{form.password_confirm.label}}
</div>
<div>
{{form.submit}}
</div>
</form>
</div>
</div>
{% endblock %}

View file

@ -1,24 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<div style="height: 100%">
<div id="registration-banner" class="parallax-container valign-wrapper">
<div class="section">
<h3 class="header-center text-darken-2">Reset Password</h3>
</div>
</div>
</div>
<div class="container">
<div class="section" style="background-color: #974355; padding: 20px;">
<form method="post">
{{ form.csrf_token }}
<div>
{{ form.email }}<br/>{{ form.email.label}}
</div>
<div>
{{form.submit}}
</div>
</form>
</div>
</div>
{% endblock %}

View file

@ -1,58 +1,69 @@
{% extends 'base.html' %}
{% extends 'layout.html' %}
{% from 'bootstrap5/form.html' import render_field %}
{% block content %}
<div style="height: 100%;">
<div id="registration-banner" class="parallax-container valign-wrapper">
<div class="section">
<h3 class="header-center text-darken-2">Registration</h3>
{% block app_content %}
<div class="card text-center">
<div class="card-body">
<img class="mb-4" src="{{ url_for('static', filename='img/banner.png')
}}" alt="GoatHacks Banner">
<h1 class="h3 mb-3 fw-normal">Welcome to GoatHacks!</h1>
<p class="card-text">Please use this page to register for this year's
Hackathon. Accounts from prior years are not carried over!</p>
<div class="text-center">
<form action="" method="post" class="form" role="form">
{{ form.csrf_token() }}
<div class="form-floating mb-3 required">
{{ form.email(class="form-control") }}
{{ form.email.label() }}
</div>
<div class="row">
<div class="col">
<div class="form-floating mb-3 required">
{{ form.password(class="form-control") }}
{{ form.password.label() }}
</div>
</div>
<div class="col">
<div class="form-floating mb-3 required">
{{ form.password_confirm(class="form-control") }}
{{ form.password_confirm.label() }}
</div>
</div>
</div>
<div class="container">
<div class="section" style="background-color: #974355; padding: 20px;">
<form method="post">
{{ form.csrf_token }}
<div>
{{ form.email}}<br/> {{ form.email.label }}
<div class="row">
<div class="col">
<div class="form-floating mb-3 required">
{{ form.first_name(class="form-control") }}
{{ form.first_name.label() }}
</div>
<div>
{{ form.password}}<br/>{{form.password.label}}
</div>
<div>
{{ form.password_confirm}}<br/>{{form.password_confirm.label}}
<div class="col">
<div class="form-floating mb-3 required">
{{ form.last_name(class="form-control") }}
{{ form.last_name.label() }}
</div>
<div>
{{form.first_name}}<br/>{{form.first_name.label}}
</div>
<div>
{{form.last_name}}<br/>{{form.last_name.label}}
</div>
<hr/>
<h3>Miscellaneous Information</h3>
<div>
{{form.phone_number}}<br/>{{form.phone_number.label}}
<div class="form-floating mb-3 required">
{{ form.school(class="form-control") }}
{{ form.school.label() }}
</div>
<div>
{{form.school}}<br/>{{form.school.label}}
<div class="form-floating mb-3 required">
{{ form.phone_number(class="form-control") }}
{{ form.phone_number.label() }}
</div>
<div>
{{form.gender.label}}{{form.gender}}
<div class="form-floating mb-3 required">
{{ form.gender(class="form-control") }}
{{ form.gender.label() }}
</div>
<hr/>
<div>
<label for="agree_coc">I confirm that I have read and agree to the
Code of Conduct</label>
<input type="checkbox" id="agree_coc" name="agree_coc">
</div>
<div>
{{form.submit}}
<div class="form-check mb-3 required">
{{ form.agree_coc }}
{{ form.agree_coc.label() }}
</div>
{{ render_field(form.submit) }}
</form>
<span><p><em>You may also want to <a
href="{{url_for('registration.login')}}">
log in</a>.</em></p></span>
</div>
</div>
</div>
{% endblock %}

View file

@ -1,69 +0,0 @@
{% include 'header.html' %}
<link href="../static/css/materialize.min.css" rel="stylesheet">
<style>
a{
color: skyblue;
}
</style>
<script>
function resumeChange() {
let val = document.getElementById('resume').value;
val = val.split(/\\|\//gi).slice(-1)[0]
document.getElementById('filename').setAttribute('value', val);
}
</script>
<div style="height: 100%;">
<div id="registration-banner" class="parallax-container valign-wrapper">
<div class="section">
<h3 class="header center text-darken-2">Registration</h3>
</div>
<div class="parallax"><img src="../static/img/background1.jpg" alt="background"></div>
</div>
<div class="container">
<div class="container">
<Center><h2>Hi {{ name }}, just a few more steps!</h2></Center>
<div class="section" style="background-color: #974355; padding: 20px;">
<form method="post" action="/register" enctype="multipart/form-data">
<div>
<p><b>If you'd like, add your resume to send to sponsors... </b></p>
<div class="file-field input-field">
<div class="btn">
<span>File</span>
<input id="resume" name="resume" type="file" oninput="resumeChange()"/>
</div>
<div class="file-path-wrapper white-text">
<input disabled id="filename" class="file-path validate white-text" type="text">
</div>
</div>
</div>
<p><i>No worries if you don't have one on hand, you can come back and upload it later via the Hack@WPI dashboard!</i></p>
<p>Please take a moment to review the following policies and check all the boxes below so we can finalize your registration:</p>
<p>
<center><a href="/tos">Hack@WPI's Terms and Conditions</a></center>
</p>
<p>
<center><a href="https://github.com/MLH/mlh-policies/blob/master/data-sharing.md">MLH's Data Sharing Notice</a></center>
</p>
<p>
<center><a href="https://mlh.io/privacy">MLH's Privacy Policy</a></center>
</p>
<p>
<center><a href="https://github.com/MLH/mlh-policies/blob/master/prize-terms-and-conditions/contest-terms.md">MLH's
Contest Terms and Conditions</a></center>
</p>
<p>
<center><a href="https://static.mlh.io/docs/mlh-code-of-conduct.pdf">MLH's Code of Conduct</a></center>
</p>
<br>
<input type="checkbox" name="tos" id="checkboxid" required><label for="checkboxid"><b style="color:white;">*I have read and agree to the Hack@WPI Terms and Conditions</b></label>
<input type="checkbox" name="mlh1" id="checkboxid1" required><label for="checkboxid1"><b style="color:white;">*I have read and agree to the MLH Code of Conduct</b></label>
<input type="checkbox" name="mlh2" id="checkboxid2" required><label for="checkboxid2"><b style="color:white;">*I authorize you to share my application/registration information with Major League Hacking for event administration, ranking, and MLH administration in-line with the MLH Privacy Policy. I further agree to the terms of both the MLH Contest Terms and Conditions and the MLH Privacy Policy.</b></label>
<input type="checkbox" name="mlh3" id="checkboxid3" required><label for="checkboxid3"><b style="color:white;">*I authorize MLH to send me pre- and post-event information emails, which contain free credit and opportunities from their partners.</b></label>
<input type="checkbox" name="mlh3" id="checkboxid4" required><label for="checkboxid4"><b style="color:white;">*I understand that in-person participation is limited to WPI students that are part of the testing protocol only.</b></label>
<br><br>
<center><input name="submit" class="btn btn-lg btn-primary btn-invert" type="submit" value="Submit"/></center>
</form>
</div>
</div>
</div>
{% include 'footer.html' %}

View file

@ -1,16 +0,0 @@
{% include 'header.html' %}
<link href="../static/css/materialize.min.css" rel="stylesheet">
<div style="margin: 16px">
<p>
I agree to hold harmless the organizers of HACK@WPI and WPIs Chapter of the Association of Computing Machinery (ACM) from any and all claims, lawsuits, demands, causes of action, liability, loss, damage and/or injury of any kind whatsoever (including without limitation all claims for monetary loss, property damager, equitable relief, personal injury and/or wrongful death), whether brought by an individual or other entity. The indemnification applies to and includes, without limitation, the payment of all penalties, fines, judgments, awards, decrees, attorneys fees, and related costs or expenses, and any reimbursements to ACM for all legal fees, expenses, and costs incurred by it.
</p>
<p>
I also acknowledge the organizers of HACK@WPI will be recording the event using video, photographs, audio recordings, and other media and give them permission to use said media in marketing/promotional materials.
</p>
</div>
<!-- This is stupid but it works -->
<div style="position: absolute; bottom: 0; width: 100%;">
{% include 'footer.html' %}
</div>

View file

@ -23,4 +23,6 @@ uWSGI==2.0.21
Werkzeug==2.2.2
WTForms==3.0.1
ulid
bootstrap-flask
Font-Awesome-Flask
tabulate