All files / modules/10-common/pages/signup SignupPage.tsx

78.05% Statements 32/41
4.55% Branches 1/22
75% Functions 3/4
78.05% Lines 32/41

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151              1x 1x 1x 1x                     1x 1x 1x 1x 1x 1x 1x     1x 1x               1x             1x 2x 2x 2x 2x 2x   2x   2x 1x   1x         1x 1x                         1x         1x       2x           2x         2x                                                                                                       1x  
/*
 * Copyright 2021 Harness Inc. All rights reserved.
 * Use of this source code is governed by the PolyForm Shield 1.0.0 license
 * that can be found in the licenses directory at the root of this repository, also available at
 * https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
 */
 
import React from 'react'
import { Link, useHistory } from 'react-router-dom'
import * as Yup from 'yup'
import {
  Button,
  FormInput,
  Formik,
  FormikForm,
  HarnessIcons,
  Icon,
  OverlaySpinner,
  Container,
  Text
} from '@wings-software/uicore'
import { Color } from '@harness/design-system'
import routes from '@common/RouteDefinitions'
import { useToaster } from '@common/components'
import { useQueryParams } from '@common/hooks'
import { useSignup, SignupDTO } from 'services/cd-ng'
import AuthLayout from '@common/components/AuthLayout/AuthLayout'
import AppStorage from 'framework/utils/AppStorage'
import type { RestResponseUserInfo } from 'services/cd-ng'
 
import AuthFooter, { AuthPage } from '@common/components/AuthLayout/AuthFooter/AuthFooter'
import { useStrings } from 'framework/strings'
import type { Module } from '@common/interfaces/RouteInterfaces'
 
interface SignupForm {
  email: string
  password: string
}
 
const setToken = async (response: RestResponseUserInfo): Promise<void> => {
  AppStorage.set('token', response.resource?.token)
  AppStorage.set('acctId', response.resource?.defaultAccountId)
  AppStorage.set('uuid', response.resource?.uuid)
  AppStorage.set('lastTokenSetTime', +new Date())
}
 
const SignupPage: React.FC = () => {
  const { showError } = useToaster()
  const { getString } = useStrings()
  const { module } = useQueryParams<{ module?: Module }>()
  const { mutate: getUserInfo, loading } = useSignup({})
  const history = useHistory()
 
  const HarnessLogo = HarnessIcons['harness-logo-black']
 
  const handleSignup = async (data: SignupForm): Promise<void> => {
    const { email, password } = data
 
    const dataToSubmit: SignupDTO = {
      email,
      password
    }
 
    try {
      const userInfoResponse = await getUserInfo(dataToSubmit)
      const accountId = userInfoResponse.resource?.defaultAccountId || ''
      await setToken(userInfoResponse as RestResponseUserInfo)
      if (module) {
        history.push({ pathname: routes.toModuleHome({ module, accountId }), search: '?source=signup' })
      } else {
        history.push(
          routes.toPurpose({
            accountId
          })
        )
      }
    } catch (error) {
      showError(error.message)
    }
  }
 
  function handleSubmit(data: SignupForm): void {
    handleSignup(data)
  }
 
  const spinner = (
    <OverlaySpinner show>
      <></>
    </OverlaySpinner>
  )
 
  const submitButton = (
    <Button type="submit" intent="primary" width="100%">
      {getString('signUp.signUp')}
    </Button>
  )
 
  return (
    <>
      <AuthLayout>
        <Container flex={{ justifyContent: 'space-between', alignItems: 'center' }} margin={{ bottom: 'xxxlarge' }}>
          <HarnessLogo height={25} />
          <Link to={routes.toLogin()}>
            <Icon name="arrow-left" color={Color.BLUE_500} margin={{ right: 'xsmall' }} />
            <Text color={Color.BLUE_500} inline font={{ size: 'medium' }}>
              {getString('signUp.signIn')}
            </Text>
          </Link>
        </Container>
 
        <Text font={{ size: 'large', weight: 'bold' }} color={Color.BLACK}>
          {getString('signUp.message.primary')}
        </Text>
        <Text font={{ size: 'medium' }} color={Color.BLACK} margin={{ top: 'xsmall' }}>
          {getString('signUp.message.secondary')}
        </Text>
 
        <Container margin={{ top: 'xxxlarge' }}>
          <Formik
            formName="signupPageForm"
            initialValues={{ name: '', email: '', password: '' }}
            onSubmit={handleSubmit}
            validationSchema={Yup.object().shape({
              email: Yup.string().email().required(),
              password: Yup.string().min(8).required()
            })}
          >
            <FormikForm>
              <FormInput.Text
                name="email"
                label={getString('signUp.form.emailLabel')}
                placeholder={getString('signUp.form.emailPlaceholder')}
              />
              <FormInput.Text
                name="password"
                label={getString('password')}
                inputGroup={{ type: 'password' }}
                placeholder={getString('signUp.form.passwordPlaceholder')}
              />
              {loading ? spinner : submitButton}
            </FormikForm>
          </Formik>
        </Container>
        <AuthFooter page={AuthPage.SignUp} />
      </AuthLayout>
    </>
  )
}
 
export default SignupPage