refactor: signup component

This commit is contained in:
2025-12-12 00:51:36 +07:00
parent 14618192ca
commit 4a384de968
3 changed files with 129 additions and 84 deletions

View File

@@ -0,0 +1,82 @@
<script lang='ts' setup>
import { toastController } from "@ionic/vue";
import { logoGoogle, phonePortraitOutline } from "ionicons/icons";
import { authClient } from "@/auth";
const emit = defineEmits<{
(e: "success", value: string): void;
}>();
const model = defineModel({ type: String, required: true });
function onEmailBlur() {
const isEmailValid = emailPattern.test(model.value);
if (!isEmailValid) {
toastController
.create({
message: "Please enter a valid email address.",
duration: 1500,
position: "bottom",
})
.then((toast) => {
toast.present();
});
}
}
async function submitSendVerification() {
const isEmailValid = emailPattern.test(model.value);
if (!isEmailValid) {
const toast = await toastController.create({
message: "Please enter a valid email address.",
duration: 1500,
position: "bottom",
});
await toast.present();
return;
}
const { data, error } = await authClient.emailOtp.sendVerificationOtp({
email: model.value, // required
type: "sign-in", // required
});
if (data?.success) {
emit("success", model.value);
}
else {
const toast = await toastController.create({
message: error?.message || "Failed to send verification code.",
duration: 1500,
position: "bottom",
});
await toast.present();
}
}
</script>
<template>
<h1><strong>What's your email?</strong></h1>
<p>You'll use this email to login and access everything we have to offer.</p>
<div>
<ui-input v-model="model" type="email" placeholder="Enter your email address" @ion-blur="onEmailBlur" />
<ion-button expand="block" class="ion-margin-top" shape="round" @click="submitSendVerification">
Sign up
</ion-button>
<ui-divider text="Or continue with" />
<ion-button color="medium" expand="block" class="ion-margin-top" shape="round">
<IonIcon slot="start" aria-hidden="true" :icon="phonePortraitOutline" />
Phone Number
</ion-button>
<ion-button color="medium" expand="block" class="ion-margin-top" shape="round">
<IonIcon slot="start" aria-hidden="true" :icon="logoGoogle" />
Google
</ion-button>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,43 @@
<script lang='ts' setup>
import { toastController } from "@ionic/vue";
const props = defineProps<{
email: string;
}>();
const emit = defineEmits<{
(e: "success", value: string): void;
}>();
const model = defineModel({ type: String, required: true });
async function submitSignup() {
if (model.value.length !== 6) {
const toast = await toastController.create({
message: "Please enter a valid 6-digit verification code.",
duration: 1500,
position: "bottom",
});
await toast.present();
return;
}
emit("success", model.value);
}
</script>
<template>
<h1><strong>Verify your email</strong></h1>
<p>We have sent a verification code to {{ email }}. Please enter the code below to verify your email address.</p>
<div>
<ion-item>
<ion-input-otp v-model="model" :length="6" />
</ion-item>
<ion-button expand="block" class="ion-margin-top" shape="round" @click="submitSignup">
Submit
</ion-button>
</div>
</template>
<style scoped></style>

View File

@@ -1,10 +1,10 @@
<script lang='ts' setup> <script lang='ts' setup>
import type { AuthUserSignup } from "../type"; import type { AuthUserSignup } from "../type";
import { toastController } from "@ionic/vue"; import { toastController } from "@ionic/vue";
import { logoGoogle, phonePortraitOutline } from "ionicons/icons";
import MaterialIconThemeGoogle from "~icons/material-icon-theme/google"; import MaterialIconThemeGoogle from "~icons/material-icon-theme/google";
import { emailPattern } from "@/utils";
import { authClient } from ".."; import { authClient } from "..";
import Step1 from "./email/step1.vue";
import Step2 from "./email/step2.vue";
const form = ref<AuthUserSignup>({ const form = ref<AuthUserSignup>({
email: "", email: "",
@@ -14,51 +14,6 @@ const form = ref<AuthUserSignup>({
}); });
const step = ref(1); const step = ref(1);
function onEmailBlur() {
const isEmailValid = emailPattern.test(form.value.email);
if (!isEmailValid) {
toastController
.create({
message: "Please enter a valid email address.",
duration: 1500,
position: "bottom",
})
.then((toast) => {
toast.present();
});
}
}
async function submitSendVerification() {
const isEmailValid = emailPattern.test(form.value.email);
if (!isEmailValid) {
const toast = await toastController.create({
message: "Please enter a valid email address.",
duration: 1500,
position: "bottom",
});
await toast.present();
return;
}
const { data, error } = await authClient.emailOtp.sendVerificationOtp({
email: form.value.email, // required
type: "sign-in", // required
});
if (data?.success) {
step.value = 2;
}
else {
const toast = await toastController.create({
message: error?.message || "Failed to send verification code.",
duration: 1500,
position: "bottom",
});
await toast.present();
}
}
function reset() { function reset() {
step.value = 1; step.value = 1;
form.value.email = ""; form.value.email = "";
@@ -96,43 +51,8 @@ async function submitSignup() {
</script> </script>
<template> <template>
<div v-if="step === 1"> <Step1 v-if="step === 1" v-model="form.email" @success="step = 2" />
<h1><strong>What's your email?</strong></h1> <Step2 v-else-if="step === 2" v-model="form.verificationCode" :email="form.email" @success="submitSignup" />
<p>You'll use this email to login and access everything we have to offer.</p>
<div>
<ui-input v-model="form.email" type="email" placeholder="Enter your email address" @ion-blur="onEmailBlur" />
<ion-button expand="block" class="ion-margin-top" shape="round" @click="submitSendVerification">
Sign up
</ion-button>
<ui-divider text="Or continue with" />
<ion-button color="medium" expand="block" class="ion-margin-top" shape="round">
<IonIcon slot="start" aria-hidden="true" :icon="phonePortraitOutline" />
Phone Number
</ion-button>
<ion-button color="medium" expand="block" class="ion-margin-top" shape="round">
<IonIcon slot="start" aria-hidden="true" :icon="logoGoogle" />
Google
</ion-button>
</div>
</div>
<div v-else-if="step === 2">
<h1><strong>Verify your email</strong></h1>
<p>We have sent a verification code to {{ form.email }}. Please enter the code below to verify your email address.</p>
<div>
<ion-item>
<ion-input-otp v-model="form.verificationCode" :length="6" />
</ion-item>
<ion-button expand="block" class="ion-margin-top" shape="round" @click="submitSignup">
Submit
</ion-button>
</div>
</div>
</template> </template>
<style lang='css' scoped></style> <style lang='css' scoped></style>