Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

newsletter module #2754

Merged
merged 15 commits into from
May 21, 2019
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ core/resource/i18n/nl-NL.json
core/resource/i18n/pl-PL.json
core/resource/i18n/pt-BR.json
core/resource/i18n/ru-RU.json
*.iml

#unit testing
/test/unit/coverage
2 changes: 1 addition & 1 deletion config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@
"fullLanguageName": "English",
"bundleAllStoreviewLanguages": true
},
"mailchimp": {
"newsletter": {
"endpoint": "http://localhost:8080/api/ext/mailchimp-subscribe/subscribe"
},
"mailer": {
Expand Down
34 changes: 3 additions & 31 deletions core/compatibility/components/blocks/MyAccount/MyNewsletter.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,7 @@
import { Newsletter } from '@vue-storefront/core/modules/newsletter/components/Newsletter'

mdesmet marked this conversation as resolved.
Show resolved Hide resolved
// this component is deprecated and is now in Newsletter module
export default {
name: 'MyNewsletter',
data () {
return {
user: {
isSubscribed: false
}
}
},
methods: {
unsubscribe () {
this.$store.dispatch('mailchimp/unsubscribe', this.$store.state.user.current.email).then(() => {
this.user.isSubscribed = false
}).catch(err =>
this.$emit('unsubscription-error', err)
)
},
subscribe () {
this.$store.dispatch('mailchimp/subscribe', this.$store.state.user.current.email).then(() => {
this.user.isSubscribed = true
}).catch(err =>
this.$emit('subscription-error', err)
)
},
updateNewsletter () {
if (this.user.isSubscribed) {
this.subscribe()
} else {
this.unsubscribe()
}
this.exitSection()
}
}
mixins: [Newsletter]
}
8 changes: 8 additions & 0 deletions core/modules/newsletter/components/Newsletter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import SubscriptionStatus from '@vue-storefront/core/modules/newsletter/mixins/SubscriptionStatus'
import Subscribe from '@vue-storefront/core/modules/newsletter/mixins/Subscribe'
import Unsubscribe from '@vue-storefront/core/modules/newsletter/mixins/Unsubscribe'

export const Newsletter = {
name: 'Newsletter',
mixins: [SubscriptionStatus, Subscribe, Unsubscribe]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import { module } from './store'
import { VueStorefrontModule, VueStorefrontModuleConfig } from '@vue-storefront/core/lib/module'
import { initCacheStorage } from '@vue-storefront/core/helpers/initCacheStorage'

export const KEY = 'mailchimp'
export const KEY = 'newsletter'
export const cacheStorage = initCacheStorage(KEY)

const moduleConfig: VueStorefrontModuleConfig = {
key: KEY,
store: { modules: [{ key: KEY, module }] },
}

export const Mailchimp = new VueStorefrontModule(moduleConfig)
export const Newsletter = new VueStorefrontModule(moduleConfig)
38 changes: 38 additions & 0 deletions core/modules/newsletter/mixins/Subscribe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { required, email } from 'vuelidate/lib/validators'

/**
* Newsletter subscription form component.
*
* #### Data
* - `email: String` - email that will be used for subscription, validated with vuelidate (email, required)
*
* #### Methods
* - `subscribe(success?: Function, failure?: Function)` dispatches `newsletter/subscribe` with `email` data property. `success(res)` and `failure(err)` are callback functions called depending on subscription result and contain response info or error.
*
*/
export default {
name: 'NewsletterSubscribe',
data () {
return {
email: ''
}
},
validations: {
email: {
required,
email
}
},
methods: {
subscribe (success?: Function, failure?: Function) {
// argument omitted for validation purposes
if (!this.$v.$invalid) {
this.$store.dispatch('newsletter/subscribe', this.email).then(res => {
if (success) success(res)
}).catch(err => {
if (failure) failure(err)
}
)}
}
}
}
63 changes: 63 additions & 0 deletions core/modules/newsletter/mixins/SubscriptionStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { required, email } from 'vuelidate/lib/validators'

/**
* Newsletter subscription form component.
*
* #### Data
* - `email: String` - email that will be used for subscription, validated with vuelidate (email, required)
*
* ### Computed
* - `isSubscribed: boolean` - returns true if user subscribed to the newsletter in this session
*
* #### Methods
* - `checkStatus(success?: Function, failure?: Function)` dispatches `newsletter/status` with `email` data property. `success(res)` and `failure(err)` are callback functions called depending on subscription result and contain response info or error.
*
*/
export default {
name: 'SubscriptionStatus',
data () {
return {
email: '',
user: {
isSubscribed: false
}
}
},
validations: {
email: {
required,
email
}
},
methods: {
onLoggedIn () {
this.email = this.$store.state.user.current.email
this.checkStatus(response => {
this.user.isSubscribed = response.result === 'subscribed'
})
},
checkStatus (success?: Function, failure?: Function) {
// argument omitted for validation purposes
if (!this.$v.$invalid) {
this.$store.dispatch('newsletter/status', this.email).then(res => {
if (success) success(res)
}).catch(err => {
if (failure) failure(err)
}
)}
}
},
beforeMount () {
// the user might already be logged in, so check the subscription status
if (this.$store.state.user.current) this.onLoggedIn()
this.$bus.$on('user-after-loggedin', this.onLoggedIn)
},
beforeDestroy () {
this.$bus.$off('user-after-loggedin', this.onLoggedIn)
},
computed: {
isSubscribed () : Boolean {
return this.$store.getters['newsletter/isSubscribed']
}
}
}
38 changes: 38 additions & 0 deletions core/modules/newsletter/mixins/Unsubscribe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { required, email } from 'vuelidate/lib/validators'

/**
* Newsletter subscription form component.
*
* #### Data
* - `email: String` - email that will be used for subscription, validated with vuelidate (email, required)
*
* #### Methods
* - `unsubscribe(success?: Function, failure?: Function)` dispatches `newsletter/unsubscribe` with `email` data property. `success(res)` and `failure(err)` are callback functions called depending on subscription result and contain response info or error.
*
*/
export default {
name: 'NewsletterUnsubscribe',
data () {
return {
email: ''
}
},
validations: {
email: {
required,
email
}
},
methods: {
unsubscribe () {
// argument omitted for validation purposes
if (!this.$v.$invalid) {
this.$store.dispatch('newsletter/unsubscribe', this.email).then(res => {
this.$emit('unsubscribed', res)
}).catch(err =>
this.$emit('unsubscription-error', err)
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import * as types from './mutation-types'
import config from 'config'
import { Module } from 'vuex'
import { mailchimpState } from '../types/mailchimpState'
import { newsletterState } from '../types/newsletterState'
import { cacheStorage } from '../'

export const module: Module<mailchimpState, any> ={
export const module: Module<newsletterState, any> ={
namespaced: true,
state: {
isSubscribed: null,
isSubscribed: false,
email: null,
},
getters: {
isSubscribed: state => state.isSubscribed,
email: state => state.email
},
mutations: {
[types.NEWSLETTER_SUBSCRIBE] (state) {
state.isSubscribed = true
Expand All @@ -22,10 +26,30 @@ export const module: Module<mailchimpState, any> ={
}
},
actions: {
status ({ commit, state }, email): Promise<Response> {
return new Promise((resolve, reject) => {
fetch(config.newsletter.endpoint + '?email=' + encodeURIComponent(email), {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
mode: 'cors'
}).then(res => res.json())
.then(res => {
if(res.result === 'subscribed') {
commit(types.SET_EMAIL, email)
commit(types.NEWSLETTER_SUBSCRIBE)
} else {
commit(types.NEWSLETTER_UNSUBSCRIBE)
}
resolve(res)
}).catch(err => {
reject(err)
})
})
},
subscribe ({ commit, state }, email): Promise<Response> {
if (!state.isSubscribed) {
return new Promise((resolve, reject) => {
fetch(config.mailchimp.endpoint, {
fetch(config.newsletter.endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
mode: 'cors',
Expand All @@ -42,9 +66,9 @@ export const module: Module<mailchimpState, any> ={
}
},
unsubscribe ({ commit, state }, email): Promise<Response> {
if (!state.isSubscribed) {
if (state.isSubscribed) {
return new Promise((resolve, reject) => {
fetch(config.mailchimp.endpoint, {
fetch(config.newsletter.endpoint, {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
mode: 'cors',
Expand Down
Loading