Initial commit, basic pages and sessions.
This commit is contained in:
177
pages/account/create.page.vue
Normal file
177
pages/account/create.page.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
<h2 class="heading">Create new account</h2>
|
||||
|
||||
<form
|
||||
class="form create"
|
||||
@submit.prevent="signup"
|
||||
>
|
||||
<div
|
||||
v-if="errorMsg"
|
||||
class="form-section form-error"
|
||||
>{{ errorMsg }}</div>
|
||||
|
||||
<div class="form-section">
|
||||
<div class="form-row">
|
||||
<input
|
||||
v-model="username"
|
||||
placeholder="Username"
|
||||
maxlength="32"
|
||||
class="input"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<input
|
||||
v-model="email"
|
||||
type="email"
|
||||
placeholder="E-mail"
|
||||
maxlength="500"
|
||||
class="input"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<input
|
||||
v-model="password"
|
||||
type="password"
|
||||
minlength="8"
|
||||
maxlength="500"
|
||||
placeholder="Password"
|
||||
class="input"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="config.captchaEnabled"
|
||||
class="form-row captcha"
|
||||
>
|
||||
<VueHcaptcha
|
||||
:sitekey="config.captchaKey"
|
||||
@verify="(token) => captchaToken = token"
|
||||
@expired="() => captchaToken = null"
|
||||
@error="() => captchaToken = null"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-section">
|
||||
<label class="check-container noselect">
|
||||
<span>
|
||||
<span class="description">I have read and accept the <a
|
||||
href="/help/user-agreement"
|
||||
target="_blank"
|
||||
class="link"
|
||||
>User Agreement</a></span>
|
||||
</span>
|
||||
|
||||
<Checkbox
|
||||
:checked="agreeTos"
|
||||
@change="(checked) => agreeTos = checked"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-row form-actions">
|
||||
<button
|
||||
:disabled="!username || !email || !password || !agreeTos || (config.captchaEnabled && !captchaToken)"
|
||||
class="button button-submit"
|
||||
>Sign up</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import VueHcaptcha from '@hcaptcha/vue3-hcaptcha';
|
||||
|
||||
import Checkbox from '../../components/form/checkbox.vue';
|
||||
|
||||
import navigate from '../../assets/js/navigate';
|
||||
import { post } from '../../assets/js/api';
|
||||
|
||||
const config = CONFIG;
|
||||
|
||||
const username = ref('');
|
||||
const email = ref('');
|
||||
const password = ref('');
|
||||
|
||||
const agreeTos = ref(false);
|
||||
const captchaToken = ref(null);
|
||||
|
||||
const errorMsg = ref(null);
|
||||
|
||||
async function signup() {
|
||||
try {
|
||||
await post('/api/users', {
|
||||
username: username.value,
|
||||
email: email.value,
|
||||
password: password.value,
|
||||
captchaToken: captchaToken.value,
|
||||
});
|
||||
|
||||
navigate('/account/login');
|
||||
} catch (error) {
|
||||
errorMsg.value = error.message;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.create {
|
||||
background: var(--background);
|
||||
padding: 1rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
position: relative;
|
||||
|
||||
.input {
|
||||
padding-left: 1.65rem;
|
||||
}
|
||||
|
||||
.prefix {
|
||||
color: var(--shadow);
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: .25rem;
|
||||
letter-spacing: .1rem;
|
||||
padding: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.access {
|
||||
font-weight: bold;
|
||||
margin-bottom: .75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.access-description {
|
||||
margin: .25rem 0 0 1.25rem;
|
||||
color: var(--shadow);
|
||||
font-size: .9rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.nsfw {
|
||||
margin-right: .5rem;
|
||||
font-weight: bold;
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
.captcha {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
142
pages/account/login.page.vue
Normal file
142
pages/account/login.page.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
<h2 class="heading">Log in</h2>
|
||||
|
||||
<form
|
||||
class="form create"
|
||||
@submit.prevent="signup"
|
||||
>
|
||||
<div
|
||||
v-if="errorMsg"
|
||||
class="form-section form-error"
|
||||
>{{ errorMsg }}</div>
|
||||
|
||||
<div class="form-section">
|
||||
<div class="form-row">
|
||||
<input
|
||||
v-model="username"
|
||||
placeholder="Username or e-mail"
|
||||
maxlength="500"
|
||||
class="input"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<input
|
||||
v-model="password"
|
||||
type="password"
|
||||
minlength="8"
|
||||
maxlength="500"
|
||||
placeholder="Password"
|
||||
class="input"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div
|
||||
v-if="$config.public.captchaEnabled"
|
||||
class="form-row captcha"
|
||||
>
|
||||
<VueHcaptcha
|
||||
:sitekey="$config.public.captchaKey"
|
||||
@verify="(token) => captchaToken = token"
|
||||
@expired="() => captchaToken = null"
|
||||
@error="() => captchaToken = null"
|
||||
/>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="form-row form-actions">
|
||||
<button
|
||||
:disabled="!username || !password"
|
||||
class="button button-submit"
|
||||
>Log in</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
// import VueHcaptcha from '@hcaptcha/vue3-hcaptcha';
|
||||
|
||||
import { post } from '../../assets/js/api';
|
||||
import navigate from '../../assets/js/navigate';
|
||||
|
||||
const username = ref('');
|
||||
const password = ref('');
|
||||
|
||||
const errorMsg = ref(null);
|
||||
|
||||
async function signup() {
|
||||
try {
|
||||
await post('/api/session', {
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
});
|
||||
|
||||
navigate('/');
|
||||
} catch (error) {
|
||||
errorMsg.value = error.statusMessage;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.create {
|
||||
background: var(--background);
|
||||
padding: 1rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
position: relative;
|
||||
|
||||
.input {
|
||||
padding-left: 1.65rem;
|
||||
}
|
||||
|
||||
.prefix {
|
||||
color: var(--shadow);
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: .25rem;
|
||||
letter-spacing: .1rem;
|
||||
padding: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.access {
|
||||
font-weight: bold;
|
||||
margin-bottom: .75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.access-description {
|
||||
margin: .25rem 0 0 1.25rem;
|
||||
color: var(--shadow);
|
||||
font-size: .9rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.nsfw {
|
||||
margin-right: .5rem;
|
||||
font-weight: bold;
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
.captcha {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user