Skip to content

Commit 50ed91e

Browse files
committed
WIP
1 parent 3e3e018 commit 50ed91e

File tree

14 files changed

+461
-0
lines changed

14 files changed

+461
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@ venv.bak/
102102

103103
# mypy
104104
.mypy_cache/
105+
106+
.DS_Store

Pipfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[[source]]
2+
name = "pypi"
3+
url = "https://pypi.org/simple"
4+
verify_ssl = true
5+
6+
[dev-packages]
7+
8+
[packages]
9+
Flask = "*"
10+
Flask-WTF = "*"
11+
Flask-Assets = "*"
12+
13+
[requires]
14+
python_version = "3.7"

Pipfile.lock

Lines changed: 105 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from flask import Flask, url_for, render_template, redirect
2+
from forms import ContactForm, SignupForm
3+
4+
app = Flask(__name__, instance_relative_config=False)
5+
app.config.from_object('config.Config')
6+
app.config['RECAPTCHA_PUBLIC_KEY'] = 'iubhiukfgjbkhfvgkdfm'
7+
app.config['RECAPTCHA_PARAMETERS'] = {'size': '100%'}
8+
9+
10+
@app.route('/')
11+
def home():
12+
return render_template('index.html')
13+
14+
15+
@app.route('/contact', methods=('GET', 'POST'))
16+
def contact():
17+
form = ContactForm()
18+
if form.validate_on_submit():
19+
return redirect(url_for('success'))
20+
return render_template('contact.html', form=form)
21+
22+
23+
@app.route('/success')
24+
def success():
25+
return render_template('success.html')
26+
27+
28+
@app.route('/signup', methods=('GET', 'POST'))
29+
def signup():
30+
form = SignupForm()
31+
if form.validate_on_submit():
32+
return redirect('/success')
33+
return render_template('signup.html',
34+
form=form)

config.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""App configuration."""
2+
from os import environ
3+
4+
5+
class Config:
6+
"""Set Flask configuration vars from .env file."""
7+
8+
# General Config
9+
SECRET_KEY = environ.get('SECRET_KEY')
10+
FLASK_APP = environ.get('FLASK_APP')
11+
FLASK_ENV = environ.get('FLASK_ENV')
12+
13+
# Static Assets
14+
STATIC_FOLDER = environ.get('STATIC_FOLDER')
15+
TEMPLATES_FOLDER = environ.get('TEMPLATES_FOLDER')

forms.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from flask_wtf import FlaskForm, RecaptchaField
2+
from wtforms import (StringField,
3+
TextAreaField,
4+
SubmitField,
5+
PasswordField,
6+
DateField,
7+
SelectField)
8+
from wtforms.validators import (DataRequired,
9+
Email,
10+
EqualTo,
11+
Length,
12+
URL)
13+
14+
15+
class ContactForm(FlaskForm):
16+
"""Contact form."""
17+
name = StringField('Name', [
18+
DataRequired()])
19+
email = StringField('Email', [
20+
Email(message=('Not a valid email address.')),
21+
DataRequired()])
22+
body = TextAreaField('Message', [
23+
DataRequired(),
24+
Length(min=4, message=('Your message is too short.'))])
25+
submit = SubmitField('Submit')
26+
27+
28+
class SignupForm(FlaskForm):
29+
"""Sign up for a user account."""
30+
email = StringField('Email', [
31+
Email(message=('Not a valid email address.')),
32+
DataRequired()])
33+
password = PasswordField('Password', [
34+
DataRequired(message="Please enter a password."),
35+
])
36+
confirmPassword = PasswordField('Repeat Password', [
37+
EqualTo(password, message='Passwords must match.')
38+
])
39+
title = SelectField('Title', [DataRequired()],
40+
choices=[('Farmer', 'Farmer'),
41+
('Corrupt Politician', 'Corrupt Politician'),
42+
('No-nonsense City Cop', 'No-nonsense City Cop'),
43+
('Professional Rocket League Player', 'Professional Rocket League Player'),
44+
('Lonely Guy At A Diner', 'Lonely Guy At A Diner'),
45+
('Pokemon Trainer', 'Pokemon Trainer')])
46+
website = StringField('Website', validators=[URL()])
47+
birthday = DateField('Your Birthday')
48+
recaptcha = RecaptchaField()
49+
submit = SubmitField('Submit')

start.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# start.sh
2+
3+
export FLASK_APP=app.py
4+
export FLASK_DEBUG=1
5+
export APP_CONFIG_FILE=config.py
6+
flask run

static/css/style.css

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
body {
2+
background: #e1eaf5;
3+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
4+
}
5+
6+
.container {
7+
padding: 80px;
8+
display: flex;
9+
justify-content: space-around;
10+
}
11+
12+
form {
13+
background: white;
14+
width: 100%;
15+
}
16+
17+
.form-field {
18+
position: relative;
19+
}
20+
21+
.title {
22+
font-size: 1.7rem;
23+
color: #5f6988;
24+
font-weight: 300;
25+
border-bottom: 1px solid #dbe3ec;
26+
padding-bottom: 5px;
27+
margin: 0 0 40px 0;
28+
}
29+
30+
.formwrapper {
31+
background: white;
32+
width: 350px;
33+
box-shadow: 0 0 5px rgba(65, 67, 144, 0.1);
34+
padding: 50px;
35+
}
36+
37+
label {
38+
font-size: .9em;
39+
color: #5f6988;
40+
margin-bottom: 3px;
41+
display: block;
42+
font-weight: 300;
43+
}
44+
45+
input, textarea, select {
46+
padding: 10px 13px;
47+
margin-bottom: 15px;
48+
width: -webkit-fill-available;
49+
border-radius: 2px;
50+
border: 1px solid #d4d9e3;
51+
font-weight: 200;
52+
color: #4d5060;
53+
font-family: 'Poppins', sans-serif;
54+
transition: all .3s ease-out;
55+
font-size: .9em;
56+
outline-color: transparent;
57+
outline-style: none;
58+
}
59+
60+
select {
61+
-webkit-appearance: none;
62+
}
63+
64+
select::after {
65+
content: "hello";
66+
width: 0;
67+
height: 0;
68+
border-left: 20px solid transparent;
69+
border-right: 20px solid transparent;
70+
display: block;
71+
border-top: 20px solid #f00;
72+
}
73+
74+
input[type="text"]::placeholder {
75+
color: #d4d9e3;
76+
}
77+
78+
input[type="text"]:hover,
79+
textarea:hover {
80+
border-color: #5eb9d7;
81+
background: #d9f6ff;
82+
}
83+
84+
input[type="text"]:focus,
85+
textarea:focus {
86+
background: white;
87+
border-color: #5eb9d7;
88+
box-shadow: unset;
89+
}
90+
91+
input[type="submit"] {
92+
background: #5eb9d7;
93+
border: 0;
94+
color: white;
95+
border-radius: 2px;
96+
margin-top: 15px;
97+
font-weight: 400;
98+
border: 1px solid #5eb9d7;
99+
transition: all .3s ease-out;
100+
}
101+
102+
input[type="submit"]:hover {
103+
cursor: pointer;
104+
background: white;
105+
color: #5eb9d7;
106+
}
107+
108+
.success-wrapper {
109+
background: white;
110+
width: 350px;
111+
box-shadow: 0 0 5px rgba(65, 67, 144, 0.1);
112+
padding: 50px;
113+
}
114+
115+
.errors {
116+
list-style: none;
117+
margin: 10px 0;
118+
position: absolute;
119+
z-index: 10;
120+
right: -222px;
121+
top: 0;
122+
bottom: 0;
123+
background: #fae7ea;
124+
padding: 9px 15px;
125+
border-radius: 3px;
126+
border: 1px solid #e1c5c5;
127+
color: #8d7575;
128+
width: 182px;
129+
text-align: center;
130+
height: fit-content;
131+
margin: auto;
132+
}

templates/contact.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{% extends 'layout.html' %}
2+
3+
{% block content %}
4+
<div class="formwrapper">
5+
<h2 class="title">Contact</h2>
6+
<form method="POST" action="/">
7+
<div class="form-field">{{ form.name.label }} {{ form.name(size=20) }}
8+
{% if form.name.errors %}
9+
<ul class="errors"> {% for error in form.name.errors %}<li>{{ error }}</li> {% endfor %} </ul>
10+
{% endif %}
11+
</div>
12+
<div class="form-field">{{ form.email.label }} {{ form.email }}
13+
{% if form.email.errors %}
14+
<ul class="errors"> {% for error in form.email.errors %}<li>{{ error }}</li> {% endfor %} </ul>
15+
{% endif %}
16+
</div>
17+
<div class="form-field">{{ form.body.label }} {{ form.body }}
18+
{% if form.body.errors %}
19+
<ul class="errors"> {% for error in form.body.errors %}<li>{{ error }}</li> {% endfor %} </ul>
20+
{% endif %}
21+
</div>
22+
{{ form.submit }}
23+
</form>
24+
</div>
25+
{% endblock %}

0 commit comments

Comments
 (0)