diff options
| author | Pitu <[email protected]> | 2019-02-26 23:13:24 +0900 |
|---|---|---|
| committer | Pitu <[email protected]> | 2019-02-26 23:13:24 +0900 |
| commit | 7a74647d3e5b5681b9d5d3fa9b6e12d062232683 (patch) | |
| tree | 318edbe05becccd8c8c77a4f4cf00913f50a5a66 /src | |
| parent | Add background to main page (diff) | |
| download | host.fuwn.me-7a74647d3e5b5681b9d5d3fa9b6e12d062232683.tar.xz host.fuwn.me-7a74647d3e5b5681b9d5d3fa9b6e12d062232683.zip | |
User management
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/routes/admin/userDemote.js | 6 | ||||
| -rw-r--r-- | src/api/routes/admin/userDisable.js | 27 | ||||
| -rw-r--r-- | src/api/routes/admin/userEnable.js | 27 | ||||
| -rw-r--r-- | src/api/routes/admin/userPromote.js | 4 | ||||
| -rw-r--r-- | src/site/components/sidebar/Sidebar.vue | 24 | ||||
| -rw-r--r-- | src/site/pages/dashboard/users.vue | 257 |
6 files changed, 332 insertions, 13 deletions
diff --git a/src/api/routes/admin/userDemote.js b/src/api/routes/admin/userDemote.js index e9c37a0..fa288fc 100644 --- a/src/api/routes/admin/userDemote.js +++ b/src/api/routes/admin/userDemote.js @@ -2,13 +2,13 @@ const Route = require('../../structures/Route'); class userDemote extends Route { constructor() { - super('/admin/users/demote', 'get', { adminOnly: true }); + super('/admin/users/demote', 'post', { adminOnly: true }); } async run(req, res, db) { if (!req.body) return res.status(400).json({ message: 'No body provided' }); const { id } = req.body; - if (!id) return res.status(400).json({ message: 'No name provided' }); + if (!id) return res.status(400).json({ message: 'No id provided' }); try { await db.table('users') @@ -19,7 +19,7 @@ class userDemote extends Route { } return res.json({ - message: 'Successfully promoted user' + message: 'Successfully demoted user' }); } } diff --git a/src/api/routes/admin/userDisable.js b/src/api/routes/admin/userDisable.js new file mode 100644 index 0000000..c7dffa8 --- /dev/null +++ b/src/api/routes/admin/userDisable.js @@ -0,0 +1,27 @@ +const Route = require('../../structures/Route'); + +class userDisable extends Route { + constructor() { + super('/admin/users/disable', 'post', { adminOnly: true }); + } + + async run(req, res, db) { + if (!req.body) return res.status(400).json({ message: 'No body provided' }); + const { id } = req.body; + if (!id) return res.status(400).json({ message: 'No id provided' }); + + try { + await db.table('users') + .where({ id }) + .update({ enabled: false }); + } catch (error) { + return super.error(res, error); + } + + return res.json({ + message: 'Successfully disabled user' + }); + } +} + +module.exports = userDisable; diff --git a/src/api/routes/admin/userEnable.js b/src/api/routes/admin/userEnable.js new file mode 100644 index 0000000..7e5743d --- /dev/null +++ b/src/api/routes/admin/userEnable.js @@ -0,0 +1,27 @@ +const Route = require('../../structures/Route'); + +class userEnable extends Route { + constructor() { + super('/admin/users/enable', 'post', { adminOnly: true }); + } + + async run(req, res, db) { + if (!req.body) return res.status(400).json({ message: 'No body provided' }); + const { id } = req.body; + if (!id) return res.status(400).json({ message: 'No id provided' }); + + try { + await db.table('users') + .where({ id }) + .update({ enabled: true }); + } catch (error) { + return super.error(res, error); + } + + return res.json({ + message: 'Successfully enabled user' + }); + } +} + +module.exports = userEnable; diff --git a/src/api/routes/admin/userPromote.js b/src/api/routes/admin/userPromote.js index caae176..4062dfa 100644 --- a/src/api/routes/admin/userPromote.js +++ b/src/api/routes/admin/userPromote.js @@ -2,13 +2,13 @@ const Route = require('../../structures/Route'); class userPromote extends Route { constructor() { - super('/admin/users/promote', 'get', { adminOnly: true }); + super('/admin/users/promote', 'post', { adminOnly: true }); } async run(req, res, db) { if (!req.body) return res.status(400).json({ message: 'No body provided' }); const { id } = req.body; - if (!id) return res.status(400).json({ message: 'No name provided' }); + if (!id) return res.status(400).json({ message: 'No id provided' }); try { await db.table('users') diff --git a/src/site/components/sidebar/Sidebar.vue b/src/site/components/sidebar/Sidebar.vue index 3317eca..cf3fc4b 100644 --- a/src/site/components/sidebar/Sidebar.vue +++ b/src/site/components/sidebar/Sidebar.vue @@ -44,15 +44,23 @@ <router-link to="/dashboard/account"> <i class="icon-ecommerce-tag-c" />Account </router-link> - <hr> - <router-link to="/dashboard/users"> - <i class="icon-setting-gear-a" />Users - </router-link> - <router-link to="/dashboard/settings"> - <i class="icon-setting-gear-a" />Settings - </router-link> + <template v-if="user.isAdmin"> + <hr> + <router-link to="/dashboard/users"> + <i class="icon-setting-gear-a" />Users + </router-link> + <router-link to="/dashboard/settings"> + <i class="icon-setting-gear-a" />Settings + </router-link> + </template> </div> </template> <script> -export default {}; +export default { + computed: { + user() { + return this.$store.state.user; + } + }, +}; </script> diff --git a/src/site/pages/dashboard/users.vue b/src/site/pages/dashboard/users.vue new file mode 100644 index 0000000..df16918 --- /dev/null +++ b/src/site/pages/dashboard/users.vue @@ -0,0 +1,257 @@ +<style lang="scss" scoped> + @import '~/assets/styles/_colors.scss'; + section { background-color: $backgroundLight1 !important; } + section.hero div.hero-body { + align-items: baseline; + } + div.search-container { + display: flex; + justify-content: center; + } + + div.view-container { + padding: 2rem; + } + div.album { + display: flex; + flex-wrap: wrap; + margin-bottom: 10px; + + div.arrow-container { + width: 2em; + height: 64px; + position: relative; + cursor: pointer; + + i { + border: 2px solid $defaultTextColor; + border-right: 0; + border-top: 0; + display: block; + height: 1em; + position: absolute; + transform: rotate(-135deg); + transform-origin: center; + width: 1em; + z-index: 4; + top: 22px; + + -webkit-transition: transform 0.1s linear; + -moz-transition: transform 0.1s linear; + -ms-transition: transform 0.1s linear; + -o-transition: transform 0.1s linear; + transition: transform 0.1s linear; + + &.active { + transform: rotate(-45deg); + } + } + } + div.thumb { + width: 64px; + height: 64px; + -webkit-box-shadow: $boxShadowLight; + box-shadow: $boxShadowLight; + } + + div.info { + margin-left: 15px; + h4 { + font-size: 1.5rem; + a { + color: $defaultTextColor; + font-weight: 400; + &:hover { text-decoration: underline; } + } + } + span { display: block; } + span:nth-child(3) { + font-size: 0.9rem; + } + } + + div.latest { + flex-grow: 1; + justify-content: flex-end; + display: flex; + margin-left: 15px; + + span.no-files { + font-size: 1.5em; + color: #b1b1b1; + padding-top: 17px; + } + + div.more { + width: 64px; + height: 64px; + background: white; + display: flex; + align-items: center; + padding: 10px; + text-align: center; + a { + line-height: 1rem; + color: $defaultTextColor; + &:hover { text-decoration: underline; } + } + } + } + + div.details { + flex: 0 1 100%; + padding-left: 2em; + padding-top: 1em; + min-height: 50px; + + .b-table { + padding: 2em 0em; + + .table-wrapper { + -webkit-box-shadow: $boxShadowLight; + box-shadow: $boxShadowLight; + } + } + } + } + + div.column > h2.subtitle { padding-top: 1px; } +</style> +<style lang="scss"> + @import '~/assets/styles/_colors.scss'; + + .b-table { + .table-wrapper { + -webkit-box-shadow: $boxShadowLight; + box-shadow: $boxShadowLight; + } + } +</style> + + +<template> + <section class="hero is-fullheight"> + <div class="hero-body"> + <div class="container"> + <div class="columns"> + <div class="column is-narrow"> + <Sidebar /> + </div> + <div class="column"> + <h2 class="subtitle">Manage your users</h2> + <hr> + + <div class="view-container"> + <b-table + :data="users || []" + :mobile-cards="true"> + <template slot-scope="props"> + <b-table-column field="id" + label="Id" + centered> + {{ props.row.id }} + </b-table-column> + + <b-table-column field="username" + label="Username" + centered> + {{ props.row.username }} + </b-table-column> + + <b-table-column field="enabled" + label="Enabled" + centered> + <b-switch v-model="props.row.enabled" + @input="changeEnabledStatus(props.row)" /> + </b-table-column> + + <b-table-column field="isAdmin" + label="Admin" + centered> + <b-switch v-model="props.row.isAdmin" + @input="changeIsAdmin(props.row)" /> + </b-table-column> + </template> + <template slot="empty"> + <div class="has-text-centered"> + <i class="icon-misc-mood-sad" /> + </div> + <div class="has-text-centered"> + Nothing here + </div> + </template> + <template slot="footer"> + <div class="has-text-right"> + {{ users.length }} users + </div> + </template> + </b-table> + </div> + </div> + </div> + </div> + </div> + </section> +</template> + +<script> +import Sidebar from '../../components/sidebar/Sidebar.vue'; + +export default { + components: { + Sidebar + }, + data() { + return { + users: [] + }; + }, + computed: { + config() { + return this.$store.state.config; + } + }, + metaInfo() { + return { title: 'Uploads' }; + }, + mounted() { + this.getUsers(); + this.$ga.page({ + page: '/dashboard/users', + title: 'Users', + location: window.location.href + }); + }, + methods: { + async getUsers() { + try { + const response = await this.axios.get(`${this.config.baseURL}/admin/users`); + this.users = response.data.users; + console.log(this.users); + } catch (error) { + console.error(error); + } + }, + async changeEnabledStatus(row) { + try { + const response = await this.axios.post(`${this.config.baseURL}/admin/users/${row.enabled ? 'enable' : 'disable'}`, { + id: row.id + }); + this.$toast.open(response.data.message); + } catch (error) { + console.error(error); + } + }, + async changeIsAdmin(row) { + try { + const response = await this.axios.post(`${this.config.baseURL}/admin/users/${row.isAdmin ? 'promote' : 'demote'}`, { + id: row.id + }); + this.$toast.open(response.data.message); + } catch (error) { + console.error(error); + } + } + } +}; +</script> |