summaryrefslogtreecommitdiff
path: root/frontend/pages
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2025-04-02 19:31:12 +0200
committerSanto Cariotti <santo@dcariotti.me>2025-04-02 19:37:12 +0200
commita9b84f3f3b1d92335188d43048587e32e0921079 (patch)
treea4313f7660a99745d7d5da4d92dc9509d0dbe35e /frontend/pages
parent2e92ccd66eb5c31b8fbbcd205d7b4a882450e9d0 (diff)
Init login and frontend
Diffstat (limited to 'frontend/pages')
-rw-r--r--frontend/pages/index.vue20
-rw-r--r--frontend/pages/login.vue124
2 files changed, 144 insertions, 0 deletions
diff --git a/frontend/pages/index.vue b/frontend/pages/index.vue
new file mode 100644
index 0000000..d097617
--- /dev/null
+++ b/frontend/pages/index.vue
@@ -0,0 +1,20 @@
+<script setup lang="ts">
+const props = defineProps<{
+ title: string;
+}>();
+
+const toast = useToast();
+
+function showToast() {
+ toast.add(props);
+}
+</script>
+
+<template>
+ <UButton
+ label="Show toast"
+ color="neutral"
+ variant="outline"
+ @click="showToast"
+ />
+</template>
diff --git a/frontend/pages/login.vue b/frontend/pages/login.vue
new file mode 100644
index 0000000..0be0372
--- /dev/null
+++ b/frontend/pages/login.vue
@@ -0,0 +1,124 @@
+<template>
+ <div
+ class="flex min-h-screen items-center justify-center px-4 py-12 sm:px-6 lg:px-8"
+ >
+ <UCard class="w-full max-w-md bg-gray-900">
+ <div class="flex flex-col items-center">
+ <h1
+ class="text-center text-2xl font-bold tracking-tight text-white"
+ >
+ Sign in to your account
+ </h1>
+ <p class="mt-2 text-center text-sm text-gray-200">
+ Or
+ <NuxtLink
+ to="/register"
+ class="font-medium text-primary hover:text-primary-dark underline"
+ >
+ create a new account
+ </NuxtLink>
+ </p>
+ </div>
+
+ <div class="mt-8">
+ <form
+ @submit.prevent="handleSubmit"
+ class="space-y-6"
+ method="POST"
+ >
+ <UFormField label="Username" name="username">
+ <UInput
+ v-model="username"
+ name="username"
+ autocomplete="username"
+ required
+ placeholder="mario.rossi"
+ class="w-full"
+ />
+ </UFormField>
+
+ <UFormField label="Password" name="password">
+ <UInput
+ v-model="password"
+ type="password"
+ name="password"
+ autocomplete="current-password"
+ required
+ placeholder="*****"
+ class="w-full"
+ />
+ </UFormField>
+
+ <div>
+ <UButton
+ type="submit"
+ block
+ :loading="isLoading"
+ color="primary"
+ variant="solid"
+ class="cursor-pointer"
+ >
+ Sign in
+ </UButton>
+ </div>
+ </form>
+ </div>
+ </UCard>
+ </div>
+</template>
+
+<script setup>
+const username = ref("");
+const password = ref("");
+const error = ref("");
+const isLoading = ref(false);
+
+const toast = useToast();
+
+const config = useRuntimeConfig();
+
+const handleSubmit = async (event) => {
+ event.preventDefault();
+
+ try {
+ error.value = null;
+ isLoading.value = true;
+ fetch(`${config.public.apiBase}/auth/login`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ username: username.value,
+ password: password.value,
+ }),
+ }).then((response) => {
+ if (response.status != 200) {
+ toast.add({
+ title: "Login Failed",
+ description: response.body,
+ color: "error",
+ });
+ } else {
+ toast.add({
+ title: "Login Successful",
+ description: "You have been successfully logged in.",
+ color: "success",
+ });
+ }
+ });
+ } catch (err) {
+ console.error("Login failed:", err);
+ error.value =
+ err.response?.data?.message || "An error occurred during login";
+
+ toast.add({
+ title: "Login Failed",
+ description: error.value,
+ color: "error",
+ });
+ } finally {
+ isLoading.value = false;
+ }
+};
+</script>