merge frontend-auth-views
This commit is contained in:
commit
f4f2d22440
4 changed files with 245 additions and 8 deletions
|
|
@ -1,7 +1,27 @@
|
|||
<script setup lang="ts">
|
||||
// CheckEmailPage - filled in by a later branch.
|
||||
// User landing after signup. Tells them to check email.
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section><h1>CheckEmailPage</h1></section>
|
||||
<section class="check-email">
|
||||
<h1>Check your email</h1>
|
||||
<p>
|
||||
We sent a confirmation link to your email. Open it to set your password and finish signing up.
|
||||
</p>
|
||||
<p class="muted">
|
||||
<router-link :to="{ name: 'login' }">Back to log in</router-link>
|
||||
</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.check-email {
|
||||
max-width: 480px;
|
||||
margin: 32px auto;
|
||||
}
|
||||
|
||||
.muted {
|
||||
margin-top: 24px;
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,74 @@
|
|||
<script setup lang="ts">
|
||||
// ConfirmEmailPage - filled in by a later branch.
|
||||
import { ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
|
||||
const auth = useAuthStore();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const password = ref("");
|
||||
const submitting = ref(false);
|
||||
|
||||
async function handleSubmit() {
|
||||
const token = String(route.query.token ?? "");
|
||||
if (!token || submitting.value) return;
|
||||
submitting.value = true;
|
||||
const ok = await auth.confirmEmail(token, password.value);
|
||||
submitting.value = false;
|
||||
if (ok) router.push({ name: "login" });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section><h1>ConfirmEmailPage</h1></section>
|
||||
<section class="confirm">
|
||||
<h1>Set your password</h1>
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<label>
|
||||
<span>Password</span>
|
||||
<input
|
||||
v-model="password"
|
||||
type="password"
|
||||
required
|
||||
minlength="8"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<small>At least 8 characters.</small>
|
||||
</label>
|
||||
<p v-if="auth.error" class="error">{{ auth.error }}</p>
|
||||
<button type="submit" :disabled="submitting">Confirm</button>
|
||||
</form>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.confirm {
|
||||
max-width: 360px;
|
||||
margin: 32px auto;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
label small {
|
||||
color: var(--color-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #b00020;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,75 @@
|
|||
<script setup lang="ts">
|
||||
// LoginPage - filled in by a later branch.
|
||||
import { ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
|
||||
const auth = useAuthStore();
|
||||
const router = useRouter();
|
||||
|
||||
const email = ref("");
|
||||
const password = ref("");
|
||||
const submitting = ref(false);
|
||||
|
||||
async function handleSubmit() {
|
||||
if (submitting.value) return;
|
||||
submitting.value = true;
|
||||
const ok = await auth.login(email.value.trim(), password.value);
|
||||
submitting.value = false;
|
||||
if (ok) router.push({ name: "home" });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section><h1>LoginPage</h1></section>
|
||||
<section class="login">
|
||||
<h1>Log in</h1>
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<label>
|
||||
<span>Email</span>
|
||||
<input v-model="email" type="email" required autocomplete="email" />
|
||||
</label>
|
||||
<label>
|
||||
<span>Password</span>
|
||||
<input v-model="password" type="password" required autocomplete="current-password" />
|
||||
</label>
|
||||
<p v-if="auth.error" class="error">{{ auth.error }}</p>
|
||||
<button type="submit" :disabled="submitting">Log in</button>
|
||||
</form>
|
||||
<p class="muted">
|
||||
No account?
|
||||
<router-link :to="{ name: 'signup' }">Sign up</router-link>
|
||||
</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.login {
|
||||
max-width: 360px;
|
||||
margin: 32px auto;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #b00020;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.muted {
|
||||
margin-top: 16px;
|
||||
color: var(--color-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,89 @@
|
|||
<script setup lang="ts">
|
||||
// SignupPage - filled in by a later branch.
|
||||
import { ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
|
||||
const auth = useAuthStore();
|
||||
const router = useRouter();
|
||||
|
||||
const email = ref("");
|
||||
const displayName = ref("");
|
||||
const submitting = ref(false);
|
||||
|
||||
async function handleSubmit() {
|
||||
if (submitting.value) return;
|
||||
submitting.value = true;
|
||||
const ok = await auth.signup(email.value.trim(), displayName.value.trim());
|
||||
submitting.value = false;
|
||||
if (ok) router.push({ name: "check-email" });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section><h1>SignupPage</h1></section>
|
||||
<section class="signup">
|
||||
<h1>Sign up</h1>
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<label>
|
||||
<span>Email</span>
|
||||
<input v-model="email" type="email" required autocomplete="email" />
|
||||
</label>
|
||||
<label>
|
||||
<span>Display name</span>
|
||||
<input
|
||||
v-model="displayName"
|
||||
type="text"
|
||||
required
|
||||
minlength="3"
|
||||
maxlength="30"
|
||||
pattern="[a-z0-9_-]+"
|
||||
autocomplete="username"
|
||||
/>
|
||||
<small>3-30 chars, lowercase letters, digits, _ or -.</small>
|
||||
</label>
|
||||
<p v-if="auth.error" class="error">{{ auth.error }}</p>
|
||||
<button type="submit" :disabled="submitting">Continue</button>
|
||||
</form>
|
||||
<p class="muted">
|
||||
Already have an account?
|
||||
<router-link :to="{ name: 'login' }">Log in</router-link>
|
||||
</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.signup {
|
||||
max-width: 360px;
|
||||
margin: 32px auto;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
label small {
|
||||
color: var(--color-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #b00020;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.muted {
|
||||
margin-top: 16px;
|
||||
color: var(--color-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue