From a5cb59a7cefc789d39825469f62f58ded19a3524 Mon Sep 17 00:00:00 2001
From: Michiel De Smet
Date: Thu, 18 Apr 2019 00:47:41 +0200
Subject: [PATCH 1/7] newsletter module
---
.gitignore | 1 +
config/default.json | 2 +-
.../blocks/MyAccount/MyNewsletter.js | 34 +---------
.../newsletter/components/Newsletter.ts | 8 +++
.../modules/newsletter}/index.ts | 6 +-
.../modules/newsletter/mixins}/Subscribe.ts | 15 ++---
.../newsletter/mixins/SubscriptionStatus.ts | 63 +++++++++++++++++++
core/modules/newsletter/mixins/Unsubscribe.ts | 28 +++++++++
.../modules/newsletter}/store/index.ts | 38 +++++++++--
.../newsletter}/store/mutation-types.ts | 0
.../newsletter/types/newsletterState.ts | 4 +-
core/scripts/installer.js | 2 +-
core/store/index.ts | 3 +-
core/types/RootState.ts | 1 +
src/modules/index.ts | 4 +-
.../mailchimp/components/Unsubscribe.ts | 17 -----
.../components/core/NewsletterPopup.vue | 7 ++-
.../core/blocks/Footer/Newsletter.vue | 10 ++-
.../core/blocks/MyAccount/MyNewsletter.vue | 8 +++
19 files changed, 167 insertions(+), 84 deletions(-)
create mode 100644 core/modules/newsletter/components/Newsletter.ts
rename {src/modules/mailchimp => core/modules/newsletter}/index.ts (79%)
rename {src/modules/mailchimp/components => core/modules/newsletter/mixins}/Subscribe.ts (76%)
create mode 100644 core/modules/newsletter/mixins/SubscriptionStatus.ts
create mode 100644 core/modules/newsletter/mixins/Unsubscribe.ts
rename {src/modules/mailchimp => core/modules/newsletter}/store/index.ts (57%)
rename {src/modules/mailchimp => core/modules/newsletter}/store/mutation-types.ts (100%)
rename src/modules/mailchimp/types/mailchimpState.ts => core/modules/newsletter/types/newsletterState.ts (59%)
delete mode 100644 src/modules/mailchimp/components/Unsubscribe.ts
diff --git a/.gitignore b/.gitignore
index 8e800e47fc..9069dc6d6c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/config/default.json b/config/default.json
index 3ebbf6e54c..48d70ccad4 100644
--- a/config/default.json
+++ b/config/default.json
@@ -385,7 +385,7 @@
"fullLanguageName": "English",
"bundleAllStoreviewLanguages": true
},
- "mailchimp": {
+ "newsletter": {
"endpoint": "http://localhost:8080/api/ext/mailchimp-subscribe/subscribe"
},
"mailer": {
diff --git a/core/compatibility/components/blocks/MyAccount/MyNewsletter.js b/core/compatibility/components/blocks/MyAccount/MyNewsletter.js
index 98c7f2e180..dd2f415edb 100644
--- a/core/compatibility/components/blocks/MyAccount/MyNewsletter.js
+++ b/core/compatibility/components/blocks/MyAccount/MyNewsletter.js
@@ -1,35 +1,7 @@
+import { Newsletter } from '@vue-storefront/core/modules/newsletter/components/Newsletter'
+
// 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]
}
diff --git a/core/modules/newsletter/components/Newsletter.ts b/core/modules/newsletter/components/Newsletter.ts
new file mode 100644
index 0000000000..c481644085
--- /dev/null
+++ b/core/modules/newsletter/components/Newsletter.ts
@@ -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]
+}
diff --git a/src/modules/mailchimp/index.ts b/core/modules/newsletter/index.ts
similarity index 79%
rename from src/modules/mailchimp/index.ts
rename to core/modules/newsletter/index.ts
index d507a71961..9cd941e019 100644
--- a/src/modules/mailchimp/index.ts
+++ b/core/modules/newsletter/index.ts
@@ -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)
\ No newline at end of file
+export const Newsletter = new VueStorefrontModule(moduleConfig)
diff --git a/src/modules/mailchimp/components/Subscribe.ts b/core/modules/newsletter/mixins/Subscribe.ts
similarity index 76%
rename from src/modules/mailchimp/components/Subscribe.ts
rename to core/modules/newsletter/mixins/Subscribe.ts
index e584b6f255..c84dfbe963 100644
--- a/src/modules/mailchimp/components/Subscribe.ts
+++ b/core/modules/newsletter/mixins/Subscribe.ts
@@ -13,8 +13,8 @@ import { required, email } from 'vuelidate/lib/validators'
* - `submit(success?: Function, failure?: Function)` dispatches `newsletter-mailchimp/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 const Subscribe = {
- name: 'MailchimpSubscribe',
+export default {
+ name: 'NewsletterSubscribe',
data () {
return {
email: ''
@@ -27,20 +27,15 @@ export const Subscribe = {
}
},
methods: {
- submit (success?: Function, failure?: Function) {
+ subscribe (success?: Function, failure?: Function) {
// argument omitted for validation purposes
if (!this.$v.$invalid) {
- this.$store.dispatch('mailchimp/subscribe', this.email).then(res => {
+ this.$store.dispatch('newsletter/subscribe', this.email).then(res => {
if (success) success(res)
}).catch(err => {
if (failure) failure(err)
}
)}
}
- },
- computed: {
- isSubscribed (): boolean {
- return this.$store.state.mailchimp.subscribed
- }
- },
+ }
}
diff --git a/core/modules/newsletter/mixins/SubscriptionStatus.ts b/core/modules/newsletter/mixins/SubscriptionStatus.ts
new file mode 100644
index 0000000000..847600e0d9
--- /dev/null
+++ b/core/modules/newsletter/mixins/SubscriptionStatus.ts
@@ -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
+ * - `submit(success?: Function, failure?: Function)` dispatches `newsletter-mailchimp/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: '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
+ 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']
+ }
+ }
+}
diff --git a/core/modules/newsletter/mixins/Unsubscribe.ts b/core/modules/newsletter/mixins/Unsubscribe.ts
new file mode 100644
index 0000000000..a2bf943257
--- /dev/null
+++ b/core/modules/newsletter/mixins/Unsubscribe.ts
@@ -0,0 +1,28 @@
+import { required, email } from 'vuelidate/lib/validators'
+
+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)
+ )
+ }
+ }
+ }
+}
diff --git a/src/modules/mailchimp/store/index.ts b/core/modules/newsletter/store/index.ts
similarity index 57%
rename from src/modules/mailchimp/store/index.ts
rename to core/modules/newsletter/store/index.ts
index 1c86b01881..1b4061993e 100644
--- a/src/modules/mailchimp/store/index.ts
+++ b/core/modules/newsletter/store/index.ts
@@ -1,15 +1,21 @@
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 '../'
+import CmsBlockState from "core/modules/cms/types/CmsBlockState";
+import RootState from "core/types/RootState";
-export const module: Module ={
+export const module: Module ={
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
@@ -22,10 +28,30 @@ export const module: Module ={
}
},
actions: {
+ status ({ commit, state }, email): Promise {
+ 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 {
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',
@@ -42,9 +68,9 @@ export const module: Module ={
}
},
unsubscribe ({ commit, state }, email): Promise {
- 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',
diff --git a/src/modules/mailchimp/store/mutation-types.ts b/core/modules/newsletter/store/mutation-types.ts
similarity index 100%
rename from src/modules/mailchimp/store/mutation-types.ts
rename to core/modules/newsletter/store/mutation-types.ts
diff --git a/src/modules/mailchimp/types/mailchimpState.ts b/core/modules/newsletter/types/newsletterState.ts
similarity index 59%
rename from src/modules/mailchimp/types/mailchimpState.ts
rename to core/modules/newsletter/types/newsletterState.ts
index cb846e20f2..cfb28cdf47 100644
--- a/src/modules/mailchimp/types/mailchimpState.ts
+++ b/core/modules/newsletter/types/newsletterState.ts
@@ -1,4 +1,4 @@
-export interface mailchimpState {
+export interface newsletterState {
isSubscribed: boolean | null,
email: string | null
-}
\ No newline at end of file
+}
diff --git a/core/scripts/installer.js b/core/scripts/installer.js
index 186b73df94..72b55ebef8 100644
--- a/core/scripts/installer.js
+++ b/core/scripts/installer.js
@@ -450,7 +450,7 @@ class Storefront extends Abstract {
config.cart.applycoupon_endpoint = `${backendPath}/api/cart/apply-coupon?token={{token}}&cartId={{cartId}}&coupon={{coupon}}`
config.reviews.create_endpoint = `${backendPath}/api/review/create?token={{token}}`
- config.mailchimp.endpoint = `${backendPath}/api/ext/mailchimp-subscribe/subscribe`
+ config.newsletter.endpoint = `${backendPath}/api/ext/mailchimp-subscribe/subscribe`
config.mailer.endpoint.send = `${backendPath}/api/ext/mail-service/send-email`
config.mailer.endpoint.token = `${backendPath}/api/ext/mail-service/get-token`
config.images.baseUrl = this.answers.images_endpoint
diff --git a/core/store/index.ts b/core/store/index.ts
index d85aba7935..4968b1a4dd 100644
--- a/core/store/index.ts
+++ b/core/store/index.ts
@@ -19,6 +19,7 @@ const state = {
shipping: {},
user: {},
ui: {},
+ newsletter: {},
wishlist: {},
attribute: '',
category: {
@@ -47,4 +48,4 @@ let rootStore = new Vuex.Store({
state
})
-export default rootStore
\ No newline at end of file
+export default rootStore
diff --git a/core/types/RootState.ts b/core/types/RootState.ts
index 515d3fc781..be459a8b0a 100644
--- a/core/types/RootState.ts
+++ b/core/types/RootState.ts
@@ -12,6 +12,7 @@ export default interface RootState {
wishlist: any,
attribute: string,
ui: any,
+ newsletter: any,
category: {
current_path: string,
current_product_query: any,
diff --git a/src/modules/index.ts b/src/modules/index.ts
index 2746a6d0ed..51d22fda1a 100644
--- a/src/modules/index.ts
+++ b/src/modules/index.ts
@@ -7,7 +7,7 @@ import { Compare } from '@vue-storefront/core/modules/compare'
import { Review } from '@vue-storefront/core/modules/review'
import { Mailer } from '@vue-storefront/core/modules/mailer'
import { Wishlist } from '@vue-storefront/core/modules/wishlist'
-import { Mailchimp } from '../modules/mailchimp'
+import { Newsletter } from '@vue-storefront/core/modules/newsletter'
import { Notification } from '@vue-storefront/core/modules/notification'
import { RecentlyViewed } from '@vue-storefront/core/modules/recently-viewed'
import { Url } from '@vue-storefront/core/modules/url'
@@ -60,7 +60,7 @@ export const registerModules: VueStorefrontModule[] = [
Review,
Mailer,
Wishlist,
- Mailchimp,
+ Newsletter,
Notification,
Ui,
RecentlyViewed,
diff --git a/src/modules/mailchimp/components/Unsubscribe.ts b/src/modules/mailchimp/components/Unsubscribe.ts
deleted file mode 100644
index 3b64c05896..0000000000
--- a/src/modules/mailchimp/components/Unsubscribe.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-export const Unsubscribe = {
- name: 'MailchimpUnsubscribe',
- methods: {
- unsubscribe () {
- this.$store.dispatch('mailchimp/unsubscribe', this.email).then(res => {
- this.$emit('unsubscribed', res)
- }).catch(err =>
- this.$emit('unsubscription-error', err)
- )
- }
- },
- computed: {
- isSubscribed () {
- return this.$store.state.mailchimp.isSubscribed
- }
- }
-}
diff --git a/src/themes/default/components/core/NewsletterPopup.vue b/src/themes/default/components/core/NewsletterPopup.vue
index 5a64ae1f21..0e545480dc 100644
--- a/src/themes/default/components/core/NewsletterPopup.vue
+++ b/src/themes/default/components/core/NewsletterPopup.vue
@@ -4,7 +4,7 @@
{{ $t('Newsletter') }}