You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
9.0 KiB

5 years ago
5 years ago
  1. <template lang="pug">
  2. v-app
  3. .register
  4. v-container(grid-list-lg)
  5. v-layout(row, wrap)
  6. v-flex(
  7. xs12
  8. offset-sm1, sm10
  9. offset-md2, md8
  10. offset-lg3, lg6
  11. offset-xl4, xl4
  12. )
  13. transition(name='fadeUp')
  14. v-card.elevation-5.md2(v-show='isShown')
  15. v-toolbar(color='indigo', flat, dense, dark)
  16. v-spacer
  17. .subheading {{ $t('auth:registerTitle') }}
  18. v-spacer
  19. v-card-text.text-xs-center
  20. h1.display-1.indigo--text.py-2 {{ siteTitle }}
  21. .body-2 {{ $t('auth:registerSubTitle') }}
  22. v-text-field.md2.mt-3(
  23. solo
  24. flat
  25. prepend-icon='email'
  26. background-color='grey lighten-4'
  27. hide-details
  28. ref='iptEmail'
  29. v-model='email'
  30. :placeholder='$t("auth:fields.email")'
  31. color='indigo'
  32. )
  33. v-text-field.md2.mt-2(
  34. solo
  35. flat
  36. prepend-icon='vpn_key'
  37. background-color='grey lighten-4'
  38. ref='iptPassword'
  39. v-model='password'
  40. :append-icon='hidePassword ? "visibility" : "visibility_off"'
  41. @click:append='() => (hidePassword = !hidePassword)'
  42. :type='hidePassword ? "password" : "text"'
  43. :placeholder='$t("auth:fields.password")'
  44. color='indigo'
  45. loading
  46. counter='255'
  47. )
  48. password-strength(slot='progress', v-model='password')
  49. v-text-field.md2.mt-2(
  50. solo
  51. flat
  52. prepend-icon='vpn_key'
  53. background-color='grey lighten-4'
  54. hide-details
  55. ref='iptVerifyPassword'
  56. v-model='verifyPassword'
  57. @click:append='() => (hidePassword = !hidePassword)'
  58. type='password'
  59. :placeholder='$t("auth:fields.verifyPassword")'
  60. color='indigo'
  61. )
  62. v-text-field.md2.mt-2(
  63. solo
  64. flat
  65. prepend-icon='person'
  66. background-color='grey lighten-4'
  67. ref='iptName'
  68. v-model='name'
  69. :placeholder='$t("auth:fields.name")'
  70. @keyup.enter='register'
  71. color='indigo'
  72. counter='255'
  73. )
  74. v-card-actions.pb-4
  75. v-spacer
  76. v-btn.md2(
  77. block
  78. large
  79. dark
  80. color='indigo'
  81. @click='register'
  82. round
  83. :loading='isLoading'
  84. ) {{ $t('auth:actions.register') }}
  85. v-spacer
  86. v-divider
  87. v-card-actions.py-3.grey.lighten-4
  88. v-spacer
  89. i18next.caption(path='auth:switchToLogin.text', tag='div')
  90. a.caption(href='/login', place='link') {{ $t('auth:switchToLogin.link') }}
  91. v-spacer
  92. loader(v-model='isLoading', :mode='loaderMode', :icon='loaderIcon', :color='loaderColor', :title='loaderTitle', :subtitle='loaderSubtitle')
  93. nav-footer(color='grey darken-4', dark-color='grey darken-4')
  94. notify
  95. </template>
  96. <script>
  97. /* global siteConfig */
  98. import _ from 'lodash'
  99. import validate from 'validate.js'
  100. import PasswordStrength from './common/password-strength.vue'
  101. import registerMutation from 'gql/register/register-mutation-create.gql'
  102. export default {
  103. i18nOptions: { namespaces: 'auth' },
  104. components: {
  105. PasswordStrength
  106. },
  107. data () {
  108. return {
  109. email: '',
  110. password: '',
  111. verifyPassword: '',
  112. name: '',
  113. hidePassword: true,
  114. isLoading: false,
  115. isShown: false,
  116. loaderColor: 'grey darken-4',
  117. loaderTitle: 'Working...',
  118. loaderSubtitle: 'Please wait',
  119. loaderMode: 'icon',
  120. loaderIcon: 'checkmark'
  121. }
  122. },
  123. computed: {
  124. siteTitle () {
  125. return siteConfig.title
  126. }
  127. },
  128. mounted () {
  129. this.isShown = true
  130. this.$nextTick(() => {
  131. this.$refs.iptEmail.focus()
  132. })
  133. },
  134. methods: {
  135. /**
  136. * REGISTER
  137. */
  138. async register () {
  139. const validation = validate({
  140. email: this.email,
  141. password: this.password,
  142. verifyPassword: this.verifyPassword,
  143. name: this.name
  144. }, {
  145. email: {
  146. presence: {
  147. message: this.$t('auth:missingEmail'),
  148. allowEmpty: false
  149. },
  150. email: {
  151. message: this.$t('auth:invalidEmail')
  152. }
  153. },
  154. password: {
  155. presence: {
  156. message: this.$t('auth:missingPassword'),
  157. allowEmpty: false
  158. },
  159. length: {
  160. minimum: 6,
  161. tooShort: this.$t('auth:passwordTooShort')
  162. }
  163. },
  164. verifyPassword: {
  165. equality: {
  166. attribute: 'password',
  167. message: this.$t('auth:passwordNotMatch')
  168. }
  169. },
  170. name: {
  171. presence: {
  172. message: this.$t('auth:missingName'),
  173. allowEmpty: false
  174. },
  175. length: {
  176. minimum: 2,
  177. maximum: 255,
  178. tooShort: this.$t('auth:nameTooShort'),
  179. tooLong: this.$t('auth:nameTooLong')
  180. }
  181. }
  182. }, { fullMessages: false })
  183. if (validation) {
  184. if (validation.email) {
  185. this.$store.commit('showNotification', {
  186. style: 'red',
  187. message: validation.email[0],
  188. icon: 'warning'
  189. })
  190. this.$refs.iptEmail.focus()
  191. } else if (validation.password) {
  192. this.$store.commit('showNotification', {
  193. style: 'red',
  194. message: validation.password[0],
  195. icon: 'warning'
  196. })
  197. this.$refs.iptPassword.focus()
  198. } else if (validation.verifyPassword) {
  199. this.$store.commit('showNotification', {
  200. style: 'red',
  201. message: validation.verifyPassword[0],
  202. icon: 'warning'
  203. })
  204. this.$refs.iptVerifyPassword.focus()
  205. } else {
  206. this.$store.commit('showNotification', {
  207. style: 'red',
  208. message: validation.name[0],
  209. icon: 'warning'
  210. })
  211. this.$refs.iptName.focus()
  212. }
  213. } else {
  214. this.loaderColor = 'grey darken-4'
  215. this.loaderTitle = this.$t('auth:registering')
  216. this.loaderSubtitle = this.$t(`auth:pleaseWait`)
  217. this.loaderMode = 'loading'
  218. this.isLoading = true
  219. try {
  220. let resp = await this.$apollo.mutate({
  221. mutation: registerMutation,
  222. variables: {
  223. email: this.email,
  224. password: this.password,
  225. name: this.name
  226. }
  227. })
  228. if (_.has(resp, 'data.authentication.register')) {
  229. let respObj = _.get(resp, 'data.authentication.register', {})
  230. if (respObj.responseResult.succeeded === true) {
  231. this.loaderColor = 'grey darken-4'
  232. this.loaderTitle = this.$t('auth:registerSuccess')
  233. this.loaderSubtitle = this.$t(`auth:registerCheckEmail`)
  234. this.loaderMode = 'icon'
  235. this.isShown = false
  236. } else {
  237. throw new Error(respObj.responseResult.message)
  238. }
  239. } else {
  240. throw new Error(this.$t('auth:genericError'))
  241. }
  242. } catch (err) {
  243. console.error(err)
  244. this.$store.commit('showNotification', {
  245. style: 'red',
  246. message: err.message,
  247. icon: 'warning'
  248. })
  249. this.isLoading = false
  250. }
  251. }
  252. }
  253. }
  254. }
  255. </script>
  256. <style lang="scss">
  257. .register {
  258. background-color: mc('indigo', '900');
  259. background-image: url('../static/svg/motif-blocks.svg');
  260. background-repeat: repeat;
  261. background-size: 200px;
  262. width: 100%;
  263. height: 100%;
  264. animation: loginBgReveal 20s linear infinite;
  265. @include keyframes(loginBgReveal) {
  266. 0% {
  267. background-position-x: 0;
  268. }
  269. 100% {
  270. background-position-x: 800px;
  271. }
  272. }
  273. &::before {
  274. content: '';
  275. position: absolute;
  276. background-image: url('../static/svg/motif-overlay.svg');
  277. background-attachment: fixed;
  278. background-size: cover;
  279. opacity: .5;
  280. top: 0;
  281. left: 0;
  282. width: 100vw;
  283. height: 100vh;
  284. }
  285. > .container {
  286. height: 100%;
  287. align-items: center;
  288. display: flex;
  289. }
  290. .v-text-field.centered input {
  291. text-align: center;
  292. }
  293. }
  294. </style>