Signup.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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 { useApplicationStore } from '#shared/stores/application.ts'
  6. import Form from '#shared/components/Form/Form.vue'
  7. import type { FormSubmitData } from '#shared/components/Form/types.ts'
  8. import { useForm } from '#shared/components/Form/useForm.ts'
  9. import { MutationHandler } from '#shared/server/apollo/handler/index.ts'
  10. import { i18n } from '#shared/i18n.ts'
  11. import { EnumPublicLinksScreen } from '#shared/graphql/types.ts'
  12. import { useNotifications } from '#shared/components/CommonNotifications/useNotifications.ts'
  13. import { NotificationTypes } from '#shared/components/CommonNotifications/types.ts'
  14. import type { SignupFormData } from '#shared/entities/user/types.ts'
  15. import LayoutPublicPage from '#desktop/components/layout/LayoutPublicPage/LayoutPublicPage.vue'
  16. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  17. import CommonPublicLinks from '#desktop/components/CommonPublicLinks/CommonPublicLinks.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. type: NotificationTypes.Success,
  73. message: __('Email sent to "%s". Please verify your email account.'),
  74. messagePlaceholder: [signupEmail.value],
  75. })
  76. })
  77. .catch(() => {
  78. notify({
  79. type: NotificationTypes.Error,
  80. message: __('The verification email could not be resent.'),
  81. })
  82. })
  83. }
  84. const goToLogin = () => {
  85. router.replace('login')
  86. }
  87. </script>
  88. <template>
  89. <LayoutPublicPage box-size="medium" :show-logo="false" :title="pageTitle">
  90. <Form
  91. v-if="!signupSent"
  92. id="signup"
  93. ref="form"
  94. form-class="mb-2.5"
  95. :schema="signupSchema"
  96. @submit="singup($event as FormSubmitData<SignupFormData>)"
  97. />
  98. <div v-else class="flex flex-col items-center gap-2.5">
  99. <CommonLabel class="py-5 text-center">
  100. {{ $t('Thanks for joining. Email sent to "%s".', signupEmail) }}
  101. </CommonLabel>
  102. <CommonLabel class="py-5 text-center">
  103. {{
  104. $t(
  105. "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.",
  106. )
  107. }}
  108. </CommonLabel>
  109. </div>
  110. <template #boxActions>
  111. <CommonButton
  112. variant="secondary"
  113. size="medium"
  114. :disabled="isDisabled"
  115. @click="goToLogin()"
  116. >
  117. {{ $t('Cancel & Go Back') }}
  118. </CommonButton>
  119. <CommonButton
  120. v-if="!signupSent"
  121. variant="submit"
  122. type="submit"
  123. size="medium"
  124. form="signup"
  125. :disabled="isDisabled"
  126. >
  127. {{ $t('Create my account') }}
  128. </CommonButton>
  129. <CommonButton
  130. v-else
  131. variant="submit"
  132. size="medium"
  133. @click="resendVerifyEmail()"
  134. >
  135. {{ $t('Resend verification email') }}
  136. </CommonButton>
  137. </template>
  138. <template #bottomContent>
  139. <div
  140. class="p-2 inline-flex items-center justify-center flex-wrap text-sm"
  141. >
  142. <CommonLabel class="text-stone-200 dark:text-neutral-500 text-center">
  143. {{
  144. $t(
  145. "You're already registered with your email address if you've been in touch with our Support team.",
  146. )
  147. }}
  148. </CommonLabel>
  149. <CommonLink v-if="$c.user_lost_password" link="/reset-password">{{
  150. $t('You can request your password here.')
  151. }}</CommonLink>
  152. </div>
  153. <CommonPublicLinks :screen="EnumPublicLinksScreen.Signup" />
  154. </template>
  155. </LayoutPublicPage>
  156. </template>