Selaa lähdekoodia

make reset dialog async

Jason Gorst 1 kuukausi sitten
vanhempi
sitoutus
b27bcd4a3c
1 muutettua tiedostoa jossa 189 lisäystä ja 0 poistoa
  1. 189 0
      app/components/SignInDialog.vue

+ 189 - 0
app/components/SignInDialog.vue

@@ -0,0 +1,189 @@
+<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>