diff --git a/app/components/forms/user-payment-info-form.js b/app/components/forms/user-payment-info-form.js new file mode 100644 index 00000000000..ad464322b6c --- /dev/null +++ b/app/components/forms/user-payment-info-form.js @@ -0,0 +1,113 @@ +import Component from '@ember/component'; +import FormMixin from 'open-event-frontend/mixins/form'; +import { validPhoneNumber } from 'open-event-frontend/utils/validators'; +import { pick, orderBy } from 'lodash-es'; +import { action, computed } from '@ember/object'; +import { countries } from 'open-event-frontend/utils/dictionary/demography'; + +export default class extends Component.extend(FormMixin) { + didInsertElement() { + super.didInsertElement(...arguments); + this.set('userBillingInfo', pick(this.authManager.currentUser, ['billingContactName', 'billingCity', 'billingPhone', 'company', 'billingTaxInfo', 'billingCountry', 'billingState', 'billingAddress', 'billingZipCode', 'billingAdditionalInfo'])); + } + + getValidationRules() { + return { + inline : true, + delay : false, + on : 'blur', + + fields: { + name: { + identifier : 'contactName', + rules : [ + { + type : 'empty', + prompt : this.l10n.t('Please enter your name') + } + ] + }, + company: { + identifier : 'company', + rules : [ + { + type : 'empty', + prompt : this.l10n.t('Please enter your company') + } + ] + }, + country: { + identifier : 'country', + rules : [ + { + type : 'empty', + prompt : this.l10n.t('Please enter your country') + } + ] + }, + address: { + identifier : 'address', + rules : [ + { + type : 'empty', + prompt : this.l10n.t('Please enter your billing address') + } + ] + }, + city: { + identifier : 'city', + rules : [ + { + type : 'empty', + prompt : this.l10n.t('Please enter your billing city') + } + ] + }, + zipCode: { + identifier : 'zip', + rules : [ + { + type : 'empty', + prompt : this.l10n.t('Please enter the zip code') + } + ] + }, + phone: { + identifier : 'phone', + rules : [ + { + type : 'empty', + prompt : this.l10n.t('Please enter a phone number.') + }, + { + type : 'regExp', + value : validPhoneNumber, + prompt : this.l10n.t('Please enter a valid phone number.') + } + ] + } + } + }; + } + + @computed() + get countries() { + return orderBy(countries, 'name'); + } + + @action + submit() { + this.onValid(async() => { + this.set('isLoading', true); + try { + this.authManager.currentUser.setProperties(this.userBillingInfo); + await this.authManager.currentUser.save(); + this.notify.success(this.l10n.t('Your billing details has been updated')); + } catch (error) { + this.authManager.currentUser.rollbackAttributes(); + this.notify.error(this.l10n.t('An unexpected error occurred')); + } + this.set('isLoading', false); + }); + } +} diff --git a/app/models/user.js b/app/models/user.js index ee2c6a30b86..9340fc7fb92 100644 --- a/app/models/user.js +++ b/app/models/user.js @@ -48,6 +48,21 @@ export default ModelBase.extend({ deletedAt : attr('moment'), lastAccessedAt : attr('moment', { readOnly: true }), + /** + * Billing Contact Information + */ + + billingContactName : attr('string'), + billingPhone : attr('string'), + billingCountry : attr('string'), + company : attr('string'), + billingAddress : attr('string'), + billingCity : attr('string'), + billingZipCode : attr('string'), + billingTaxInfo : attr('string'), + billingAdditionalInfo : attr('string'), + billingState : attr('string'), + status: computed('lastAccessedAt', 'deletedAt', function() { if (this.deletedAt == null) { if (this.lastAccessedAt == null) { diff --git a/app/router.js b/app/router.js index bac71b7f1a9..5fa8f170cc2 100644 --- a/app/router.js +++ b/app/router.js @@ -113,7 +113,7 @@ router.map(function() { this.route('email-preferences'); this.route('applications'); this.route('danger-zone'); - this.route('billing-info', function() { + this.route('billing', function() { this.route('payment-info'); this.route('invoices'); }); diff --git a/app/routes/account/billing-info/invoices.js b/app/routes/account/billing-info/invoices.js deleted file mode 100644 index 6c74252aa1b..00000000000 --- a/app/routes/account/billing-info/invoices.js +++ /dev/null @@ -1,4 +0,0 @@ -import Route from '@ember/routing/route'; - -export default Route.extend({ -}); diff --git a/app/routes/account/billing-info/payment-info.js b/app/routes/account/billing-info/payment-info.js deleted file mode 100644 index 6c74252aa1b..00000000000 --- a/app/routes/account/billing-info/payment-info.js +++ /dev/null @@ -1,4 +0,0 @@ -import Route from '@ember/routing/route'; - -export default Route.extend({ -}); diff --git a/app/routes/account/billing-info.js b/app/routes/account/billing.js similarity index 100% rename from app/routes/account/billing-info.js rename to app/routes/account/billing.js diff --git a/app/routes/account/billing/index.js b/app/routes/account/billing/index.js new file mode 100644 index 00000000000..7e9a38db3a6 --- /dev/null +++ b/app/routes/account/billing/index.js @@ -0,0 +1,13 @@ +import Route from '@ember/routing/route'; +import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; + +export default class extends Route.extend(AuthenticatedRouteMixin) { + titleToken() { + return this.l10n.t('Billing Info'); + } + + beforeModel() { + super.beforeModel(...arguments); + this.replaceWith('account.billing.payment-info'); + } +} diff --git a/app/routes/account/billing/invoices.js b/app/routes/account/billing/invoices.js new file mode 100644 index 00000000000..940655cb5dc --- /dev/null +++ b/app/routes/account/billing/invoices.js @@ -0,0 +1,7 @@ +import Route from '@ember/routing/route'; + +export default class extends Route { + titleToken() { + return this.l10n.t('Invoices'); + } +} diff --git a/app/routes/account/billing/payment-info.js b/app/routes/account/billing/payment-info.js new file mode 100644 index 00000000000..3248990a07c --- /dev/null +++ b/app/routes/account/billing/payment-info.js @@ -0,0 +1,8 @@ +import Route from '@ember/routing/route'; +import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; + +export default class extends Route.extend(AuthenticatedRouteMixin) { + titleToken() { + return this.l10n.t('Payment Info'); + } +} \ No newline at end of file diff --git a/app/templates/account.hbs b/app/templates/account.hbs index e21accdee8c..798eb2ec647 100644 --- a/app/templates/account.hbs +++ b/app/templates/account.hbs @@ -4,7 +4,7 @@ {{#link-to 'account.profile' class='item'}} {{t 'Profile'}} {{/link-to}} - {{#link-to 'account.billing-info' class='item'}} + {{#link-to 'account.billing' class='item'}} {{t 'Billing Info'}} {{/link-to}} {{#link-to 'account.password' class='item'}} diff --git a/app/templates/account/billing-info/payment-info.hbs b/app/templates/account/billing-info/payment-info.hbs deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/app/templates/account/billing-info.hbs b/app/templates/account/billing.hbs similarity index 75% rename from app/templates/account/billing-info.hbs rename to app/templates/account/billing.hbs index bb0065c9612..0a16e012c10 100644 --- a/app/templates/account/billing-info.hbs +++ b/app/templates/account/billing.hbs @@ -2,10 +2,10 @@
{{#tabbed-navigation isVertical=true}} - {{#link-to 'account.billing-info.payment-info' class='item'}} + {{#link-to 'account.billing.payment-info' class='item'}} {{t 'Payment Information'}} {{/link-to}} - {{#link-to 'account.billing-info.invoices' class='item'}} + {{#link-to 'account.billing.invoices' class='item'}} {{t 'Invoices'}} {{/link-to}} {{/tabbed-navigation}} diff --git a/app/templates/account/billing-info/invoices.hbs b/app/templates/account/billing/invoices.hbs similarity index 100% rename from app/templates/account/billing-info/invoices.hbs rename to app/templates/account/billing/invoices.hbs diff --git a/app/templates/account/billing/payment-info.hbs b/app/templates/account/billing/payment-info.hbs new file mode 100644 index 00000000000..9714abc29a7 --- /dev/null +++ b/app/templates/account/billing/payment-info.hbs @@ -0,0 +1,3 @@ +
+ {{forms/user-payment-info-form}} +
\ No newline at end of file diff --git a/app/templates/components/forms/user-payment-info-form.hbs b/app/templates/components/forms/user-payment-info-form.hbs new file mode 100644 index 00000000000..9aa1ee424a6 --- /dev/null +++ b/app/templates/components/forms/user-payment-info-form.hbs @@ -0,0 +1,62 @@ +
+

+ {{t 'Payment Information'}} +

+
+ + {{input type='text' id='contactName' value=userBillingInfo.billingContactName}} +
+
+ + {{input type='text' id='phone' value=userBillingInfo.billingPhone}} +
+
+ + {{input type='text' id='company' value=userBillingInfo.company}} +
+
+ + {{input type='text' id='taxID' value=userBillingInfo.billingTaxInfo}} +
+
+ + {{textarea rows='2' id='address' value=userBillingInfo.billingAddress}} +
+
+ + {{input type='text' id='city' value=userBillingInfo.billingCity}} +
+
+ + {{input type='text' id='state' value=userBillingInfo.billingState}} +
+
+ + {{#ui-dropdown class='search selection' selected=userBillingInfo.billingCountry forceSelection=false + fullTextSearch=true}} + {{input type='hidden' id='country' value=userBillingInfo.billingCountry}} + +
{{t 'Select country'}}
+ + {{/ui-dropdown}} +
+
+ + {{input type='text' id='zip' value=userBillingInfo.billingZipCode}} +
+
+ + {{textarea rows='4' id='additionalInfo' value=userBillingInfo.billingAdditionalInfo}} +
+ + +
diff --git a/tests/acceptance/billing-info-test.js b/tests/acceptance/billing-info-test.js index 51d3a7ecb45..69d57eb52fb 100644 --- a/tests/acceptance/billing-info-test.js +++ b/tests/acceptance/billing-info-test.js @@ -4,18 +4,18 @@ import { currentURL, visit } from '@ember/test-helpers'; import { login } from 'open-event-frontend/tests/helpers/custom-helpers'; -module('Acceptance | account/billing-info', function(hooks) { +module('Acceptance | account/billing', function(hooks) { setupApplicationTest(hooks); - test('visiting account/billing-info without login', async function(assert) { - await visit('account/billing-info'); + test('visiting account/billing without login', async function(assert) { + await visit('account/billing'); assert.equal(currentURL(), '/login'); }); - test('visiting account/billing-info with login', async function(assert) { + test('visiting account/billing with login', async function(assert) { await login(assert); - await visit('account/billing-info'); - assert.equal(currentURL(), 'account/billing-info'); + await visit('account/billing'); + assert.equal(currentURL(), '/account/billing/payment-info'); }); }); \ No newline at end of file diff --git a/tests/acceptance/invoices-test.js b/tests/acceptance/invoices-test.js index 5fc236452e0..d2ff55eb155 100644 --- a/tests/acceptance/invoices-test.js +++ b/tests/acceptance/invoices-test.js @@ -4,18 +4,18 @@ import { currentURL, visit } from '@ember/test-helpers'; import { login } from 'open-event-frontend/tests/helpers/custom-helpers'; -module('Acceptance | account/billing-info/invoices', function(hooks) { +module('Acceptance | account/billing/invoices', function(hooks) { setupApplicationTest(hooks); - test('visiting account/billing-info/invoices without login', async function(assert) { - await visit('account/billing-info/invoices'); + test('visiting account/billing/invoices without login', async function(assert) { + await visit('account/billing/invoices'); assert.equal(currentURL(), '/login'); }); - test('visiting account/billing-info/invoices with login', async function(assert) { + test('visiting account/billing/invoices with login', async function(assert) { await login(assert); - await visit('/account/billing-info/invoices'); - assert.equal(currentURL(), '/account/billing-info/invoices'); + await visit('/account/billing/invoices'); + assert.equal(currentURL(), '/account/billing/invoices'); }); }); \ No newline at end of file diff --git a/tests/acceptance/payment-info-test.js b/tests/acceptance/payment-info-test.js index dca5d4b69a0..ef5820ac66c 100644 --- a/tests/acceptance/payment-info-test.js +++ b/tests/acceptance/payment-info-test.js @@ -4,18 +4,18 @@ import { currentURL, visit } from '@ember/test-helpers'; import { login } from 'open-event-frontend/tests/helpers/custom-helpers'; -module('Acceptance | account/billing-info/payment-info', function(hooks) { +module('Acceptance | account/billing/payment-info', function(hooks) { setupApplicationTest(hooks); - test('visiting account/billing-info/payment-info without login', async function(assert) { - await visit('account/billing-info/payment-info'); + test('visiting account/billing/payment-info without login', async function(assert) { + await visit('account/billing/payment-info'); assert.equal(currentURL(), '/login'); }); - test('visiting account/billing-info/payment-info with login', async function(assert) { + test('visiting account/billing/payment-info with login', async function(assert) { await login(assert); - await visit('/account/billing-info/payment-info'); - assert.equal(currentURL(), '/account/billing-info/payment-info'); + await visit('/account/billing/payment-info'); + assert.equal(currentURL(), '/account/billing/payment-info'); }); }); \ No newline at end of file