| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- <template>
- <div>
- <Form
- class="flex flex-col gap-2 p-5"
- v-slot="$form"
- :initialValues="initialValues"
- :resolver="resolver"
- :validateOnValueUpdate="false"
- :validateOnBlur="true"
- @submit="onFormSubmit"
- >
- <div class="flex flex-col">
- <label
- for="signin_email"
- class="ml-1 text-sm text-primary dark:text-primary"
- >
- Email Address
- </label>
- <InputText
- name="email"
- fluid
- id="signin_email"
- type="email"
- placeholder="Email address"
- autocomplete="email"
- autofocus
- />
- <Message
- v-if="$form.email?.invalid"
- severity="error"
- size="small"
- variant="simple"
- >
- {{ $form.email?.error?.message }}
- </Message>
- </div>
- <div class="flex flex-col">
- <label
- for="signin_password"
- class="ml-1 text-sm text-primary dark:text-primary"
- >
- Password
- </label>
- <Password
- name="password"
- :feedback="false"
- fluid
- inputId="signin_password"
- toggleMask
- autocomplete="current-password"
- placeholder="Password"
- >
- <template #maskicon="{ toggleCallback }">
- <Icon
- class="absolute inset-e-3 top-1/2 -mt-2 h-4 w-4 text-surface-500
- dark:text-surface-400"
- name="ph:eye-slash-bold"
- @click="toggleCallback"
- />
- </template>
- <template #unmaskicon="{ toggleCallback }">
- <Icon
- class="absolute inset-e-3 top-1/2 -mt-2 h-4 w-4 text-surface-500
- dark:text-surface-400"
- name="ph:eye-bold"
- @click="toggleCallback"
- />
- </template>
- </Password>
- <Message
- v-if="$form.password?.invalid"
- severity="error"
- size="small"
- variant="simple"
- >
- {{ $form.password?.error?.message }}
- </Message>
- </div>
- <Button
- label="Sign In"
- type="submit"
- fluid
- :disabled="!$form.valid"
- :loading="isLoading"
- class="mt-5"
- >
- <template #icon>
- <Icon name="ph:sign-in-bold" />
- </template>
- <template #loadingicon>
- <Icon
- class="animate-spin"
- name="ph:circle-notch-bold"
- />
- </template>
- </Button>
- </Form>
- <div class="flex flex-col p-5 pt-0">
- <Button
- variant="text"
- @click="resetPasswordRequest()"
- >
- Forgot Password
- </Button>
- </div>
- </div>
- </template>
- <script setup>
- import { zodResolver } from "@primeuix/forms/resolvers/zod"
- import { hydrateOnVisible } from "vue"
- const ResetPasswordRequestDialog = defineAsyncComponent({
- loader: () => import("~/components/ResetPasswordRequestDialog.vue"),
- hydrate: hydrateOnVisible()
- })
- const { signIn } = useAuthClient()
- const dynamicDialog = useDynamicDialog()
- const toast = useToast()
- const dialogRef = inject("dialogRef")
- const resolver = ref(
- zodResolver(
- z.object({
- email: z.email("Not an email address."),
- password: z.string().min(1, "Password is required.")
- })
- )
- )
- const isLoading = ref(false)
- const initialValues = ref({ email: "", password: "" })
- async function onFormSubmit({ valid, values }) {
- if (valid) {
- await signInWithPassword(values)
- closeDialog()
- }
- }
- async function signInWithPassword(values) {
- if (isLoading.value) {
- return
- }
- isLoading.value = true
- const { error } = await signIn(values)
- isLoading.value = false
- if (error) {
- console.error(error)
- toast.add({
- severity: "error",
- summary: "SignIn Error.",
- detail: error.data?.message || error.message
- })
- } else {
- toast.add({
- severity: "success",
- summary: "Signed In.",
- detail: "You are now signed in.",
- life: 3000
- })
- }
- }
- async function resetPasswordRequest() {
- closeDialog()
- // noinspection JSUnresolvedReference
- dynamicDialog.open(ResetPasswordRequestDialog)
- }
- function closeDialog() {
- dialogRef.value.close()
- }
- </script>
- <style scoped></style>
|