Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React from 'react'
- import {
- View,
- Dimensions,
- BackHandler,
- Platform
- } from 'react-native'
- import PropTypes from 'prop-types'
- import { connect } from 'react-redux'
- import Moment from 'moment'
- import _ from 'lodash'
- import { Styles } from '../../styles'
- import {
- getSurvey,
- createSurveyAnswer,
- getSurveyList,
- updateSurveyAnswer
- } from './store/actions'
- import {
- surveySelector,
- createSurveyAnswerSelector,
- updateSurveyAnswerSelector,
- surveyListSelector
- } from './store/selectors'
- import { OfflineNotifier, LoadingSurvey } from './components'
- import { SurveyHeader, SurveyStatus, InfoPopup } from './surveyComponents'
- import { validateNHS, validateSSN } from './regex'
- import {
- Survey,
- EQ5DSurvey,
- SurveyNavigationControl,
- EQ5DNavigationControl
- } from './'
- import translate from '../../content-config/content/main'
- import { getSelectors, validatePropsData } from '../../lib/store/dataHelpers'
- import { setLocalUser, setUser } from '../../store/common/actions'
- import { userSelector } from '../../store/common/selectors'
- import { deleteConsentData } from '../consent/store/actions'
- import Config from './config'
- import ErrorHandling from '../../utils/ErrorHandling'
- import { validateConditions } from './validateConditions'
- import { GoogleapisServiceProvider } from '../../lib/api/googleapis'
- import { isTokenError } from '../../utils'
- const GoogleapisService = GoogleapisServiceProvider()
- const screen = Dimensions.get('window')
- const dateFormat = 'YYYY-MM-DD HH:mm:ss'
- const defaultState = {
- surveyData: null,
- surveyStartedAt: null,
- tooltip: true,
- nextPage: null,
- pageCounter: 1,
- noOfPages: null,
- eq5d: null,
- loading: false,
- pageOrder: [],
- responses: {},
- resumeSurvey: false,
- error: null,
- surveyCompleted: false,
- leaveSurvey: false,
- goBack: false,
- errorSubmittingSurvey: false,
- getSurveyError: null,
- surveyId: null,
- thankYouScreenData: {},
- errorCode: null,
- multipleChoiceQuestions: [],
- showUnselectDragDropPopup: null
- }
- const isLoadingProps = (props, state) => {
- const { surveyLoading, createSurveyAnswerLoading,
- surveyListLoading, updateSurveyAnswerLoading } = props
- const { goBack, loading } = state
- // SurveyListLoading && goBack, need to be theer so that we check if the lsit
- // is loading only when we press the goback button, and not when we open a survey
- return !loading && (surveyLoading || createSurveyAnswerLoading || updateSurveyAnswerLoading ||
- !props.localUser.token || (surveyListLoading && goBack))
- }
- class SurveyContainer extends ErrorHandling {
- constructor (props) {
- super(props)
- this.state = { ...defaultState }
- this.multipleChoicesMainPages = {}
- this.multipleChoicesMainPageAnswers = {}
- }
- componentDidMount () {
- this.getSurveyFromBackend()
- if (Platform.OS === 'android') {
- BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid)
- }
- }
- componentWillUnmount () {
- BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid)
- }
- static getDerivedStateFromProps (props, state) {
- const { surveySuccess, createSurveyAnswerError, updateSurveyAnswerError, surveyError } = props
- if (isLoadingProps(props, state)) return { loading: true }
- if (surveySuccess && state.error) return { error: false, loading: false }
- if ((createSurveyAnswerError || updateSurveyAnswerError) &&
- !isTokenError(createSurveyAnswerError) && !isTokenError(updateSurveyAnswerError))
- {
- return {
- loading: false,
- leaveSurvey: false,
- errorCode: null,
- errorSubmittingSurvey: true
- }
- }
- // if we retry call (token expired) we don't want to set loading to false
- if (surveyError && !isTokenError(surveyError)) return { loading: false, getSurveyError: true }
- return null
- }
- componentDidUpdate (prevProps, prevState) {
- const {
- surveySuccess,
- surveyError,
- appState
- } = this.props
- if (prevProps.appState.match(/active|inactive/) && appState === 'background') {
- this.createResponseData(true)
- }
- if (surveySuccess && validatePropsData('success', 'survey', prevProps, this.props)) {
- return this.onSurveySuccess(surveySuccess)
- }
- if (surveySuccess &&
- (validatePropsData('success', 'createSurveyAnswer', prevProps, this.props) ||
- (validatePropsData('success', 'updateSurveyAnswer', prevProps, this.props)))) {
- this.onSurveyAnswerSuccess()
- }
- if (surveyError && validatePropsData('error', 'survey', prevProps, this.props)) {
- return this.checkTokenError(surveyError, () => this.getSurveyFromBackend(), true)
- }
- if ((validatePropsData('error', 'createSurveyAnswer', prevProps, this.props)) ||
- (validatePropsData('error', 'updateSurveyAnswer', prevProps, this.props))) {
- const { createSurveyAnswerError, updateSurveyAnswerError } = this.props
- return this.checkTokenError(createSurveyAnswerError || updateSurveyAnswerError,
- () => this.createOrUpdateSurveyAnswer(), false)
- }
- this.onValidatePropsDataSurveysList(prevProps)
- }
- checkTokenError (error, callback, surveyError) {
- if (isTokenError(error)) {
- if (this.retryCounter > 0) {
- this.retryCounter = 0
- return this.setState({
- loading: false,
- getSurveyError: surveyError,
- errorSubmittingSurvey: true,
- errorCode: null,
- leaveSurvey: false
- })
- }
- this.refreshTokenAndRetry(() => callback()) // method found in ErrorHandling
- }
- }
- onSurveyAnswerSuccess () {
- const surveyAnswerResponse = this.getSurveyAnswerResponse()
- this.setState(prevState => ({
- loading: false,
- copyResponses: JSON.stringify(prevState.responses),
- surveyWithAnswerData: surveyAnswerResponse
- }))
- // If survey completed
- if (surveyAnswerResponse.status === 'completed') this.onSurveyCompleted(surveyAnswerResponse)
- // When navigating back or or putting survey in background
- if (this.state.goBack) this.retrieveSurveysList()
- // call doesn't end when putting app in background
- // this.setState({ appState: AppState.currentState }) // TODO: ????
- }
- getSurveyAnswerResponse () {
- const { createSurveyAnswerTimestamp, updateSurveyAnswerTimestamp,
- createSurveyAnswerSuccess, updateSurveyAnswerSuccess
- } = this.props
- return createSurveyAnswerTimestamp > updateSurveyAnswerTimestamp
- ? createSurveyAnswerSuccess
- : updateSurveyAnswerSuccess
- }
- onSurveyCompleted (surveyAnswerResponse) {
- this.retrieveSurveysList()
- this.setCompletedSurveyValue(surveyAnswerResponse)
- }
- getSurveyFromBackend = () => {
- const { surveyId, localUser, getSurvey } = this.props
- if (localUser && surveyId) {
- const { token, language } = localUser
- getSurvey(surveyId, {
- params: {
- accessToken: token,
- language
- }
- })
- }
- }
- onValidatePropsDataSurveysList (prevProps) {
- const { goBack } = this.state
- if ((validatePropsData('success', 'surveyList', prevProps, this.props) && goBack) ||
- validatePropsData('error', 'surveyList', prevProps, this.props)) {
- this.goToEdiary()
- }
- }
- goToEdiary () { this.setState({ leaveSurvey: false }, () => this.props.goBack()) }
- isResumeOrExpiredScreenShown = () => {
- const { data } = this.props
- const { resumeSurvey, surveyAnswerId, surveyData } = this.state
- const answerSurveysId = (data && data.answerId) || surveyAnswerId
- return (surveyAnswerId && surveyData && !resumeSurvey) ||
- (answerSurveysId && !resumeSurvey)
- }
- onBackAndroid = () => {
- const { surveyLoading, goBack } = this.props
- const { leaveSurvey } = this.state
- if (leaveSurvey || surveyLoading || this.isResumeOrExpiredScreenShown()) goBack()
- else this.onSurveyModalPressed(true)
- return true
- }
- goBack = () => {
- const { responses, showPopupDate } = this.state
- const { fromNotifier, goToDashboard, goBack } = this.props
- if (Object.keys(responses).length > 0 || showPopupDate) {
- this.leavePageCheckValidInput(() => this.createResponseData(true, 'goBack'))
- return
- }
- if (fromNotifier) return goToDashboard()
- goBack()
- }
- toggleInfoPopup = (value, firstTime) => {
- const { surveyData } = this.state
- if (firstTime && surveyData.showDragAndDropPopup === 'no') return
- if (firstTime && surveyData.showDragAndDropPopup === 'yes') {
- return this.setState({ showInfoPopup: value, firstTimePopup: true, updateDragDropModalValue: true })
- }
- this.setState({ showInfoPopup: value })
- }
- onCloseFirstTimePopup = () => {
- this.setState({ showInfoPopup: false, firstTimePopup: false })
- }
- retrieveSurveysList () {
- const { localUser, getSurveyList } = this.props
- const { token, language } = localUser
- getSurveyList({
- params: {
- accessToken: token,
- language
- }
- })
- }
- setResumeSurveyValue = () => {
- this.setState({
- resumeSurvey: true,
- // We reset startedAt when we start again, an expired response
- surveyStartedAt: Moment().format(dateFormat)
- })
- }
- setCompletedSurveyValue = surveyAnswerResponse => {
- this.setState({
- surveyCompleted: true,
- thankYouScreenData: surveyAnswerResponse
- })
- }
- setError = value => this.setState({ error: value })
- addResponse = (id, response, callback) => {
- const { pageOrder, pageCounter, responses, surveyData, multipleChoiceQuestions } = this.state
- const currentPage = pageOrder[pageCounter - 1]
- response.page = currentPage
- responses[id] = response
- const minPages = surveyData.pages[currentPage].minPages
- const pageInputType = surveyData.pages[pageOrder[pageCounter - 1]].pageInputType
- let lengthMultipleChoiceElements = 0
- if (this.multipleChoicesMainPageAnswers[currentPage]) {
- const mainPage = this.multipleChoicesMainPages[this.multipleChoicesMainPageAnswers[currentPage].mainPage]
- lengthMultipleChoiceElements = this.getLenghtMultipleChoiceOrMainArray(multipleChoiceQuestions, mainPage, currentPage)
- }
- let mQuestions = multipleChoiceQuestions
- // Case multiple choice, and exclude multiple choice and radio types of answers
- if (pageInputType === 'multipleChoices' && typeof response.value === 'object') {
- const result = this.addReponseForMultipleChoice(response, lengthMultipleChoiceElements)
- mQuestions = result.mQuestions
- lengthMultipleChoiceElements = result.lengthMultipleChoiceElements
- }
- this.setState({
- responses,
- multipleChoiceQuestions: mQuestions,
- noOfPages: minPages + pageCounter - 1 + lengthMultipleChoiceElements
- }, () => {
- if (callback) return callback()
- this.checkNextPage()
- })
- }
- deleteSurveyConsentData = () => this.props.deleteConsentData('surveys_consent')
- deleteResponse = id => { // uncheck answer
- const { responses, noOfPages, surveyData, pageOrder, pageCounter } = this.state
- const pageInputType = surveyData.pages[pageOrder[pageCounter - 1]].pageInputType
- delete responses[id]
- // Case multiple choice answers
- if (pageInputType === 'multipleChoices') {
- this.deleteDataMultipleChoice()
- return this.setState({
- responses,
- noOfPages: noOfPages - 1,
- multipleChoiceQuestions: []
- }, this.checkNextPage)
- }
- this.checkNextPage()
- }
- setSurveyWithAnswers (survey, surveyAnswer) {
- const { responses, minPagesLeft, pageOrder, id, multipleChoiceQuestions = [],
- multipleChoicesMainPageAnswers, multipleChoicesMainPages } = surveyAnswer
- const length = pageOrder.length
- const { variablePrefix } = survey
- const multipleChoiceQuestionsLength = multipleChoiceQuestions.length > 0
- ? multipleChoiceQuestions.length : 0
- this.multipleChoicesMainPageAnswers = multipleChoicesMainPageAnswers || []
- this.multipleChoicesMainPages = multipleChoicesMainPages || []
- this.setState({
- surveyAnswerId: id,
- surveyData: survey,
- pageOrder,
- responses,
- multipleChoiceQuestions,
- noOfPages: length + minPagesLeft - 1 + multipleChoiceQuestionsLength,
- pageCounter: length,
- eq5d: variablePrefix === 'eq_5d',
- loading: false,
- copyResponses: JSON.stringify(responses),
- errorCode: null
- }, this.checkNextPage)
- }
- setSurvey (survey) {
- const { pageOrder } = this.state
- const { pages, firstPage, variablePrefix } = survey
- pageOrder.length = 0
- pageOrder.push(survey.firstPage)
- this.setState({
- surveyData: survey,
- surveyStartedAt: Moment().format(dateFormat),
- noOfPages: pages[firstPage].minPages,
- eq5d: variablePrefix === 'eq_5d',
- loading: false,
- nextPage: survey.firstPage,
- errorCode: null,
- responses: {},
- pageCounter: 1
- })
- }
- onSurveySuccess (surveyResponse) {
- const { survey, surveyAnswer } = surveyResponse
- const expired = surveyAnswer && surveyAnswer.status === 'expired'
- if (surveyAnswer && !expired) return this.setSurveyWithAnswers(survey, surveyAnswer)
- this.setSurvey(survey)
- }
- onSurveyModalPressed = value => {
- const { surveyError } = this.props
- if (surveyError) return this.props.goBack()
- this.setState({ leaveSurvey: value })
- }
- swithThroughConditions (conditions, responses) {
- let conditionsPassed = true
- conditions.map(block => {
- // skip the other validations if there is a failed condition
- if (conditionsPassed) {
- const response = responses[block.inputId]
- conditionsPassed = validateConditions[block.condition](block, response)
- }
- })
- return conditionsPassed
- }
- getNextPage (nextPage, responses) {
- let result = null
- let conditions = null
- const conditionals = nextPage.if ? nextPage.if : null
- if (conditionals) {
- conditionals.map(cond => {
- // skip the other conditionals if a result has been found
- if (!result) {
- conditions = cond.conditions
- if (this.swithThroughConditions(conditions, responses)) result = cond
- }
- })
- if (result) return result.page
- if (nextPage.else) return nextPage.else
- return nextPage.page
- }
- return nextPage.page
- }
- hasResponseData (data) {
- if (!data) return false
- return data.value !== null && data.value !== undefined && data.value !== ''
- }
- hasItemDependencies (item, responses) {
- const { disableDependency } = item
- if (!disableDependency) return false
- let hasData = true
- disableDependency.map(dependency => {
- // if there is an undefined response the other dependencies are skipped
- if (hasData) {
- hasData = this.hasResponseData(responses[dependency])
- }
- })
- return hasData
- }
- isRequiredItem (item) { return item.input && (item.required === 1) }
- addSliderDefalutResponse (item) {
- const { id, field, parents, sliderInfo } = item
- const defaultVal = (sliderInfo && (sliderInfo.min || sliderInfo.min === 0)) ? sliderInfo.min : ''
- const response = {
- field: field,
- value: defaultVal,
- parents: parents,
- disabled: false
- }
- this.addResponse(id, response, () => {
- return true
- })
- }
- validatePageData (pageData, responses) {
- const { items } = pageData
- let isValid = true
- let timburdenPreviousItemValue = null
- items.map(item => {
- const { validation } = item
- if (item.value) timburdenPreviousItemValue = item.value
- // if an invalid response is found will skip the other checks
- if (item.sliderInfo && (item.sliderInfo.min || item.sliderInfo.min === 0) &&
- !(this.hasResponseData(responses[item.id]))) {
- return this.addSliderDefalutResponse(item)
- }
- if (isValid && this.isRequiredItem(item) &&
- (!(this.hasResponseData(responses[item.id]) || item.value || timburdenPreviousItemValue)) &&
- !this.hasItemDependencies(item, responses)) {
- if (validation === 'hours') {
- this.setState({ error: Config.surveysGeneralConfig.errorMessages['hours'] })
- } else this.setState({ error: Config.surveysGeneralConfig.errorMessages[item.input] })
- isValid = false
- }
- if (isValid && validation && validation !== 'month') {
- const value = (responses[item.id] && responses[item.id].value) || item.value
- if (!value && !this.isRequiredItem(item)) return // if no value, and field is optional => no need for validations
- if (validation === 'SSN') { // here should be added validation for popup if needed
- isValid = validateNHS(value) || validateSSN(value) //validate for UK and US
- if (!isValid) this.setState({ error: Config.surveysGeneralConfig.errorMessages['nhs'] })
- }
- }
- })
- return isValid
- }
- checkNextPage () {
- const { pageOrder, pageCounter, surveyData, responses } = this.state
- const currentPage = pageOrder[pageCounter - 1]
- const nextPage = this.getNextPage(surveyData.pages[currentPage].nextPage, responses)
- this.setState({ nextPage, error: null })
- return nextPage
- }
- processString (string) { return string.replace(/\s/g, '').toLowerCase() }
- interpretAsyncResults = ({results, status}, callback, zipCode) => {
- const { country } = this.props.localUser
- let avCountriesZipcode = false
- let zipCodeMatch = false
- let userCountry = country
- if (country === 'UK') userCountry = 'GB'
- if (status !== 'OK') return callback(status, 'zipCode')
- if (results[0] && results[0].address_components && (results[0].types[0] === 'postal_code')) {
- results[0].address_components.map(({ types, short_name }) => {
- if (types && (types[0] === 'postal_code') &&
- (this.processString(short_name) === this.processString(zipCode))) {
- zipCodeMatch = true
- }
- if (types && (types[0] === 'country') &&
- (userCountry === short_name)) {
- avCountriesZipcode = true
- }
- })
- if (avCountriesZipcode && zipCodeMatch) return callback(null)
- }
- this.setState({ error: translate('surveyItemErrors', 'zipcode') })
- return callback(status, 'zipCode')
- }
- resolveValidationPromises = (promises, callback, zipCode) => {
- let noAsyncValidation = false
- Promise.all(promises).then((results) => {
- results.forEach((response, index) => {
- if (response === 'noAsyncValidation') noAsyncValidation = true
- else return this.interpretAsyncResults(response, callback, zipCode)
- if (noAsyncValidation && index === results.length - 1) {
- return callback(null, 'no_async_validation')
- }
- })
- })
- }
- checkItemAsyncValidations = ({items}, responses, callback) => {
- const promises = []
- let zipCode = ''
- items.forEach(({id, value, field}) => {
- const usedValue = (responses[id] && typeof responses[id].value === 'string')
- ? responses[id].value
- : value
- if (field === 'zipCode') {
- const language = this.props.localUser.language
- promises.push(GoogleapisService.checkZipcode({ zipCode: usedValue, language }))
- zipCode = usedValue
- } else promises.push('noAsyncValidation')
- })
- this.resolveValidationPromises(promises, callback, zipCode)
- }
- onPressPrevious = () => {
- const { pageOrder, pageCounter } = this.state
- const currentPageNo = pageCounter
- pageOrder.pop()
- currentPageNo >= 1 && this.setState({
- pageCounter: currentPageNo - 1,
- pageOrder: pageOrder,
- error: null
- }, () => this.checkNextPage)
- }
- onPressNext = () => {
- const { pageOrder, pageCounter, surveyData, responses } = this.state
- const currentPage = pageOrder[pageCounter - 1]
- const pageData = surveyData.pages[currentPage]
- if (this.pageHasAsyncValidation(pageData)) {
- return this.checkItemAsyncValidations(pageData, responses, (err, field) => {
- if (err && field === 'zipCode') {
- return this.setState({ error: translate('surveyItemErrors', 'zipcode') })
- }
- this.validateDataAndGetNextPage(pageData, responses)
- })
- }
- this.validateDataAndGetNextPage(pageData, responses)
- }
- pageHasAsyncValidation (pageData) {
- const pageInputType = pageData.pageInputType || null
- return pageInputType && pageInputType === 'hasAsyncValidations'
- }
- leavePageCheckValidInput = (callback) => {
- const { pageOrder, pageCounter, surveyData, responses } = this.state
- const pageData = surveyData.pages[pageOrder[pageCounter - 1]]
- if (this.pageHasAsyncValidation(pageData)) {
- return this.checkItemAsyncValidations(pageData, responses, (err, field) => {
- if (err && field === 'zipCode') {
- const { id, value } = pageData.items[0]
- responses[id].value = value
- this.setState({ responses })
- }
- callback()
- })
- }
- callback()
- }
- composeResponseData = intermediary => {
- const {
- pageOrder,
- pageCounter,
- surveyData,
- responses,
- surveyStartedAt,
- multipleChoiceQuestions
- } = this.state
- const { title, version, expiresIn } = surveyData
- const { surveyId, localUser } = this.props
- const { timezoneOffset } = localUser
- const currentPage = pageOrder[pageCounter - 1]
- const newData = {
- title,
- version: version || null,
- expiresIn,
- surveyId,
- responses,
- pageOrder,
- timezoneOffset,
- multipleChoiceQuestions,
- multipleChoicesMainPages: this.multipleChoicesMainPages,
- multipleChoicesMainPageAnswers: this.multipleChoicesMainPageAnswers,
- startedAt: surveyStartedAt,
- minPagesLeft: surveyData.pages[currentPage].minPages,
- completionDate: !intermediary && Moment().format()
- }
- return newData
- }
- doNotCreadeOrUpdateSurveyAnswer (requestSource) {
- const {
- responses,
- copyResponses,
- showPopupDate
- } = this.state
- const {
- createSurveyAnswerLoading,
- updateSurveyAnswerLoading
- } = this.props
- const sameResponses = copyResponses === JSON.stringify(responses)
- const responseIsEmpty = JSON.stringify(responses) === '{}'
- // Verify if not the same response, but if there is another call in progress
- return ((sameResponses ||
- responseIsEmpty ||
- createSurveyAnswerLoading ||
- updateSurveyAnswerLoading) &&
- !showPopupDate &&
- requestSource !== 'goBack' &&
- requestSource !== 'endSurvey')
- }
- resetErrorSubmit = () => this.setState({ errorSubmittingSurvey: false })
- update (...args) { this.props.updateSurveyAnswer(...args) }
- createOrUpdateSurveyAnswer (intermediary) {
- const { surveyAnswerId, surveyWithAnswerData, updateDragDropModalValue } = this.state
- const { createSurveyAnswer, answerId, data, localUser } = this.props
- const newData = this.composeResponseData(intermediary)
- if (updateDragDropModalValue) {
- newData.showDragAndDropPopup = 'no'
- this.setState({ updateDragDropModalValue: false })
- }
- const surveyWithAnswerId = surveyWithAnswerData && surveyWithAnswerData.surveyAnswerId
- const answerSurveysId = answerId || surveyAnswerId || surveyWithAnswerId
- const { token, language } = localUser
- const params = {params: {accessToken: token, language}}
- answerSurveysId && token && (data.status !== 'expired' ||
- (surveyWithAnswerData && surveyWithAnswerData.status !== 'expired'))
- ? this.update(answerSurveysId, newData, params)
- : createSurveyAnswer(newData, params)
- }
- createResponseData (intermediary, requestSource) {
- const { surveyData } = this.state
- if (!surveyData) return
- if (requestSource === 'goBack') this.setState({goBack: true})
- else this.setState({goBack: false})
- if (this.doNotCreadeOrUpdateSurveyAnswer(requestSource)) return
- this.createOrUpdateSurveyAnswer(intermediary)
- }
- // HERE STARTS MULTIPLE CHOICE QUESTION LOGIC
- deleteMultipleChoice = () => { // 'don't know' answer
- const { noOfPages, multipleChoiceQuestions } = this.state
- const lengthMultipleChoiceElements = multipleChoiceQuestions.length
- this.deleteDataMultipleChoice()
- this.setState({
- multipleChoiceQuestions: [],
- noOfPages: noOfPages - lengthMultipleChoiceElements
- })
- }
- deleteDataMultipleChoice () {
- const { surveyData, pageOrder, pageCounter } = this.state
- const currentPage = pageOrder[pageCounter - 1]
- // temporary fix becauase it's called every time uncheck a box on any question
- if (surveyData.pages[pageOrder[pageCounter - 1]].pageInputType === 'multipleChoices') {
- this.multipleChoicesMainPages[currentPage] = {}
- this.multipleChoicesMainPageAnswers = _.pickBy(this.multipleChoicesMainPageAnswers, value => value.mainPage !== currentPage)
- }
- }
- addReponseForMultipleChoice = (response, lengthMultipleChoiceElements) => {
- const { pageOrder, pageCounter, responses, surveyData } = this.state
- const currentPage = pageOrder[pageCounter - 1]
- const data = {
- responses,
- pageData: surveyData.pages[currentPage],
- nextPage: surveyData.pages[pageOrder[pageCounter - 1]].nextPage,
- lengthMultipleChoiceElements
- }
- const optionValues = surveyData.pages[pageOrder[pageCounter - 1]].items[0].values
- const { multipleChoicePickedValues } =
- this.getMultipleChoicePickedValues(data, response.value, optionValues, { isAddResponse: true })
- return {
- mQuestions: multipleChoicePickedValues,
- lengthMultipleChoiceElements: response.value.length
- }
- }
- getLenghtMultipleChoiceOrMainArray = (multipleChoiceQuestions, mainPage, currentPage) => {
- let lengthMultipleChoiceElements = multipleChoiceQuestions.length
- let mainPageArray = Object.keys(mainPage)
- const mainPageLength = mainPageArray.length
- mainPageArray = mainPageArray.slice(mainPageArray.indexOf(currentPage) + 1, mainPageLength)
- if (mainPageLength > 3) lengthMultipleChoiceElements = mainPageArray.length
- return lengthMultipleChoiceElements
- }
- updateStateAndCheckNextPage = (data) => this.setState(data, () => this.checkNextPage())
- getMultipleChoicePickedValues = (data, pickedValues, allPossibleValues, isAddResponse) => {
- const { pageData } = data
- const { pageOrder, pageCounter } = this.state
- const currentPage = pageOrder[pageCounter - 1]
- const multipleChoicePickedValues = []
- allPossibleValues.map((allValue, index) => {
- pickedValues.map(pickedValue => {
- if (allValue === pickedValue) {
- multipleChoicePickedValues.push(pageData.multipleChoiceQuestions[index])
- }
- })
- })
- this.refreshMainPageAnswers(multipleChoicePickedValues, currentPage)
- const isInPageOrder = pageOrder.findIndex(val => val === multipleChoicePickedValues[0])
- const newLength = multipleChoicePickedValues.length
- if (isInPageOrder < 0 && !isAddResponse) {
- pageOrder.push(multipleChoicePickedValues[0])
- multipleChoicePickedValues.splice(0, 1)
- }
- return { multipleChoicePickedValues, newLength }
- }
- refreshMainPageAnswers (pickedValues, currentPage) {
- this.multipleChoicesMainPages[currentPage] = {}
- const newAnswers = {}
- newAnswers[currentPage] = { nextPage: pickedValues[0] }
- pickedValues.forEach((object, index) => {
- newAnswers[object] = { nextPage: pickedValues[index + 1] }
- if (!this.multipleChoicesMainPageAnswers[object]) {
- this.multipleChoicesMainPageAnswers[object] = { mainPage: currentPage }
- }
- })
- this.multipleChoicesMainPages[currentPage] = newAnswers
- }
- updatePageProgressIfPickedValues = (data, pickedValues) => {
- const { nextPage } = data
- const { pageOrder, pageCounter, surveyData } = this.state
- const allPossibleValues = surveyData.pages[pageOrder[pageCounter - 1]].items[0].values
- const {
- multipleChoicePickedValues,
- newLength
- } = this.getMultipleChoicePickedValues(data, pickedValues, allPossibleValues)
- const stateData = {
- multipleChoiceQuestions: multipleChoicePickedValues,
- pageCounter: pageCounter + 1,
- pageOrder,
- noOfPages: surveyData.pages[nextPage].minPages + pageCounter + newLength
- }
- this.updateStateAndCheckNextPage(stateData)
- }
- updatePageProgressIfMultipleQuestion = (data) => {
- const { responses, nextPage, lengthMultipleChoiceElements } = data
- const { pageOrder, pageCounter } = this.state
- const pickedValues = responses[pageOrder[pageCounter - 1] + '_item1'] &&
- responses[pageOrder[pageCounter - 1] + '_item1'].value
- if (!pickedValues) return this.updatePageProgressAnyQuestion(nextPage, lengthMultipleChoiceElements)
- this.updatePageProgressIfPickedValues(data, pickedValues)
- }
- updatePageProgressAnyQuestion = (nextPage, lengthMultipleChoiceElements) => {
- const { pageOrder, pageCounter, surveyData } = this.state
- pageOrder.push(nextPage)
- const stateData = {
- pageCounter: pageCounter + 1,
- pageOrder,
- noOfPages: surveyData.pages[nextPage].minPages + pageCounter + lengthMultipleChoiceElements
- }
- this.updateStateAndCheckNextPage(stateData)
- }
- getLenghtAndUpdateMultipleChoice = (multipleChoiceQuestions, mainPage, currentPage) => {
- multipleChoiceQuestions.splice(0, 1)
- this.setState({ multipleChoiceQuestions })
- let lengthMultipleChoiceElements = multipleChoiceQuestions.length
- let mainPageArray = Object.keys(mainPage)
- const mainPageLength = mainPageArray.length
- mainPageArray = mainPageArray.slice(mainPageArray.indexOf(currentPage) + 2, mainPageLength)
- if (mainPageLength > 3) lengthMultipleChoiceElements = mainPageArray.length
- return lengthMultipleChoiceElements
- }
- validateDataAndGetNextPage = (pageData, responses) => {
- const { multipleChoiceQuestions, pageOrder, pageCounter } = this.state
- const currentPage = pageOrder[pageCounter - 1]
- let lengthMultipleChoiceElements = 0
- if (!this.validatePageData(pageData, responses)) return false
- let nextPage = this.getNextPage(pageData.nextPage, responses)
- if (this.multipleChoicesMainPageAnswers[currentPage]) {
- const mainPage = this.multipleChoicesMainPages[this.multipleChoicesMainPageAnswers[currentPage].mainPage]
- if (mainPage[currentPage].nextPage) nextPage = mainPage[currentPage].nextPage
- lengthMultipleChoiceElements = this.getLenghtAndUpdateMultipleChoice(multipleChoiceQuestions, mainPage, currentPage)
- }
- if (pageData.pageInputType === 'multipleChoices') { // new multiple choice page
- const data = { pageData, responses, nextPage, lengthMultipleChoiceElements }
- return this.updatePageProgressIfMultipleQuestion(data)
- }
- if (nextPage) return this.updatePageProgressAnyQuestion(nextPage, lengthMultipleChoiceElements)
- // the extra check of next page it's for not selecting any option yet
- this.createResponseData(false, 'endSurvey')
- }
- // HERE ENDS MULTIPLE CHOICE QUESTION LOGIC
- renderHeader () {
- const { eq5d, pageCounter, noOfPages, surveyData } = this.state
- return (
- <SurveyHeader
- eq5d={eq5d}
- pageCounter={pageCounter}
- onBackPressed={this.onBackAndroid}
- noOfPages={noOfPages}
- surveyData={surveyData} />
- )
- }
- renderSurveyPages () {
- const {
- pageOrder,
- pageCounter,
- surveyData,
- eq5d,
- responses,
- error,
- leaveSurvey,
- loading
- } = this.state
- const { navigate } = this.props
- const currentPage = pageOrder[pageCounter - 1]
- const firstPage = surveyData.firstPage
- const pages = surveyData.pages
- const pageData = currentPage && (pages[currentPage] || pages[firstPage] || {})
- return eq5d
- ? <EQ5DSurvey
- goBack={this.goBack}
- leaveSurvey={leaveSurvey}
- onSurveyModalPressed={this.onSurveyModalPressed}
- addResponse={this.addResponse}
- deleteResponse={this.deleteResponse}
- id={currentPage}
- pageOrder={pageOrder}
- isLoading={loading}
- page={pageData}
- error={error}
- responses={responses}
- setError={this.setError} />
- : <Survey
- goBack={this.goBack}
- toggleInfoPopup={this.toggleInfoPopup}
- leaveSurvey={leaveSurvey}
- onSurveyModalPressed={this.onSurveyModalPressed}
- error={error}
- addResponse={this.addResponse}
- deleteResponse={this.deleteResponse}
- id={currentPage}
- pageOrder={pageOrder}
- isLoading={loading}
- navigate={navigate}
- deleteMultipleChoice={this.deleteMultipleChoice}
- page={pageData}
- responses={responses}
- setError={this.setError}
- createTimeburdenSpecialAnswer={this.createTimeburdenSpecialAnswer} />
- }
- renderBottomControls () {
- const {
- pageCounter,
- surveyData,
- eq5d,
- nextPage,
- noOfPages,
- loading,
- errorSubmittingSurvey
- } = this.state
- const isLastPage = pageCounter === noOfPages && typeof nextPage !== 'string'
- return eq5d
- ? <EQ5DNavigationControl
- eq5d={eq5d}
- isFirstPage={ pageCounter < 2 }
- isLastPage={isLastPage}
- loading={loading}
- errorSubmit={errorSubmittingSurvey}
- buttonInfo={surveyData}
- onPressNext={this.onPressNext}
- onPressPrevious={this.onPressPrevious} />
- : <SurveyNavigationControl
- eq5d={eq5d}
- isFirstPage={ pageCounter < 2 }
- isLastPage={isLastPage}
- loading={loading}
- resetErrorSubmit={this.resetErrorSubmit}
- errorSubmit={errorSubmittingSurvey}
- buttonInfo={surveyData}
- onPressNext={this.onPressNext}
- onPressPrevious={this.onPressPrevious} />
- }
- renderLoadingSurveyData () {
- const { surveyLoading } = this.props
- const { getSurveyError } = this.state
- const { text, icon, error, button } = Config.loadingConfig.loading
- let loadingMessage = text
- if (getSurveyError) loadingMessage = error
- if (surveyLoading) loadingMessage = text
- return (
- <LoadingSurvey
- loadingImage={icon}
- loadingError={getSurveyError && !surveyLoading}
- button={button}
- onButtonPressed={() => this.getSurveyFromBackend()}
- message={loadingMessage} />
- )
- }
- renderSurveyStatus () {
- const { data, goBack, surveyError } = this.props
- const {
- pageCounter,
- noOfPages,
- surveyCompleted,
- surveyData,
- thankYouScreenData
- } = this.state
- const surveyDataInfo = Object.keys(data).length ? data : surveyData
- const { surveyLoading } = this.props
- console.log(this.state, { data })
- return (
- <SurveyStatus
- loadingData={surveyLoading}
- surveyError={surveyError}
- goToSurvey={this.setResumeSurveyValue}
- surveyCompleted={surveyCompleted}
- pageCounter={pageCounter}
- noOfPages={noOfPages}
- goBack={goBack}
- surveyData={surveyDataInfo}
- thankYouScreen={thankYouScreenData} />
- )
- }
- renderInfoPopup = () => {
- const { showInfoPopup, firstTimePopup } = this.state
- if (showInfoPopup) {
- return (
- <InfoPopup
- firstTimePopup={firstTimePopup}
- onCloseFirstTimePopup={this.onCloseFirstTimePopup}
- onPopupShown={this.toggleInfoPopup} />
- )
- }
- }
- renderOfflineNotifier () {
- return (
- <OfflineNotifier
- text={translate('general', 'noInternetConnection')}
- />
- )
- }
- renderSurveyContent () {
- const { surveyLoading, surveyError } = this.props
- const { eq5d, surveyData } = this.state
- const backgroundColor = eq5d
- ? Styles.mainColors.WHITE
- : Styles.mainColors.SCREEN_DEFAULT_BACKGROUND_COLOR
- return (
- <View style={{ height: screen.height, backgroundColor }}>
- {this.renderHeader()}
- {this.renderOfflineNotifier()}
- {(surveyLoading || surveyError || !surveyData) && this.renderLoadingSurveyData()}
- {!surveyLoading && surveyData && this.renderSurveyPages()}
- {this.renderInfoPopup()}
- {!surveyLoading && surveyData && this.renderBottomControls()}
- </View>
- )
- }
- render () {
- const { data } = this.props
- const { resumeSurvey, surveyCompleted, surveyAnswerId, surveyData } = this.state
- const answerSurveysId = (data && data.answerId) || surveyAnswerId
- if ((surveyAnswerId && surveyData && !resumeSurvey) ||
- (answerSurveysId && !resumeSurvey) || surveyCompleted) {
- return this.renderSurveyStatus()
- }
- return this.renderSurveyContent()
- }
- }
- const mapStateToProps = state => {
- return {
- ...getSelectors(surveySelector, 'surveySelector', state),
- ...getSelectors(createSurveyAnswerSelector, 'createSurveyAnswerSelector', state),
- ...getSelectors(updateSurveyAnswerSelector, 'updateSurveyAnswerSelector', state),
- ...getSelectors(surveyListSelector, 'surveyListSelector', state),
- localUser: userSelector(state) || {}
- }
- }
- const mapDispatchToProps = {
- getSurvey,
- getSurveyList,
- createSurveyAnswer,
- updateSurveyAnswer,
- deleteConsentData,
- setLocalUser,
- setUser
- }
- export default connect(mapStateToProps, mapDispatchToProps)(SurveyContainer)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement