Skip to content
This repository has been archived by the owner on Mar 27, 2023. It is now read-only.

Commit

Permalink
Revert "Release (#1188)"
Browse files Browse the repository at this point in the history
This reverts commit 5f33843.
  • Loading branch information
vincemtnz committed Jun 14, 2018
1 parent 5f33843 commit 40ba347
Show file tree
Hide file tree
Showing 17 changed files with 1,108 additions and 67 deletions.
23 changes: 20 additions & 3 deletions app/javascript/components/ComponentWrapper.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
/* @flow */
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { IntlProvider } from 'react-intl';
import { IntlProvider, addLocaleData } from 'react-intl';
import loadTranslations from '../util/TranslationsLoader';
import enLocaleData from 'react-intl/locale-data/en';
import deLocaleData from 'react-intl/locale-data/de';
import frLocaleData from 'react-intl/locale-data/fr';
import esLocaleData from 'react-intl/locale-data/es';

addLocaleData([
...enLocaleData,
...deLocaleData,
...frLocaleData,
...esLocaleData,
]);

function WrapInStore({ store, children }) {
if (store) {
return <Provider store={store}>{children}</Provider>;
return (
<Provider store={store}>
{children}
</Provider>
);
}
return children;
}
Expand Down Expand Up @@ -41,7 +56,9 @@ export default class ComponentWrapper extends Component {
messages={this.props.messages || loadTranslations(this.props.locale)}
>
<WrapInStore store={this.props.store}>
<div className="App">{this.props.children}</div>
<div className="App">
{this.props.children}
</div>
</WrapInStore>
</IntlProvider>
);
Expand Down
5 changes: 1 addition & 4 deletions app/javascript/member-facing/backbone/action_form.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import $ from 'jquery';
import I18n from 'champaign-i18n';
import React from 'react';
import { render } from 'react-dom';
import _ from 'lodash';
Expand Down Expand Up @@ -314,9 +313,7 @@ const ActionForm = Backbone.View.extend({
},

handleSuccess(e, data) {
// FIXME: we should return consistently from the backend
// FIXME: we should not rely on mutating function arguments of unkown type
if (typeof data === 'object') data.petitionForm = this.formValues();
data.petitionForm = this.formValues();
Backbone.trigger('form:submitted', e, data);
},

Expand Down
198 changes: 198 additions & 0 deletions app/javascript/member-facing/backbone/braintree_hosted_fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import $ from 'jquery';
import _ from 'lodash';
import Backbone from 'backbone';

const BRAINTREE_TOKEN_URL =
process.env.BRAINTREE_TOKEN_URL || '/api/payment/braintree/token';

const BraintreeHostedFields = Backbone.View.extend({
el: '.hosted-fields-view',
TOKEN_WAIT_BEFORE_RETRY: 1500,
TOKEN_RETRY_LIMIT: 5,
SELECTOR_TO_HIDE_ON_PAYPAL_SUCCESS:
'.hosted-fields__credit-card-fields, .hosted-fields__direct-debit-container',

initialize() {
this.getClientToken(this.setupFields.bind(this));
this.tokenRetries = 0;
},

braintreeSettings() {
return {
id: 'hosted-fields',
onPaymentMethodReceived: this.paymentMethodReceived.bind(this),
onError: this.handleErrors.bind(this),
onReady: bt => {
this.deviceData = bt.deviceData;
this.hideSpinner();
},
dataCollector: {
kount: { environment: 'production' },
},
paypal: {
container: 'hosted-fields__paypal',
onCancelled: () => {
this.$(this.SELECTOR_TO_HIDE_ON_PAYPAL_SUCCESS).slideDown();
},
onSuccess: () => {
this.$(this.SELECTOR_TO_HIDE_ON_PAYPAL_SUCCESS).slideUp();
},
locale: I18n.currentLocale(),
},
hostedFields: {
number: {
selector: '.hosted-fields__number',
placeholder: I18n.t('fundraiser.fields.number'),
},
cvv: {
selector: '.hosted-fields__cvv',
placeholder: I18n.t('fundraiser.fields.cvv'),
},
expirationDate: {
selector: '.hosted-fields__expiration',
placeholder: I18n.t('fundraiser.fields.expiration_format'),
},
styles: {
input: {
'font-size': '16px',
},
},
onFieldEvent: this.fieldUpdate.bind(this),
},
};
},

injectDeviceData(deviceData) {
const $form = this.$('form');

form.append(
$("<input name='device_data' type='hidden' />").val(deviceData)
);
},

fieldUpdate(event) {
if (event.type === 'fieldStateChange') {
if (event.isPotentiallyValid) {
this.clearError(event.target.fieldKey);
} else {
this.showError(
event.target.fieldKey,
I18n.t('errors.probably_invalid')
);
}
if (event.target.fieldKey == 'number') {
if (event.isEmpty) {
this.$('.hosted-fields__button-container').removeClass(
'hosted-fields--grayed-out'
);
} else {
this.$('.hosted-fields__button-container').addClass(
'hosted-fields--grayed-out'
);
}
}
this.showCardType(event.card);
}
},

setupFields(clientToken) {
braintree.setup(clientToken, 'custom', this.braintreeSettings());
},

hideSpinner() {
this.$('.fundraiser-bar__fields-loading').addClass('hidden-closed');
this.$('#hosted-fields').removeClass('hidden-closed');
Backbone.trigger('sidebar:height_change');
},

handleErrors(error) {
Backbone.trigger('fundraiser:server_error');
if (
error.details !== undefined &&
error.details.invalidFieldKeys !== undefined
) {
_.each(error.details.invalidFieldKeys, key => {
this.showError(key, I18n.t('errors.is_invalid'));
});
}
},

showError(fieldName, msg) {
fieldName = this.standardizeFieldName(fieldName);
const $holder = $(`.hosted-fields__${fieldName}`).parent();
$holder.find('.error-msg').remove();
$holder.append(
`<div class='error-msg'>${this.translateFieldName(
fieldName
)} ${msg}</div>`
);
},

showCardType(card) {
if (card == null || card.type == null) {
this.$('.hosted-fields__card-type').addClass('hidden-irrelevant');
} else {
const icons = {
'diners-club': 'fa-cc-diners-club',
jcb: 'fa-cc-jcb',
'american-express': 'fa-cc-amex',
discover: 'fa-cc-discover',
'master-card': 'fa-cc-mastercard',
visa: 'fa-cc-visa',
};
const $cardType = this.$('.hosted-fields__card-type');
$cardType.removeClass($cardType.data('card-class'));
if (icons[card.type] !== undefined) {
$cardType
.addClass(icons[card.type])
.data('card-class', icons[card.type])
.removeClass('hidden-irrelevant');
}
}
},

clearError(fieldName) {
fieldName = this.standardizeFieldName(fieldName);
this.$(`.hosted-fields__${fieldName}`).parent().find('.error-msg').remove();
},

standardizeFieldName(fieldName) {
return /expiration/.test(fieldName) ? 'expiration' : fieldName;
},

translateFieldName(fieldName) {
if (
['expiration', 'cvv', 'number', 'postalCode'].indexOf(
this.standardizeFieldName(fieldName)
) > -1
) {
return I18n.t(`fundraiser.field_names.${fieldName}`);
} else {
return fieldName;
}
},

getClientToken(callback) {
$.get(BRAINTREE_TOKEN_URL, function(resp, success) {
callback(resp.token);
}).fail(error => {
// this code tries to fetch the token again and again
// when fetching the token fails
this.tokenRetries += 1;
if (this.tokenRetries < this.TOKEN_RETRY_LIMIT) {
window.setTimeout(() => {
this.getClientToken(callback);
}, this.TOKEN_WAIT_BEFORE_RETRY);
}
});
},

paymentMethodReceived(data) {
Backbone.trigger('fundraiser:nonce_received', {
nonce: data.nonce,
deviceData: this.deviceData,
});
},
});

export default BraintreeHostedFields;
96 changes: 96 additions & 0 deletions app/javascript/member-facing/backbone/currency_methods.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import _ from 'lodash';

const CurrencyMethods = {
DEFAULT_CURRENCY: 'USD',
DEFAULT_DONATION_BANDS: {
GBP: [1, 3, 10, 15, 35],
USD: [2, 5, 10, 25, 50],
EUR: [2, 5, 10, 25, 45],
CHF: [1, 3, 10, 15, 35],
AUD: [3, 10, 15, 35, 70],
CAD: [3, 10, 15, 35, 70],
NZD: [3, 10, 15, 35, 75],
},
CURRENCY_SYMBOLS: {
USD: '$',
EUR: '€',
GBP: '£',
CHF: 'Fr',
CAD: '$',
AUD: '$',
NZD: '$',
},

showDonationBandForCurrency(currency) {
const candidates = [
[this.donationBands, currency],
[this.DEFAULT_DONATION_BANDS, currency],
[this.donationBands, 'USD'],
[this.DEFAULT_DONATION_BANDS, 'USD'],
];
for (let ii = 0; ii < candidates.length; ii++) {
const denomination = candidates[ii][1];
const band = candidates[ii][0][denomination];
if (band !== undefined) {
return this.showDonationBand(band, currency);
}
}
},

showDonationBand(amounts, currency) {
const $buttonContainer = this.$('.fundraiser-bar__amount-buttons');
$buttonContainer.html('');
for (let ii = 0; ii < amounts.length; ii++) {
const tag = `<div class="fundraiser-bar__amount-button" data-amount="${
amounts[ii]
}">${this.CURRENCY_SYMBOLS[currency]}${amounts[ii]}</div>`;
$buttonContainer.append(tag);
}
},

setCurrency(currency_with_case) {
const currency = currency_with_case.toUpperCase();
if (this.CURRENCY_SYMBOLS[currency] === undefined) {
this.currency = this.DEFAULT_CURRENCY;
} else {
this.currency = currency;
}
this.$('.fundraiser-bar__current-currency').text(
I18n.t('fundraiser.currency_in', { currency: this.currency })
);
this.$('select.fundraiser-bar__currency-selector')
.find('option')
.prop('selected', false);
this.$('select.fundraiser-bar__currency-selector')
.find(`option[value="${this.currency}"]`)
.prop('selected', true);
this.showDonationBandForCurrency(this.currency);
},

setupCurrencySelector() {
const $select = this.$('select.fundraiser-bar__currency-selector');
_.each(_.keys(this.CURRENCY_SYMBOLS), function(currency, ii) {
const option = `<option value="${currency}">${currency}</option>`;
$select.append(option);
});
},

switchCurrency(e) {
this.setCurrency(this.$('select.fundraiser-bar__currency-selector').val());
},

initializeCurrency(currency, donationBands) {
this.setupCurrencySelector();
this.donationBands = donationBands || this.DEFAULT_DONATION_BANDS;
this.setCurrency(currency || this.DEFAULT_CURRENCY);
},

showCurrencySwitcher(e) {
this.$('.fundraiser-bar__engage-currency-switcher').addClass(
'hidden-irrelevant'
);
this.$('.fundraiser-bar__currency-selector').slideDown();
},
};

export default CurrencyMethods;
Loading

0 comments on commit 40ba347

Please sign in to comment.