All files / src/modules/booking/create Create.page.js

70% Statements 28/40
50% Branches 6/12
50% Functions 8/16
69.23% Lines 27/39

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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186                          1x 2x   1x 2x   2x       2x       2x     1x 2x     1x                     2x 2x 2x 2x 2x   2x 2x 8x   8x     2x   2x           2x     2x                                                         2x                                                                                                       2x                                     2x     1x                          
import React, { useState } from 'react'
import * as PropTypes from 'prop-types'
import Input from 'common/components/input'
import Button from 'common/components/button'
import * as generalUtils from 'common/utils/general.utils'
import * as createConstants from './Create.constants'
import Warning from 'common/components/warning'
import SomethingWrongImg from 'common/components/warning/something-wrong.svg'
import EmailImg from 'common/components/warning/email.svg'
import LoadingImg from 'modules/main/loading.svg'
 
import './Create.scss'
 
const isFormValid = (fields) =>
  Object.values(fields).every(({ value, isValid }) => !!value && isValid)
 
const getPageState = ({ eventEndTime, showSuccessState }) => {
  const isEventExpired = eventEndTime < generalUtils.unix()
 
  Iif (isEventExpired) {
    return createConstants.PAGE_STATE.EXPIRED
  }
 
  Iif (showSuccessState) {
    return createConstants.PAGE_STATE.SUCCESS
  }
 
  return createConstants.PAGE_STATE.FORM
}
 
const CreatePageWrapper = ({ children }) => (
  <section className="create-page animate__animated animate__fadeIn">{children}</section>
)
 
const CreatePage = ({
  translate,
  availableTimesAndSeats,
  acceptedDomains,
  onSubmit,
  isSubmitting,
  eventEndTime,
  showSuccessState,
  showInvalidBookingMessage,
  resetFormAction,
}) => {
  const pageState = getPageState({ showSuccessState, eventEndTime })
  const [name, setName] = useState(generalUtils.setFieldInitialState())
  const [corporateEmail, setCorporateEmail] = useState(generalUtils.setFieldInitialState())
  const [seats, setSeats] = useState(generalUtils.setFieldInitialState())
  const [preferredTime, setPreferredTime] = useState(generalUtils.setFieldInitialState())
 
  const fields = { name, corporateEmail, seats, preferredTime }
  const fieldsValue = Object.keys(fields).reduce((fieldsVal, field) => {
    fieldsVal[field] = fields[field].value
 
    return fieldsVal
  }, {})
 
  const isSubmitButtonDisabled = isSubmitting || !isFormValid(fields)
 
  const resetFormActionInner = () => {
    setSeats(generalUtils.setFieldInitialState())
    setPreferredTime(generalUtils.setFieldInitialState())
    resetFormAction()
  }
 
  const setCorporateEmailInner = ({ value, ...fields }) =>
    setCorporateEmail({ value: value.trim(), ...fields })
 
  const PAGES_BY_STATE = {
    [createConstants.PAGE_STATE.SUCCESS]: () => (
      <Warning
        image={EmailImg}
        imageAlt={translate('Email illustration')}
        title={translate('Check your email')}
        description={translate(
          'You are almost there to reserve your room for this event! Please make sure to finish your reservation as soon as possible to avoid losing your booking.',
        )}
        footerMessage={translate("If you can't found the email, check your spam folder.")}
        callToActionType="secondary"
        callToActionText={translate('New booking')}
        onClickCallToAction={resetFormActionInner}
      />
    ),
    [createConstants.PAGE_STATE.LOADING]: () => (
      <div role="presentation">
        <LoadingImg />
      </div>
    ),
    [createConstants.PAGE_STATE.EXPIRED]: () => (
      <Warning
        image={SomethingWrongImg}
        imageAlt={translate('Something wrong happened')}
        title={translate('This event has ended')}
      />
    ),
 
    [createConstants.PAGE_STATE.FORM]: () => (
      <div className="animate__animated animate__fadeIn">
        <div className="create-page__title">
          {translate('Fill in the details below to make your office reservation')}
        </div>
        <form
          aria-label={translate('Office reservation')}
          onSubmit={(e) => {
            e.preventDefault()
          }}
        >
          <div className="create-page__content">
            <Input
              translate={translate}
              id="name"
              type="text"
              value={name.value}
              onChange={setName}
              title={translate('Name')}
            />
            <Input
              translate={translate}
              id="corporateEmail"
              type="text"
              value={corporateEmail.value}
              onChange={setCorporateEmailInner}
              title={translate('Corporate email')}
              displayErrors={corporateEmail.isTouched}
              validation={generalUtils.validateEmail(translate, acceptedDomains)}
            />
 
            <Input
              translate={translate}
              id="preferredTime"
              title={translate('Book your preferences for this event')}
              type="select"
              list={generalUtils.getPreferredTimeData(availableTimesAndSeats)}
              value={preferredTime.value}
              onChange={setPreferredTime}
              placeholder={translate('Preferred time')}
            />
 
            <Input
              translate={translate}
              id="seats"
              type="select"
              disabled={preferredTime.value === ''}
              list={generalUtils.getSeatsList({ preferredTime, availableTimesAndSeats, translate })}
              value={seats.value}
              onChange={setSeats}
              placeholder={translate('Number of seats')}
              displayErrors={showInvalidBookingMessage}
              validation={{
                test: () => !showInvalidBookingMessage,
                message: () => translate('Your booking preferences has changed'),
              }}
            />
          </div>
 
          <div className="create-page__footer">
            <Button
              onClick={() => !isSubmitButtonDisabled && onSubmit(fieldsValue)}
              isDisabled={isSubmitButtonDisabled}
            >
              {isSubmitting ? translate('Please wait ...') : translate('Continue')}
            </Button>
          </div>
        </form>
      </div>
    ),
  }
 
  return <CreatePageWrapper>{PAGES_BY_STATE[pageState]()}</CreatePageWrapper>
}
 
CreatePage.propTypes = {
  translate: PropTypes.func,
  availableTimesAndSeats: PropTypes.array,
  acceptedDomains: PropTypes.arrayOf(PropTypes.string),
  onSubmit: PropTypes.func,
  isSubmitting: PropTypes.bool,
  eventEndTime: PropTypes.number,
  showSuccessState: PropTypes.bool,
  showInvalidBookingMessage: PropTypes.bool,
  resetFormAction: PropTypes.func,
}
 
export default CreatePage