Signup.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { computed, ref } from 'vue'
  4. import { useRouter } from 'vue-router'
  5. import { NotificationTypes } from '#shared/components/CommonNotifications/types.ts'
  6. import { useNotifications } from '#shared/components/CommonNotifications/useNotifications.ts'
  7. import Form from '#shared/components/Form/Form.vue'
  8. import type { FormSubmitData } from '#shared/components/Form/types.ts'
  9. import { useForm } from '#shared/components/Form/useForm.ts'
  10. import type { SignupFormData } from '#shared/entities/user/types.ts'
  11. import { EnumPublicLinksScreen } from '#shared/graphql/types.ts'
  12. import { i18n } from '#shared/i18n.ts'
  13. import { MutationHandler } from '#shared/server/apollo/handler/index.ts'
  14. import { useApplicationStore } from '#shared/stores/application.ts'
  15. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  16. import CommonPublicLinks from '#desktop/components/CommonPublicLinks/CommonPublicLinks.vue'
  17. import LayoutPublicPage from '#desktop/components/layout/LayoutPublicPage/LayoutPublicPage.vue'
  18. import { useSignupForm } from '#desktop/composables/authentication/useSignupForm.ts'
  19. import { useUserSignupMutation } from '../graphql/mutations/userSignup.api.ts'
  20. import { useUserSignupResendMutation } from '../graphql/mutations/userSignupResend.api.ts'
  21. defineOptions({
  22. beforeRouteEnter(to) {
  23. const application = useApplicationStore()
  24. if (!application.config.user_create_account) {
  25. return to.redirectedFrom ? false : '/'
  26. }
  27. return true
  28. },
  29. })
  30. const application = useApplicationStore()
  31. const router = useRouter()
  32. const { signupSchema } = useSignupForm()
  33. const { form, isDisabled } = useForm()
  34. const signupSent = ref(false)
  35. const signupEmail = ref('')
  36. const pageTitle = computed(() => {
  37. if (signupSent.value) return __('Registration successful!')
  38. return i18n.t('Join %s', application.config.product_name)
  39. })
  40. const singup = async (data: SignupFormData) => {
  41. const sendSignup = new MutationHandler(useUserSignupMutation())
  42. return sendSignup
  43. .send({
  44. input: {
  45. firstname: data.firstname,
  46. lastname: data.lastname,
  47. email: data.email,
  48. password: data.password,
  49. },
  50. })
  51. .then(() => {
  52. signupSent.value = true
  53. signupEmail.value = data.email
  54. })
  55. }
  56. const { notify } = useNotifications()
  57. const resendVerifyEmail = () => {
  58. const resendVerifyEmail = new MutationHandler(
  59. useUserSignupResendMutation({
  60. variables: {
  61. email: signupEmail.value,
  62. },
  63. }),
  64. {
  65. errorShowNotification: false,
  66. },
  67. )
  68. resendVerifyEmail
  69. .send()
  70. .then(() => {
  71. notify({
  72. id: 'resend-verify-email',
  73. type: NotificationTypes.Success,
  74. message: __('Email sent to "%s". Please verify your email account.'),
  75. messagePlaceholder: [signupEmail.value],
  76. })
  77. })
  78. .catch(() => {
  79. notify({
  80. id: 'resend-verify-email-error',
  81. type: NotificationTypes.Error,
  82. message: __('The verification email could not be resent.'),
  83. })
  84. })
  85. }
  86. const goToLogin = () => {
  87. router.replace('login')
  88. }
  89. </script>
  90. <template>
  91. <LayoutPublicPage box-size="medium" :show-logo="false" :title="pageTitle">
  92. <Form
  93. v-if="!signupSent"
  94. id="signup"
  95. ref="form"
  96. form-class="mb-2.5"
  97. :schema="signupSchema"
  98. @submit="singup($event as FormSubmitData<SignupFormData>)"
  99. />
  100. <div v-else class="flex flex-col items-center gap-2.5">
  101. <CommonLabel class="py-5 text-center">
  102. {{ $t('Thanks for joining. Email sent to "%s".', signupEmail) }}
  103. </CommonLabel>
  104. <CommonLabel class="py-5 text-center">
  105. {{
  106. $t(
  107. "Please click on the link in the verification email. If you don't see the email, check other places it might be, like your junk, spam, social, or other folders.",
  108. )
  109. }}
  110. </CommonLabel>
  111. </div>
  112. <template #boxActions>
  113. <CommonButton
  114. variant="secondary"
  115. size="medium"
  116. :disabled="isDisabled"
  117. @click="goToLogin()"
  118. >
  119. {{ $t('Cancel & Go Back') }}
  120. </CommonButton>
  121. <CommonButton
  122. v-if="!signupSent"
  123. variant="submit"
  124. type="submit"
  125. size="medium"
  126. form="signup"
  127. :disabled="isDisabled"
  128. >
  129. {{ $t('Create my account') }}
  130. </CommonButton>
  131. <CommonButton
  132. v-else
  133. variant="submit"
  134. size="medium"
  135. @click="resendVerifyEmail()"
  136. >
  137. {{ $t('Resend verification email') }}
  138. </CommonButton>
  139. </template>
  140. <template #bottomContent>
  141. <div
  142. class="inline-flex flex-wrap items-center justify-center p-2 text-sm"
  143. >
  144. <CommonLabel class="text-center text-stone-200 dark:text-neutral-500">
  145. {{
  146. $t(
  147. "You're already registered with your email address if you've been in touch with our Support team.",
  148. )
  149. }}
  150. </CommonLabel>
  151. <CommonLink v-if="$c.user_lost_password" link="/reset-password">{{
  152. $t('You can request your password here.')
  153. }}</CommonLink>
  154. </div>
  155. <CommonPublicLinks :screen="EnumPublicLinksScreen.Signup" />
  156. </template>
  157. </LayoutPublicPage>
  158. </template>