Files
edx-platform/lms/static/js/dashboard/donation.js
Syed Ali Abbas Zaidi 8480dbc228 chore: apply amnesty on existing not fixable issues (#32215)
* fix: eslint operator-linebreak issue

* fix: eslint quotes issue

* fix: react jsx indent and props issues

* fix: eslint trailing spaces issues

* fix: eslint line around directives issue

* fix: eslint semi rule

* fix: eslint newline per chain rule

* fix: eslint space infix ops rule

* fix: eslint space-in-parens issue

* fix: eslint space before function paren issue

* fix: eslint space before blocks issue

* fix: eslint arrow body style issue

* fix: eslint dot-location issue

* fix: eslint quotes issue

* fix: eslint quote props issue

* fix: eslint operator assignment issue

* fix: eslint new line after import issue

* fix: indent issues

* fix: operator assignment issue

* fix: all autofixable eslint issues

* fix: all react related fixable issues

* fix: autofixable eslint issues

* chore: remove all template literals

* fix: remaining autofixable issues

* chore: apply amnesty on all existing issues

* fix: failing xss-lint issues

* refactor: apply amnesty on remaining issues

* refactor: apply amnesty on new issues

* fix: remove file level suppressions

* refactor: apply amnesty on new issues
2023-08-07 19:13:19 +05:00

242 lines
8.6 KiB
JavaScript

var edx = edx || {};
(function($) {
'use strict';
edx.dashboard = edx.dashboard || {};
edx.dashboard.donation = {};
/**
* View for making donations for a course.
* @constructor
* @param {Object} params
* @param {Object} params.el - The container element.
* @param {string} params.course - The ID of the course for the donation.
*/
edx.dashboard.donation.DonationView = function(params) {
/**
* Dynamically configure a form, which the client can submit
* to the payment processor.
* @param {Object} form - The form to modify.
* @param {string} method - The HTTP method used to submit the form.
* @param {string} url - The URL where the form data will be submitted.
* @param {Object} params - Form data, included as hidden inputs.
*/
// eslint-disable-next-line no-shadow
var configureForm = function(form, method, url, params) {
$('input', form).remove();
form.attr('action', url);
form.attr('method', method);
_.each(params, function(value, key) {
$('<input>').attr({
type: 'hidden',
name: key,
value: value
}).appendTo(form); // xss-lint: disable=javascript-jquery-insert-into-target
});
};
/**
* Fire an analytics event indicating that the user
* is about to be sent to the external payment processor.
*
* @param {string} course - The course ID for the donation.
*/
var firePaymentAnalyticsEvent = function(course) {
analytics.track(
'edx.bi.user.payment_processor.visited',
{
category: 'donations',
label: course
}
);
};
/**
* Add a donation to the user's cart.
*
* @param {string} amount - The amount of the donation (e.g. "23.45")
* @param {string} course - The ID of the course.
* @returns {Object} The promise from the AJAX call to the server,
* which resolves with a data object of the form
* { payment_url: <string>, payment_params: <Object> }
*/
var addDonationToCart = function(amount, course) {
return $.ajax({
url: '/shoppingcart/donation/',
type: 'POST',
data: {
amount: amount,
course_id: course
}
});
};
var view = {
/**
* Initialize the view.
*
* @param {Object} params
* @param {JQuery selector} params.el - The container element.
* @param {string} params.course - The ID of the course for the donation.
* @returns {DonationView}
*/
// eslint-disable-next-line no-shadow
initialize: function(params) {
this.$el = params.el;
this.course = params.course;
_.bindAll(view,
'render', 'donate', 'startPayment',
'validate', 'startPayment',
'displayServerError', 'submitPaymentForm'
);
return this;
},
/**
* Render the form for making a donation for a course.
*
* @returns {DonationView}
*/
render: function() {
var html = _.template($('#donation-tpl').html())({});
this.$el.html(html); // xss-lint: disable=javascript-jquery-html
this.$amount = $('input[name="amount"]', this.$el);
this.$submit = $('.action-donate', this.$el);
this.$errorMsg = $('.donation-error-msg', this.$el);
this.$paymentForm = $('.payment-form', this.$el);
this.$submit.click(this.donate);
return this;
},
/**
* Handle a click event on the "donate" button.
* This will contact the LMS server to add the donation
* to the user's cart, then send the user to the
* external payment processor.
*
* @param {Object} event - The click event.
*/
donate: function(event) {
// Prevent form submission
if (event) {
event.preventDefault();
}
// Immediately disable the submit button to prevent duplicate submissions
this.$submit.addClass('disabled');
if (this.validate()) {
var amount = this.$amount.val();
addDonationToCart(amount, this.course)
.done(this.startPayment)
.fail(this.displayServerError);
} else {
// If an error occurred, allow the user to resubmit
this.$submit.removeClass('disabled');
}
},
/**
* Send signed payment parameters to the external
* payment processor.
*
* @param {Object} data - The signed payment data received from the LMS server.
* @param {string} data.payment_url - The URL of the external payment processor.
* @param {Object} data.payment_data - Parameters to send to the external payment processor.
*/
startPayment: function(data) {
configureForm(
this.$paymentForm,
'post',
data.payment_url,
data.payment_params
);
firePaymentAnalyticsEvent(this.course);
this.submitPaymentForm(this.$paymentForm);
},
/**
* Validate the donation amount and mark any validation errors.
*
* @returns {boolean} True iff the form is valid.
*/
validate: function() {
var amount = this.$amount.val();
var isValid = this.validateAmount(amount);
if (isValid) {
this.$amount.removeClass('validation-error');
this.$errorMsg.text('');
} else {
this.$amount.addClass('validation-error');
this.$errorMsg.text(
gettext('Please enter a valid donation amount.')
);
}
return isValid;
},
/**
* Validate that the given amount is a valid currency string.
*
* @param {string} amount
* @returns {boolean} True iff the amount is valid.
*/
validateAmount: function(amount) {
var amountRegex = /^\d+.\d{2}$|^\d+$/i;
if (!amountRegex.test(amount)) {
return false;
}
if (parseFloat(amount) < 0.01) {
return false;
}
return true;
},
/**
* Display an error message when we receive an error from the LMS server.
*/
displayServerError: function() {
// Display the error message
this.$errorMsg.text(gettext('Your donation could not be submitted.'));
// Re-enable the submit button to allow the user to retry
this.$submit.removeClass('disabled');
},
/**
* Submit the payment from to the external payment processor.
* This is a separate function so we can easily stub it out in tests.
*
* @param {Object} form - The dynamically constructed payment form.
*/
submitPaymentForm: function(form) {
form.submit();
}
};
view.initialize(params);
return view;
};
$(document).ready(function() {
// There may be multiple donation forms on the page
// (one for each newly enrolled course).
// For each one, create a new donation view to handle
// that form, and parameterize it based on the
// "data-course" attribute (the course ID).
$('.donate-container').each(function() {
var $container = $(this);
var course = $container.data('course');
var view = new edx.dashboard.donation.DonationView({
el: $container,
course: course
}).render();
});
});
}(jQuery));