mirror of
https://github.com/discourse/discourse-subscriptions.git
synced 2025-07-08 15:22:46 +00:00
Add donations causes
This commit is contained in:
parent
d686ece85b
commit
45ece34200
@ -48,6 +48,7 @@ module DiscourseDonations
|
|||||||
begin
|
begin
|
||||||
Rails.logger.debug "Creating a Stripe charge for #{user_params[:amount]}"
|
Rails.logger.debug "Creating a Stripe charge for #{user_params[:amount]}"
|
||||||
opts = {
|
opts = {
|
||||||
|
cause: user_params[:cause],
|
||||||
email: @email,
|
email: @email,
|
||||||
token: user_params[:stripeToken],
|
token: user_params[:stripeToken],
|
||||||
amount: user_params[:amount]
|
amount: user_params[:amount]
|
||||||
@ -153,7 +154,7 @@ module DiscourseDonations
|
|||||||
end
|
end
|
||||||
|
|
||||||
def user_params
|
def user_params
|
||||||
params.permit(:user_id, :name, :username, :email, :password, :stripeToken, :type, :amount, :create_account)
|
params.permit(:user_id, :name, :username, :email, :password, :stripeToken, :cause, :type, :amount, :create_account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_user
|
def set_user
|
||||||
|
@ -1 +1,2 @@
|
|||||||
load File.expand_path('../regular/donation_user.rb', __FILE__)
|
load File.expand_path('../regular/donation_user.rb', __FILE__)
|
||||||
|
load File.expand_path('../scheduled/update_category_donation_statistics.rb', __FILE__)
|
||||||
|
69
app/jobs/scheduled/update_category_donation_statistics.rb
Normal file
69
app/jobs/scheduled/update_category_donation_statistics.rb
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
module Jobs
|
||||||
|
class UpdateCategoryDonationStatistics < ::Jobs::Scheduled
|
||||||
|
every 1.hour
|
||||||
|
|
||||||
|
def execute(args)
|
||||||
|
return unless SiteSetting.discourse_donations_cause_category
|
||||||
|
|
||||||
|
::Stripe.api_key = SiteSetting.discourse_donations_secret_key
|
||||||
|
totals = {}
|
||||||
|
backers = {}
|
||||||
|
categories = []
|
||||||
|
|
||||||
|
raw_charges = ::Stripe::Charge.list(
|
||||||
|
expand: ['data.invoice.subscription', 'data.customer']
|
||||||
|
)
|
||||||
|
raw_charges = raw_charges.is_a?(Object) ? raw_charges['data'] : []
|
||||||
|
|
||||||
|
raw_charges.each do |c|
|
||||||
|
cause_base = c['invoice'] && c['invoice']['subscription'] ? c['invoice']['subscription'] : c
|
||||||
|
category_id = cause_base['metadata']['discourse_cause'].to_i
|
||||||
|
|
||||||
|
backer_base = c['customer']
|
||||||
|
backer_user_id = backer_base['metadata']['discourse_user_id'].to_i
|
||||||
|
backer_email = backer_base['email']
|
||||||
|
|
||||||
|
if category_id > 0 && Category.exists?(id: category_id)
|
||||||
|
categories.push(category_id)
|
||||||
|
|
||||||
|
current = totals[category_id] || {}
|
||||||
|
amount = c['amount'].to_i
|
||||||
|
date = Time.at(c['created']).to_datetime
|
||||||
|
|
||||||
|
totals[category_id] ||= {}
|
||||||
|
totals[category_id][:total] ||= 0
|
||||||
|
totals[category_id][:month] ||= 0
|
||||||
|
|
||||||
|
totals[category_id][:total] += amount
|
||||||
|
|
||||||
|
if date.month == Date.today.month
|
||||||
|
totals[category_id][:month] += amount
|
||||||
|
end
|
||||||
|
|
||||||
|
backers[category_id] ||= []
|
||||||
|
|
||||||
|
if backer_user_id > 0 && User.exists?(id: backer_user_id)
|
||||||
|
backers[category_id].push(backer_user_id) unless backers[category_id].include? backer_user_id
|
||||||
|
elsif user = User.find_by_email(backer_email)
|
||||||
|
backers[category_id].push(user.id) unless backers[category_id].include? user.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
categories.each do |category_id|
|
||||||
|
category = Category.find(category_id)
|
||||||
|
|
||||||
|
if totals[category_id]
|
||||||
|
category.custom_fields['donations_total'] = totals[category_id][:total]
|
||||||
|
category.custom_fields['donations_month'] = totals[category_id][:month]
|
||||||
|
end
|
||||||
|
|
||||||
|
if backers[category_id]
|
||||||
|
category.custom_fields['donations_backers'] = backers[category_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
category.save_custom_fields(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -41,7 +41,11 @@ module DiscourseDonations
|
|||||||
amount: opts[:amount],
|
amount: opts[:amount],
|
||||||
description: @description,
|
description: @description,
|
||||||
currency: @currency,
|
currency: @currency,
|
||||||
receipt_email: customer.email
|
receipt_email: customer.email,
|
||||||
|
metadata: {
|
||||||
|
discourse_cause: opts[:cause],
|
||||||
|
discourse_user_id: user.id
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@charge
|
@charge
|
||||||
@ -72,7 +76,11 @@ module DiscourseDonations
|
|||||||
customer: customer.id,
|
customer: customer.id,
|
||||||
items: [{
|
items: [{
|
||||||
plan: plan_id
|
plan: plan_id
|
||||||
}]
|
}],
|
||||||
|
metadata: {
|
||||||
|
discourse_cause: opts[:cause],
|
||||||
|
discourse_user_id: user.id
|
||||||
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -186,10 +194,18 @@ module DiscourseDonations
|
|||||||
end
|
end
|
||||||
|
|
||||||
if !customer && opts[:create]
|
if !customer && opts[:create]
|
||||||
customer = ::Stripe::Customer.create(
|
customer_opts = {
|
||||||
email: opts[:email],
|
email: opts[:email],
|
||||||
source: opts[:source]
|
source: opts[:source]
|
||||||
)
|
}
|
||||||
|
|
||||||
|
if user
|
||||||
|
customer_opts[:metadata] = {
|
||||||
|
discourse_user_id: user.id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
customer = ::Stripe::Customer.create(customer_opts)
|
||||||
|
|
||||||
if user
|
if user
|
||||||
user.custom_fields['stripe_customer_id'] = customer.id
|
user.custom_fields['stripe_customer_id'] = customer.id
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { ajax } from 'discourse/lib/ajax';
|
|
||||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
classNames: 'donation-list',
|
classNames: 'donation-list',
|
||||||
hasSubscriptions: Ember.computed.notEmpty('subscriptions'),
|
hasSubscriptions: Ember.computed.notEmpty('subscriptions'),
|
||||||
hasCharges: Ember.computed.notEmpty('charges')
|
hasCharges: Ember.computed.notEmpty('charges')
|
||||||
})
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
import { formatAnchor, formatAmount } from '../lib/donation-utilities';
|
import { formatAnchor, formatAmount } from '../lib/donation-utilities';
|
||||||
import { default as computed, observes, on } from 'ember-addons/ember-computed-decorators';
|
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||||
import showModal from "discourse/lib/show-modal";
|
import showModal from "discourse/lib/show-modal";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
@ -60,7 +60,7 @@ export default Ember.Component.extend({
|
|||||||
period(anchor, interval) {
|
period(anchor, interval) {
|
||||||
return I18n.t(`discourse_donations.period.${interval}`, {
|
return I18n.t(`discourse_donations.period.${interval}`, {
|
||||||
anchor: formatAnchor(interval, moment.unix(anchor))
|
anchor: formatAnchor(interval, moment.unix(anchor))
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
cancelSubscription() {
|
cancelSubscription() {
|
||||||
@ -93,4 +93,4 @@ export default Ember.Component.extend({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import { formatAnchor, zeroDecimalCurrencies } from '../lib/donation-utilities';
|
import { formatAnchor, zeroDecimalCurrencies } from '../lib/donation-utilities';
|
||||||
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
import { default as computed } from 'ember-addons/ember-computed-decorators';
|
||||||
import { emailValid } from "discourse/lib/utilities";
|
import { emailValid as emailValidHelper } from "discourse/lib/utilities";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
result: [],
|
result: [],
|
||||||
@ -29,6 +29,34 @@ export default Ember.Component.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@computed
|
||||||
|
causes() {
|
||||||
|
const categoryEnabled = Discourse.SiteSettings.discourse_donations_cause_category;
|
||||||
|
|
||||||
|
if (categoryEnabled) {
|
||||||
|
let categoryIds = Discourse.SiteSettings.discourse_donations_causes_categories.split('|');
|
||||||
|
|
||||||
|
if (categoryIds.length) {
|
||||||
|
categoryIds = categoryIds.map(Number);
|
||||||
|
return this.site
|
||||||
|
.get("categoriesList")
|
||||||
|
.filter(c => {
|
||||||
|
return categoryIds.indexOf(c.id) > -1;
|
||||||
|
}).map(c => {
|
||||||
|
return {
|
||||||
|
id: c.id,
|
||||||
|
name: c.name
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const causes = Discourse.SiteSettings.discourse_donations_causes;
|
||||||
|
return causes ? causes.split('|') : [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
@computed('types')
|
@computed('types')
|
||||||
donationTypes(types) {
|
donationTypes(types) {
|
||||||
return types.map((type) => {
|
return types.map((type) => {
|
||||||
@ -97,7 +125,7 @@ export default Ember.Component.extend({
|
|||||||
|
|
||||||
@computed('email')
|
@computed('email')
|
||||||
emailValid(email) {
|
emailValid(email) {
|
||||||
return emailValid(email);
|
return emailValidHelper(email);
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('email', 'emailValid')
|
@computed('email', 'emailValid')
|
||||||
@ -110,9 +138,14 @@ export default Ember.Component.extend({
|
|||||||
return currentUser || emailValid;
|
return currentUser || emailValid;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('userReady', 'stripeReady')
|
@computed('cause')
|
||||||
formIncomplete(userReady, stripeReady) {
|
causeValid(cause) {
|
||||||
return !userReady || !stripeReady;
|
return cause || !Discourse.SiteSettings.discourse_donations_cause_required;
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('userReady', 'stripeReady', 'causeValid')
|
||||||
|
formIncomplete(userReady, stripeReady, causeValid) {
|
||||||
|
return !userReady || !stripeReady || !causeValid;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed('transactionInProgress', 'formIncomplete')
|
@computed('transactionInProgress', 'formIncomplete')
|
||||||
@ -181,6 +214,7 @@ export default Ember.Component.extend({
|
|||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
stripeToken: data.token.id,
|
stripeToken: data.token.id,
|
||||||
|
cause: self.get('cause'),
|
||||||
type: self.get('type'),
|
type: self.get('type'),
|
||||||
amount,
|
amount,
|
||||||
email: self.get('email'),
|
email: self.get('email'),
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
{{#if siteSettings.discourse_donations_cause_category}}
|
||||||
|
{{mount-widget widget="category-header-widget"}}
|
||||||
|
{{/if}}
|
@ -0,0 +1,11 @@
|
|||||||
|
{{#if siteSettings.discourse_donations_cause_category}}
|
||||||
|
<section class='field'>
|
||||||
|
<label>{{i18n 'discourse_donations.cause.github.setting_label'}}</label>
|
||||||
|
{{text-field value=category.custom_fields.donations_github placeholderKey="discourse_donations.cause.github.setting_placeholder"}}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class='field'>
|
||||||
|
<label>{{i18n 'discourse_donations.cause.maintainers.label'}}</label>
|
||||||
|
{{user-selector usernames=category.custom_fields.donations_maintainers}}
|
||||||
|
</section>
|
||||||
|
{{/if}}
|
@ -9,4 +9,4 @@ export default Ember.Controller.extend({
|
|||||||
this.send('closeModal');
|
this.send('closeModal');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
@ -2,6 +2,7 @@ import { default as computed } from 'ember-addons/ember-computed-decorators';
|
|||||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import { getOwner } from 'discourse-common/lib/get-owner';
|
import { getOwner } from 'discourse-common/lib/get-owner';
|
||||||
|
import { emailValid } from "discourse/lib/utilities";
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
loadingDonations: false,
|
loadingDonations: false,
|
||||||
@ -41,8 +42,8 @@ export default Ember.Controller.extend({
|
|||||||
|
|
||||||
Ember.run.later(() => {
|
Ember.run.later(() => {
|
||||||
this.set('hasEmailResult', false);
|
this.set('hasEmailResult', false);
|
||||||
}, 6000)
|
}, 6000);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
showLogin() {
|
showLogin() {
|
||||||
@ -50,4 +51,4 @@ export default Ember.Controller.extend({
|
|||||||
controller.send('showLogin');
|
controller.send('showLogin');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
@ -2,28 +2,37 @@ import { withPluginApi } from 'discourse/lib/plugin-api';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'donations-edits',
|
name: 'donations-edits',
|
||||||
initialize() {
|
initialize(container) {
|
||||||
|
const siteSettings = container.lookup('site-settings:main');
|
||||||
|
|
||||||
withPluginApi('0.8.12', api => {
|
withPluginApi('0.8.12', api => {
|
||||||
api.decorateCooked($post => {
|
api.decorateCooked($post => {
|
||||||
const $form = $post.find('.stripe-checkout');
|
const $form = $post.find('.stripe-checkout');
|
||||||
if ($form.length) {
|
if ($form.length) {
|
||||||
const $input = $form.find('input');
|
const $input = $form.find('input');
|
||||||
const settings = Discourse.SiteSettings;
|
|
||||||
var s = document.createElement('script');
|
var s = document.createElement('script');
|
||||||
s.src = 'https://checkout.stripe.com/checkout.js';
|
s.src = 'https://checkout.stripe.com/checkout.js';
|
||||||
s.setAttribute('class', 'stripe-button');
|
s.setAttribute('class', 'stripe-button');
|
||||||
s.setAttribute('data-key', settings.discourse_donations_public_key);
|
s.setAttribute('data-key', siteSettings.discourse_donations_public_key);
|
||||||
s.setAttribute('data-amount', $input.attr('amount'));
|
s.setAttribute('data-amount', $input.attr('amount'));
|
||||||
s.setAttribute('data-name', settings.discourse_donations_shop_name);
|
s.setAttribute('data-name', siteSettings.discourse_donations_shop_name);
|
||||||
s.setAttribute('data-description', $form.attr('content'));
|
s.setAttribute('data-description', $form.attr('content'));
|
||||||
s.setAttribute('data-image', $form.attr('image') || '');
|
s.setAttribute('data-image', $form.attr('image') || '');
|
||||||
s.setAttribute('data-locale', 'auto');
|
s.setAttribute('data-locale', 'auto');
|
||||||
s.setAttribute('data-zip-code', settings.discourse_donations_zip_code);
|
s.setAttribute('data-zip-code', siteSettings.discourse_donations_zip_code);
|
||||||
s.setAttribute('data-billing-address', settings.discourse_donations_billing_address);
|
s.setAttribute('data-billing-address', siteSettings.discourse_donations_billing_address);
|
||||||
s.setAttribute('data-currency', settings.discourse_donations_currency);
|
s.setAttribute('data-currency', siteSettings.discourse_donations_currency);
|
||||||
$form.append(s);
|
$form.append(s);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (siteSettings.discourse_donations_cause_category) {
|
||||||
|
api.decorateWidget('category-header-widget:after', helper => {
|
||||||
|
helper.widget.appEvents.on('page:changed', () => {
|
||||||
|
helper.widget.scheduleRerender();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
<form id="payment-form" class="form-horizontal">
|
<form id="payment-form" class="form-horizontal">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">
|
||||||
|
{{i18n 'discourse_donations.cause.label'}}
|
||||||
|
</label>
|
||||||
|
<div class="controls controls-dropdown">
|
||||||
|
{{combo-box content=causes value=cause none='discourse_donations.cause.placeholder'}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">
|
<label class="control-label">
|
||||||
{{i18n 'discourse_donations.type'}}
|
{{i18n 'discourse_donations.type'}}
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
import { createWidget } from 'discourse/widgets/widget';
|
||||||
|
import { h } from 'virtual-dom';
|
||||||
|
import { avatarFor } from 'discourse/widgets/post';
|
||||||
|
|
||||||
|
function donationDisplay(amount, type) {
|
||||||
|
return h(`div.donations-${type}`, [
|
||||||
|
h('span', I18n.t(`discourse_donations.cause.category.${type}`)),
|
||||||
|
h('span', `$${(amount/100).toFixed(2)}`)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
createWidget('category-header-widget', {
|
||||||
|
tagName: 'span',
|
||||||
|
|
||||||
|
html() {
|
||||||
|
const path = window.location.pathname;
|
||||||
|
let category;
|
||||||
|
|
||||||
|
const controller = this.container.lookup('controller:navigation/category');
|
||||||
|
category = controller.get("category");
|
||||||
|
|
||||||
|
if(/^\/c\//.test(path)) {
|
||||||
|
$("body").addClass("donations-category");
|
||||||
|
|
||||||
|
let contents = [
|
||||||
|
h('div.donations-category-contents', [
|
||||||
|
h('h1', category.name),
|
||||||
|
h('div.category-title-description', h('p', category.description_text))
|
||||||
|
]),
|
||||||
|
h('div.donations-category-metadata', [
|
||||||
|
donationDisplay(category.donations_total || 0, 'total'),
|
||||||
|
donationDisplay(category.donations_month || 0, 'month'),
|
||||||
|
h('div.donations-github', this.attach('link', {
|
||||||
|
icon: 'github',
|
||||||
|
label: 'discourse_donations.cause.github.label',
|
||||||
|
href: category.donations_github
|
||||||
|
}))
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
let userContents = [];
|
||||||
|
|
||||||
|
if (category.donations_backers.length) {
|
||||||
|
userContents.push(h('div.donations-backers', [
|
||||||
|
h('div.donations-backers-title', I18n.t('discourse_donations.cause.backers.label')),
|
||||||
|
category.donations_backers.map(user => {
|
||||||
|
return avatarFor('medium', {
|
||||||
|
template: user.avatar_template,
|
||||||
|
username: user.username,
|
||||||
|
name: user.name,
|
||||||
|
url: user.usernameUrl,
|
||||||
|
className: "backer-avatar"
|
||||||
|
});
|
||||||
|
})
|
||||||
|
]));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (category.donations_maintainers.length) {
|
||||||
|
userContents.push(h('div.donations-maintainers', [
|
||||||
|
h('div.donations-maintainers-title', I18n.t('discourse_donations.cause.maintainers.label')),
|
||||||
|
category.donations_maintainers.map(user => {
|
||||||
|
if (user) {
|
||||||
|
return avatarFor('medium', {
|
||||||
|
template: user.avatar_template,
|
||||||
|
username: user.username,
|
||||||
|
name: user.name,
|
||||||
|
url: user.usernameUrl,
|
||||||
|
className: "maintainer-avatar"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userContents.length) {
|
||||||
|
contents.push(h('div.donations-category-users', userContents));
|
||||||
|
}
|
||||||
|
|
||||||
|
return h('div.donations-category-header', {
|
||||||
|
"attributes" : {
|
||||||
|
"style" : "background-color: #" + category.color + "; color: #" + category.text_color + ";"
|
||||||
|
}
|
||||||
|
}, contents);
|
||||||
|
} else {
|
||||||
|
$("body").removeClass("donations-category");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -108,3 +108,70 @@ div.stripe-errors {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.donations-category-header {
|
||||||
|
padding-top: 60px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.donations-category-contents {
|
||||||
|
width: 500px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 40px 40px 10px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
i {
|
||||||
|
margin-right: .25em;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-transform: capitalize;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.donations-category-metadata {
|
||||||
|
width: 500px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
|
||||||
|
.donations-total span:first-of-type, .donations-month span:first-of-type {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.donations-github a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.donations-category-users {
|
||||||
|
width: 500px;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.donations-backers, .donations-maintainers {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backer-avatar, .maintainer-avatar {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.donations-backers-title, .donations-maintainers-title {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.donations-category {
|
||||||
|
#main-outlet {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,6 +18,10 @@ en:
|
|||||||
discourse_donations_amounts: "Donation amounts available to user. First listed will be the default."
|
discourse_donations_amounts: "Donation amounts available to user. First listed will be the default."
|
||||||
discourse_donations_custom_amount: "Allow custom donation amount"
|
discourse_donations_custom_amount: "Allow custom donation amount"
|
||||||
discourse_donations_types: "Donation types. First listed will be the default."
|
discourse_donations_types: "Donation types. First listed will be the default."
|
||||||
|
discourse_donations_causes: "Custom causes a user can donate to."
|
||||||
|
discourse_donations_causes_categories: "Categories of cause a user can donate do."
|
||||||
|
discourse_donations_cause_category: "Category causes enabled."
|
||||||
|
discourse_donations_cause_required: "Require user to select a cause when donating."
|
||||||
errors:
|
errors:
|
||||||
discourse_donations_amount_must_be_number: "Amounts must be numbers"
|
discourse_donations_amount_must_be_number: "Amounts must be numbers"
|
||||||
|
|
||||||
@ -32,6 +36,20 @@ en:
|
|||||||
invoice: "invoice"
|
invoice: "invoice"
|
||||||
invoice_prefix: "You gave"
|
invoice_prefix: "You gave"
|
||||||
receipt: "Receipt sent to {{email}}."
|
receipt: "Receipt sent to {{email}}."
|
||||||
|
cause:
|
||||||
|
label: "Cause"
|
||||||
|
placeholder: "Select a cause"
|
||||||
|
category:
|
||||||
|
total: "Total"
|
||||||
|
month: "Month"
|
||||||
|
backers:
|
||||||
|
label: "Backers"
|
||||||
|
github:
|
||||||
|
label: "Repository"
|
||||||
|
setting_label: "Github"
|
||||||
|
setting_placeholder: "repoistory url"
|
||||||
|
maintainers:
|
||||||
|
label: "Maintainers"
|
||||||
subscription:
|
subscription:
|
||||||
cancel:
|
cancel:
|
||||||
title: "Cancel Recurring Donation"
|
title: "Cancel Recurring Donation"
|
||||||
|
@ -3,20 +3,20 @@ plugins:
|
|||||||
default: false
|
default: false
|
||||||
client: true
|
client: true
|
||||||
discourse_donations_secret_key:
|
discourse_donations_secret_key:
|
||||||
default: 'YOUR STRIPE API SECRET'
|
default: ''
|
||||||
client: false
|
client: false
|
||||||
discourse_donations_public_key:
|
discourse_donations_public_key:
|
||||||
default: 'YOUR STRIPE API KEY'
|
default: ''
|
||||||
client: true
|
client: true
|
||||||
discourse_donations_enable_create_accounts:
|
discourse_donations_enable_create_accounts:
|
||||||
client: true
|
client: true
|
||||||
default: false
|
default: false
|
||||||
discourse_donations_description:
|
discourse_donations_description:
|
||||||
client: true
|
client: true
|
||||||
default: 'Donation'
|
default: ''
|
||||||
discourse_donations_shop_name:
|
discourse_donations_shop_name:
|
||||||
client: true
|
client: true
|
||||||
default: 'Your shop name'
|
default: ''
|
||||||
discourse_donations_currency:
|
discourse_donations_currency:
|
||||||
client: true
|
client: true
|
||||||
default: 'USD'
|
default: 'USD'
|
||||||
@ -53,9 +53,23 @@ plugins:
|
|||||||
discourse_donations_types:
|
discourse_donations_types:
|
||||||
client: true
|
client: true
|
||||||
type: list
|
type: list
|
||||||
default: 'month|once'
|
default: 'once|month'
|
||||||
choices:
|
choices:
|
||||||
- year
|
- year
|
||||||
- month
|
- month
|
||||||
- week
|
- week
|
||||||
- once
|
- once
|
||||||
|
discourse_donations_causes:
|
||||||
|
client: true
|
||||||
|
type: list
|
||||||
|
default: ''
|
||||||
|
discourse_donations_causes_categories:
|
||||||
|
client: true
|
||||||
|
type: category_list
|
||||||
|
default: ''
|
||||||
|
discourse_donations_cause_category:
|
||||||
|
client: true
|
||||||
|
default: false
|
||||||
|
discourse_donations_cause_required:
|
||||||
|
client: true
|
||||||
|
default: false
|
||||||
|
60
plugin.rb
60
plugin.rb
@ -34,4 +34,64 @@ after_initialize do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ::Category
|
||||||
|
def donations_total
|
||||||
|
if custom_fields['donations_total']
|
||||||
|
custom_fields['donations_total']
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def donations_month
|
||||||
|
if custom_fields['donations_month']
|
||||||
|
custom_fields['donations_month']
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def donations_backers
|
||||||
|
if custom_fields['donations_backers']
|
||||||
|
[*custom_fields['donations_backers']].map do |user_id|
|
||||||
|
User.find_by(id: user_id.to_i)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def donations_maintainers
|
||||||
|
if custom_fields['donations_maintainers']
|
||||||
|
custom_fields['donations_maintainers'].split(',').map do |username|
|
||||||
|
User.find_by(username: username)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def donations_github
|
||||||
|
if custom_fields['donations_github']
|
||||||
|
custom_fields['donations_github']
|
||||||
|
else
|
||||||
|
''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if SiteSetting.discourse_donations_cause_category
|
||||||
|
add_to_serializer(:basic_category, :donations_total) { object.donations_total }
|
||||||
|
add_to_serializer(:basic_category, :donations_month) { object.donations_month }
|
||||||
|
add_to_serializer(:basic_category, :donations_backers) {
|
||||||
|
ActiveModel::ArraySerializer.new(object.donations_backers, each_serializer: BasicUserSerializer).as_json
|
||||||
|
}
|
||||||
|
add_to_serializer(:basic_category, :donations_maintainers) {
|
||||||
|
ActiveModel::ArraySerializer.new(object.donations_maintainers, each_serializer: BasicUserSerializer).as_json
|
||||||
|
}
|
||||||
|
add_to_serializer(:basic_category, :donations_github) { object.donations_github }
|
||||||
|
end
|
||||||
|
|
||||||
|
DiscourseEvent.trigger(:donations_ready)
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user