Flesh out donation page
This commit is contained in:
parent
eaa42767aa
commit
7a144f71f0
|
@ -6,6 +6,7 @@ from fosspay.common import *
|
|||
from fosspay.config import _cfg, load_config
|
||||
|
||||
import locale
|
||||
import bcrypt
|
||||
|
||||
encoding = locale.getdefaultlocale()[1]
|
||||
html = Blueprint('html', __name__, template_folder='../../templates')
|
||||
|
@ -15,7 +16,8 @@ def index():
|
|||
if User.query.count() == 0:
|
||||
load_config()
|
||||
return render_template("setup.html")
|
||||
return render_template("index.html")
|
||||
projects = sorted(Project.query.all(), key=lambda p: p.name)
|
||||
return render_template("index.html", projects=projects)
|
||||
|
||||
@html.route("/setup", methods=["POST"])
|
||||
def setup():
|
||||
|
@ -37,12 +39,15 @@ def setup():
|
|||
def admin():
|
||||
first = request.args.get("first-run") is not None
|
||||
projects = Project.query.all()
|
||||
unspecified = Donation.query.filter(Donation.project == None).all()
|
||||
return render_template("admin.html",
|
||||
first=first,
|
||||
projects=projects,
|
||||
one_times=lambda p: sum([d.amount for d in p.donations if d.type == DonationType.one_time]),
|
||||
recurring=lambda p: sum([d.amount for d in p.donations if d.type == DonationType.recurring])
|
||||
)
|
||||
first=first,
|
||||
projects=projects,
|
||||
one_times=lambda p: sum([d.amount for d in p.donations if d.type == DonationType.one_time]),
|
||||
recurring=lambda p: sum([d.amount for d in p.donations if d.type == DonationType.recurring]),
|
||||
unspecified_one_times=sum([d.amount for d in unspecified if d.type == DonationType.one_time]),
|
||||
unspecified_recurring=sum([d.amount for d in unspecified if d.type == DonationType.recurring])
|
||||
)
|
||||
|
||||
@html.route("/create-project", methods=["POST"])
|
||||
@adminrequired
|
||||
|
@ -53,6 +58,22 @@ def create_project():
|
|||
db.commit()
|
||||
return redirect("/admin")
|
||||
|
||||
@html.route("/login", methods=["GET", "POST"])
|
||||
def login():
|
||||
if request.method == "GET":
|
||||
return render_template("login.html")
|
||||
email = request.form.get("email")
|
||||
password = request.form.get("password")
|
||||
if not email or not password:
|
||||
return render_template("login.html", errors=True)
|
||||
user = User.query.filter(User.email == email).first()
|
||||
if not user:
|
||||
return render_template("login.html", errors=True)
|
||||
if not bcrypt.hashpw(password.encode('UTF-8'), user.password.encode('UTF-8')) == user.password.encode('UTF-8'):
|
||||
return render_template("login.html", errors=True)
|
||||
login_user(user)
|
||||
return redirect("/")
|
||||
|
||||
@html.route("/logout")
|
||||
@loginrequired
|
||||
def logout():
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
{% block title %}
|
||||
<title>Donation Admin</title>
|
||||
{% endblock %}
|
||||
{% block container %}
|
||||
<a href="/logout" class="pull-right">Log out</a>
|
||||
<h1>Fosspay Admin</h1>
|
||||
{% if first %}
|
||||
|
@ -50,11 +53,19 @@
|
|||
<td><a href="#" class="btn btn-primary btn-sm">Get Markdown</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>(not specified)</td>
|
||||
<td>${{ unspecified_one_times }}</td>
|
||||
<td>${{ unspecified_recurring }}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-6 well">
|
||||
<h4>Add Project</h4>
|
||||
<p>Donors will not be given a choice of project unless you have at least 2.</p>
|
||||
<form method="POST" action="/create-project">
|
||||
<div class="form-group">
|
||||
<input class="form-control" type="text" placeholder="Project name" name="name" />
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<p>
|
||||
Donations accumulate until they reach enough to support a week of full
|
||||
time work. Once they get to this amount, a week will be scheduled. The
|
||||
amount of time each project receives is planned based on the amount of
|
||||
donations received that specify that project in the drop-down.
|
||||
</p>
|
||||
<p>
|
||||
If one project receives a million dollars and another project receives
|
||||
one dollar, at least an hour will be spent on the second project.
|
||||
</p>
|
|
@ -0,0 +1,112 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
<div class="well">
|
||||
<div class="container">
|
||||
<h1>Donate to {{ _cfg("your-name") }}</h1>
|
||||
<p><a href="#" data-toggle="modal" data-target="#how-this-works-modal">How does this work?</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<noscript>
|
||||
<div class="container">
|
||||
<div class="alert alert-danger">
|
||||
<p>This page requires Javascript. It's necessary to send your credit card number to
|
||||
<a href="https://stripe.com/">Stripe</a> directly, so you don't need to trust me with it.</p>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
<div class="container text-center">
|
||||
<h3>How much?</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">$5</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">$10</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">$20</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">$50</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">Custom</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3>How often?</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<div class="btn-group btn-group-justified" role="group" aria-label="...">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">Once</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-default">Monthly</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if len(projects) > 1 %}
|
||||
<h3>What project?</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<div class="form-group">
|
||||
<select>
|
||||
<option value="none">None in particular</option>
|
||||
{% for project in projects %}
|
||||
<option value="{{ project.id }}">{{ project.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="Any comments?" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 50px">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<button class="btn btn-block btn-success">Donate</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="container text-center">
|
||||
<p>
|
||||
<small class="text-muted">
|
||||
Been here before? <a href="/login">Log in</a> to view your donation
|
||||
history, edit recurring donations, and so on.
|
||||
</small>
|
||||
</p>
|
||||
<p>
|
||||
<small class="text-muted">
|
||||
Powered by <a href="https://github.com/SirCmpwn/fosspay">fosspay</a>.
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="how-this-works-modal" tabindex="-1" role="dialog" aria-labelledby="how-label">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="how-label">How does this work?</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% include "how-this-works.html" %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Dismiss</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -5,10 +5,15 @@
|
|||
<title>Donate to {{_cfg("your-name")}}</title>
|
||||
{% endblock %}
|
||||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
|
||||
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
{% block body %}
|
||||
<div class="container">
|
||||
{% block body %}{% endblock %}
|
||||
{% block container %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
{% extends "layout.html" %}
|
||||
{% block container %}
|
||||
<h1>Log In</h1>
|
||||
{% if errors %}
|
||||
<div class="alert alert-danger">
|
||||
<p>
|
||||
Username or password incorrect.
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<form action="/login" method="POST">
|
||||
<div class="form-group">
|
||||
<input class="form-control" type="text" name="email" placeholder="you@email.com" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input class="form-control" type="password" name="password" placeholder="Password" />
|
||||
</div>
|
||||
<input type="submit" value="Log in" class="btn btn-primary" />
|
||||
</form>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue