<template> <div class="login-container"> <div v-if="user"> You are already logged in as {{ user.username }}. <ul> <li> <a :href="`/user/${user.username}`" class="link" >View my profile</a> </li> <li> <a :href="`/updates`" class="link" >Check out latest porn updates</a> </li> <li> <a :href="`/actors`" class="link" >Browse the hottest porn stars</a> </li> </ul> </div> <form v-else autocomplete="off" class="login-panel" @submit.prevent="signup" > <div v-if="errorMsg" class="error" >{{ errorMsg }}</div> <input ref="userInput" v-model="username" placeholder="Username" class="input" required > <input v-model="email" type="email" placeholder="E-mail" class="input" required > <div class="password-container"> <input v-model="password" :type="showPassword ? 'input' : 'password'" autocomplete="new-password" minlength="3" placeholder="Password" class="password input" required > <div class="password-show" @click="showPassword = !showPassword" > <Icon v-show="!showPassword" icon="eye" class="password-show" /> <Icon v-show="showPassword" icon="eye-blocked" class="password-show" /> </div> </div> <div class="password-container"> <input v-model="passwordConfirm" :type="showPassword ? 'input' : 'password'" autocomplete="new-password" minlength="3" placeholder="Confirm password" class="password input" required > <div class="password-show" @click="showPassword = !showPassword" > <Icon v-show="!showPassword" icon="eye" class="password-show" /> <Icon v-show="showPassword" icon="eye-blocked" class="password-show" /> </div> </div> <button class="button button-submit">Sign up</button> <a href="/login" class="link" >I already have an account</a> </form> </div> </template> <script setup> import { ref, onMounted, inject } from 'vue'; import { post } from '#/src/api.js'; import navigate from '#/src/navigate.js'; const pageContext = inject('pageContext'); const user = pageContext.user; const username = ref(''); const email = ref(''); const password = ref(''); const passwordConfirm = ref(''); const errorMsg = ref(null); const userInput = ref(null); const showPassword = ref(false); async function signup() { errorMsg.value = null; if (password.value !== passwordConfirm.value) { errorMsg.value = 'Passwords do not match'; return; } try { const newUser = await post('/users', { username: username.value, email: email.value, password: password.value, redirect: pageContext.urlParsed.search.r, }); navigate(`/user/${newUser.username}`, null, { redirect: true }); } catch (error) { errorMsg.value = error.message; } } onMounted(() => { userInput.value.focus(); }); </script> <style scoped> .login-container { display: flex; flex-grow: 1; justify-content: center; align-items: center; background: var(--background-base-10); } .login-panel { width: 20rem; max-width: 100%; display: flex; flex-direction: column; gap: .5rem; padding: 1rem; margin: 1rem; border-radius: .5rem; box-shadow: 0 0 3px var(--shadow-weak-30); background: var(--background-base); font-size: 1rem; .button { justify-content: center; } .link { margin-top: .5rem; text-align: center; } } .password-container { display: flex; position: relative; } .password { flex-grow: 1; } .password-show { height: 100%; display: flex; align-items: center; position: absolute; right: 0; padding: 0 1rem 0 .5rem; .icon { fill: var(--shadow); } &:hover { cursor: pointer; .icon { fill: var(--primary); } } } .error { background: var(--error); color: var(--text-light); padding: .75rem 1rem; border-radius: .25rem; margin-bottom: .5rem; font-size: .9rem; font-weight: bold; text-align: center; } </style>