diff options
| author | Pitu <[email protected]> | 2018-09-19 04:45:50 -0300 |
|---|---|---|
| committer | Pitu <[email protected]> | 2018-09-19 04:45:50 -0300 |
| commit | 430af8306b1ab17e59a6dabf8f65ab816d28695d (patch) | |
| tree | 975814e80919cc7b8c5d820080a30def32a371ea /src/site/pages | |
| parent | Some adjustements to public album view (diff) | |
| download | host.fuwn.me-430af8306b1ab17e59a6dabf8f65ab816d28695d.tar.xz host.fuwn.me-430af8306b1ab17e59a6dabf8f65ab816d28695d.zip | |
Switch to Nuxt.js
Diffstat (limited to 'src/site/pages')
| -rw-r--r-- | src/site/pages/a/_identifier.vue | 141 | ||||
| -rw-r--r-- | src/site/pages/dashboard/albums.vue | 371 | ||||
| -rw-r--r-- | src/site/pages/dashboard/index.vue | 76 | ||||
| -rw-r--r-- | src/site/pages/dashboard/settings.vue | 75 | ||||
| -rw-r--r-- | src/site/pages/index.vue | 95 | ||||
| -rw-r--r-- | src/site/pages/login.vue | 155 | ||||
| -rw-r--r-- | src/site/pages/register.vue | 103 |
7 files changed, 1016 insertions, 0 deletions
diff --git a/src/site/pages/a/_identifier.vue b/src/site/pages/a/_identifier.vue new file mode 100644 index 0000000..624c835 --- /dev/null +++ b/src/site/pages/a/_identifier.vue @@ -0,0 +1,141 @@ +<style lang="scss" scoped> + @import '~/assets/styles/_colors.scss'; + section { background-color: $backgroundLight1 !important; } + + section.hero div.hero-body.align-top { + align-items: baseline; + flex-grow: 0; + padding-bottom: 0; + } + + div.loading-container { + justify-content: center; + display: flex; + } +</style> +<style lang="scss"> + @import '~/assets/styles/_colors.scss'; +</style> + +<template> + <section class="hero is-fullheight"> + <template v-if="files && files.length"> + <div class="hero-body align-top"> + <div class="container"> + <h1 class="title">{{ name }}</h1> + <h2 class="subtitle">Serving {{ files ? files.length : 0 }} files</h2> + <a v-if="downloadLink" + :href="downloadLink">Download Album</a> + <hr> + </div> + </div> + <div class="hero-body"> + <div class="container"> + <Grid v-if="files && files.length" + :files="files" + :isPublic="true" + :width="200"/> + </div> + </div> + </template> + <template v-else> + <div class="hero-body"> + <div class="container loading-container"> + <Loading class="square"/> + </div> + </div> + </template> + </section> +</template> + +<script> +import Grid from '~/components/grid/Grid.vue'; +import Loading from '~/components/loading/CubeShadow.vue'; +import axios from 'axios'; +import config from '~/config.js'; + +export default { + components: { Grid, Loading }, + async asyncData({ params, error }) { + try { + const res = await axios.get(`${config.baseURL}/album/${params.identifier}`); + const downloadLink = res.data.downloadEnabled ? `${config.baseURL}/album/${params.identifier}/zip` : null; + return { + name: res.data.name, + downloadEnabled: res.data.downloadEnabled, + files: res.data.files, + downloadLink + }; + } catch (err) { + /* + return { + name: null, + downloadEnabled: false, + files: [], + downloadLink: null, + error: error.response.status + }; + */ + error({ statusCode: 404, message: 'Post not found' }); + } + }, + data() { + return {}; + }, + computed: { + config() { + return this.$store.state.config; + } + }, + metaInfo() { + if (this.files) { + return { + title: `${this.name ? this.name : ''}`, + meta: [ + { vmid: 'theme-color', name: 'theme-color', content: '#30a9ed' }, + { vmid: 'twitter:card', name: 'twitter:card', content: 'summary' }, + { vmid: 'twitter:title', name: 'twitter:title', content: `Album: ${this.name} | Files: ${this.files.length}` }, + { vmid: 'twitter:description', name: 'twitter:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' }, + { vmid: 'twitter:image', name: 'twitter:image', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` }, + { vmid: 'twitter:image:src', name: 'twitter:image:src', value: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` }, + + { vmid: 'og:url', property: 'og:url', content: `${config.URL}/a/${this.$route.params.identifier}` }, + { vmid: 'og:title', property: 'og:title', content: `Album: ${this.name} | Files: ${this.files.length}` }, + { vmid: 'og:description', property: 'og:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' }, + { vmid: 'og:image', property: 'og:image', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` }, + { vmid: 'og:image:secure_url', property: 'og:image:secure_url', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` } + ] + }; + } + return { + title: `${this.name ? this.name : ''}`, + meta: [ + { vmid: 'theme-color', name: 'theme-color', content: '#30a9ed' }, + { vmid: 'twitter:card', name: 'twitter:card', content: 'summary' }, + { vmid: 'twitter:title', name: 'twitter:title', content: 'lolisafe' }, + { vmid: 'twitter:description', name: 'twitter:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' }, + { vmid: 'og:url', property: 'og:url', content: `${config.URL}/a/${this.$route.params.identifier}` }, + { vmid: 'og:title', property: 'og:title', content: 'lolisafe' }, + { vmid: 'og:description', property: 'og:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' } + ] + }; + }, + mounted() { + /* + if (this.error) { + if (this.error === 404) { + this.$toast.open('Album not found', true, 3000); + setTimeout(() => this.$router.push('/404'), 3000); + return; + } + this.$toast.open(`Error code ${this.error}`, true, 3000); + } + */ + this.$ga.page({ + page: `/a/${this.$route.params.identifier}`, + title: `Album | ${this.name}`, + location: window.location.href + }); + } +}; +</script> diff --git a/src/site/pages/dashboard/albums.vue b/src/site/pages/dashboard/albums.vue new file mode 100644 index 0000000..f8c0e36 --- /dev/null +++ b/src/site/pages/dashboard/albums.vue @@ -0,0 +1,371 @@ +<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 albums</h2> + <hr> + + <div class="search-container"> + <b-field> + <b-input v-model="newAlbumName" + placeholder="Album name..." + type="text" + @keyup.enter.native="createAlbum" /> + <p class="control"> + <button class="button is-primary" + @click="createAlbum">Create album</button> + </p> + </b-field> + </div> + + <div class="view-container"> + <div v-for="album in albums" + :key="album.id" + class="album"> + <div class="arrow-container" + @click="album.isDetailsOpen = !album.isDetailsOpen"> + <i :class="{ active: album.isDetailsOpen }" + class="icon-arrow" /> + </div> + <div class="thumb"> + <figure class="image is-64x64 thumb"> + <img src="../../assets/images/blank.png"> + </figure> + </div> + <div class="info"> + <h4> + <router-link :to="`/dashboard/albums/${album.id}`">{{ album.name }}</router-link> + </h4> + <span>Updated <timeago :since="album.editedAt" /></span> + <span>{{ album.fileCount || 0 }} files</span> + </div> + <div class="latest is-hidden-mobile"> + <template v-if="album.fileCount > 0"> + <div v-for="file of album.files" + :key="file.id" + class="thumb"> + <figure class="image is-64x64"> + <a :href="file.url" + target="_blank"> + <img :src="file.thumbSquare"> + </a> + </figure> + </div> + <div v-if="album.fileCount > 5" + class="thumb more no-background"> + <router-link :to="`/dashboard/albums/${album.id}`">{{ album.fileCount - 5 }}+ more</router-link> + </div> + </template> + <template v-else> + <span class="no-files">Nothing to show here</span> + </template> + </div> + + <div v-if="album.isDetailsOpen" + class="details"> + + + <h2>Public links for this album:</h2> + + <b-table + :data="album.links.length ? album.links : []" + :mobile-cards="true"> + <template slot-scope="props"> + <b-table-column field="identifier" + label="Link" + centered> + <a :href="`${config.URL}/a/${props.row.identifier}`" + target="_blank"> + {{ props.row.identifier }} + </a> + </b-table-column> + + <b-table-column field="views" + label="Views" + centered> + {{ props.row.views }} + </b-table-column> + + <b-table-column field="enableDownload" + label="Allow download" + centered> + <b-switch v-model="props.row.enableDownload" + @input="linkOptionsChanged(props.row)" /> + </b-table-column> + + <b-table-column field="enabled" + label="Enabled" + centered> + <b-switch v-model="props.row.enabled" + @input="linkOptionsChanged(props.row)" /> + </b-table-column> + + <!-- + Until it's decided if we want to delete links or just hide them from the list + this setting will be hidden. Discussion about it is encouraged on Discord. + --> + <!-- + <b-table-column field="actions" + label="Actions" + centered> + <button class="button is-danger" + @click="deleteLink(props.row.identifier)">Delete link</button> + </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"> + <button :class="{ 'is-loading': album.isCreatingLink }" + class="button is-primary" + style="float: left" + @click="createLink(album)">Create new link</button> + {{ album.links.length }} / {{ config.maxLinksPerAlbum }} links created + </div> + </template> + </b-table> + + </div> + </div> + </div> + </div> + </div> + </div> + </div> + </section> +</template> + +<script> +import Sidebar from '../../components/sidebar/Sidebar.vue'; + +export default { + components: { + Sidebar + }, + data() { + return { + albums: [], + newAlbumName: null + }; + }, + computed: { + config() { + return this.$store.state.config; + } + }, + metaInfo() { + return { title: 'Uploads' }; + }, + mounted() { + this.getAlbums(); + this.$ga.page({ + page: '/dashboard/albums', + title: 'Albums', + location: window.location.href + }); + }, + methods: { + async linkOptionsChanged(link) { + try { + const response = await this.axios.post(`${this.config.baseURL}/album/link/edit`, + { + identifier: link.identifier, + enableDownload: link.enableDownload, + enabled: link.enabled + }); + this.$toast.open(response.data.message); + } catch (error) { + this.$onPromiseError(error); + } + }, + async createLink(album) { + album.isCreatingLink = true; + try { + const response = await this.axios.post(`${this.config.baseURL}/album/link/new`, + { albumId: album.id }); + this.$toast.open(response.data.message); + album.links.push({ + identifier: response.data.identifier, + views: 0, + enabled: true, + enableDownload: true, + expiresAt: null + }); + album.isCreatingLink = false; + } catch (error) { + this.$onPromiseError(error); + album.isCreatingLink = false; + } + }, + async createAlbum() { + if (!this.newAlbumName || this.newAlbumName === '') return; + try { + const response = await this.axios.post(`${this.config.baseURL}/album/new`, + { name: this.newAlbumName }); + this.newAlbumName = null; + this.$toast.open(response.data.message); + this.getAlbums(); + return; + } catch (error) { + this.$onPromiseError(error); + } + }, + async getAlbums() { + try { + const response = await this.axios.get(`${this.config.baseURL}/albums/mini`); + for (const album of response.data.albums) { + album.isDetailsOpen = false; + } + this.albums = response.data.albums; + console.log(this.albums); + } catch (error) { + console.error(error); + } + } + } +}; +</script> diff --git a/src/site/pages/dashboard/index.vue b/src/site/pages/dashboard/index.vue new file mode 100644 index 0000000..0d89aaf --- /dev/null +++ b/src/site/pages/dashboard/index.vue @@ -0,0 +1,76 @@ +<style lang="scss" scoped> + @import '~/assets/styles/_colors.scss'; + section { background-color: $backgroundLight1 !important; } + section.hero div.hero-body { + align-items: baseline; + } +</style> +<style lang="scss"> + @import '~/assets/styles/_colors.scss'; +</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"> + <!-- + <h1 class="title">Uploads</h1> + <h2 class="subtitle">Keep track of all your uploads in here</h2> + <hr> + --> + <Grid v-if="files.length" + :files="files" /> + </div> + </div> + </div> + </div> + </section> +</template> + +<script> +import Sidebar from '~/components/sidebar/Sidebar.vue'; +import Grid from '~/components/grid/Grid.vue'; + +export default { + components: { + Sidebar, + Grid + }, + data() { + return { files: [] }; + }, + computed: { + config() { + return this.$store.state.config; + } + }, + metaInfo() { + return { title: 'Uploads' }; + }, + mounted() { + this.getFiles(); + this.$ga.page({ + page: '/dashboard', + title: 'Dashboard', + location: window.location.href + }); + }, + methods: { + async getFiles() { + try { + const response = await this.axios.get(`${this.config.baseURL}/files`); + this.files = response.data.files; + console.log(this.files); + } catch (error) { + console.error(error); + } + } + } +}; +</script> diff --git a/src/site/pages/dashboard/settings.vue b/src/site/pages/dashboard/settings.vue new file mode 100644 index 0000000..d6c6189 --- /dev/null +++ b/src/site/pages/dashboard/settings.vue @@ -0,0 +1,75 @@ +<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; + } +</style> +<style lang="scss"> + @import '~/assets/styles/_colors.scss'; +</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"> + <!-- + <h1 class="title">Uploads</h1> + <h2 class="subtitle">Keep track of all your uploads in here</h2> + <hr> + --> + + <div class="field"> + <b-switch v-model="options.removeExif" + true-value="Remove exif data when uploading files" + false-value="Don't remove exif data when uploading files" + type="is-success"> + {{ options.removeExif }} + </b-switch> + </div> + </div> + </div> + </div> + </div> + </section> +</template> + +<script> +import Sidebar from '~/components/sidebar/Sidebar.vue'; + +export default { + components: { + Sidebar + }, + data() { + return { + options: { + removeExif: false + } + }; + }, + metaInfo() { + return { title: 'Settings' }; + }, + mounted() { + this.$ga.page({ + page: '/dashboard/settings', + title: 'Settings', + location: window.location.href + }); + }, + methods: { + + } +}; +</script> diff --git a/src/site/pages/index.vue b/src/site/pages/index.vue new file mode 100644 index 0000000..7342b97 --- /dev/null +++ b/src/site/pages/index.vue @@ -0,0 +1,95 @@ +<style lang="scss" scoped> + @import "~/assets/styles/_colors.scss"; + div.home { + color: $textColor; + .columns { + .column { + &.centered { + display: flex; + align-items: center; + } + } + } + + h4 { + color: $textColorHighlight; + margin-bottom: 1em; + } + + p { + font-size: 1.25em; + font-weight: 600; + line-height: 1.5; + + strong { + color: $textColorHighlight; + } + } + } +</style> + +<template> + <div class="home"> + <section class="hero is-fullheight has-text-centered"> + <Navbar :isWhite="true" /> + <div class="hero-body"> + <div class="container"> + <div class="columns"> + <div class="column is-3 is-offset-2"> + <div class="logo"> + <Logo/> + </div> + </div> + <div class="column is-5 centered"> + <div class="content-wrapper"> + <h4>Blazing fast file uploader. For real.</h4> + <p> + A <strong>modern</strong> and <strong>self-hosted</strong> file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind. + </p> + </div> + </div> + </div> + <div class="spacer mt7" /> + <Uploader /> + </div> + </div> + <div class="hero-foot"> + <div class="container"> + <Links /> + </div> + </div> + </section> + </div> +</template> + +<script> +import Navbar from '~/components/navbar/Navbar.vue'; +import Logo from '~/components/logo/Logo.vue'; +import Uploader from '~/components/uploader/Uploader.vue'; +import Links from '~/components/home/links/Links.vue'; + +export default { + name: 'Home', + components: { + Navbar, + Logo, + Uploader, + Links + }, + data() { + return { albums: [] }; + }, + computed: { + loggedIn() { + return this.$store.state.loggedIn; + } + }, + mounted() { + this.$ga.page({ + page: '/', + title: 'Home', + location: window.location.href + }); + } +}; +</script> diff --git a/src/site/pages/login.vue b/src/site/pages/login.vue new file mode 100644 index 0000000..e4a1c9d --- /dev/null +++ b/src/site/pages/login.vue @@ -0,0 +1,155 @@ +<style lang="scss" scoped> + @import '~/assets/styles/_colors.scss'; +</style> + +<template> + <section id="login" + class="hero is-fullheight"> + <Navbar/> + <div class="hero-body"> + <div class="container"> + <h1 class="title"> + Dashboard Access + </h1> + <h2 class="subtitle"> + Login or register + </h2> + <div class="columns"> + <div class="column is-4"> + <b-field> + <b-input v-model="username" + type="text" + placeholder="Username" + @keyup.enter.native="login" /> + </b-field> + <b-field> + <b-input v-model="password" + type="password" + placeholder="Password" + password-reveal + @keyup.enter.native="login" /> + </b-field> + + <p class="control has-addons is-pulled-right"> + <router-link to="/register" + class="is-text">Don't have an account?</router-link> + <a id="loginBtn" + class="button" + @click="login">Log in</a> + </p> + </div> + </div> + </div> + </div> + + <!-- + <b-modal :active.sync="isMfaModalActive" + :canCancel="true" + has-modal-card> + <div class="card mfa"> + <div class="card-content"> + <div class="content"> + <p>Enter your Two-Factor code to proceed.</p> + <b-field> + <b-input v-model="mfaCode" + placeholder="Your MFA Code" + type="text" + @keyup.enter.native="mfa"/> + <p class="control"> + <button :class="{ 'is-loading': isLoading }" + class="button is-primary" + @click="mfa">Submit</button> + </p> + </b-field> + </div> + </div> + </div> + </b-modal> + --> + </section> +</template> + +<script> +import Navbar from '~/components/navbar/Navbar.vue'; + +export default { + name: 'Login', + components: { Navbar }, + data() { + return { + username: null, + password: null, + mfaCode: null, + isMfaModalActive: false, + isLoading: false + }; + }, + computed: { + config() { + return this.$store.state.config; + } + }, + metaInfo() { + return { title: 'Login' }; + }, + mounted() { + this.$ga.page({ + page: '/login', + title: 'Login', + location: window.location.href + }); + }, + methods: { + login() { + if (this.isLoading) return; + if (!this.username || !this.password) { + this.$showToast('Please fill both fields before attempting to log in.', true); + return; + } + this.isLoading = true; + this.axios.post(`${this.config.baseURL}/auth/login`, { + username: this.username, + password: this.password + }).then(res => { + this.$store.commit('token', res.data.token); + this.$store.commit('user', res.data.user); + /* + if (res.data.mfa) { + this.isMfaModalActive = true; + this.isLoading = false; + } else { + this.getUserData(); + } + */ + this.redirect(); + }).catch(err => { + this.isLoading = false; + this.$onPromiseError(err); + }); + }, + /* + mfa() { + if (!this.mfaCode) return; + if (this.isLoading) return; + this.isLoading = true; + this.axios.post(`${this.$BASE_URL}/login/mfa`, { token: this.mfaCode }) + .then(res => { + this.$store.commit('token', res.data.token); + this.redirect(); + }) + .catch(err => { + this.isLoading = false; + this.$onPromiseError(err); + }); + },*/ + redirect() { + this.$store.commit('loggedIn', true); + if (typeof this.$route.query.redirect !== 'undefined') { + this.$router.push(this.$route.query.redirect); + return; + } + this.$router.push('/dashboard'); + } + } +}; +</script> diff --git a/src/site/pages/register.vue b/src/site/pages/register.vue new file mode 100644 index 0000000..c331f36 --- /dev/null +++ b/src/site/pages/register.vue @@ -0,0 +1,103 @@ +<style lang="scss" scoped> + @import '~/assets/styles/_colors.scss'; +</style> + +<template> + <section id="register" + class="hero is-fullheight"> + <Navbar/> + <div class="hero-body"> + <div class="container"> + <h1 class="title"> + Dashboard Access + </h1> + <h2 class="subtitle"> + Register for a new account + </h2> + <div class="columns"> + <div class="column is-4"> + <b-field> + <b-input v-model="username" + type="text" + placeholder="Username" /> + </b-field> + <b-field> + <b-input v-model="password" + type="password" + placeholder="Password" + password-reveal /> + </b-field> + <b-field> + <b-input v-model="rePassword" + type="password" + placeholder="Re-type Password" + password-reveal + @keyup.enter.native="register" /> + </b-field> + + <p class="control has-addons is-pulled-right"> + <router-link to="/login" + class="is-text">Already have an account?</router-link> + <a :class="{ 'is-loading': isLoading }" + class="button is-themed" + @click="register">Register</a> + </p> + </div> + </div> + </div> + </div> + </section> +</template> + +<script> +import Navbar from '~/components/navbar/Navbar.vue'; + +export default { + name: 'Register', + components: { Navbar }, + data() { + return { + username: null, + password: null, + rePassword: null, + isLoading: false + }; + }, + computed: { + config() { + return this.$store.state.config; + } + }, + metaInfo() { + return { title: 'Register' }; + }, + mounted() { + this.$ga.page({ + page: '/register', + title: 'Register', + location: window.location.href + }); + }, + methods: { + register() { + if (this.isLoading) return; + if (this.password !== this.rePassword) { + this.$showToast('Passwords don\'t match', true); + return; + } + this.isLoading = true; + this.axios.post(`${this.config.baseURL}/auth/register`, { + username: this.username, + password: this.password + }).then(response => { + this.$showToast(response.data.message); + this.isLoading = false; + return this.$router.push('/login'); + }).catch(err => { + this.isLoading = false; + this.$onPromiseError(err); + }); + } + } +}; +</script> |