Flesh out admin, support multiple donations

This commit is contained in:
Drew DeVault 2015-09-06 15:45:23 -04:00
parent 76aae6d57e
commit 6a6cddc5b4
8 changed files with 73 additions and 12 deletions

View File

@ -74,5 +74,6 @@ def inject():
'user': current_user,
'_cfg': _cfg,
'_cfgi': _cfgi,
'debug': app.debug
'debug': app.debug,
'str': str
}

View File

@ -53,9 +53,11 @@ def admin():
first = request.args.get("first-run") is not None
projects = Project.query.all()
unspecified = Donation.query.filter(Donation.project == None).all()
donations = Donation.query.order_by(Donation.created.desc()).limit(50).all()
return render_template("admin.html",
first=first,
projects=projects,
donations=donations,
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.monthly]),
unspecified_one_times=sum([d.amount for d in unspecified if d.type == DonationType.one_time]),
@ -108,6 +110,8 @@ def donate():
type = request.form.get("type")
comment = request.form.get("comment")
project_id = request.form.get("project")
# validate and rejigger the form inputs
if not email or not stripe_token or not amount or not type:
return { "success": False, "reason": "Invalid request" }, 400
try:
@ -134,8 +138,13 @@ def donate():
customer = stripe.Customer.create(email=user.email, card=stripe_token)
user.stripe_customer = customer.id
db.add(user)
else:
customer = stripe.Customer.retrieve(user.stripe_customer)
new_source = customer.sources.create(source=stripe_token)
customer.default_source = new_source.id
customer.save()
donation = Donation(user, type, amount, project)
donation = Donation(user, type, amount, project, comment)
db.add(donation)
try:

View File

@ -60,14 +60,16 @@ class Donation(Base):
amount = Column(Integer, nullable=False)
created = Column(DateTime, nullable=False)
emailed_about = Column(Boolean, nullable=False)
comment = Column(String(512))
def __init__(self, user, type, amount, project=None):
def __init__(self, user, type, amount, project=None, comment=None):
self.user = user
self.type = type
self.amount = amount
self.created = datetime.now()
self.emailed_about = False
self.project = project
self.comment = comment
def __repr__(self):
return "<Donation {} from {}: ${} ({})>".format(

View File

@ -64,6 +64,8 @@
return;
}
donation.comment = document.getElementById("comments").value;
var handler = StripeCheckout.configure({
name: your_name,
key: window.stripe_key,

View File

@ -6,9 +6,14 @@
<div class="well">
<div class="container">
<p class="pull-right">
<a class="btn btn-default" href="logout">Log Out</a>
<a class="btn btn-primary" href="#" data-toggle="modal" data-target="#donation-button-modal">
Get donation button
</a>
<a class="btn btn-default" href="logout">Log out</a>
</p>
<h1>Donation Admin</h1>
<p>Combine this with your <a href="https://dashboard.stripe.com">Stripe
dashboard</a> for the full effect.</p>
</div>
</div>
<div class="container">
@ -52,7 +57,6 @@
<th>Project Name</th>
<th>One-time</th>
<th>Recurring</th>
<th>README Button</th>
</tr>
</thead>
<tbody>
@ -62,7 +66,6 @@
<td>{{ project.name }}</td>
<td>${{ "{:.2f}".format(one_times(project) / 100) }}</td>
<td>${{ "{:.2f}".format(recurring(project) / 100) }}</td>
<td><a href="#" class="btn btn-primary btn-sm">Get Markdown</a></td>
</tr>
{% endfor %}
<tr>
@ -70,7 +73,6 @@
<td>(not specified)</td>
<td>${{ "{:.2f}".format(unspecified_one_times / 100) }}</td>
<td>${{ "{:.2f}".format(unspecified_recurring / 100) }}</td>
<td></td>
</tr>
</tbody>
</table>
@ -86,7 +88,7 @@
</form>
</div>
</div>
<h2>Donation History</h2>
<h2>Recent Donations <small>50 most recent</small></h2>
<table class="table">
<thead>
<tr>
@ -94,9 +96,53 @@
<th>Project</th>
<th>Comment</th>
<th>Amount</th>
<th style="width: 10%">Recurring</th>
<th>Type</th>
</tr>
</thead>
<tbody>
{% for donation in donations %}
<tr>
<td><a href="mailto:{{ donation.user.email }}">{{ donation.user.email }}</a></td>
<td>{{ donation.project.name if donation.project else "" }}</td>
<td title="{{ donation.comment }}">{{ donation.comment if donation.comment else "" }}</td>
<td>${{ "{:.2f}".format(donation.amount / 100) }}</td>
<td>{{ "Once" if str(donation.type) == "DonationType.one_time" else "Monthly" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="modal fade" id="donation-button-modal" tabindex="-1" role="dialog" aria-labelledby="donation-modal-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">&times;</span>
</button>
<h4 class="modal-title" id="donation-modal-label">Donation buttons</h4>
</div>
<div class="modal-body">
<p>
You can include a donation button in various places to
drive people to your donation page. Here's how it looks:
<a href="..">
<img src="../static/donate-with-fosspay.png" />
</a>
</p>
<p>If you add <code>?project=1</code> to your URL, it will pre-select that project
(where 1 is the 1st project you have listed on this page) when users arrive to donate.</p>
<p><strong>Markdown</strong></p>
<pre>[![Donate with fosspay]({{root}}/static/donate-with-fosspay.png)]({{root}})</pre>
<p><strong>HTML</strong></p>
<pre>&lt;a href="{{root}}"&gt;&lt;img src="{{root}}/static/donate-with-fosspay.png" alt="Donate with fosspay" /&gt;&lt;/a&gt;</pre>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
Dismiss
</button>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -123,7 +123,7 @@ window.default_type = "{{ _cfg("default-type") }}";
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="form-group">
<input type="text" id="comments" class="form-control" placeholder="Any comments?" />
<input type="text" id="comments" class="form-control" placeholder="Any comments?" maxlength="512" />
</div>
</div>
</div>

View File

@ -2,6 +2,7 @@
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="static/icon.png" type="image/png" />
{% block title %}
<title>Donate to {{_cfg("your-name")}}</title>

View File

@ -3,8 +3,8 @@
<div class="well">
<div class="container">
<p class="pull-right">
<a class="btn btn-primary" href="..">Donate Again</a>
<a class="btn btn-default" href="logout">Log Out</a>
<a class="btn btn-primary" href="..">Donate again</a>
<a class="btn btn-default" href="logout">Log out</a>
</p>
<h1>Your Donations</h1>
</div>