diff --git a/app/components/modal-import-members.js b/app/components/modal-import-members.js
new file mode 100644
index 000000000..8da3a14b2
--- /dev/null
+++ b/app/components/modal-import-members.js
@@ -0,0 +1,43 @@
+import ModalComponent from 'ghost-admin/components/modal-base';
+import ghostPaths from 'ghost-admin/utils/ghost-paths';
+import {computed} from '@ember/object';
+
+export default ModalComponent.extend({
+ labelText: 'Select or drag-and-drop a CSV File',
+
+ response: null,
+ closeDisabled: false,
+
+ // Allowed actions
+ confirm: () => {},
+
+ uploadUrl: computed(function () {
+ return `${ghostPaths().apiRoot}/members/csv/`;
+ }),
+
+ actions: {
+ uploadStarted() {
+ this.set('closeDisabled', true);
+ },
+
+ uploadFinished() {
+ this.set('closeDisabled', false);
+ },
+
+ uploadSuccess(response) {
+ this.set('response', response.meta.stats);
+ // invoke the passed in confirm action
+ this.confirm();
+ },
+
+ confirm() {
+ // noop - we don't want the enter key doing anything
+ },
+
+ closeModal() {
+ if (!this.closeDisabled) {
+ this._super(...arguments);
+ }
+ }
+ }
+});
diff --git a/app/controllers/members.js b/app/controllers/members.js
index 4f4615ff7..6732dae94 100644
--- a/app/controllers/members.js
+++ b/app/controllers/members.js
@@ -1,4 +1,5 @@
import Controller from '@ember/controller';
+import ghostPaths from 'ghost-admin/utils/ghost-paths';
import moment from 'moment';
import {computed} from '@ember/object';
import {inject as service} from '@ember/service';
@@ -32,6 +33,22 @@ export default Controller.extend({
return filtered;
}),
+
+ actions: {
+ exportData() {
+ let exportUrl = ghostPaths().url.api('members/csv');
+ let downloadURL = `${exportUrl}`;
+ let iframe = document.getElementById('iframeDownload');
+
+ if (!iframe) {
+ iframe = document.createElement('iframe');
+ iframe.id = 'iframeDownload';
+ iframe.style.display = 'none';
+ document.body.append(iframe);
+ }
+ iframe.setAttribute('src', downloadURL);
+ }
+ },
fetchMembers: task(function* () {
let newFetchDate = new Date();
diff --git a/app/controllers/members/import.js b/app/controllers/members/import.js
new file mode 100644
index 000000000..cf070a79b
--- /dev/null
+++ b/app/controllers/members/import.js
@@ -0,0 +1,19 @@
+import Controller from '@ember/controller';
+import {inject as controller} from '@ember/controller';
+import {inject as service} from '@ember/service';
+
+/* eslint-disable ghost/ember/alias-model-in-controller */
+export default Controller.extend({
+ members: controller(),
+ router: service(),
+
+ actions: {
+ fetchNewMembers() {
+ this.members.fetchMembers.perform();
+ },
+
+ close() {
+ this.router.transitionTo('members');
+ }
+ }
+});
diff --git a/app/router.js b/app/router.js
index 5638d8d97..e4751fd74 100644
--- a/app/router.js
+++ b/app/router.js
@@ -58,7 +58,9 @@ Router.map(function () {
this.route('settings.integrations.unsplash', {path: '/settings/integrations/unsplash'});
this.route('settings.integrations.zapier', {path: '/settings/integrations/zapier'});
- this.route('members');
+ this.route('members', function () {
+ this.route('import');
+ });
this.route('member', {path: '/members/:member_id'});
this.route('subscribers', function () {
diff --git a/app/routes/members/import.js b/app/routes/members/import.js
new file mode 100644
index 000000000..6c74252aa
--- /dev/null
+++ b/app/routes/members/import.js
@@ -0,0 +1,4 @@
+import Route from '@ember/routing/route';
+
+export default Route.extend({
+});
diff --git a/app/styles/layouts/members.css b/app/styles/layouts/members.css
index 2f94d9a83..0e45190cc 100644
--- a/app/styles/layouts/members.css
+++ b/app/styles/layouts/members.css
@@ -27,4 +27,12 @@ p.gh-members-list-email {
textarea.gh-member-details-textarea {
max-width: 100%;
height: 123px;
+}
+
+/* Import modal
+/* ---------------------------------------------------------- */
+
+.members-import-results {
+ margin: 0;
+ width: auto;
}
\ No newline at end of file
diff --git a/app/templates/components/modal-import-members.hbs b/app/templates/components/modal-import-members.hbs
new file mode 100644
index 000000000..2472d9550
--- /dev/null
+++ b/app/templates/components/modal-import-members.hbs
@@ -0,0 +1,47 @@
+
+ {{#if response}}
+ Import Successful
+ {{else}}
+ Import Members
+ {{/if}}
+
+
Imported: | +{{response.imported}} | +
Duplicates: | +{{response.duplicates}} | +
Invalid: | +{{response.invalid}} | +