diff --git a/src/components/CommonKit/Button/StyledButtonValid.tsx b/src/components/CommonKit/Button/StyledButtonValid.tsx index b7383291700898a61d99b2f753493fb241d58f1b..349cc268d2dbb2c4a1470a33b5b938c67957081d 100644 --- a/src/components/CommonKit/Button/StyledButtonValid.tsx +++ b/src/components/CommonKit/Button/StyledButtonValid.tsx @@ -45,6 +45,9 @@ const BaseButton = withStyles({ fontSize: '1rem', lineHeight: '120%', }, + disabled: { + opacity: '0.4', + }, })(MuiButton) const PrimaryButton = withStyles({ @@ -55,6 +58,9 @@ const PrimaryButton = withStyles({ color: 'var(--textBlack)', fontWeight: 'bold', }, + disabled: { + background: 'var(--blueBackground) !important', + }, })(BaseButton) const SecondaryButton = withStyles({ diff --git a/src/components/ContainerComponents/ViewContainer/AvailableChallengeDetailsViewContainer.tsx b/src/components/ContainerComponents/ViewContainer/AvailableChallengeDetailsViewContainer.tsx index d9c4c0deaae82aa8034a97e6256581ddef929a50..27f2683314cfe8141e958b7e20cc64e1519c518d 100644 --- a/src/components/ContainerComponents/ViewContainer/AvailableChallengeDetailsViewContainer.tsx +++ b/src/components/ContainerComponents/ViewContainer/AvailableChallengeDetailsViewContainer.tsx @@ -13,6 +13,8 @@ import { Client, withClient } from 'cozy-client' import StyledButtonValid from 'components/CommonKit/Button/StyledButtonValid' import { ScreenType } from 'enum/screen.enum' import AvailableChallengeIcon from 'assets/png/badges/available-big.png' +import ConsumptionDataManager from 'services/consumptionDataManagerService' +import { DateTime } from 'luxon' interface AvailableChallengeDetailsViewProps { location: any @@ -27,11 +29,16 @@ const AvailableChallengeDetailsViewContainer: React.FC<AvailableChallengeDetails const t = props.t const client = props.client const challengeManager = new ChallengeManager(client) - const { refreshCurrentChallenge, screenType } = useContext(AppContext) + const { refreshCurrentChallenge, screenType, fluidTypes } = useContext( + AppContext + ) const [redirect, setRedirect] = useState(false) const [challenge, setChallenge] = useState<ChallengeType | null>(null) const [userChallenge, setUserChallenge] = useState<UserChallenge | null>(null) const [headerHeight, setHeaderHeight] = useState<number>(0) + const [lackOfDataForChallenge, setLackOfDataForChallenge] = useState<boolean>( + false + ) const defineHeaderHeight = (height: number) => { setHeaderHeight(height) @@ -41,7 +48,7 @@ const AvailableChallengeDetailsViewContainer: React.FC<AvailableChallengeDetails if (challenge) { const data = await challengeManager.startChallenge( challenge, - [0, 1, 2], + fluidTypes, challenge.availableEcogestures ) const chal = await challengeManager.getCurrentChallenge() @@ -69,6 +76,33 @@ const AvailableChallengeDetailsViewContainer: React.FC<AvailableChallengeDetails } useEffect(() => { + const lag = challengeManager.getLagDays(fluidTypes) + + const timePeriod = { + startDate: DateTime.local() + .plus({ days: -6 }) + .startOf('day'), + endDate: DateTime.local() + .plus({ days: -lag }) + .endOf('day'), + } + + async function checkPreviousData() { + const cdm = new ConsumptionDataManager(client) + const fetchedPerformanceIndicators = await cdm.getPerformanceIndicators( + timePeriod, + 20, + fluidTypes + ) + if (fetchedPerformanceIndicators) { + fetchedPerformanceIndicators.forEach(element => { + !element.value ? setLackOfDataForChallenge(true) : null + }) + } else { + setLackOfDataForChallenge(true) + } + } + checkPreviousData() if (props.location.state) { setChallenge(props && props.location.state.challenge) } @@ -114,6 +148,7 @@ const AvailableChallengeDetailsViewContainer: React.FC<AvailableChallengeDetails </div> <div className="cp-right-button"> <StyledButtonValid + disabled={lackOfDataForChallenge} color="primary" onClick={handleStartClick} > @@ -122,6 +157,11 @@ const AvailableChallengeDetailsViewContainer: React.FC<AvailableChallengeDetails </StyledButtonValid> </div> </div> + <div className="lack-of-data-challenge"> + {lackOfDataForChallenge + ? t('CHALLENGE.LACK_OF_DATA') + : null} + </div> </div> </div> </div> diff --git a/src/components/ContainerComponents/ViewContainer/HomeViewContainer.tsx b/src/components/ContainerComponents/ViewContainer/HomeViewContainer.tsx index c1a4e4a76488678ad88bc5977307d59c2d02e0be..b17278c282a74a8a5893064dcca49042eb6791df 100644 --- a/src/components/ContainerComponents/ViewContainer/HomeViewContainer.tsx +++ b/src/components/ContainerComponents/ViewContainer/HomeViewContainer.tsx @@ -1,4 +1,4 @@ -import React, { useState, useContext } from 'react' +import React, { useState, useContext, useEffect } from 'react' import StyledSpinner from 'components/CommonKit/Spinner/StyledSpinner' import CozyBar from 'components/ContainerComponents/CozyBar/CozyBar' import Header from 'components/ContainerComponents/Header/Header' @@ -12,9 +12,12 @@ import ChallengeCardContainer from 'components/ContainerComponents/ChallengeCard import KonnectorViewerContainer from 'components/ContainerComponents/KonnectorViewerContainer/KonnectorViewerContainer' const HomeViewContainer: React.FC = () => { - const { fluidTypes, previousTimeStep, setPreviousTimeStep } = useContext( - AppContext - ) + const { + fluidTypes, + previousTimeStep, + setPreviousTimeStep, + chartIsLoaded, + } = useContext(AppContext) const [timeStep, setTimeStep] = useState<TimeStep>( previousTimeStep && previousTimeStep !== TimeStep.HALF_AN_HOUR ? previousTimeStep @@ -65,24 +68,32 @@ const HomeViewContainer: React.FC = () => { /> </Header> <Content height={headerHeight}> - {(isChartLoading || isIndicatorsLoading) && ( + {(isChartLoading || isIndicatorsLoading || !chartIsLoaded) && ( <div className="content-view-loading"> <StyledSpinner size="5em" /> </div> )} - <FluidContainer - timeStep={timeStep} - fluidTypes={fluidTypes} - resetReferenceDate={resetRefenceDate} - multiFluid={true} - handleClickTimeStep={handleClickTimeStepForFluidContainer} - setChartLoaded={setChartLoaded} - /> - <MultliFluidIndicatorsContainer - timeStep={timeStep} - setIndicatorsLoaded={setIndicatorsLoaded} - /> - <ChallengeCardContainer /> + <div + className={`${ + isChartLoading || isIndicatorsLoading || !chartIsLoaded + ? 'chart-indicator-none' + : 'chart-indicator-block' + }`} + > + <FluidContainer + timeStep={timeStep} + fluidTypes={fluidTypes} + resetReferenceDate={resetRefenceDate} + multiFluid={true} + handleClickTimeStep={handleClickTimeStepForFluidContainer} + setChartLoaded={setChartLoaded} + /> + <MultliFluidIndicatorsContainer + timeStep={timeStep} + setIndicatorsLoaded={setIndicatorsLoaded} + /> + <ChallengeCardContainer /> + </div> </Content> </> ) : ( diff --git a/src/components/ContainerComponents/ViewContainer/SingleFluidViewContainer.tsx b/src/components/ContainerComponents/ViewContainer/SingleFluidViewContainer.tsx index 882df7e31342b3200032309439f28d202850df3b..9394f64f5f368eb045273a8ba4d913ff97c63d99 100644 --- a/src/components/ContainerComponents/ViewContainer/SingleFluidViewContainer.tsx +++ b/src/components/ContainerComponents/ViewContainer/SingleFluidViewContainer.tsx @@ -16,7 +16,9 @@ interface SingleFluidViewContainerProps { const SingleFluidViewContainer: React.FC<SingleFluidViewContainerProps> = ({ fluidTypes, }: SingleFluidViewContainerProps) => { - const { setPreviousTimeStep, previousTimeStep } = useContext(AppContext) + const { setPreviousTimeStep, previousTimeStep, chartIsLoaded } = useContext( + AppContext + ) const [timeStep, setTimeStep] = useState<TimeStep | null>( previousTimeStep && previousTimeStep !== TimeStep.HALF_AN_HOUR @@ -71,14 +73,16 @@ const SingleFluidViewContainer: React.FC<SingleFluidViewContainerProps> = ({ /> </Header> <Content height={headerHeight}> - {(isChartLoading || isIndicatorsLoading) && ( + {(isChartLoading || isIndicatorsLoading || !chartIsLoaded) && ( <div className="content-view-loading"> <StyledSpinner size="5em" fluidTypes={fluidTypes} /> </div> )} <div className={`${ - isChartLoading ? 'chart-indicator-none' : 'chart-indicator-display' + isChartLoading || isIndicatorsLoading || !chartIsLoaded + ? 'chart-indicator-none' + : 'chart-indicator-block' }`} > <FluidChartContainer diff --git a/src/components/ContentComponents/Challenge/FollowChallengeTimeline.tsx b/src/components/ContentComponents/Challenge/FollowChallengeTimeline.tsx index e8b3edc7b58b0113e22d46c298786d4273144daa..6cc015ff90dd0bd569bd5f4722b1b7eaf68e7ccd 100644 --- a/src/components/ContentComponents/Challenge/FollowChallengeTimeline.tsx +++ b/src/components/ContentComponents/Challenge/FollowChallengeTimeline.tsx @@ -23,7 +23,7 @@ const FollowChallengeTimeline: React.FC<FollowChallengeTimelineViewProps> = ({ if (challenge && challenge.challengeType) { const startingDate = challenge.startingDate return startingDate.plus({ - days: challengeManager.getLagDays(fluidTypes), + days: challengeManager.getLagDays(challenge.fluidTypes), }) } else { return DateTime.local() diff --git a/src/components/ContentComponents/Challenge/OngoingChallengeViewingDate.tsx b/src/components/ContentComponents/Challenge/OngoingChallengeViewingDate.tsx index f6f20ed409d389a3bafa7d01c8969388e0fe36a6..85dd1f3734738666cd4be57f06e1e93d81b275fb 100644 --- a/src/components/ContentComponents/Challenge/OngoingChallengeViewingDate.tsx +++ b/src/components/ContentComponents/Challenge/OngoingChallengeViewingDate.tsx @@ -28,7 +28,7 @@ const OngoingChallengeViewingDate: React.FC<OngoingChallengeViewingDateProps> = useEffect(() => { if (challenge) { - const lag = challengeManager.getLagDays(fluidTypes) + const lag = challengeManager.getLagDays(challenge.fluidTypes) setFirstDateWithData( challenge.startingDate.plus({ days: lag, diff --git a/src/components/ContentComponents/ChallengeList/ChallengesList.tsx b/src/components/ContentComponents/ChallengeList/ChallengesList.tsx index 46c71e6a2a1b9d196c22ba3ec965492e0fbc1269..0a5fbeed1cb1d917696fba1f69841037f9b9cf20 100644 --- a/src/components/ContentComponents/ChallengeList/ChallengesList.tsx +++ b/src/components/ContentComponents/ChallengeList/ChallengesList.tsx @@ -27,6 +27,10 @@ const ChallengesList: React.FC<ChallengesListProps> = ({ ongoingChallenge, setOngoingChallenge, ] = useState<UserChallenge | null>(null) + const [ + ongoingChallengeModal, + setOngoingChallengeModal, + ] = useState<UserChallenge | null>(null) const [challengesType, setChallengesType] = useState<ChallengeType[] | null>( null ) @@ -41,6 +45,7 @@ const ChallengesList: React.FC<ChallengesListProps> = ({ const handleCloseClick = () => { setOngoingChallenge(null) setOpenChallengeModal(false) + setOngoingChallengeModal(null) } const setRightChallengeInTheMiddle = ( @@ -97,6 +102,7 @@ const ChallengesList: React.FC<ChallengesListProps> = ({ setChallengesType(dataAllCT) setUserChallenges(dataAllUC) setOngoingChallenge(ongoingChallengeTmp) + setOngoingChallengeModal(ongoingChallengeTmp) setUserLevel(levelOfUser) if ( await challengeManager.isChallengeOver( @@ -107,6 +113,7 @@ const ChallengesList: React.FC<ChallengesListProps> = ({ setOpenChallengeModal(true) await challengeManager.endChallenge(ongoingChallengeTmp, fluidTypes) await refreshCurrentChallenge() + setOngoingChallenge(null) } } } @@ -200,9 +207,9 @@ const ChallengesList: React.FC<ChallengesListProps> = ({ )} <ChallengeModal opened={openChallengeModal} - challenge={ongoingChallenge} + challenge={ongoingChallengeModal} handleCloseClick={handleCloseClick} - badgeStatus={ongoingChallenge && ongoingChallenge.badge} + badgeStatus={ongoingChallengeModal && ongoingChallengeModal.badge} /> </> ) diff --git a/src/components/ContentComponents/ChallengeModal/ChallengeModal.tsx b/src/components/ContentComponents/ChallengeModal/ChallengeModal.tsx index a428aa8ab05a9fbfd502f0f1e49f9aaabee45c87..13cec17b7b28a4957a181419413da42d2ec7257c 100644 --- a/src/components/ContentComponents/ChallengeModal/ChallengeModal.tsx +++ b/src/components/ContentComponents/ChallengeModal/ChallengeModal.tsx @@ -90,7 +90,7 @@ const ChallengeModal: React.FC<ChallengeModalProps> = ({ {' '} {challengeId === 'CHA00000001' ? ( <> - <div className="text-18-medium"> + <div className="text-18-normal"> {t('CHALLENGE.WIN_TEXT_ECOLYO')} </div> <div className="cm-text-new-available text-18-bold"> diff --git a/src/components/ContentComponents/Charts/BarChart.tsx b/src/components/ContentComponents/Charts/BarChart.tsx index 093c301c0b6c434c3a5dcf4b34c9ad950633701b..1e2fd9ab7a39fb104abbe77498f6765f65eec53d 100644 --- a/src/components/ContentComponents/Charts/BarChart.tsx +++ b/src/components/ContentComponents/Charts/BarChart.tsx @@ -76,7 +76,7 @@ const BarChart: React.FC<BarChartProps> = (props: BarChartProps) => { const maxCompare = chartData.comparisonData ? Math.max(...chartData.comparisonData.map(d => d.value)) : 0 - max = max === -1 ? 15 : max + max = max <= 0 ? 15 : max return showCompare ? Math.max(max, maxCompare) : max } diff --git a/src/components/ContentComponents/ConsumptionVisualizer/DataloadConsumptionVisualizer.tsx b/src/components/ContentComponents/ConsumptionVisualizer/DataloadConsumptionVisualizer.tsx index 3db01de8b2a673d9361077a073bfd30f2450e3fc..af8a52377b7de0e8461aaf060f9f38b9e7b820f3 100644 --- a/src/components/ContentComponents/ConsumptionVisualizer/DataloadConsumptionVisualizer.tsx +++ b/src/components/ContentComponents/ConsumptionVisualizer/DataloadConsumptionVisualizer.tsx @@ -42,10 +42,14 @@ const DataloadConsumptionVisualizer = ({ : FluidType[fluidTypes[0]] useEffect(() => { - if (dataload && dataload.value && dataload.value === -1) { - setHasData(false) + if ((dataload && dataload.value) || (dataload && dataload.value === 0)) { + if (dataload.value === -1) { + setHasData(false) + } else { + setHasData(true) + } } else { - setHasData(true) + setHasData(false) } if ( compareDataload && @@ -72,7 +76,7 @@ const DataloadConsumptionVisualizer = ({ className={`cv-load-value ${fluidStyle.toLowerCase()}-compare chart-result`} > {formatNumberValues(compareDataload.value)} - <span className="text-18-medium">{`${t( + <span className="text-18-normal">{`${t( 'FLUID.' + fluidStyle + '.UNIT' )}`}</span> </div> @@ -100,7 +104,7 @@ const DataloadConsumptionVisualizer = ({ ltcc.Convert(dataload.value, fluidTypes[0]) ) : formatNumberValues(dataload.value)} - <span className="text-18-medium">{`${t( + <span className="text-18-normal">{`${t( 'FLUID.' + fluidStyle + '.UNIT' )}`}</span> </div> diff --git a/src/components/ContentComponents/FluidChart/FluidChartSlide.tsx b/src/components/ContentComponents/FluidChart/FluidChartSlide.tsx index 22ff38c90b2fda2f0ac2772ad92d62d50f13b718..09bddac34d0973f6863c5b4286c1848de2ab4f9e 100644 --- a/src/components/ContentComponents/FluidChart/FluidChartSlide.tsx +++ b/src/components/ContentComponents/FluidChart/FluidChartSlide.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react' +import React, { useState, useEffect, useContext } from 'react' import { DateTime } from 'luxon' import { IConsumptionDataManager, @@ -12,6 +12,7 @@ import { defineTimePeriod } from 'services/dateChartService' import { FluidType } from 'enum/fluid.enum' import BarChart from 'components/ContentComponents/Charts/BarChart' +import { AppContext } from 'components/Contexts/AppContextProvider' interface FluidChartSlideProps { index: number @@ -48,9 +49,10 @@ const FluidChartSlide: React.FC<FluidChartSlideProps> = ({ const [chartData, setChartData] = useState<IChartData>(new ChartData([])) const [isLoaded, setIsLoaded] = useState<boolean>(false) + const { setChartIsLoaded, chartIsLoaded } = useContext(AppContext) + useEffect(() => { let subscribed = true - async function loadData() { const [timePeriod, compareTimePeriod] = await Promise.all([ defineTimePeriod(referenceDate, timeStep, index), @@ -65,9 +67,11 @@ const FluidChartSlide: React.FC<FluidChartSlideProps> = ({ if (subscribed && graphData && graphData.actualData.length > 0) { setChartData(graphData) setIsLoaded(true) + setChartIsLoaded(true) } } setIsLoaded(false) + loadData() return () => { subscribed = false diff --git a/src/components/ContentComponents/Konnector/KonnectorResult.tsx b/src/components/ContentComponents/Konnector/KonnectorResult.tsx index b9f30f6410cfd8889e667c0e9f047c72fa438428..1ef6d5849c0f3740d0d4a1bc01e127706cff712f 100644 --- a/src/components/ContentComponents/Konnector/KonnectorResult.tsx +++ b/src/components/ContentComponents/Konnector/KonnectorResult.tsx @@ -41,10 +41,9 @@ const KonnectorResult: React.FC<KonnectorResultProps> = ({ const updateState = async (trigger: Trigger) => { const triggerState = await TriggerService.fetchTriggerState(client, trigger) - if (triggerState) { - setLastExecutionDate( - new Date(triggerState.last_execution).toLocaleString() - ) + + if (triggerState !== 'errored') { + setLastExecutionDate(new Date(triggerState.last_success).toLocaleString()) setStatus(triggerState.status) handleJobState(triggerState.status) await context.refreshFluidTypes() diff --git a/src/components/Contexts/AppContextProvider.tsx b/src/components/Contexts/AppContextProvider.tsx index 3d3b89b4fe08032dc51fcc82d9f45e4cb21dd5cf..55efeda0ccf15c9ce2c9880d45aa3bf904a84ba7 100644 --- a/src/components/Contexts/AppContextProvider.tsx +++ b/src/components/Contexts/AppContextProvider.tsx @@ -29,6 +29,8 @@ interface AppContextProps { setPreviousTimeStep: Function userProfile: UserProfile | null setWelcomeModalViewed: Function + chartIsLoaded: boolean + setChartIsLoaded: Function } export const AppContext = React.createContext<AppContextProps>({ @@ -52,6 +54,8 @@ export const AppContext = React.createContext<AppContextProps>({ userProfile: null, setPreviousTimeStep: () => null, setWelcomeModalViewed: () => null, + chartIsLoaded: false, + setChartIsLoaded: () => null, }) interface AppContextProviderProps { @@ -63,6 +67,7 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ children, client, }: AppContextProviderProps) => { + const [chartIsLoaded, setChartIsLoaded] = useState<boolean>(false) const [isIndexesLoading, setIndexesLoading] = useState<boolean>(false) const [isIndexesLoadingSuccess, setIndexesLoadingSuccess] = useState< boolean | null @@ -149,12 +154,13 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ const refreshCurrentChallenge = async (): Promise<boolean> => { const im = new InitDataManager(client) try { - const resultUpdateChallenge = await im.checkCurrentChallenge(fluidTypes) + const resultUpdateChallenge = await im.checkCurrentChallenge() setCurrentChallenge(resultUpdateChallenge) + if (resultUpdateChallenge) { const resultNotificationChallenge = await im.isCurrentChallengeOver( resultUpdateChallenge, - fluidTypes + resultUpdateChallenge.fluidTypes ) if (resultNotificationChallenge) { setChallengeNotification(resultNotificationChallenge) @@ -224,13 +230,13 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ // Update current challenge if exists setCurrentChallengeUpdateLoading(true) try { - const resultUpdateChallenge = await im.checkCurrentChallenge( - resultFluidTypes ? resultFluidTypes : [] - ) + const resultUpdateChallenge = await im.checkCurrentChallenge() if (subscribed && resultUpdateChallenge) { const resultNotificationChallenge = await im.isCurrentChallengeOver( resultUpdateChallenge, - resultFluidTypes ? resultFluidTypes : [] + resultUpdateChallenge.fluidTypes + ? resultUpdateChallenge.fluidTypes + : [] ) if (subscribed && resultNotificationChallenge) { setChallengeNotification(resultNotificationChallenge) @@ -317,6 +323,8 @@ const AppContextProvider: React.FC<AppContextProviderProps> = ({ previousTimeStep, setPreviousTimeStep, setWelcomeModalViewed, + setChartIsLoaded, + chartIsLoaded, }} > {children} diff --git a/src/locales/fr.json b/src/locales/fr.json index 8e5b55437e223d9e7d24040abd524c78be766470..de2006ddc82fcd6d9549940413b37aa6439672c5 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -168,6 +168,7 @@ "FULLY_LOCKED": "Ce défi sera disponible dans une prochaine mise à jour", "START": "Allons-y !", "NOT_NOW": "Pas maintenant !", + "LACK_OF_DATA": "Il manque des données de comparaison pour lancer ce défi", "STOP": "Arrêter le défi", "BACK": "I'll be back", "ECOGESTURE": "Voir l'écogeste", diff --git a/src/services/challengeDataManagerService.ts b/src/services/challengeDataManagerService.ts index 6da8ff4b80846bb72f731101bafd4d876e1f866d..6ee13730484d8fc5952acc8096ac1321ab4bff38 100644 --- a/src/services/challengeDataManagerService.ts +++ b/src/services/challengeDataManagerService.ts @@ -38,7 +38,7 @@ export default class ChallengeManager implements IChallengeManager { public async getMaxEnergy( challenge: UserChallenge, client: Client, - fluidTypes: FluidType[] + challengeFluidTypes: FluidType[] ) { const cdm = new ConsumptionDataManager(client) let durationTimeStep = '' @@ -55,7 +55,7 @@ export default class ChallengeManager implements IChallengeManager { const fetchedPerformanceIndicators = await cdm.getPerformanceIndicators( period, TimeStep.DAY, - fluidTypes + challengeFluidTypes ) const maxEnergy = PerformanceIndicatorAggregateCalculator.aggregatePerformanceIndicators( fetchedPerformanceIndicators @@ -69,7 +69,7 @@ export default class ChallengeManager implements IChallengeManager { public async setMaxEnergy( challenge: UserChallenge, client: Client, - fluidTypes: FluidType[] + challengeFluidTypes: FluidType[] ): Promise<number> { const cdm = new ConsumptionDataManager(client) let durationTimeStep = '' @@ -86,7 +86,7 @@ export default class ChallengeManager implements IChallengeManager { const fetchedPerformanceIndicators = await cdm.getPerformanceIndicators( period, TimeStep.DAY, - fluidTypes + challengeFluidTypes ) const maxEnergy = PerformanceIndicatorAggregateCalculator.aggregatePerformanceIndicators( fetchedPerformanceIndicators @@ -119,16 +119,16 @@ export default class ChallengeManager implements IChallengeManager { public async getSpentEnergy( challenge: UserChallenge, client: Client, - fluidTypes: FluidType[] + challengeFluidTypes: FluidType[] ) { - const lagDays = this.getLagDays(fluidTypes) + const lagDays = this.getLagDays(challengeFluidTypes) if (DateTime.local() > challenge.startingDate.plus({ days: lagDays })) { const cdm = new ConsumptionDataManager(client) const startDate = challenge.startingDate let endDate = DateTime.local() .plus({ days: -lagDays }) .endOf('day') - if (await this.isChallengeOver(challenge, fluidTypes)) { + if (await this.isChallengeOver(challenge, challengeFluidTypes)) { endDate = challenge.endingDate.plus({ days: -1 }).endOf('day') } const period = { startDate, endDate } @@ -136,7 +136,7 @@ export default class ChallengeManager implements IChallengeManager { const fetchedPerformanceIndicators = await cdm.getPerformanceIndicators( period, TimeStep.DAY, - fluidTypes + challengeFluidTypes ) const spentEnergy = PerformanceIndicatorAggregateCalculator.aggregatePerformanceIndicators( @@ -154,16 +154,16 @@ export default class ChallengeManager implements IChallengeManager { public async setSpentEnergy( challenge: UserChallenge, client: Client, - fluidTypes: FluidType[] + challengeFluidTypes: FluidType[] ): Promise<number> { - const lagDays = this.getLagDays(fluidTypes) + const lagDays = this.getLagDays(challengeFluidTypes) if (DateTime.local() > challenge.startingDate.plus({ days: lagDays })) { const cdm = new ConsumptionDataManager(client) const startDate = challenge.startingDate let endDate = DateTime.local() .plus({ days: -lagDays }) .endOf('day') - if (await this.isChallengeOver(challenge, fluidTypes)) { + if (await this.isChallengeOver(challenge, challengeFluidTypes)) { endDate = challenge.endingDate.plus({ days: -1 }).endOf('day') } const period = { startDate, endDate } @@ -171,7 +171,7 @@ export default class ChallengeManager implements IChallengeManager { const fetchedPerformanceIndicators = await cdm.getPerformanceIndicators( period, TimeStep.DAY, - fluidTypes + challengeFluidTypes ) const spentEnergy = PerformanceIndicatorAggregateCalculator.aggregatePerformanceIndicators( fetchedPerformanceIndicators @@ -340,13 +340,10 @@ export default class ChallengeManager implements IChallengeManager { * Return the date of the first day for which * we can calculate the data in function of configured fluidTypes */ - public getViewingDate = ( - challenge: UserChallenge, - fluidTypes: FluidType[] - ): DateTime => { + public getViewingDate = (challenge: UserChallenge): DateTime => { const startingDate = challenge.startingDate - if (fluidTypes.length > 0) { - const lagDays = this.getLagDays(fluidTypes) + if (challenge && challenge.fluidTypes.length > 0) { + const lagDays = this.getLagDays(challenge.fluidTypes) return startingDate.plus({ days: lagDays }) } else { return startingDate @@ -473,7 +470,8 @@ export default class ChallengeManager implements IChallengeManager { challenge, -1, -1, - -1 + -1, + fluidTypes ) const resultUserChallenge = await this._client.create( diff --git a/src/services/challengeDataMapperService.ts b/src/services/challengeDataMapperService.ts index 198957092047d279716b35bd75c3cc5b7ecea59b..c865ca78e1c5646085e235aa3f5203af44745433 100644 --- a/src/services/challengeDataMapperService.ts +++ b/src/services/challengeDataMapperService.ts @@ -19,6 +19,7 @@ export class UserChallengeEntity { currentEnergy: number badge: BadgeState relationships: any + fluidTypes: FluidType[] constructor( startingDate: string, @@ -28,6 +29,7 @@ export class UserChallengeEntity { currentEnergy: number, badge: BadgeState, relationships: any, + fluidTypes: FluidType[], _id?: string ) { this.startingDate = startingDate @@ -38,6 +40,7 @@ export class UserChallengeEntity { this.badge = badge this._id = _id this.relationships = relationships + this.fluidTypes = fluidTypes } } @@ -89,6 +92,7 @@ export default class ChallengeDataMapper { state: userChallenge.state, maxEnergy: userChallenge.maxEnergy, currentEnergy: userChallenge.currentEnergy, + fluidTypes: userChallenge.fluidTypes, relationships: { selectedEcogestures: { data: mappedEcogestures, @@ -141,6 +145,7 @@ export default class ChallengeDataMapper { userChallengeEntity.maxEnergy, userChallengeEntity.currentEnergy, userChallengeEntity.badge, + userChallengeEntity.fluidTypes, userChallengeEntity._id ) return mappedUserChallenge @@ -149,8 +154,8 @@ export default class ChallengeDataMapper { public mapToChallengeType( challengeEntity: ChallengeTypeEntity, challengeTypeEntityRelationships?: any | null, - unlockedEcogestures?: string[], - fluidTypes?: FluidType[] + unlockedEcogestures?: string[] + // fluidTypes?: FluidType[] ): ChallengeType { const completeAvailableEcogestures: any[] = [] @@ -219,15 +224,15 @@ export default class ChallengeDataMapper { public mapToChallengeTypes( challengeEntities: ChallengeTypeEntity[], challengeTypeEntityRelationships?: any | null, - unlockedEcogestures?: any, - fluidTypes?: FluidType[] + unlockedEcogestures?: any + // fluidTypes?: FluidType[] ): ChallengeType[] { return challengeEntities.map(challengeEntity => this.mapToChallengeType( challengeEntity, challengeTypeEntityRelationships, - unlockedEcogestures, - fluidTypes + unlockedEcogestures + // fluidTypes ) ) } diff --git a/src/services/dataChallengeContracts.ts b/src/services/dataChallengeContracts.ts index 1300951bc537335ef6e6d5848509c49d999c4a1a..766705ac0ab45e6866a32107b6866e7f24c871f9 100644 --- a/src/services/dataChallengeContracts.ts +++ b/src/services/dataChallengeContracts.ts @@ -103,6 +103,7 @@ export class UserChallenge { maxEnergy: number currentEnergy: number badge: BadgeState | null + fluidTypes: FluidType[] constructor( startingDate: DateTime, @@ -113,6 +114,7 @@ export class UserChallenge { maxEnergy: number, currentEnergy: number, badge: BadgeState | null, + fluidTypes: FluidType[], id?: string ) { this.startingDate = startingDate @@ -123,6 +125,7 @@ export class UserChallenge { this.maxEnergy = maxEnergy this.currentEnergy = currentEnergy this.badge = badge + this.fluidTypes = fluidTypes this.id = id } @@ -164,7 +167,7 @@ export interface IChallengeManager { ): Promise<UserChallenge | null> cancelChallenge(id: string): Promise<UserChallenge | null> - fulfillChallenge(challenge: UserChallenge): Promise<UserChallenge | null> + // fulfillChallenge(challenge: UserChallenge): Promise<UserChallenge | null> startChallenge( challenge: ChallengeType, @@ -176,7 +179,7 @@ export interface IChallengeManager { fluidTypes?: FluidType[] ): Promise<ChallengeType[] | null> - getUnlockedBadges(): Promise<ChallengeType[] | null> + // getUnlockedBadges(): Promise<ChallengeType[] | null> getUnlockedEcogestures(): Promise<EcogestureType[] | null> } diff --git a/src/services/initDataManagerService.ts b/src/services/initDataManagerService.ts index 3b30f88b80b03ee277e91d413adbcc9e704a9e08..194f9e022b0fd0264057bea3c2f1f8160d08354d 100644 --- a/src/services/initDataManagerService.ts +++ b/src/services/initDataManagerService.ts @@ -405,9 +405,7 @@ export default class InitDataManager { * Search for a current challenge * and update it if found */ - public async checkCurrentChallenge( - fluidTypes: FluidType[] - ): Promise<UserChallenge | null> { + public async checkCurrentChallenge(): Promise<UserChallenge | null> { try { // get the current challenge const cdm = new ChallengeDataManager(this._client) @@ -422,13 +420,13 @@ export default class InitDataManager { currentChallenge.challengeType.type === TypeChallenge.CHALLENGE ) { // Check if we are in the viewing timezone for current challenge - const viewingDate = cdm.getViewingDate(currentChallenge, fluidTypes) + const viewingDate = cdm.getViewingDate(currentChallenge) if (DateTime.local() >= viewingDate) { if (currentChallenge.maxEnergy === -1) { const maxEnergyResult = await cdm.setMaxEnergy( currentChallenge, this._client, - fluidTypes + currentChallenge.fluidTypes ) if (maxEnergyResult > 0) { currentChallenge.maxEnergy = maxEnergyResult @@ -437,7 +435,7 @@ export default class InitDataManager { const currentEnergyResult = await cdm.setSpentEnergy( currentChallenge, this._client, - fluidTypes + currentChallenge.fluidTypes ) if (currentEnergyResult) { currentChallenge.currentEnergy = currentEnergyResult diff --git a/src/styles/base/_typography.scss b/src/styles/base/_typography.scss index a65a2f753f28ddfdf0a9bbead7f459c8999c5dfc..4eb61d770ee73594e87456c93b9d360efdab7536 100644 --- a/src/styles/base/_typography.scss +++ b/src/styles/base/_typography.scss @@ -93,7 +93,7 @@ p { font-size: 1rem; line-height: 120%; } -.text-18-medium { +.text-18-normal { font-family: $text-font; font-style: normal; font-weight: 500; diff --git a/src/styles/components/_challenges.scss b/src/styles/components/_challenges.scss index 37c2cbd0a1ce82a7eaab4c8017b4506aa07e1349..0d270b0263529ce98cfcaa0d321978ee15ead4d1 100644 --- a/src/styles/components/_challenges.scss +++ b/src/styles/components/_challenges.scss @@ -511,6 +511,10 @@ width: 100%; } } + .lack-of-data-challenge { + text-align: center; + width: 90%; + } } .cp-follow { width: 90%; diff --git a/src/styles/components/_faq.scss b/src/styles/components/_faq.scss index 29f2e1c3dc44eeececd675484caab87d1ad6797e..6a2872239e6c0a128c2f23f7df3a6f0daa554c52 100644 --- a/src/styles/components/_faq.scss +++ b/src/styles/components/_faq.scss @@ -11,6 +11,9 @@ .faq-content { margin-bottom: -1rem; width: 45.75rem; + a { + text-decoration: none; + } @media #{$large-phone} { width: 100%; } @@ -42,6 +45,7 @@ .faq-card-content-title { margin: 0 1rem; align-self: center; + text-decoration: none; } } } diff --git a/src/styles/components/_fluid.scss b/src/styles/components/_fluid.scss index a1c53b76daf79a2a717da446cc17b23e0b03e8f1..270a37b2c3f0af3a11a3ec8c1b3a2cb52ef47b1a 100644 --- a/src/styles/components/_fluid.scss +++ b/src/styles/components/_fluid.scss @@ -112,10 +112,12 @@ } } .chart-indicator-none { - display: none; + visibility: hidden; + height: 0; } .chart-indicator-block { - display: block; + visibility: visible; + height: auto; } diff --git a/src/styles/components/_legalnotice.scss b/src/styles/components/_legalnotice.scss index 35d83076eb1438b0770d6fcb277a9b06710e41d3..f87acfd3d41dca7549f4012a0c58aac15f47b29f 100644 --- a/src/styles/components/_legalnotice.scss +++ b/src/styles/components/_legalnotice.scss @@ -8,6 +8,7 @@ align-items: center; justify-content: center; color: $text-white; + padding: 1.5rem; .legal-notice-content { p { color: $text-white; @@ -29,11 +30,9 @@ .ln-contact { color: $multi-color; } - padding: 1.5rem 2.5rem; width: 45.75rem; @media #{$large-phone} { - width: 85%; - padding: 1.5rem 1.5rem; + width: 100%; } } } @@ -61,32 +60,3 @@ } } } - -// Legal -// .legal-notice-view-root { -// display: flex; -// flex-direction: column; -// align-items: center; -// justify-content: center; -// padding: 1rem 0; -// margin-top: 1.5rem; -// .legal-notice-view-content { -// width: 45.75rem; -// @media #{$large-phone} { -// width: 100%; -// } -// .legal-notice-content-detail { -// padding-bottom: 0.6rem; -// .text-bold { -// font-weight: bold; -// } -// .text-underline { -// text-decoration: underline; -// } -// .spaceline { -// height: 0.6rem; -// display: block; -// } -// } -// } -// } diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 1eb5346e23684c8f1a681c0f97a3ee36f8c7d3dd..befddaeb59d4853e54140fc792277f01e929dee6 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -115,10 +115,14 @@ export function getFuildType(type: string) { } } export function formatNumberValues(value: number) { - return value.toLocaleString('fr-FR', { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - }) + if (value || value === 0) { + return value.toLocaleString('fr-FR', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }) + } else { + return '--,--' + } } export function compareDates(dateA: DateTime, dateB: DateTime) {