Flesh out admin, support multiple donations
This commit is contained in:
parent
76aae6d57e
commit
6a6cddc5b4
|
@ -74,5 +74,6 @@ def inject():
|
|||
'user': current_user,
|
||||
'_cfg': _cfg,
|
||||
'_cfgi': _cfgi,
|
||||
'debug': app.debug
|
||||
'debug': app.debug,
|
||||
'str': str
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
return;
|
||||
}
|
||||
|
||||
donation.comment = document.getElementById("comments").value;
|
||||
|
||||
var handler = StripeCheckout.configure({
|
||||
name: your_name,
|
||||
key: window.stripe_key,
|
||||
|
|
|
@ -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">×</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><a href="{{root}}"><img src="{{root}}/static/donate-with-fosspay.png" alt="Donate with fosspay" /></a></pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue