Add site url and logo url to donate page output

Breaks up javascript into inherited views, based on core/payment.js. Adds a
migration to add the two fields.
front-end-standardization
Anthony Johnson 2015-04-16 13:46:03 -07:00
parent c5d39b83a1
commit 56ea87f6a1
12 changed files with 10322 additions and 14 deletions

View File

@ -13,7 +13,10 @@ var sources = {
'readthedocs/projects/static-src/**/tools.js'
],
'readthedocs/gold': [
'readthedocs/gold/static-src/**/payment.js'
'readthedocs/gold/static-src/**/gold.js'
],
'readthedocs/donate': [
'readthedocs/donate/static-src/**/donate.js'
]
};

View File

@ -719,6 +719,20 @@ ul.donate-supporters.donate-supporters-large > li {
overflow: hidden;
}
ul.donate-supporters div.supporter-logo {
height: 128px;
overflow: hidden;
line-height: 64px;
text-align: center;
}
ul.donate-supporters div.supporter-logo img {
display: inline;
width: 128px;
max-height: 128px;
vertical-align: bottom;
}
ul.donate-supporters div.supporter-name {
padding: 4px;
overflow: hidden;

View File

@ -18,13 +18,13 @@ if (typeof(window) != 'undefined' && typeof(window.Stripe) != 'undefined') {
stripe = window.Stripe || {};
}
function GoldView (config) {
function PaymentView (config) {
var self = this,
config = config || {};
// Config
stripe.publishableKey = self.stripe_key = config.key;
self.form = config.form || $('form#gold-payment');
self.form = config.form;
// Credit card parameters
self.cc_number = ko.observable(null);
@ -86,7 +86,7 @@ function GoldView (config) {
};
}
GoldView.prototype.initialize_form = function () {
PaymentView.prototype.initialize_form = function () {
var cc_number = $('input#cc-number'),
cc_cvv = $('input#cc-cvv'),
cc_expiry = $('input#cc-expiry');
@ -96,14 +96,14 @@ GoldView.prototype.initialize_form = function () {
cc_cvv.payment('formatCardCVC');
};
GoldView.init = function (config, obj) {
PaymentView.init = function (config, obj) {
var view = new GoldView(config),
obj = obj || $('#payment-form')[0];
ko.applyBindings(view, obj);
return view;
}
module.exports.GoldView = GoldView;
module.exports.PaymentView = PaymentView;
if (typeof(window) != 'undefined') {

View File

@ -21,13 +21,29 @@ class SupporterForm(forms.ModelForm):
'name',
'email',
'dollars',
'logo_url',
'site_url',
'public',
)
labels = {
'public': _('Make this donation public'),
}
help_texts = {
'public': _('Your name and gravatar will be displayed on the donation page'),
'public': _('Your name and image will be displayed on the donation page'),
'email': _('Your email is used for Gravatar and so we can send you a receipt'),
'logo_url': _("URL of your company's logo, images should be 300x300 pixels or less"),
'dollars': _('Companies donating over $400 can specify a logo URL and site link'),
}
widgets = {
'dollars': forms.Select(attrs={
'data-bind': 'value: dollars'
}),
'logo_url': forms.TextInput(attrs={
'data-bind': 'value: logo_url, enable: urls_enabled'
}),
'site_url': forms.TextInput(attrs={
'data-bind': 'value: site_url, enable: urls_enabled'
})
}
last_4_digits = forms.CharField(widget=forms.HiddenInput(), required=True)
@ -38,6 +54,11 @@ class SupporterForm(forms.ModelForm):
super(SupporterForm, self).__init__(*args, **kwargs)
def clean(self):
'''Call stripe for payment (not ideal here) and clean up logo < $200'''
dollars = self.cleaned_data['dollars']
if dollars < 200:
self.cleaned_data['logo_url'] = None
self.cleaned_data['site_url'] = None
try:
stripe.api_key = settings.STRIPE_SECRET
stripe.Charge.create(

View File

@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Supporter.logo_url'
db.add_column(u'donate_supporter', 'logo_url',
self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True),
keep_default=False)
# Adding field 'Supporter.site_url'
db.add_column(u'donate_supporter', 'site_url',
self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Supporter.logo_url'
db.delete_column(u'donate_supporter', 'logo_url')
# Deleting field 'Supporter.site_url'
db.delete_column(u'donate_supporter', 'site_url')
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'donate.supporter': {
'Meta': {'object_name': 'Supporter'},
'dollars': ('django.db.models.fields.IntegerField', [], {'default': '50', 'max_length': '30'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '200', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_4_digits': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'site_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'stripe_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'subscribed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'goldonce'", 'null': 'True', 'to': u"orm['auth.User']"})
}
}
complete_apps = ['donate']

View File

@ -27,6 +27,10 @@ class Supporter(models.Model):
related_name='goldonce', blank=True, null=True)
dollars = models.IntegerField(_('Amount'), max_length=30,
choices=AMOUNT_CHOICES, default=50)
logo_url = models.URLField(_('Logo URL'), max_length=255, blank=True,
null=True)
site_url = models.URLField(_('Site URL'), max_length=255, blank=True,
null=True)
last_4_digits = models.CharField(max_length=4)
stripe_id = models.CharField(max_length=255)

View File

@ -0,0 +1,45 @@
// Donate payment views
var payment = require('../../../../core/static-src/core/js/payment'),
ko = require('knockout');
function DonateView (config) {
var self = this,
config = config || {};
ko.utils.extend(self, new payment.PaymentView(config));
self.dollars = ko.observable();
self.logo_url = ko.observable();
self.site_url = ko.observable();
ko.computed(function () {
var input_logo = window.$('input#id_logo_url').closest('p'),
input_site = window.$('input#id_site_url').closest('p');
if (self.dollars() < 400) {
self.logo_url(null);
self.site_url(null);
input_logo.hide();
input_site.hide();
}
else {
input_logo.show();
input_site.show();
}
});
self.urls_enabled = ko.computed(function () {
return (self.dollars() >= 400);
});
}
DonateView.init = function (config, obj) {
var view = new DonateView(config),
obj = obj || $('#donate-payment')[0];
ko.applyBindings(view, obj);
return view;
}
module.exports.DonateView = DonateView;
if (typeof(window) != 'undefined') {
window.donate = module.exports;
}

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
{% block extra_scripts %}
<script src="https://js.stripe.com/v2/" type="text/javascript"></script>
<script type="text/javascript" src="{% static 'gold/js/payment.js' %}"></script>
<script type="text/javascript" src="{% static 'donate/js/donate.js' %}"></script>
<script type="text/javascript">
$(document).ready(function () {
var key;
@ -15,7 +15,7 @@ $(document).ready(function () {
key = '{{ publishable }}';
//]]>
var view = payment.GoldView.init({
var view = donate.DonateView.init({
key: key,
form: $('form#donate-payment')
});

View File

@ -105,7 +105,13 @@
<ul class="donate-supporters donate-supporters-large">
{% for user in supporters|slice:"0:50" %}
<li>
<div class="supporter-gravatar">{% gravatar user.email 128 %}</div>
{% if user.logo_url %}
<div class="supporter-logo">
<a href="{{ user.site_url }}"><img src="{{ user.logo_url }}" alt="{{ user.name }}" /></a>
</div>
{% else %}
<div class="supporter-gravatar">{% gravatar user.email 128 %}</div>
{% endif %}
<div class="supporter-name">{{ user.name|truncatechars:50 }}</div>
</li>
{% endfor %}

View File

@ -0,0 +1,25 @@
// Gold payment views
var payment = require('../../../../core/static-src/core/js/payment'),
ko = require('knockout');
function GoldView (config) {
var self = this,
config = config || {};
ko.utils.extend(self, new payment.PaymentView(config));
}
GoldView.init = function (config, obj) {
var view = new GoldView(config),
obj = obj || $('#payment-form')[0];
ko.applyBindings(view, obj);
return view;
}
module.exports.GoldView = GoldView;
if (typeof(window) != 'undefined') {
window.payment = module.exports;
}

View File

@ -9936,13 +9936,13 @@ if (typeof(window) != 'undefined' && typeof(window.Stripe) != 'undefined') {
stripe = window.Stripe || {};
}
function GoldView (config) {
function PaymentView (config) {
var self = this,
config = config || {};
// Config
stripe.publishableKey = self.stripe_key = config.key;
self.form = config.form || $('form#gold-payment');
self.form = config.form;
// Credit card parameters
self.cc_number = ko.observable(null);
@ -10004,7 +10004,7 @@ function GoldView (config) {
};
}
GoldView.prototype.initialize_form = function () {
PaymentView.prototype.initialize_form = function () {
var cc_number = $('input#cc-number'),
cc_cvv = $('input#cc-cvv'),
cc_expiry = $('input#cc-expiry');
@ -10014,6 +10014,33 @@ GoldView.prototype.initialize_form = function () {
cc_cvv.payment('formatCardCVC');
};
PaymentView.init = function (config, obj) {
var view = new GoldView(config),
obj = obj || $('#payment-form')[0];
ko.applyBindings(view, obj);
return view;
}
module.exports.PaymentView = PaymentView;
if (typeof(window) != 'undefined') {
window.payment = module.exports;
}
},{"./../../../../../bower_components/jquery.payment/lib/jquery.payment.js":1,"./../../../../../bower_components/jquery/dist/jquery.js":2,"./../../../../../bower_components/knockout/dist/knockout.js":3}],5:[function(require,module,exports){
// Gold payment views
var payment = require('../../../../core/static-src/core/js/payment'),
ko = require("./../../../../../bower_components/knockout/dist/knockout.js");
function GoldView (config) {
var self = this,
config = config || {};
ko.utils.extend(self, new payment.PaymentView(config));
}
GoldView.init = function (config, obj) {
var view = new GoldView(config),
obj = obj || $('#payment-form')[0];
@ -10028,4 +10055,4 @@ if (typeof(window) != 'undefined') {
window.payment = module.exports;
}
},{"./../../../../../bower_components/jquery.payment/lib/jquery.payment.js":1,"./../../../../../bower_components/jquery/dist/jquery.js":2,"./../../../../../bower_components/knockout/dist/knockout.js":3}]},{},[4])
},{"../../../../core/static-src/core/js/payment":4,"./../../../../../bower_components/knockout/dist/knockout.js":3}]},{},[5])