mirror of https://github.com/Requarks/wiki.git
15 changed files with 368 additions and 276 deletions
Split View
Diff Options
-
85client/js/app.js
-
21client/js/components/alert.vue
-
56client/js/modals/admin-users-create.js
-
93client/js/modals/admin-users-create.vue
-
28client/js/pages/admin-profile.component.js
-
4client/js/pages/admin.js
-
2client/js/pages/view.js
-
25client/js/store/index.js
-
15client/js/store/modules/admin-users-create.js
-
32client/js/store/modules/alert.js
-
150client/scss/components/alert.scss
-
3package.json
-
2server/views/layout.pug
-
71server/views/pages/admin/users.pug
-
57yarn.lock
@ -0,0 +1,21 @@ |
|||
<template lang="pug"> |
|||
transition(name='alert', enter-active-class="animated zoomIn", leave-active-class="animated fadeOutRight") |
|||
.alert(v-if='shown', v-bind:class='style') |
|||
.alert-icon: i(v-bind:class='icon') |
|||
.alert-msg {{ msg }} |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'alert', |
|||
data () { |
|||
return {} |
|||
}, |
|||
computed: { |
|||
shown() { return this.$store.state.alert.shown }, |
|||
style() { return 'is-' + this.$store.state.alert.style }, |
|||
icon() { return 'icon-' + this.$store.state.alert.icon }, |
|||
msg() { return this.$store.state.alert.msg }, |
|||
} |
|||
} |
|||
</script> |
@ -1,56 +0,0 @@ |
|||
'use strict' |
|||
|
|||
import $ from 'jquery' |
|||
import Vue from 'vue' |
|||
|
|||
// Vue Create User instance
|
|||
|
|||
module.exports = (alerts) => { |
|||
let vueCreateUser = new Vue({ |
|||
el: '#modal-admin-users-create', |
|||
data: { |
|||
email: '', |
|||
provider: 'local', |
|||
password: '', |
|||
name: '', |
|||
loading: false |
|||
}, |
|||
methods: { |
|||
open: (ev) => { |
|||
$('#modal-admin-users-create').addClass('is-active') |
|||
$('#modal-admin-users-create input').first().focus() |
|||
}, |
|||
cancel: (ev) => { |
|||
$('#modal-admin-users-create').removeClass('is-active') |
|||
vueCreateUser.email = '' |
|||
vueCreateUser.provider = 'local' |
|||
}, |
|||
create: (ev) => { |
|||
vueCreateUser.loading = true |
|||
$.ajax('/admin/users/create', { |
|||
data: { |
|||
email: vueCreateUser.email, |
|||
provider: vueCreateUser.provider, |
|||
password: vueCreateUser.password, |
|||
name: vueCreateUser.name |
|||
}, |
|||
dataType: 'json', |
|||
method: 'POST' |
|||
}).then((rData, rStatus, rXHR) => { |
|||
vueCreateUser.loading = false |
|||
if (rData.ok) { |
|||
vueCreateUser.cancel() |
|||
window.location.reload(true) |
|||
} else { |
|||
alerts.pushError('Something went wrong', rData.msg) |
|||
} |
|||
}, (rXHR, rStatus, err) => { |
|||
vueCreateUser.loading = false |
|||
alerts.pushError('Error', rXHR.responseJSON.msg) |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
|
|||
$('.btn-create-prompt').on('click', vueCreateUser.open) |
|||
} |
@ -0,0 +1,93 @@ |
|||
<template lang="pug"> |
|||
.modal(v-bind:class='{ "is-active": isShown }') |
|||
.modal-background |
|||
.modal-container |
|||
.modal-content |
|||
header.is-blue |
|||
span Create / Authorize User |
|||
p.modal-notify(v-bind:class='{ "is-active": loading }'): i |
|||
section |
|||
label.label Email address: |
|||
p.control.is-fullwidth |
|||
input.input(type='text', placeholder='e.g. john.doe@company.com', v-model='email', autofocus) |
|||
section |
|||
label.label Provider: |
|||
p.control.is-fullwidth |
|||
select(v-model='provider') |
|||
option(value='local') Local Database |
|||
option(value='windowslive') Microsoft Account |
|||
option(value='google') Google ID |
|||
option(value='facebook') Facebook |
|||
option(value='github') GitHub |
|||
option(value='slack') Slack |
|||
section(v-if='provider=="local"') |
|||
label.label Password: |
|||
p.control.is-fullwidth |
|||
input.input(type='password', placeholder='', v-model='password') |
|||
section(v-if='provider=="local"') |
|||
label.label Full Name: |
|||
p.control.is-fullwidth |
|||
input.input(type='text', placeholder='e.g. John Doe', v-model='name') |
|||
footer |
|||
a.button.is-grey.is-outlined(v-on:click='cancel') Discard |
|||
a.button(v-on:click='create', v-if='provider=="local"', v-bind:disabled='loading', v-bind:class='{ "is-disabled": loading, "is-blue": !loading }') Create User |
|||
a.button(v-on:click='create', v-if='provider!="local"', v-bind:disabled='loading', v-bind:class='{ "is-disabled": loading, "is-blue": !loading }') Authorize User |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'admin-users-create', |
|||
data () { |
|||
return { |
|||
email: '', |
|||
provider: 'local', |
|||
password: '', |
|||
name: '', |
|||
loading: false |
|||
} |
|||
}, |
|||
computed: { |
|||
isShown () { |
|||
return this.$store.state.adminUsersCreate.shown |
|||
} |
|||
}, |
|||
methods: { |
|||
cancel () { |
|||
this.$store.dispatch('adminUsersCreateClose') |
|||
this.email = '' |
|||
this.provider = 'local' |
|||
}, |
|||
create () { |
|||
let self = this |
|||
this.loading = true |
|||
this.$http.post('/admin/users/create', { |
|||
email: this.email, |
|||
provider: this.provider, |
|||
password: this.password, |
|||
name: this.name |
|||
}).then(resp => { |
|||
return resp.json() |
|||
}).then(resp => { |
|||
this.loading = false |
|||
if (resp.ok) { |
|||
this.cancel() |
|||
window.location.reload(true) |
|||
} else { |
|||
self.$store.dispatch('alert', { |
|||
style: 'red', |
|||
icon: 'square-cross', |
|||
msg: resp.msg |
|||
}) |
|||
} |
|||
}).catch(err => { |
|||
this.loading = false |
|||
self.$store.dispatch('alert', { |
|||
style: 'red', |
|||
icon: 'square-cross', |
|||
msg: 'Error: ' + err.body.msg |
|||
}) |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,25 @@ |
|||
import Vue from 'vue' |
|||
import Vuex from 'vuex' |
|||
|
|||
import alert from './modules/alert' |
|||
import adminUsersCreate from './modules/admin-users-create' |
|||
|
|||
Vue.use(Vuex) |
|||
|
|||
export default new Vuex.Store({ |
|||
state: { |
|||
loading: false |
|||
}, |
|||
mutations: { |
|||
loadingChange: (state, loadingState) => { state.loading = loadingState } |
|||
}, |
|||
actions: { |
|||
startLoading({ commit }) { commit('loadingChange', true) }, |
|||
stopLoading({ commit }) { commit('loadingChange', false) } |
|||
}, |
|||
getters: {}, |
|||
modules: { |
|||
alert, |
|||
adminUsersCreate |
|||
} |
|||
}) |
@ -0,0 +1,15 @@ |
|||
'use strict' |
|||
|
|||
export default { |
|||
state: { |
|||
shown: false |
|||
}, |
|||
getters: {}, |
|||
mutations: { |
|||
shownChange: (state, shownState) => { state.shown = shownState } |
|||
}, |
|||
actions: { |
|||
adminUsersCreateOpen({ commit }) { commit('shownChange', true) }, |
|||
adminUsersCreateClose({ commit }) { commit('shownChange', false) } |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
'use strict' |
|||
|
|||
import _ from 'lodash' |
|||
|
|||
export default { |
|||
state: { |
|||
shown: false, |
|||
style: 'green', |
|||
icon: 'check', |
|||
msg: '' |
|||
}, |
|||
getters: {}, |
|||
mutations: { |
|||
alertChange: (state, opts) => { |
|||
state.shown = (opts.shown === true) |
|||
state.style = opts.style || 'green' |
|||
state.icon = opts.icon || 'check' |
|||
state.msg = opts.msg || '' |
|||
} |
|||
}, |
|||
actions: { |
|||
alert({ commit, dispatch }, opts) { |
|||
opts.shown = true |
|||
commit('alertChange', opts) |
|||
dispatch('alertDismiss') |
|||
}, |
|||
alertDismiss: _.debounce(({ commit }) => { |
|||
let opts = { shown: false } |
|||
commit('alertChange', opts) |
|||
}, 3000) |
|||
} |
|||
} |
@ -1,114 +1,48 @@ |
|||
/*#alerts { |
|||
position: fixed; |
|||
top: 60px; |
|||
right: 10px; |
|||
width: 350px; |
|||
z-index: 10; |
|||
text-shadow: 1px 1px 0 rgba(0,0,0,0.1); |
|||
|
|||
.notification { |
|||
animation: 0.5s ease slideInRight; |
|||
margin-top: 5px; |
|||
|
|||
&.exit { |
|||
animation: 0.5s ease fadeOutRight; |
|||
} |
|||
|
|||
} |
|||
|
|||
h3 { |
|||
font-size: 16px; |
|||
font-size: 500; |
|||
} |
|||
|
|||
}*/ |
|||
|
|||
#alerts { |
|||
position: fixed; |
|||
top: 55px; |
|||
right: 10px; |
|||
width: 350px; |
|||
z-index: 100; |
|||
|
|||
> ul { |
|||
margin: 0; |
|||
padding: 0; |
|||
list-style-type: none; |
|||
|
|||
> li { |
|||
background-color: material-color('blue-grey', '800'); |
|||
box-shadow: 5px 5px 0 transparentize(material-color('blue-grey', '900'), 0.7); |
|||
border: 1px solid material-color('blue-grey', '500'); |
|||
border-left-width: 5px; |
|||
margin-top: 5px; |
|||
padding: 8px 12px; |
|||
animation-name: slideFromRight; |
|||
animation-duration: 1s; |
|||
cursor: pointer; |
|||
position: relative; |
|||
|
|||
&:hover { |
|||
background-color: material-color('blue-grey', '900'); |
|||
} |
|||
|
|||
&.exit { |
|||
animation-name: zoomOut; |
|||
animation-duration: 1s; |
|||
transform-origin: top center; |
|||
} |
|||
|
|||
> button { |
|||
background-color: transparent; |
|||
border: none; |
|||
color: #FFF; |
|||
width: 15px; |
|||
height: 15px; |
|||
padding: 0; |
|||
position: absolute; |
|||
top: 10px; |
|||
right: 10px; |
|||
|
|||
&:before { |
|||
content: 'X'; |
|||
} |
|||
|
|||
.alert { |
|||
background-color: #FFF; |
|||
border-right: 3px solid mc('grey', '500'); |
|||
position: fixed; |
|||
top: 60px; |
|||
margin-left: 10px; |
|||
right: 10px; |
|||
max-width: 500px; |
|||
z-index: 1000; |
|||
display: flex; |
|||
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); |
|||
animation-duration: .6s; |
|||
|
|||
&-icon { |
|||
width: 50px; |
|||
height: 50px; |
|||
background-color: mc('grey', '500'); |
|||
color: #FFF; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
&-msg { |
|||
padding: 0 15px; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
border-top: 1px solid mc('grey', '200'); |
|||
font-size: 14px; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
@each $color, $colorvalue in $material-colors { |
|||
&.is-#{$color} { |
|||
border-right-color: mc($color, '500'); |
|||
|
|||
.alert-icon { |
|||
background-color: mc($color, '500'); |
|||
} |
|||
.alert-msg { |
|||
color: mc($color, '900'); |
|||
} |
|||
|
|||
> strong { |
|||
display: block; |
|||
font-size: 13px; |
|||
font-weight: 500; |
|||
color: #FFF; |
|||
|
|||
> i { |
|||
margin-right: 5px; |
|||
} |
|||
|
|||
} |
|||
|
|||
> span { |
|||
font-size: 12px; |
|||
font-weight: 500; |
|||
color: material-color('blue-grey', '100'); |
|||
} |
|||
|
|||
&.error { |
|||
border-color: material-color('red', '400'); |
|||
background-color: material-color('red', '600'); |
|||
> span { |
|||
color: material-color('red', '50'); |
|||
} |
|||
} |
|||
&.success { |
|||
border-color: material-color('green', '400'); |
|||
background-color: material-color('green', '700'); |
|||
> span { |
|||
color: material-color('green', '50'); |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} |
Write
Preview
Loading…
Cancel
Save