ChangePasswordDialog.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <Form
  3. class="flex flex-col gap-2 p-5"
  4. v-slot="$form"
  5. :initialValues="initialValues"
  6. :resolver="resolver"
  7. :validateOnValueUpdate="false"
  8. :validateOnBlur="true"
  9. @submit="onFormSubmit"
  10. >
  11. <div class="flex flex-col">
  12. <label
  13. for="current_password"
  14. class="ml-1 text-sm text-primary dark:text-primary"
  15. >
  16. Current Password
  17. </label>
  18. <Password
  19. name="currentPassword"
  20. :feedback="false"
  21. fluid
  22. toggleMask
  23. inputId="current_password"
  24. placeholder="Current password"
  25. autocomplete="current-password"
  26. >
  27. <template #maskicon="{ toggleCallback }">
  28. <Icon
  29. class="absolute inset-e-3 top-1/2 -mt-2 h-4 w-4 text-surface-500 dark:text-surface-400"
  30. name="ph:eye-slash-bold"
  31. @click="toggleCallback"
  32. />
  33. </template>
  34. <template #unmaskicon="{ toggleCallback }">
  35. <Icon
  36. class="absolute inset-e-3 top-1/2 -mt-2 h-4 w-4 text-surface-500 dark:text-surface-400"
  37. name="ph:eye-bold"
  38. @click="toggleCallback"
  39. />
  40. </template>
  41. </Password>
  42. <Message
  43. v-if="$form.currentPassword?.invalid"
  44. severity="error"
  45. size="small"
  46. variant="simple"
  47. >
  48. {{ $form.currentPassword?.error?.message }}
  49. </Message>
  50. </div>
  51. <div class="flex flex-col">
  52. <label
  53. for="new_password"
  54. class="ml-1 text-sm text-primary dark:text-primary"
  55. >
  56. New Password
  57. </label>
  58. <Password
  59. name="newPassword"
  60. :feedback="false"
  61. fluid
  62. toggleMask
  63. inputId="new_password"
  64. placeholder="New password"
  65. autocomplete="new-password"
  66. >
  67. <template #maskicon="{ toggleCallback }">
  68. <Icon
  69. class="absolute inset-e-3 top-1/2 -mt-2 h-4 w-4 text-surface-500 dark:text-surface-400"
  70. name="ph:eye-slash-bold"
  71. @click="toggleCallback"
  72. />
  73. </template>
  74. <template #unmaskicon="{ toggleCallback }">
  75. <Icon
  76. class="absolute inset-e-3 top-1/2 -mt-2 h-4 w-4 text-surface-500 dark:text-surface-400"
  77. name="ph:eye-bold"
  78. @click="toggleCallback"
  79. />
  80. </template>
  81. </Password>
  82. <Message
  83. v-if="$form.newPassword?.invalid"
  84. severity="error"
  85. size="small"
  86. variant="simple"
  87. >
  88. {{ $form.newPassword?.error?.message }}
  89. </Message>
  90. </div>
  91. <Button
  92. label="Change Password"
  93. type="submit"
  94. fluid
  95. :disabled="!$form.valid"
  96. :loading="isLoading"
  97. class="mt-5"
  98. >
  99. <template #loadingicon>
  100. <Icon
  101. class="animate-spin"
  102. name="ph:circle-notch-bold"
  103. />
  104. </template>
  105. </Button>
  106. </Form>
  107. </template>
  108. <script setup>
  109. import { zodResolver } from "@primeuix/forms/resolvers/zod"
  110. const dialogRef = inject("dialogRef")
  111. const toast = useToast()
  112. const { authClient } = useAuthClient()
  113. const resolver = ref(
  114. zodResolver(
  115. z.object({
  116. currentPassword: z.string().min(1, "Current password is required."),
  117. confirmPassword: z
  118. .string()
  119. .min(12, "New password must be at least 12 characters.")
  120. })
  121. )
  122. )
  123. const initialValues = ref({
  124. currentPassword: "",
  125. newPassword: ""
  126. })
  127. const isLoading = ref(false)
  128. async function onFormSubmit({ valid, values }) {
  129. if (valid) {
  130. await changePassword(values)
  131. closeDialog()
  132. }
  133. }
  134. async function changePassword(values) {
  135. if (isLoading.value) {
  136. return
  137. }
  138. isLoading.value = true
  139. // noinspection JSUnresolvedReference
  140. const { error } = await authClient.changePassword(values)
  141. isLoading.value = false
  142. if (error) {
  143. console.error(error)
  144. toast.add({
  145. severity: "error",
  146. summary: "Change Password Error.",
  147. detail: error.data?.message || error.message
  148. })
  149. } else {
  150. toast.add({
  151. severity: "success",
  152. summary: "Password Changed.",
  153. detail: "Your password is changed.",
  154. life: 3000
  155. })
  156. }
  157. }
  158. function closeDialog() {
  159. dialogRef.value.close()
  160. }
  161. </script>
  162. <style scoped></style>