diff --git a/package-lock.json b/package-lock.json
index 0d447cb..c1e99f1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2767,6 +2767,11 @@
"integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
"dev": true
},
+ "bulma": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.7.4.tgz",
+ "integrity": "sha512-krG2rP6eAX1WE0sf6O0SC/FUVSOBX4m1PBC2+GKLpb2pX0qanaDqcv9U2nu75egFrsHkI0zdWYuk/oGwoszVWg=="
+ },
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@@ -5499,8 +5504,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -5521,14 +5525,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -5543,20 +5545,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -5673,8 +5672,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -5686,7 +5684,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -5701,7 +5698,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -5709,14 +5705,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -5735,7 +5729,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -5816,8 +5809,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -5829,7 +5821,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -5915,8 +5906,7 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -5952,7 +5942,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -5972,7 +5961,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -6016,14 +6004,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -9730,8 +9716,7 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
"integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
- "dev": true,
- "optional": true
+ "dev": true
},
"rx-lite-aggregates": {
"version": "4.0.8",
diff --git a/package.json b/package.json
index 3d0739d..36c5629 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"dependencies": {
"ajv": "^5.5.2",
"axios": "^0.18.0",
+ "bulma": "^0.7.4",
"vue": "^2.6.10",
"vue-router": "^3.0.1",
"vuex": "^3.0.1",
diff --git a/src/api/invitation/index.js b/src/api/invitation/index.js
new file mode 100644
index 0000000..121cd55
--- /dev/null
+++ b/src/api/invitation/index.js
@@ -0,0 +1,13 @@
+import api from '@/api';
+import getHeader from '@/api/utils/get-header';
+
+export default {
+ async listInvitations(sessionID) {
+ const res = (await api.client.get('/admin/invitations', getHeader(sessionID))).data.invitations;
+ return res;
+ },
+ async createInvitation(sessionID, email) {
+ const res = (await api.client.post('/admin/invitations', { email }, getHeader(sessionID))).data.invitations;
+ return res;
+ },
+};
diff --git a/src/router.js b/src/router.js
index 3e24533..4c75095 100644
--- a/src/router.js
+++ b/src/router.js
@@ -79,6 +79,12 @@ const router = new Router({
name: 'profile',
component: () => import(/* webpackChunkName: "profile" */ './views/memberIntroduction/Profile.vue'),
},
+ {
+ path: '/admin/invitations',
+ name: 'invitation',
+ component: () => import(/* webpackChunkName: "invitation" */ './views/admin/Invitation.vue'),
+ meta: { requiresAdmin: true },
+ },
],
});
@@ -101,11 +107,24 @@ router.beforeEach(async (to, from, next) => {
console.error(e);
store.commit('session/clearSessionID');
}
+
+ if (to.matched.some(record => record.meta.requiresAdmin) && !store.getters['user/isAdmin']) {
+ store.commit('criticalError/createError', {
+ response: {
+ status: 404,
+ data: {
+ message: 'Page not Found',
+ },
+ },
+ });
+ return;
+ }
if (to.matched.some(record => record.meta.requiresAuth) && !store.getters['session/loggedIn']) {
next({ path: '/login', query: { redirect: to.fullPath } });
- } else {
- next();
+ return;
}
+
+ next();
});
export default router;
diff --git a/src/store/index.js b/src/store/index.js
index 557a996..e31c8cf 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -10,6 +10,7 @@ import achievement from './modules/achievement';
import emailConfirmations from './modules/emailConfirmations';
import memberIntroduction from './modules/memberIntroduction';
import editUser from './modules/editUser';
+import invitation from './modules/invitation';
Vue.use(Vuex);
@@ -25,6 +26,7 @@ export default new Vuex.Store({
emailConfirmations,
memberIntroduction,
editUser,
+ invitation,
},
plugins: [
createPersistedState({
diff --git a/src/store/modules/invitation/index.js b/src/store/modules/invitation/index.js
new file mode 100644
index 0000000..a489281
--- /dev/null
+++ b/src/store/modules/invitation/index.js
@@ -0,0 +1,42 @@
+import invitationClient from '@/api/invitation';
+
+export default {
+ namespaced: true,
+ state: {
+ invitations: null,
+ invitationError: null,
+ },
+ /* eslint-disable no-param-reassign */
+ mutations: {
+ setInvitations(state, invitations) {
+ state.invitations = invitations;
+ },
+ clearInvitationError(state) {
+ state.invitationError = null;
+ },
+ setInvitationError(state, error) {
+ state.invitationError = error;
+ },
+ },
+ /* eslint-enable no-param-reassign */
+ actions: {
+ async listInvitations({ commit }, sessionID) {
+ try {
+ commit('setInvitations', await invitationClient.listInvitations(sessionID));
+ } catch (e) {
+ commit('criticalError/createError', e, { root: true });
+ }
+ },
+ async invite({ commit, dispatch }, { sessionID, rawEmails }) {
+ commit('clearInvitationError');
+ const emails = rawEmails.split(/\r\n|\n/).map(email => email.trim()).filter(email => email);
+ try {
+ await Promise.all(emails.map(email => invitationClient.createInvitation(sessionID, email)));
+ } catch (e) {
+ commit('setInvitationError', e);
+ }
+
+ dispatch('listInvitations', sessionID);
+ },
+ },
+};
diff --git a/src/store/modules/user/index.js b/src/store/modules/user/index.js
index 4503e53..3962e4b 100644
--- a/src/store/modules/user/index.js
+++ b/src/store/modules/user/index.js
@@ -50,4 +50,9 @@ export default {
}
},
},
+ getters: {
+ isAdmin(state) {
+ return state.userData && state.userData.authority === 'ADMIN';
+ },
+ },
};
diff --git a/src/views/admin/Invitation.vue b/src/views/admin/Invitation.vue
new file mode 100644
index 0000000..6990c63
--- /dev/null
+++ b/src/views/admin/Invitation.vue
@@ -0,0 +1,77 @@
+
+
+
+
+ 招待されたメールアドレス
+
+
+
+ ID |
+ メールアドレス |
+
+
+
+
+ {{ invitation.invitation_id }} |
+ {{ invitation.email }} |
+
+
+
+
+
+
+
+
+
+