90 lines
2.5 KiB
Vue
90 lines
2.5 KiB
Vue
<script lang='ts' setup>
|
|
import type { InputCustomEvent } from "@ionic/vue";
|
|
import { toastController } from "@ionic/vue";
|
|
import { logoGoogle, phonePortraitOutline } from "ionicons/icons";
|
|
import { authClient } from "@/auth";
|
|
|
|
const { t } = useI18n();
|
|
|
|
const emit = defineEmits<{
|
|
(e: "success", value: string): void;
|
|
}>();
|
|
|
|
const model = defineModel({ type: String, required: true });
|
|
const inputInstance = useTemplateRef<InputInstance>("inputInstance");
|
|
|
|
function markTouched() {
|
|
inputInstance.value?.$el.classList.add("ion-touched");
|
|
}
|
|
function validate(value: string) {
|
|
inputInstance.value?.$el.classList.remove("ion-valid");
|
|
inputInstance.value?.$el.classList.remove("ion-invalid");
|
|
|
|
if (value === "") {
|
|
return false;
|
|
}
|
|
const isEmailValid = emailPattern.test(model.value);
|
|
|
|
isEmailValid ? inputInstance.value?.$el.classList.add("ion-valid") : inputInstance.value?.$el.classList.add("ion-invalid");
|
|
|
|
return isEmailValid;
|
|
}
|
|
|
|
async function submitSendVerification() {
|
|
const isEmailValid = validate(model.value);
|
|
if (!isEmailValid) {
|
|
inputInstance.value?.$el.classList.remove("ion-invalid");
|
|
inputInstance.value?.$el.classList.add("ion-invalid");
|
|
inputInstance.value?.$el.classList.add("ion-touched");
|
|
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 || t('auth.common.failedSendCode'),
|
|
duration: 1500,
|
|
position: "bottom",
|
|
});
|
|
|
|
await toast.present();
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<h1 class="title">
|
|
<strong>{{ t('auth.login.title') }}</strong>
|
|
</h1>
|
|
|
|
<ui-input-label
|
|
ref="inputInstance"
|
|
v-model="model"
|
|
:label="t('auth.common.email')"
|
|
:placeholder="t('auth.common.enterEmail')"
|
|
type="email"
|
|
:error-text="t('auth.common.validEmailError')"
|
|
@ion-input="validate($event.target.value as string)"
|
|
@ion-blur="markTouched"
|
|
/>
|
|
|
|
<ion-button expand="block" class="ion-margin-top" shape="round" @click="submitSendVerification">
|
|
{{ t('auth.common.next') }}
|
|
</ion-button>
|
|
|
|
<ui-divider :text="t('auth.common.orContinueWith')" />
|
|
|
|
<ion-button color="medium" expand="block" class="ion-margin-top" shape="round">
|
|
<IonIcon slot="start" aria-hidden="true" :icon="logoGoogle" />
|
|
{{ t('auth.common.google') }}
|
|
</ion-button>
|
|
</template>
|
|
|
|
<style scoped></style>
|