refactor: signup component
This commit is contained in:
82
src/auth/components/email/step1.vue
Normal file
82
src/auth/components/email/step1.vue
Normal 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>
|
||||||
43
src/auth/components/email/step2.vue
Normal file
43
src/auth/components/email/step2.vue
Normal 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>
|
||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user