mitlist/fe/src/pages/SignupPage.vue
2025-05-08 15:02:09 +02:00

129 lines
3.2 KiB
Vue

<template>
<q-page class="flex flex-center">
<q-card class="signup-card">
<q-card-section>
<div class="text-h6">Sign Up</div>
</q-card-section>
<q-card-section>
<q-form @submit="onSubmit" class="q-gutter-md">
<q-input
v-model="name"
label="Full Name"
:rules="[(val) => !!val || 'Name is required']"
/>
<q-input
v-model="email"
label="Email"
type="email"
:rules="[(val) => !!val || 'Email is required', isValidEmail]"
/>
<q-input
v-model="password"
label="Password"
:type="isPwd ? 'password' : 'text'"
:rules="[
(val) => !!val || 'Password is required',
(val) => val.length >= 8 || 'Password must be at least 8 characters',
]"
>
<template v-slot:append>
<q-icon
:name="isPwd ? 'visibility_off' : 'visibility'"
class="cursor-pointer"
@click="isPwd = !isPwd"
/>
</template>
</q-input>
<q-input
v-model="confirmPassword"
label="Confirm Password"
:type="isPwd ? 'password' : 'text'"
:rules="[
(val) => !!val || 'Please confirm your password',
(val) => val === password || 'Passwords do not match',
]"
/>
<div>
<q-btn
label="Sign Up"
type="submit"
color="primary"
class="full-width"
:loading="loading"
/>
</div>
<div class="text-center q-mt-sm">
<router-link to="/login" class="text-primary"
>Already have an account? Login</router-link
>
</div>
</q-form>
</q-card-section>
</q-card>
</q-page>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import { useAuthStore } from 'stores/auth';
const $q = useQuasar();
const router = useRouter();
const authStore = useAuthStore();
const name = ref('');
const email = ref('');
const password = ref('');
const confirmPassword = ref('');
const isPwd = ref(true);
const loading = ref(false);
const isValidEmail = (val: string) => {
const emailPattern =
/^(?=[a-zA-Z0-9@._%+-]{6,254}$)[a-zA-Z0-9._%+-]{1,64}@(?:[a-zA-Z0-9-]{1,63}\.){1,8}[a-zA-Z]{2,63}$/;
return emailPattern.test(val) || 'Invalid email';
};
const onSubmit = async () => {
try {
loading.value = true;
await authStore.signup({
name: name.value,
email: email.value,
password: password.value,
});
$q.notify({
color: 'positive',
message: 'Account created successfully',
position: 'top',
});
await router.push('/login');
} catch (error: unknown) {
$q.notify({
color: 'negative',
message: error instanceof Error ? error.message : 'Signup failed',
position: 'top',
});
} finally {
loading.value = false;
}
};
</script>
<style scoped>
.signup-card {
width: 100%;
max-width: 400px;
padding: 20px;
}
</style>