Newer
Older
import { Button } from '@material-ui/core'
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 lockedDuel from 'assets/icons/visu/duel/locked.svg'
import classNames from 'classnames'
import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
import StarsContainer from 'components/CommonKit/StarsContainer/StarsContainer'
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
import {
UserActionState,
UserChallengeUpdateFlag,
UserDuelState,
UserExplorationState,
UserQuizState,
} from 'enums'
import React, { useEffect, useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import ChallengeService from 'services/challenge.service'
import { updateUserChallengeList } from 'store/challenge/challenge.slice'
import { useAppDispatch, useAppSelector } from 'store/hooks'
import { getChallengeTitleWithLineReturn, importIconById } from 'utils/utils'
import ChallengeNoFluidModal from '../ChallengeNoFluidModal/ChallengeNoFluidModal'
const navigate = useNavigate()
const dispatch = useAppDispatch()
const {
challenge: { currentDataload },
global: { fluidTypes, fluidStatus },
} = useAppSelector(state => state.ecolyo)
const [noFluidConnected, setNoFluidConnected] = useState<boolean>(false)
const [challengeIcon, setChallengeIcon] = useState<string>(defaultIcon)
const [isDone, setIsDone] = useState<boolean>(false)
const [isLoading, setIsLoading] = useState<boolean>(false)
const {
progress: { actionProgress, explorationProgress, quizProgress },
target,
duel,
} = userChallenge
const quizFinished = userChallenge.progress.quizProgress === 5
const explorationFinished = userChallenge.progress.explorationProgress === 5
const actionFinished = userChallenge.progress.actionProgress === 5
const challengeService = useMemo(() => new ChallengeService(client), [client])
// Check if at least one fluid is up
if (fluidTypes.length !== 0) {
if (userChallenge.duel.state !== UserDuelState.ONGOING) {
const updatedChallenge = await challengeService.updateUserChallenge(
userChallenge,
UserChallengeUpdateFlag.DUEL_UPDATE_THRESHOLD,
undefined,
fluidStatus
)
dispatch(updateUserChallengeList(updatedChallenge))
}
navigate(`/challenges/duel?id=${userChallenge.id}`)
} else {
if (userChallenge.quiz.state !== UserQuizState.ONGOING) {
const updatedChallenge = await challengeService.updateUserChallenge(
userChallenge,
UserChallengeUpdateFlag.QUIZ_RESET
if (userChallenge.progress.quizProgress !== 5) navigate('/challenges/quiz')
if (userChallenge.progress.explorationProgress !== 5)
navigate('/challenges/exploration')
const goAction = () => {
if (userChallenge.progress.actionProgress !== 5)
navigate('/challenges/action')
importIconById(userChallenge.id, 'challenge').then(icon => {
icon ? setChallengeIcon(icon) : setChallengeIcon(defaultChallengeIcon)
return () => {
subscribed = false
}
const isChallengeDone = challengeService.isChallengeDone(
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()
}, [currentDataload, userChallenge, dispatch, challengeService])
title={t('challenge.card.ongoing.quiz')}
tabIndex={quizFinished ? -1 : 0}
})}
onClick={goQuiz}
>
<StyledIcon
className="cardIcon"
icon={quizFinished ? circleChecked : circleUnchecked}
size={25}
/>
<div className="content">
<span>{t('challenge.card.ongoing.quiz')}</span>
<StarsContainer result={userChallenge.progress.quizProgress} />
)
const explorationButton = () => (
title={t('challenge.card.ongoing.exploration')}
tabIndex={explorationFinished ? -1 : 0}
className={classNames('smallCard explorationCard', {
['finished']: explorationFinished,
})}
onClick={goExploration}
>
<StyledIcon
className="cardIcon"
icon={explorationFinished ? circleChecked : circleUnchecked}
size={25}
/>
{userChallenge.exploration.state ===
UserExplorationState.NOTIFICATION && (
<div className="notifChallenge">1</div>
)}
<div className="content">
<span>{t('challenge.card.ongoing.exploration')}</span>
<StarsContainer result={userChallenge.progress.explorationProgress} />
</div>
title={t('challenge.card.ongoing.action')}
tabIndex={actionFinished ? -1 : 0}
className={classNames('smallCard actionCard', {
['finished']: actionFinished,
})}
onClick={goAction}
>
<StyledIcon
className="cardIcon"
icon={actionFinished ? circleChecked : circleUnchecked}
size={25}
/>
{userChallenge.action.state === UserActionState.NOTIFICATION && (
<div className="notifChallenge">1</div>
)}
<div className="content">
<span>{t('challenge.card.ongoing.action')}</span>
<StarsContainer result={userChallenge.progress.actionProgress} />
</div>
<Button className="smallCard goDuel" onClick={goDuel}>
{isLoading ? (
<div className="spinner-container">
<Loader color="black" />
) : (
<>
{t('challenge.card.ongoing.duel')}
<StyledIcon
className="challengeminIcon"
icon={challengeIcon}
size={60}
/>
</>
)}
)
const duelCard = (content: JSX.Element, extraClassName = '') => (
<Button className={`smallCard duelCard ${extraClassName}`} onClick={goDuel}>
{content}
<StyledIcon className="circleStar" icon={challengeIcon} size={60} />
)
const duelContainer = () => {
if (
duel.state === UserDuelState.NO_REF_PERIOD_VALID ||
(actionProgress + explorationProgress + quizProgress >= target &&
duel.state === UserDuelState.UNLOCKED)
) {
return duelButton
} else if (duel.state === UserDuelState.ONGOING && !isDone) {
return duelCard(
<div className="finalDuel">
<span>{t('challenge.card.ongoing.duel')}</span>
<p className="starCount">
<span className="blueNumber">{`${duel.userConsumption} € `}</span>
<span>{` / ${duel.threshold} €`}</span>
</p>
</div>,
'active'
)
} else if (duel.state === UserDuelState.ONGOING && isDone) {
return duelCard(
<>
<div className="finalDuel result">
<span>{t('challenge.card.ongoing.result')}</span>
<span className="lowercase">
{t('challenge.card.ongoing.duelDone')}
</span>
<Button className="smallCard duelCard duelLocked" disabled>
<div className="starCount">
<StyledIcon icon={circleStar} size={30} />
<span className="blueNumber">
{quizProgress + explorationProgress + actionProgress}
</span>
<span>{` / ${target}`}</span>
</div>
<StyledIcon className="circleStar" icon={lockedDuel} size={60} />
</Button>
)
}
}
return (
<div className="cardContent onGoing">
<div className="titleBlock">
<span className="challengeTitle">
{getChallengeTitleWithLineReturn(userChallenge.id)}
</span>
</div>
{quizButton()}
{explorationButton()}
{actionButton()}
{duelContainer()}
open={noFluidConnected}
handleCloseClick={() => setNoFluidConnected(false)}
export default ChallengeCardOnGoing