supporters: Fix monthly amounts, validate minimum amount in frontend, update PayPal info
This commit is contained in:
parent
e9f0909d8c
commit
68c5199bb5
5 changed files with 34 additions and 17 deletions
|
@ -3,9 +3,6 @@ from django.utils.safestring import mark_safe
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from .models import SustainerOrder
|
from .models import SustainerOrder
|
||||||
|
|
||||||
MONTH_MINIMUM = 10
|
|
||||||
YEAR_MINIMUM = 120
|
|
||||||
|
|
||||||
class SustainerFormRenderer(forms.renderers.DjangoTemplates):
|
class SustainerFormRenderer(forms.renderers.DjangoTemplates):
|
||||||
# Customised layout with labels on own row
|
# Customised layout with labels on own row
|
||||||
field_template_name = 'supporters/field.html'
|
field_template_name = 'supporters/field.html'
|
||||||
|
@ -33,8 +30,10 @@ class SustainerForm(forms.ModelForm):
|
||||||
|
|
||||||
template_name = 'supporters/sustainer_form.html'
|
template_name = 'supporters/sustainer_form.html'
|
||||||
|
|
||||||
MONTH_OPTIONS = [12, 25, 50, 100]
|
MONTH_OPTIONS = [12, 23, 45, 87]
|
||||||
YEAR_OPTIONS = [128, 250, 500, 1000]
|
YEAR_OPTIONS = [128, 256, 512, 1024]
|
||||||
|
MONTH_MINIMUM = 10
|
||||||
|
YEAR_MINIMUM = 120
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SustainerOrder
|
model = SustainerOrder
|
||||||
|
@ -70,6 +69,8 @@ class SustainerForm(forms.ModelForm):
|
||||||
# So we can write to this field easily from Alpine JS.
|
# So we can write to this field easily from Alpine JS.
|
||||||
self.fields['amount'].widget.attrs['x-ref'] = 'amount'
|
self.fields['amount'].widget.attrs['x-ref'] = 'amount'
|
||||||
self.fields['amount'].widget.attrs['style'] = 'width: 5rem'
|
self.fields['amount'].widget.attrs['style'] = 'width: 5rem'
|
||||||
|
self.fields['amount'].widget.attrs['onblur'] = 'this.reportValidity()'
|
||||||
|
self.fields['amount'].widget.attrs['x-bind:min'] = 'amount_minimum'
|
||||||
self.fields['email'].help_text = 'For your payment receipt'
|
self.fields['email'].help_text = 'For your payment receipt'
|
||||||
self.fields['tshirt_size'].help_text = mark_safe("""Sizing chart: <a href="/videos/women-2017-to-2020-t-shirt-sizing.jpg" target="_blank" class="black-60">Women's</a>, <a href="/videos/men-2017-to-2020-t-shirt-sizing.jpg" target="_blank" class="black-60">Men's</a>""")
|
self.fields['tshirt_size'].help_text = mark_safe("""Sizing chart: <a href="/videos/women-2017-to-2020-t-shirt-sizing.jpg" target="_blank" class="black-60">Women's</a>, <a href="/videos/men-2017-to-2020-t-shirt-sizing.jpg" target="_blank" class="black-60">Men's</a>""")
|
||||||
self.fields['tshirt_size'].widget.attrs['x-model'] = 'tshirt_size'
|
self.fields['tshirt_size'].widget.attrs['x-model'] = 'tshirt_size'
|
||||||
|
@ -78,7 +79,7 @@ class SustainerForm(forms.ModelForm):
|
||||||
super().clean()
|
super().clean()
|
||||||
recurring = self.cleaned_data.get('recurring', '')
|
recurring = self.cleaned_data.get('recurring', '')
|
||||||
amount = self.cleaned_data.get('amount', 0)
|
amount = self.cleaned_data.get('amount', 0)
|
||||||
minimum = MONTH_MINIMUM if recurring == 'month' else YEAR_MINIMUM
|
minimum = self.MONTH_MINIMUM if recurring == 'month' else self.YEAR_MINIMUM
|
||||||
donate_url = reverse('donate')
|
donate_url = reverse('donate')
|
||||||
if amount < minimum:
|
if amount < minimum:
|
||||||
self.add_error(
|
self.add_error(
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
.button-select label > span {
|
.button-select label > span {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
user-select: none;
|
||||||
padding: 0.5rem 0;
|
padding: 0.5rem 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: #ddd;
|
background: #ddd;
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
<!-- Custom <span> wrapper around the label to enable radio fields to be styled like buttons. -->
|
<!-- Custom <span> wrapper around the label to enable radio fields to be styled like buttons. -->
|
||||||
{% if widget.wrap_label %}<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %}>{% endif %}{% include "django/forms/widgets/input.html" %}{% if widget.wrap_label %} <span>{{ widget.label }}</span></label>{% endif %}
|
{% if widget.wrap_label %}<label onclick="click()"{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %}>{% endif %}{% include "django/forms/widgets/input.html" %}{% if widget.wrap_label %} <span>{{ widget.label }}</span></label>{% endif %}
|
||||||
|
|
|
@ -4,5 +4,12 @@
|
||||||
{% block category %}sustainer{% endblock %}
|
{% block category %}sustainer{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="lh-title tc mt4 mb4">Thanks!</h1>
|
<h1 class="lh-title tc mt4">Thanks</h1>
|
||||||
|
<p class="measure-wide center tc">Thank you for helping make our work possible!</p>
|
||||||
|
|
||||||
|
<div class="mt4 tc">
|
||||||
|
<img src="{% static 'img/conservancy-supporter-heart.png' %}" alt="Heart with Conservancy logo">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="tc mt4 mb5">Return to our <a href="{% url 'sustainers' %}">sustainers</a> page.</p>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -63,25 +63,33 @@
|
||||||
let year_options = {{ form.YEAR_OPTIONS|escapejs }};
|
let year_options = {{ form.YEAR_OPTIONS|escapejs }};
|
||||||
return this.recurring === 'month' ? month_options : year_options;
|
return this.recurring === 'month' ? month_options : year_options;
|
||||||
},
|
},
|
||||||
|
amount_minimum: function() {
|
||||||
|
let month_minimum = {{ form.MONTH_MINIMUM|escapejs }};
|
||||||
|
let year_minimum = {{ form.YEAR_MINIMUM|escapejs }};
|
||||||
|
return this.recurring === 'month' ? month_minimum : year_minimum;
|
||||||
|
},
|
||||||
tshirt_size: '{{ form.tshirt_size.value|escapejs }}',
|
tshirt_size: '{{ form.tshirt_size.value|escapejs }}',
|
||||||
}">
|
}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<fieldset class="bg-black-05 pa3 br3 center" style="border: 1px solid #ccc">
|
<fieldset class="bg-black-05 pa3 br3 center" style="border: 1px solid #ccc">
|
||||||
<legend class="b f5">Become a Sustainer</legend>
|
<legend class="b f5">Become a Sustainer</legend>
|
||||||
{{ form.non_field_errors }}
|
{{ form.non_field_errors }}
|
||||||
|
|
||||||
<div>{{ form.recurring.as_field_group }}</div>
|
<div>{{ form.recurring.as_field_group }}</div>
|
||||||
|
|
||||||
<div class="mt3">
|
<div class="mt3">
|
||||||
<div id="amount_options" class="button-select">
|
<div id="amount_options" class="button-select">
|
||||||
<template x-for="m in amount_options">
|
<template x-for="m in amount_options">
|
||||||
<label>
|
{# Additional click handler ensures a click-drag activates the radio (similar to a real button). #}
|
||||||
<input type="radio" name="amount_option" x-bind:value="m" x-on:change="$refs.amount.value = $event.currentTarget.value" x-model="amount_option" required>
|
<label onclick="this.click()">
|
||||||
|
{# It seems to be important that all radios have a unique value to avoid UI glitches. #}
|
||||||
|
<input type="radio" name="amount_option" x-bind:value="m" x-on:change="$refs.amount.value = m" x-model="amount_option" required>
|
||||||
<span>$<span x-text="m.toLocaleString()"></span></span>
|
<span>$<span x-text="m.toLocaleString()"></span></span>
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
<!-- Hide if no JS -->
|
<!-- Hide if no JS -->
|
||||||
<template x-if="true">
|
<template x-if="true">
|
||||||
<label>
|
<label onclick="this.click()">
|
||||||
<input type="radio" name="amount_option" value="other" x-on:change="$refs.amount.value = ''" x-model="amount_option" required>
|
<input type="radio" name="amount_option" value="other" x-on:change="$refs.amount.value = ''" x-model="amount_option" required>
|
||||||
<span>Other</span>
|
<span>Other</span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -122,7 +130,12 @@
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p class="f7 mt3">Credit card and ACH payments are processed with Stripe. We also accept payment by paper check and wire transfer and PayPal (see below). Our sustainer program has a minimum of $120 USD per year, but we also accept <a href="/donate/">donations of smaller amounts</a>.</p>
|
<p class="f7 mt3">Credit card and ACH payments are processed with Stripe. We also accept payment by PayPal, paper check and wire transfer (see below). Our sustainer program has a minimum of $120 USD per year, but we also accept <a href="/donate/">donations of smaller amounts</a>.</p>
|
||||||
|
|
||||||
|
<details id="paypal">
|
||||||
|
<summary class="f6">PayPal</summary>
|
||||||
|
<p>If you would prefer not to use our Stripe payment service above you can use <a href="{% url 'sustainer_paypal' %}">PayPal</a>.</p>
|
||||||
|
</details>
|
||||||
|
|
||||||
<details id="wire-transfer">
|
<details id="wire-transfer">
|
||||||
<summary class="f6">Wire Transfer</summary>
|
<summary class="f6">Wire Transfer</summary>
|
||||||
|
@ -139,11 +152,6 @@
|
||||||
<p>Please write <q>SUSTAINER</q>, T-shirt size, if you are renewing, and if
|
<p>Please write <q>SUSTAINER</q>, T-shirt size, if you are renewing, and if
|
||||||
you want public acknowledgment in memo line.</p>
|
you want public acknowledgment in memo line.</p>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details id="paypal">
|
|
||||||
<summary class="f6">PayPal</summary>
|
|
||||||
<p>Please visit our <a href="{% url 'sustainer_paypal' %}">Become a Sustainer by PayPal</a> page.</p>
|
|
||||||
</details>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section style="grid-row: 1 / span 2">
|
<section style="grid-row: 1 / span 2">
|
||||||
|
|
Loading…
Reference in a new issue