use vue-router, use pug in templates

This commit is contained in:
Evert Prants 2017-12-05 17:19:22 +02:00
parent 22c4addc0f
commit 73049447cd
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
11 changed files with 216 additions and 281 deletions

6
package-lock.json generated
View File

@ -6192,6 +6192,12 @@
"got": "7.1.0" "got": "7.1.0"
} }
}, },
"vue-router": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.1.tgz",
"integrity": "sha512-vLLoY452L+JBpALMP5UHum9+7nzR9PeIBCghU9ZtJ1eWm6ieUI8Zb/DI3MYxH32bxkjzYV1LRjNv4qr8d+uX/w==",
"dev": true
},
"vue-style-loader": { "vue-style-loader": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-3.0.3.tgz", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-3.0.3.tgz",

View File

@ -70,6 +70,7 @@
"uglifyjs-webpack-plugin": "^0.4.6", "uglifyjs-webpack-plugin": "^0.4.6",
"vue-loader": "^13.5.0", "vue-loader": "^13.5.0",
"vue-resource": "^1.3.4", "vue-resource": "^1.3.4",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.5.9", "vue-template-compiler": "^2.5.9",
"watch": "^1.0.2", "watch": "^1.0.2",
"webpack": "^3.10.0", "webpack": "^3.10.0",

View File

@ -1,68 +1,24 @@
import Vue from 'vue' import Vue from 'vue'
import VueResource from 'vue-resource' import VueResource from 'vue-resource'
import VueRouter from 'vue-router'
import UserList from './component/UserList.vue' import Users from './views/Users.vue'
import BanList from './component/BanList.vue' import OAuth2 from './views/OAuth2.vue'
const csrfToken = document.querySelector('meta[name="csrf-token"]').content
Vue.use(VueResource) Vue.use(VueResource)
Vue.use(VueRouter)
Vue.component('Modal', { const routes = [
template: '#modal-template', { path: '/', component: Users },
props: ['show'], { path: '/oauth2', component: OAuth2 }
methods: { ]
close: function () {
this.$emit('close')
}
},
mounted: function () {
document.addEventListener('keydown', (e) => {
if (this.show && e.keyCode === 27) {
this.close()
}
})
}
})
Vue.component('BanModal', { const router = new VueRouter({
template: '#ban-modal-template', routes
props: ['show', 'id'],
data: function () {
return {
error: '',
reason: '',
expires_at: null
}
},
methods: {
close: function () {
this.$emit('close')
this.error = ''
this.reason = ''
this.expires_at = null
},
submit: function () {
this.$http.post('/admin/api/ban', {
user_id: this.id,
reason: this.reason,
expires_at: this.expires_at,
csrf: csrfToken
}).then(data => {
this.close()
this.$root.$emit('reload_bans')
}).catch(err => {
console.log(err)
if (err.body && err.body.error) this.error = err.body.error
})
}
}
}) })
const app = new Vue({ const app = new Vue({
el: '#app', router
components: {
UserList,
BanList
}
}) })
app.$mount('#app')

View File

@ -1,53 +1,41 @@
<template> <template lang="pug">
<div id="banlist"> #banlist
<h3>Bans ({{pagination.total}})</h3> h3 Bans ({{pagination.total}})
<div class="message error" v-if="error">{{ error }}</div> .message.error(v-if='error') {{ error }}
<div class="entry" v-else="v-else"> .entry(v-else='v-else')
<div class="pgn"> .pgn
<span class="pagenum">Page {{ pagination.page }} of {{ pagination.pages }}</span> span.pagenum Page {{ pagination.page }} of {{ pagination.pages }}
<div class="button" v-if="pagination.page &gt; 1" v-on:click="getBans(pagination.page - 1)">Previous</div> .button(v-if='pagination.page > 1', v-on:click='getBans(pagination.page - 1)') Previous
<div class="button" v-for="n in pagination.pages" v-on:click="getBans(n)" v-bind:class="{active: n == pagination.page}">{{ n }}</div> .button(v-for='n in pagination.pages', v-on:click='getBans(n)', v-bind:class='{active: n == pagination.page}') {{ n }}
<div class="button" v-if="pagination.page &lt; pagination.pages" v-on:click="getBans(pagination.page + 1)">Next</div> .button(v-if='pagination.page < pagination.pages', v-on:click='getBans(pagination.page + 1)') Next
</div> .list.bans
<div class="list bans"> .ban.list-item(v-for='ban in bans')
<div class="ban list-item" v-for="ban in bans"> .stamps
<div class="stamps"> .noactive(title='Expired', v-if='ban.expired')
<div class="noactive" title="Expired" v-if="ban.expired"> i.fa.fa-fw.fa-ban
<i class="fa fa-fw fa-ban"></i> .info
</div> .section
</div> span.key User
<div class="info"> span.value {{ ban.user.display_name }}
<div class="section"> .section
<span class="key">User</span> span.key Admin
<span class="value">{{ ban.user.display_name }}</span> span.value {{ ban.admin.display_name }}
</div> .section
<div class="section"> span.key Reason
<span class="key">Admin</span> span.value {{ ban.reason }}
<span class="value">{{ ban.admin.display_name }}</span> .section
</div> span.key Placed
<div class="section"> span.value {{ new Date(ban.created_at).toString() }}
<span class="key">Reason</span> .section
<span class="value">{{ ban.reason }}</span> span.key Expires
</div> span.value(v-if='ban.expires_at') {{ new Date(ban.expires_at).toString() }}
<div class="section"> span.value(v-else='v-else')
<span class="key">Placed</span> b This ban is permanent.
<span class="value">{{ new Date(ban.created_at).toString() }}</span> .button.remove(@click='pardon(ban.id)') Pardon
</div>
<div class="section">
<span class="key">Expires</span>
<span class="value" v-if="ban.expires_at">{{ new Date(ban.expires_at).toString() }}</span>
<span class="value" v-else="v-else"><b>This ban is permanent.</b></span>
</div>
<div class="button remove" @click="pardon(ban.id)">Pardon</div>
</div>
</div>
</div>
</div>
</div>
</template> </template>
<script type="text/javascript"> <script type="text/javascript">
module.exports = { export default {
data: function () { data: function () {
return { return {
pagination: { pagination: {

View File

@ -0,0 +1,56 @@
<template lang="pug">
modal(:show='show', @close='close')
.modal-header
h3 Ban user
.modal-body
.message.error(v-if='error') {{ error }}
input(type='hidden', name='user_id', :value='id')
label(for='reason') Reason
input#reason(type='text', name='reason', v-model='reason')
label(for='expires_at') Expires
input#expires_at(type='date', name='expires_at', v-model='expires_at')
.modal-footer.text-right
button(@click='submit') Ban
button(@click='close') Cancel
</template>
<script type="text/javascript">
import Modal from './Modal.vue'
const csrfToken = document.querySelector('meta[name="csrf-token"]').content
export default {
props: ['show', 'id'],
data: function () {
return {
error: '',
reason: '',
expires_at: null
}
},
components: {
Modal
},
methods: {
close: function () {
this.$emit('close')
this.error = ''
this.reason = ''
this.expires_at = null
},
submit: function () {
this.$http.post('/admin/api/ban', {
user_id: this.id,
reason: this.reason,
expires_at: this.expires_at,
csrf: csrfToken
}).then(data => {
this.close()
this.$root.$emit('reload_bans')
}).catch(err => {
console.log(err)
if (err.body && err.body.error) this.error = err.body.error
})
}
}
}
</script>

View File

@ -0,0 +1,25 @@
<template lang="pug">
transition(name='modal')
.modal-mask(@click='close', v-show='show')
.modal-wrapper
.modal-container(@click.stop='')
slot
</template>
<script type="text/javascript">
export default {
props: ['show'],
methods: {
close: function () {
this.$emit('close')
}
},
mounted: function () {
document.addEventListener('keydown', (e) => {
if (this.show && e.keyCode === 27) {
this.close()
}
})
}
}
</script>

View File

@ -1,42 +1,37 @@
<template> <template lang="pug">
<div id="userlist"> #userlist
<h3>Registered Users ({{ pagination.total }})</h3> h3 Registered Users ({{ pagination.total }})
<div class="pgn"> .pgn
<span class="pagenum">Page {{ pagination.page }} of {{ pagination.pages }}</span> span.pagenum Page {{ pagination.page }} of {{ pagination.pages }}
<div class="button" v-if="pagination.page &gt; 1" v-on:click="getUsers(pagination.page - 1)">Previous</div> .button(v-if='pagination.page > 1', v-on:click='getUsers(pagination.page - 1)') Previous
<div class="button" v-for="n in pagination.pages" v-on:click="getUsers(n)" v-bind:class="{active: n == pagination.page}">{{ n }}</div> .button(v-for='n in pagination.pages', v-on:click='getUsers(n)', v-bind:class='{active: n == pagination.page}') {{ n }}
<div class="button" v-if="pagination.page &lt; pagination.pages" v-on:click="getUsers(pagination.page + 1)">Next</div> .button(v-if='pagination.page < pagination.pages', v-on:click='getUsers(pagination.page + 1)') Next
</div> .list.users
<div class="list users"> .user.list-item(v-for='user in users')
<div class="user list-item" v-for="user in users"> .avatar
<div class="avatar"> img(v-if='user.avatar_file', v-bind:src="'/usercontent/images/' + user.avatar_file")
<img v-if="user.avatar_file" v-bind:src="'/usercontent/images/' + user.avatar_file"/> img(v-else='v-else', src='/static/image/avatar.png')
<img v-else="v-else" src="/static/image/avatar.png"/> .info
</div> .stamps
<div class="info"> .noactive(v-if='user.activated == false', title='Not activated.')
<div class="stamps"> i.fa.fa-fw.fa-envelope
<div class="noactive" v-if="user.activated == false" title="Not activated."> .display_name {{ user.display_name }}
<i class="fa fa-fw fa-envelope"></i> .username {{ user.id }} - {{ user.username }} ({{ user.uuid }})
</div> .email {{ user.email }}
</div> .privilege Privilege: level {{ user.nw_privilege }}
<div class="display_name">{{ user.display_name }}</div> .timestamp {{ new Date(user.created_at).toString() }}
<div class="username">{{ user.id }} - {{ user.username }} ({{ user.uuid }})</div> .external(v-if='!user.password')
<div class="email">{{ user.email }}</div> b Used external login
<div class="privilege">Privilege: level {{ user.nw_privilege }}</div> .button.ban(v-if='user.bannable', v-on:click='banning = user.id')
<div class="timestamp">{{ new Date(user.created_at).toString() }}</div> i.fa.fa-fw.fa-ban
<div class="external" v-if="!user.password"><b>Used external login</b></div> | Ban User
<div class="button ban" v-if="user.bannable" v-on:click="banning = user.id"> ban-modal(:show='banning', @close='banning = 0', :id='banning')
<i class="fa fa-fw fa-ban"></i>Ban User
</div>
</div>
</div>
<ban-modal :show="banning" @close="banning = 0" :id="banning"></ban-modal>
</div>
</div>
</template> </template>
<script> <script>
module.exports = { import BanModal from './BanModal.vue'
export default {
data: function () { data: function () {
return { return {
pagination: { pagination: {
@ -50,14 +45,15 @@
banning: 0 banning: 0
} }
}, },
components: {
BanModal
},
methods: { methods: {
getUsers: function (page) { getUsers: function (page) {
this.$http.get('/admin/api/users?page=' + page).then(data => { this.$http.get('/admin/api/users?page=' + page).then(data => {
if (data.body && data.body.error) return if (data.body && data.body.error) return
this.pagination = data.body.page this.pagination = data.body.page
this.users = data.body.users this.users = data.body.users
console.log(this.pagination)
}) })
} }
}, },

View File

@ -0,0 +1,8 @@
<template lang="pug">
.root
h1 Manage OAuth2 Clients
</template>
<script type="text/javascript">
export default {}
</script>

View File

@ -0,0 +1,18 @@
<template lang="pug">
.root
h1 Welcome to the Admin Panel
.left
user-list
.right
ban-list
</template>
<script type="text/javascript">
import UserList from '../component/UserList.vue'
import BanList from '../component/BanList.vue'
export default {
components: {
UserList, BanList
}
}
</script>

View File

@ -2,122 +2,9 @@ extends layout.pug
block body block body
.container .container
.content#app .content
h1 Welcome to the Admin Panel router-view
.left
user-list
.right
ban-list
.templates .templates
script(type="text/x-template" id="user-list-template").
<div id="userlist">
<h3>Registered Users ({{ pagination.total }})</h3>
<div class="pgn">
<span class="pagenum">Page {{ pagination.page }} of {{ pagination.pages }}</span>
<div class="button" v-if="pagination.page &gt; 1" v-on:click="getUsers(pagination.page - 1)">Previous</div>
<div class="button" v-for="n in pagination.pages" v-on:click="getUsers(n)" v-bind:class="{active: n == pagination.page}">{{ n }}</div>
<div class="button" v-if="pagination.page &lt; pagination.pages" v-on:click="getUsers(pagination.page + 1)">Next</div>
</div>
<div class="list users">
<div class="user list-item" v-for="user in users">
<div class="avatar">
<img v-if="user.avatar_file" v-bind:src="'/usercontent/images/' + user.avatar_file"/>
<img v-else="v-else" src="/static/image/avatar.png"/>
</div>
<div class="info">
<div class="stamps">
<div class="noactive" v-if="user.activated == false" title="Not activated.">
<i class="fa fa-fw fa-envelope"></i>
</div>
</div>
<div class="display_name">{{ user.display_name }}</div>
<div class="username">{{ user.id }} - {{ user.username }} ({{ user.uuid }})</div>
<div class="email">{{ user.email }}</div>
<div class="privilege">Privilege: level {{ user.nw_privilege }}</div>
<div class="timestamp">{{ new Date(user.created_at).toString() }}</div>
<div class="external" v-if="!user.password"><b>Used external login</b></div>
<div class="button ban" v-if="user.bannable" v-on:click="banning = user.id">
<i class="fa fa-fw fa-ban"></i>Ban User
</div>
</div>
</div>
<ban-modal :show="banning" @close="banning = 0" :id="banning"></ban-modal>
</div>
</div>
script(type="text/x-template" id="ban-list-template").
<div id="banlist">
<h3>Bans ({{pagination.total}})</h3>
<div class="message error" v-if="error">{{ error }}</div>
<div class="entry" v-else="v-else">
<div class="pgn">
<span class="pagenum">Page {{ pagination.page }} of {{ pagination.pages }}</span>
<div class="button" v-if="pagination.page &gt; 1" v-on:click="getBans(pagination.page - 1)">Previous</div>
<div class="button" v-for="n in pagination.pages" v-on:click="getBans(n)" v-bind:class="{active: n == pagination.page}">{{ n }}</div>
<div class="button" v-if="pagination.page &lt; pagination.pages" v-on:click="getBans(pagination.page + 1)">Next</div>
</div>
<div class="list bans">
<div class="ban list-item" v-for="ban in bans">
<div class="stamps">
<div class="noactive" title="Expired" v-if="ban.expired">
<i class="fa fa-fw fa-ban"></i>
</div>
</div>
<div class="info">
<div class="section">
<span class="key">User</span>
<span class="value">{{ ban.user.display_name }}</span>
</div>
<div class="section">
<span class="key">Admin</span>
<span class="value">{{ ban.admin.display_name }}</span>
</div>
<div class="section">
<span class="key">Reason</span>
<span class="value">{{ ban.reason }}</span>
</div>
<div class="section">
<span class="key">Placed</span>
<span class="value">{{ new Date(ban.created_at).toString() }}</span>
</div>
<div class="section">
<span class="key">Expires</span>
<span class="value" v-if="ban.expires_at">{{ new Date(ban.expires_at).toString() }}</span>
<span class="value" v-else="v-else"><b>This ban is permanent.</b></span>
</div>
<div class="button remove" @click="pardon(ban.id)">Pardon</div>
</div>
</div>
</div>
</div>
</div>
script(type="text/x-template" id="modal-template").
<transition name="modal">
<div class="modal-mask" @click="close" v-show="show">
<div class="modal-wrapper" @click.stop>
<div class="modal-container">
<slot></slot>
</div>
</div>
</div>
</transition>
script(type="text/x-template" id="ban-modal-template"). script(type="text/x-template" id="ban-modal-template").
<modal :show="show" @close="close">
<div class="modal-header">
<h3>Ban user</h3>
</div>
<div class="modal-body">
<div class="message error" v-if="error">{{ error }}</div>
<input type="hidden" name="user_id" :value="id">
<label for="reason">Reason</label>
<input type="text" id="reason" name="reason" v-model="reason">
<label for="expires_at">Expires</label>
<input type="date" id="expires_at" name="expires_at" v-model="expires_at">
</div>
<div class="modal-footer text-right">
<button @click="submit">Ban</button>
<button @click="close">Cancel</button>
</div>
</modal>

View File

@ -15,26 +15,20 @@ html
block title block title
|Icy Network - Administration |Icy Network - Administration
body body
block navigation #app
nav block navigation
ul nav
li ul
a.navlogo(href="/") Icy Network li
li a.navlogo(href="/") Icy Network
a(href="/admin/") Home li
li router-link(to="/") Home
a(href="/admin/oauth2/") OAuth2 li
ul.right router-link(to="/oauth2") OAuth2
li ul.right
a(href="/user/manage") #{user.display_name} li
block dialog a(href="/user/manage") #{user.display_name}
.dialog-drop#dialog
.dialog .wrapper
.head block body
#title script(src="/script/admin.js")
#close
i.fa.fa-fw.fa-times
.content#content
.wrapper
block body
script(src="/script/admin.js")