Tracking PR for registration rewrite #5
10 changed files with 902 additions and 2 deletions
|
@ -1,6 +1,12 @@
|
|||
from flask import Blueprint, flash
|
||||
from datetime import datetime
|
||||
from flask import Blueprint, flash, render_template, request
|
||||
import flask_login
|
||||
from flask_login import current_user
|
||||
from goathacks.registration.forms import LoginForm, RegisterForm
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
from goathacks import db
|
||||
from goathacks.models import User
|
||||
|
||||
bp = Blueprint('registration', __name__, url_prefix="/registration")
|
||||
|
||||
|
@ -9,4 +15,31 @@ def register():
|
|||
if current_user.is_authenticated:
|
||||
flash("You are already registered and logged in!")
|
||||
|
||||
form = RegisterForm(request.form)
|
||||
if request.method == 'POST' and form.validate():
|
||||
email = request.form.get('email')
|
||||
first_name = request.form.get('first_name')
|
||||
last_name = request.form.get('last_name')
|
||||
password = request.form.get('password')
|
||||
password_c = request.form.get('password_confirm')
|
||||
|
||||
|
||||
if password == password_c:
|
||||
# Passwords match!
|
||||
user = User(
|
||||
email=email,
|
||||
password=generate_password_hash(password),
|
||||
first_name=first_name,
|
||||
last_name=last_name,
|
||||
last_login=datetime.now(),
|
||||
)
|
||||
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
flask_login.login_user(user)
|
||||
|
||||
return "OK"
|
||||
else:
|
||||
flash("Passwords do not match")
|
||||
|
||||
return render_template("register.html", form=form)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import PasswordField, StringField
|
||||
from wtforms import BooleanField, PasswordField, StringField, SubmitField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
class RegisterForm(FlaskForm):
|
||||
|
@ -10,4 +10,11 @@ class RegisterForm(FlaskForm):
|
|||
password = PasswordField("Password", validators=[DataRequired()])
|
||||
password_confirm = PasswordField("Confirm Password",
|
||||
validators=[DataRequired()])
|
||||
agree_coc = BooleanField("I confirm that I have read and agree to the Code of Conduct", validators=[DataRequired()])
|
||||
submit = SubmitField("Register")
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
email = StringField("Email", validators=[DataRequired()])
|
||||
password = PasswordField("Password", validators=[DataRequired()])
|
||||
submit = SubmitField("Sign in")
|
||||
|
||||
|
|
279
goathacks/templates/admin.html
Normal file
279
goathacks/templates/admin.html
Normal file
|
@ -0,0 +1,279 @@
|
|||
<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>
|
||||
|
||||
<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="../static/js/admin.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
|
||||
</head>
|
||||
|
||||
|
||||
<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="/hackers">JSON</a> <a href="/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">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Options</th>
|
||||
<th>Checked In?</th>
|
||||
<th>Waitlisted?</th>
|
||||
<th>Admin</th>
|
||||
<th>MLH ID</th>
|
||||
<th>Time Registered</th>
|
||||
<th>Email</th>
|
||||
<th>Name</th>
|
||||
<th>Phone</th>
|
||||
<th>Shirt</th>
|
||||
<th>Special</th>
|
||||
<th>School</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% 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
|
||||
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>
|
||||
{% 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>
|
||||
{% endif %}
|
||||
<li class="divider"></li>
|
||||
{% if not hacker['checked_in'] %}
|
||||
<li><a class="drop" id="{{ hacker['id'] }}-drop" href="#">Drop Application</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if hacker['admin'] %}
|
||||
<li><a class="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>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
<td id="{{ hacker['id'] }}-checked_in">{{ hacker['checked_in'] }}</td>
|
||||
<td id="{{ hacker['id'] }}-waitlisted">{{ hacker['waitlisted'] }}</td>
|
||||
<td>{{ hacker['admin'] }}</td>
|
||||
<td>{{ hacker['id'] }}</td>
|
||||
<td>{{ hacker['registration_time'] }}</td>
|
||||
<td>{{ hacker['email'] }}</td>
|
||||
<td>{{ hacker['first_name'] + ' ' + hacker['last_name'] }}</td>
|
||||
<td>{{ hacker['phone_number'] }}</td>
|
||||
<td>{{ hacker['shirt_size'] }}</td>
|
||||
<td>{{ hacker['special_needs'] }}</td>
|
||||
<td>{{ hacker['school']['name'] }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
142
goathacks/templates/dashboard.html
Normal file
142
goathacks/templates/dashboard.html
Normal file
|
@ -0,0 +1,142 @@
|
|||
{% include 'header.html' %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
|
||||
<link href="../static/css/materialize.min.css" rel="stylesheet">
|
||||
<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 = "/drop?mlh_id=" + id;
|
||||
}
|
||||
// swal({
|
||||
// title: 'Drop your application?',
|
||||
// text: 'Are you sure you wish to drop your application? This cannot be undone. (patiently wait after clicking the button)',
|
||||
// type: 'warning',
|
||||
// showCancelButton: true,
|
||||
// closeOnConfirm: false,
|
||||
// confirmButtonText: 'Yes, drop!',
|
||||
// confirmButtonColor: errColor
|
||||
// }, () => {
|
||||
// $.get('/drop?mlh_id=' + id, (data) => {
|
||||
// let title = ''
|
||||
// let msg = ''
|
||||
// let type = ''
|
||||
// if (data.status === 'success'
|
||||
// )
|
||||
// {
|
||||
// title = 'Dropped!'
|
||||
// msg = 'Your application was successfully dropped!'
|
||||
// type = 'success'
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// title = 'Error!'
|
||||
// msg = JSON.stringify(data)
|
||||
// type = 'error'
|
||||
// }
|
||||
// swal(title, msg, type)
|
||||
// if (data.status === 'success') {
|
||||
// setTimeout(() => {window.location = '/'
|
||||
// },
|
||||
// 5000
|
||||
// )
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
}
|
||||
|
||||
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 {{ name }}!</h1>
|
||||
{% if waitlisted %}
|
||||
<h2>You are waitlisted, if space opens up we will let you know...</h2>
|
||||
{% 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">
|
||||
<h5>Make sure to join the Slack and enter your shirt size below!</h5>
|
||||
<p>(Please note that due to COVID-19 constraints, we can't guarantee that all participants will receive Hack@WPI t-shirts this year but we are trying to find a way!)</p>
|
||||
<a href="https://join.slack.com/t/wpi-rqw4180/shared_invite/zt-1089kvjx1-3b6v152r6a_fX7NS8EGL9g" style="margin: 5px;" class="btn btn-lg btn-primary btn-invert">Slack</a>
|
||||
</div>
|
||||
<div class="row center justify-content-center" style="background-color: #974355; padding: 20; margin-left: 20; margin-right: 20; border-radius: 5px;">
|
||||
<form method="get" action="/shirtpost">
|
||||
<br>
|
||||
<p><b>Optional Info:</b></p>
|
||||
<div>
|
||||
<p>Shirt Size (Currently selected: {{shirt_size}})</p>
|
||||
<input type="radio" id="shirtxs" name="size" value="xs">
|
||||
<label for="shirtxs">XS</label>
|
||||
<input type="radio" id="shirts" name="size" value="s">
|
||||
<label for="shirts">S</label>
|
||||
<input type="radio" id="shirtm" name="size" value="m">
|
||||
<label for="shirtm">M</label>
|
||||
<input type="radio" id="shirtl" name="size" value="l">
|
||||
<label for="shirtl">L</label>
|
||||
<input type="radio" id="shirtxl" name="size" value="xl">
|
||||
<label for="shirtxl">XL</label>
|
||||
<input type="radio" id="shirtxxl" name="size" value="xxl">
|
||||
<label for="shirtxxl">XXL</label>
|
||||
<input type="radio" id="no" name="size" value="no">
|
||||
<label for="no">Don't want one</label>
|
||||
<p>Special Needs/Accommodations:</p>
|
||||
<input type="text" name="special_needs" id="special_needs" value="{{ special_needs }}">
|
||||
</div>
|
||||
<br><br>
|
||||
<input name="save" class="btn btn-lg btn-primary btn-invert" type="submit" value="Save"/>
|
||||
<br><br><br>
|
||||
</form>
|
||||
</div>
|
||||
<div class="row center justify-content-center">
|
||||
<form method="post" action="/resumepost" enctype="multipart/form-data">
|
||||
<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>
|
||||
<input name="submit" class="btn btn-lg btn-primary btn-invert" type="submit" value="Submit"/>
|
||||
</form>
|
||||
{% endif %}
|
||||
<br>
|
||||
</div>
|
||||
{% if 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('{{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>
|
||||
|
||||
{% include 'footer.html' %}
|
16
goathacks/templates/footer.html
Normal file
16
goathacks/templates/footer.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!-- 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>
|
42
goathacks/templates/header.html
Normal file
42
goathacks/templates/header.html
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
<!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/style.css" rel="stylesheet">
|
||||
</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="/">Hack@WPI</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://static.mlh.io/docs/mlh-code-of-conduct.pdf">Code of Conduct</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
195
goathacks/templates/index.html
Executable file
195
goathacks/templates/index.html
Executable file
|
@ -0,0 +1,195 @@
|
|||
{% 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 don’t 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 don’t 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, that’s 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.
|
||||
It’s 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' %}
|
101
goathacks/templates/mail.html
Normal file
101
goathacks/templates/mail.html
Normal file
|
@ -0,0 +1,101 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>🍪CookieMailer</title>
|
||||
<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>
|
||||
<label for="recipients">To: </label>
|
||||
<br/>
|
||||
<select id="recipients" name="recipients">
|
||||
<option value="admin">Test Email (SysAdmin)</option>
|
||||
<option value="org">Test Email (Organizers)</option>
|
||||
<!-- <option value="wpi">WPI Only</option> -->
|
||||
<option value="all">All Participants ({{NUM_HACKERS}})</option>
|
||||
</select>
|
||||
<br/>
|
||||
<label for="subject">Subject: </label>
|
||||
<br/>
|
||||
<input id="subject" name="subject" width="100%" type="text" value="Hack@WPI" />
|
||||
<br/>
|
||||
<br/>
|
||||
<textarea id="content" name="content">
|
||||
Message
|
||||
<br/>
|
||||
<br/>
|
||||
Best,<br/>
|
||||
<b>Hack@WPI Team</b><br/>
|
||||
<i><a href="mailto:hack@wpi.edu">hack@wpi.edu</a></i><br/>
|
||||
<img height="75px" width="75px" src="https://media.discordapp.net/attachments/829437603291856938/930311998057635880/hack317-min.png">
|
||||
</textarea>
|
||||
<br/>
|
||||
<br/>
|
||||
<input type="button" onClick="send()" value="Send"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript">
|
||||
window.onload = function(){
|
||||
tinymce.init({
|
||||
selector: '#content',
|
||||
plugins: 'advlist,link'
|
||||
});
|
||||
|
||||
setTimeout(function(){
|
||||
document.getElementById("loader").remove();
|
||||
},1000);
|
||||
};
|
||||
|
||||
function send() {
|
||||
let rec = document.getElementById("recipients").value;
|
||||
let subject = document.getElementById("subject").value;
|
||||
let text = tinyMCE.activeEditor.getContent({ format: 'text' });
|
||||
let html = tinyMCE.activeEditor.getContent({ format: 'html' });
|
||||
|
||||
let body = {
|
||||
"recipients": rec,
|
||||
"subject": subject,
|
||||
"text": text,
|
||||
"html": html
|
||||
}
|
||||
|
||||
console.log("Sending Email:"+JSON.stringify(body))
|
||||
|
||||
const headers = [
|
||||
["Content-Type", "application/json"],
|
||||
];
|
||||
|
||||
if((rec != "all" && window.confirm("Send test email?")) || (rec == "all" && window.confirm("Send email to {{NUM_HACKERS}} recipients?"))) {
|
||||
fetch('/send', {method: 'POST', body: JSON.stringify(body), headers: headers}).then(async (res) => {
|
||||
window.alert(await res.text());
|
||||
}).catch((err) => {
|
||||
window.alert("Error sending message - see console for details");
|
||||
console.log(err);
|
||||
});
|
||||
} else {
|
||||
window.alert("Nothing was sent");
|
||||
}
|
||||
|
||||
// fetch('/send', {method: 'POST', body: JSON.stringify(body), headers: headers}).then(async (res) => {
|
||||
// alert("Message sent");
|
||||
// document.body.innerHTML = await res.text()
|
||||
// }).catch((err) => {
|
||||
// alert("Error sending message");
|
||||
// document.body.innerHTML = err;
|
||||
// })
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
69
goathacks/templates/register.html
Normal file
69
goathacks/templates/register.html
Normal file
|
@ -0,0 +1,69 @@
|
|||
{% 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' %}
|
16
goathacks/templates/tos.html
Normal file
16
goathacks/templates/tos.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% 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 WPI’s 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>
|
Loading…
Add table
Reference in a new issue