Skip to content

Commit 9238e0b

Browse files
committed
feat(frontend): add register page
1 parent 0f8e928 commit 9238e0b

File tree

4 files changed

+122
-4
lines changed

4 files changed

+122
-4
lines changed

components/Nav.vue

+7-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
class="relative md:pb-0 md:pt-0 md:flex md:flex-row"
3131
>
3232
<ul
33-
class="absolute -right-1 md:-top-6 text-grayscale-950 rounded-md bg-grayscale-400 md:bg-inherit pl-8 pr-4 mt-4 md:pl-0 md:pr-0 md:m-0 md:flex md:flex-row text-right"
33+
class="absolute -right-1 md:-top-6 text-grayscale-950 rounded-md bg-grayscale-400 md:bg-inherit pl-12 pr-6 mt-4 md:pl-0 md:pr-0 md:m-0 md:flex md:flex-row text-right"
3434
>
3535
<li v-if="user.id">
3636
<div class="flex flex-row md:p-4 py-2 gap-1">
@@ -40,7 +40,12 @@
4040
>
4141
</div>
4242
</li>
43-
<li v-else>
43+
<li v-if="!user.id">
44+
<a href="/register" class="md:p-4 py-2 block"
45+
>Register</a
46+
>
47+
</li>
48+
<li v-if="!user.id">
4449
<a href="/login" class="md:p-4 py-2 block">Login</a>
4550
</li>
4651
<li>

pages/login.vue

+1-2
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,8 @@
8585
import { ref } from "vue";
8686
8787
import { useAuthStore } from "~/utils/authStore";
88-
import { pinia } from "~/utils/pinia";
8988
90-
const userStore = useAuthStore(pinia);
89+
const userStore = useAuthStore();
9190
9291
// Check if the user has selected username or email
9392
const formIsEmail = ref(false);

pages/register.vue

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<template>
2+
<Layout
3+
title="Register | Readconquista"
4+
description="Register an account in Readconquista!"
5+
>
6+
<div
7+
class="flex h-full items-center justify-center flex-col gap-4 md:gap-8"
8+
>
9+
<h2 class="text-3xl md:text-5xl font-black">Register</h2>
10+
<form class="flex flex-col gap-4" @submit.prevent="register()">
11+
<div>
12+
<input
13+
v-model="email"
14+
type="email"
15+
class="rounded-lg resize-none w-full block bg-grayscale-400 px-4 py-2 placeholder:justify-center"
16+
placeholder="Email address"
17+
/>
18+
</div>
19+
<div>
20+
<input
21+
v-model="username"
22+
class="rounded-lg resize-none w-full block bg-grayscale-400 px-4 py-2 placeholder:justify-center"
23+
placeholder="Username"
24+
/>
25+
</div>
26+
<div>
27+
<input
28+
v-model="password"
29+
type="password"
30+
class="rounded-lg resize-none w-full block bg-grayscale-400 px-4 py-2 placeholder:justify-center"
31+
placeholder="Password"
32+
/>
33+
</div>
34+
<div class="mt-4">
35+
<button
36+
type="submit"
37+
class="rounded-xl w-full p-2"
38+
:disabled="!email || !password || !username"
39+
:class="
40+
email && username && password
41+
? 'bg-grayscale-900 text-grayscale-400'
42+
: 'bg-grayscale-400 text-grayscale-900'
43+
"
44+
>
45+
Register
46+
</button>
47+
</div>
48+
</form>
49+
<div v-if="error" class="mt-2 flex flex-row justify-center">
50+
<span class="text-red-500 font-bold"
51+
>{{ error.statusCode }} - {{ error.statusMessage }}</span
52+
>
53+
</div>
54+
</div>
55+
</Layout>
56+
</template>
57+
58+
<script setup lang="ts">
59+
import { ref } from "vue";
60+
61+
import { useAuthStore } from "~/utils/authStore";
62+
63+
const userStore = useAuthStore();
64+
65+
const email = ref("");
66+
const username = ref("");
67+
const password = ref("");
68+
69+
const error = ref();
70+
71+
const router = useRouter();
72+
73+
const register = async () => {
74+
const { data, requestState } = await userStore.register(
75+
password.value,
76+
username.value,
77+
email.value,
78+
);
79+
80+
if (requestState.error) error.value = requestState.error;
81+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
82+
else if (data) await router.push("/");
83+
};
84+
</script>

utils/authStore.ts

+30
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,35 @@ export const useAuthStore = defineStore("auth", {
7474

7575
this.user = {} as UserState;
7676
},
77+
78+
async register(
79+
password: string,
80+
username: string,
81+
email: string,
82+
): Promise<{ data: UserState; requestState: RequestState }> {
83+
const requestState: RequestState = {
84+
loading: true,
85+
error: null,
86+
};
87+
88+
try {
89+
const data: UserState = await $fetch("/api/auth/register", {
90+
method: "post",
91+
headers: { "Content-Type": "application/json" },
92+
body: {
93+
password,
94+
username,
95+
email,
96+
},
97+
});
98+
requestState.loading = false;
99+
this.user = data;
100+
return { data, requestState };
101+
} catch (error) {
102+
requestState.loading = false;
103+
requestState.error = error as Error;
104+
return { data: {} as UserState, requestState };
105+
}
106+
},
77107
},
78108
});

0 commit comments

Comments
 (0)