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 .models import SustainerOrder | ||||
| 
 | ||||
| MONTH_MINIMUM = 10 | ||||
| YEAR_MINIMUM = 120 | ||||
| 
 | ||||
| class SustainerFormRenderer(forms.renderers.DjangoTemplates): | ||||
|     # Customised layout with labels on own row | ||||
|     field_template_name = 'supporters/field.html' | ||||
|  | @ -33,8 +30,10 @@ class SustainerForm(forms.ModelForm): | |||
| 
 | ||||
|     template_name = 'supporters/sustainer_form.html' | ||||
| 
 | ||||
|     MONTH_OPTIONS = [12, 25, 50, 100] | ||||
|     YEAR_OPTIONS = [128, 250, 500, 1000] | ||||
|     MONTH_OPTIONS = [12, 23, 45, 87] | ||||
|     YEAR_OPTIONS = [128, 256, 512, 1024] | ||||
|     MONTH_MINIMUM = 10 | ||||
|     YEAR_MINIMUM = 120 | ||||
| 
 | ||||
|     class Meta: | ||||
|         model = SustainerOrder | ||||
|  | @ -70,6 +69,8 @@ class SustainerForm(forms.ModelForm): | |||
|         # So we can write to this field easily from Alpine JS. | ||||
|         self.fields['amount'].widget.attrs['x-ref'] = 'amount' | ||||
|         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['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' | ||||
|  | @ -78,7 +79,7 @@ class SustainerForm(forms.ModelForm): | |||
|         super().clean() | ||||
|         recurring = self.cleaned_data.get('recurring', '') | ||||
|         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') | ||||
|         if amount < minimum: | ||||
|             self.add_error( | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
| .button-select label > span { | ||||
|   text-align: center; | ||||
|   display: inline-block; | ||||
|   user-select: none; | ||||
|   padding: 0.5rem 0; | ||||
|   width: 100%; | ||||
|   background: #ddd; | ||||
|  |  | |||
|  | @ -1,2 +1,2 @@ | |||
| <!-- 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 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 %} | ||||
|  |  | |||
|  | @ -63,25 +63,33 @@ | |||
|                    let year_options = {{ form.YEAR_OPTIONS|escapejs }}; | ||||
|                    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 }}', | ||||
|               }"> | ||||
|         {% csrf_token %} | ||||
|         <fieldset class="bg-black-05 pa3 br3 center" style="border: 1px solid #ccc"> | ||||
|           <legend class="b f5">Become a Sustainer</legend> | ||||
|           {{ form.non_field_errors }} | ||||
| 
 | ||||
|           <div>{{ form.recurring.as_field_group }}</div> | ||||
| 
 | ||||
|           <div class="mt3"> | ||||
|             <div id="amount_options" class="button-select"> | ||||
|               <template x-for="m in amount_options"> | ||||
|                 <label> | ||||
|                   <input type="radio" name="amount_option" x-bind:value="m" x-on:change="$refs.amount.value = $event.currentTarget.value" x-model="amount_option" required> | ||||
|                 {# Additional click handler ensures a click-drag activates the radio (similar to a real button). #} | ||||
|                 <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> | ||||
|                 </label> | ||||
|               </template> | ||||
|               <!-- Hide if no JS --> | ||||
|               <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> | ||||
|                   <span>Other</span> | ||||
|                 </label> | ||||
|  | @ -122,7 +130,12 @@ | |||
|         </fieldset> | ||||
|       </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"> | ||||
|         <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 | ||||
|           you want public acknowledgment in memo line.</p> | ||||
|       </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 style="grid-row: 1 / span 2"> | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue