Skip to content
Snippets Groups Projects
ChallengeCardOnGoing.tsx 10.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bastien DUMONT's avatar
    Bastien DUMONT committed
    import defaultChallengeIcon from 'assets/icons/visu/challenge/CHALLENGE0001.svg'
    import circleChecked from 'assets/icons/visu/challenge/circleChecked.svg'
    import circleUnchecked from 'assets/icons/visu/challenge/circleUnchecked.svg'
    import circleStar from 'assets/icons/visu/duel/circleStar.svg'
    import defaultIcon from 'assets/icons/visu/duel/default.svg'
    import duelLocked from 'assets/icons/visu/duel/locked.svg'
    import classNames from 'classnames'
    import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import Loader from 'components/Loader/Loader'
    
    import { Client, useClient } from 'cozy-client'
    
    import { useI18n } from 'cozy-ui/transpiled/react/I18n'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { UserActionState } from 'enum/userAction.enum'
    import { UserChallengeUpdateFlag } from 'enum/userChallenge.enum'
    import { UserDuelState } from 'enum/userDuel.enum'
    import { UserExplorationState } from 'enum/userExploration.enum'
    import { UserQuizState } from 'enum/userQuiz.enum'
    import { UserChallenge } from 'models'
    import React, { useCallback, useEffect, useState } from 'react'
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
    import { useDispatch, useSelector } from 'react-redux'
    
    import { useHistory } from 'react-router-dom'
    
    import ChallengeService from 'services/challenge.service'
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
    import { AppStore } from 'store'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import { updateUserChallengeList } from 'store/challenge/challenge.actions'
    import { getChallengeTitleWithLineReturn, importIconbyId } from 'utils/utils'
    import './challengeCardOnGoing.scss'
    
    import ChallengeNoFluidModal from './ChallengeNoFluidModal'
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    import StarsContainer from './StarsContainer'
    
    interface ChallengeCardOnGoingProps {
    
      userChallenge: UserChallenge
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
    }
    
    const ChallengeCardOnGoing: React.FC<ChallengeCardOnGoingProps> = ({
    
    }: ChallengeCardOnGoingProps) => {
    
      const client: Client = useClient()
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
      const { t } = useI18n()
    
      const dispatch = useDispatch()
      const history = useHistory()
    
      const [isOneFluidUp, setIsOneFluidUp] = useState<boolean>(true)
      const [challengeIcon, setChallengeIcon] = useState<string>(defaultIcon)
      const [isDone, setisDone] = useState<boolean>(false)
      const [isLoading, setIsLoading] = useState<boolean>(false)
    
      const {
        challenge: { currentDataload },
        global: { fluidTypes, fluidStatus },
      } = useSelector((state: AppStore) => state.ecolyo)
    
      const toggleNoFluidModal = useCallback(() => {
        setIsOneFluidUp(prev => !prev)
      }, [])
    
      const goDuel = async () => {
    
        setIsLoading(true)
    
        //Check if at least one fluid is up
        if (fluidTypes.length !== 0) {
          if (userChallenge.duel.state !== UserDuelState.ONGOING) {
            const challengeService = new ChallengeService(client)
            const updatedChallenge = await challengeService.updateUserChallenge(
              userChallenge,
    
              UserChallengeUpdateFlag.DUEL_UPDATE_THRESHOLD,
              undefined,
              fluidStatus
    
            )
            dispatch(updateUserChallengeList(updatedChallenge))
          }
    
          setIsLoading(false)
    
          history.push('/challenges/duel?id=' + userChallenge.id)
    
          setIsLoading(false)
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
      const goQuiz = async () => {
    
        if (userChallenge.quiz.state !== UserQuizState.ONGOING) {
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
          const challengeService = new ChallengeService(client)
          const updatedChallenge = await challengeService.updateUserChallenge(
            userChallenge,
    
            UserChallengeUpdateFlag.QUIZ_RESET
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
          )
          dispatch(updateUserChallengeList(updatedChallenge))
        }
    
        if (userChallenge.progress.quizProgress !== 5)
          history.push('/challenges/quiz')
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
      }
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
      const goExploration = () => {
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
        if (userChallenge.progress.explorationProgress !== 5)
          history.push('/challenges/exploration')
      }
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
      const goAction = () => {
        if (userChallenge.progress.actionProgress !== 5)
          history.push('/challenges/action')
      }
    
      useEffect(() => {
    
        let subscribed = true
        async function importIcon() {
          importIconbyId(userChallenge.id, 'challenge').then(icon => {
            if (subscribed) {
              icon ? setChallengeIcon(icon) : setChallengeIcon(defaultChallengeIcon)
            }
          })
        }
        importIcon()
        return () => {
          subscribed = false
        }
    
      }, [userChallenge])
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
      useEffect(() => {
        const challengeService = new ChallengeService(client)
        let subscribed = true
        async function setChallengeResult() {
    
    unknown's avatar
    unknown committed
          const isChallengeDone = await challengeService.isChallengeDone(
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
            userChallenge,
            currentDataload
          )
          if (subscribed) {
    
    unknown's avatar
    unknown committed
            setisDone(isChallengeDone.isDone)
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
        const unlockDuel = async () => {
          if (
            userChallenge.duel.state === UserDuelState.LOCKED &&
            userChallenge.progress.actionProgress === 5 &&
            userChallenge.progress.quizProgress === 5 &&
            userChallenge.progress.explorationProgress === 5
          ) {
            const updatedChallenge = await challengeService.updateUserChallenge(
              {
                ...userChallenge,
                progress: {
                  ...userChallenge.progress,
                  explorationProgress: 5,
                  actionProgress: 5,
                },
              },
              UserChallengeUpdateFlag.DUEL_UNLOCK
            )
            dispatch(updateUserChallengeList(updatedChallenge))
          }
        }
        unlockDuel()
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
        setChallengeResult()
        return () => {
          subscribed = false
        }
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
      }, [client, currentDataload, userChallenge, dispatch])
    
      return (
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
        <div className="cardContent onGoing">
          <div className="titleBlock">
    
            <span className="challengeTitle">
              {getChallengeTitleWithLineReturn(userChallenge.id)}
            </span>
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
          </div>
    
    Hugo's avatar
    Hugo committed
          <button
            title={t('challenge.card.ongoing.quiz')}
            tabIndex={userChallenge.progress.quizProgress === 5 ? -1 : 0}
    
            className={classNames('smallCard', {
    
              ['finished']: userChallenge.progress.quizProgress === 5,
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
            onClick={goQuiz}
    
            <StyledIcon
              className="cardIcon"
              icon={
    
                userChallenge.progress.quizProgress === 5
                  ? circleChecked
                  : circleUnchecked
    
              }
              size={25}
            />
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
            <div className="content">
    
              <span>{t('challenge.card.ongoing.quiz')}</span>
    
              <StarsContainer result={userChallenge.progress.quizProgress} />
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
            </div>
    
    Hugo's avatar
    Hugo committed
          </button>
          <button
            title={t('challenge.card.ongoing.exploration')}
            tabIndex={userChallenge.progress.explorationProgress === 5 ? -1 : 0}
    
            className={classNames('smallCard explorationCard', {
    
              ['finished']: userChallenge.progress.explorationProgress === 5,
    
    Rémi PAPIN's avatar
    Rémi PAPIN committed
            onClick={goExploration}
    
            <StyledIcon
              className="cardIcon"
    
                userChallenge.progress.explorationProgress === 5
    
                  ? circleChecked
                  : circleUnchecked
              }
    
              size={25}
            />
    
            {userChallenge.exploration.state ===
              UserExplorationState.NOTIFICATION && (
              <div className="notifChallenge">1</div>
            )}
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
            <div className="content">
    
              <span>{t('challenge.card.ongoing.exploration')}</span>
              <StarsContainer result={userChallenge.progress.explorationProgress} />
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
            </div>
    
    Hugo's avatar
    Hugo committed
          </button>
          <button
            title={t('challenge.card.ongoing.action')}
            tabIndex={userChallenge.progress.actionProgress === 5 ? -1 : 0}
    
            className={classNames('smallCard actionCard', {
    
              ['finished']: userChallenge.progress.actionProgress === 5,
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
            onClick={goAction}
    
            <StyledIcon
              className="cardIcon"
    
              icon={
                userChallenge.progress.actionProgress === 5
                  ? circleChecked
                  : circleUnchecked
              }
    
              size={25}
            />
    
            {userChallenge.action.state === UserActionState.NOTIFICATION && (
              <div className="notifChallenge">1</div>
            )}
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
            <div className="content">
    
              <span>{t('challenge.card.ongoing.action')}</span>
    
              <StarsContainer result={userChallenge.progress.actionProgress} />
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
            </div>
    
    Hugo's avatar
    Hugo committed
          </button>
    
          {(userChallenge.progress.actionProgress +
    
            userChallenge.progress.explorationProgress +
    
            userChallenge.progress.quizProgress >=
            userChallenge.target &&
    
            userChallenge.duel.state === UserDuelState.UNLOCKED) ||
          userChallenge.duel.state === UserDuelState.NO_REF_PERIOD_VALID ? (
    
            <button className="smallCard goDuel" onClick={goDuel}>
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
                <div className="spinner-container">
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
                  <Loader color="black" />
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
                </div>
    
              ) : (
                <>
                  {t('challenge.card.ongoing.duel')}
                  <StyledIcon
                    className="challengeminIcon"
                    icon={challengeIcon}
                    size={60}
                  />
                </>
              )}
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
          ) : userChallenge.duel.state === UserDuelState.ONGOING && !isDone ? (
    
    Yoan VALLET's avatar
    Yoan VALLET committed
            <div className={'smallCard duelCard active'} onClick={goDuel}>
    
              <div className="finalDuel">
    
                <span>{t('challenge.card.ongoing.duel')}</span>
    
                <p className="starCount">
    
    Yoan VALLET's avatar
    Yoan VALLET committed
                  <span className="blueNumber">{`${userChallenge.duel.userConsumption} €  `}</span>
                  <span>{` / ${userChallenge.duel.threshold} €`}</span>
    
              <StyledIcon className="circleStar" icon={challengeIcon} size={60} />
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
          ) : userChallenge.duel.state === UserDuelState.ONGOING && isDone ? (
            <div className={'smallCard duelCard active'} onClick={goDuel}>
              <div className="finalDuel result">
                <span>{t('challenge.card.ongoing.result')}</span>
                <span>{t('challenge.card.ongoing.duelDone')}</span>
              </div>
              <StyledIcon className="duelLocked" icon={challengeIcon} size={60} />
    
    Yoan VALLET's avatar
    Yoan VALLET committed
              <div className="notifChallenge">1</div>
    
    Yoan VALLET's avatar
    Yoan VALLET committed
            <div className={'smallCard duelCard'}>
    
              <p className="starCount">
                <StyledIcon icon={circleStar} size={30} />
    
                <span className="blueNumber">{`${
                  userChallenge.progress.quizProgress +
    
                  userChallenge.progress.explorationProgress +
    
                  userChallenge.progress.actionProgress
                }  `}</span>
    
                <span>{` / ${userChallenge.target}`}</span>
    
              </p>
              <StyledIcon className="duelLocked" icon={duelLocked} size={60} />
    
    Guilhem CARRON's avatar
    Guilhem CARRON committed
          )}
    
          <ChallengeNoFluidModal
            open={!isOneFluidUp}
            handleCloseClick={toggleNoFluidModal}
          />
    
    export default ChallengeCardOnGoing