diff --git a/src/components/Analysis/Comparison/Comparison.spec.tsx b/src/components/Analysis/Comparison/Comparison.spec.tsx index f1ebd36e99f37dbeecae2b3d3efb3c15eedeede6..ed2847a86bf768486b680d59cb8db63444bd379e 100644 --- a/src/components/Analysis/Comparison/Comparison.spec.tsx +++ b/src/components/Analysis/Comparison/Comparison.spec.tsx @@ -8,6 +8,11 @@ import { setPeriod } from 'store/analysis/analysis.slice' import { createMockEcolyoStore, mockAnalysisState } from 'tests/__mocks__/store' import Comparison from './Comparison' +jest.mock( + 'components/Analysis/Comparison/TemperatureComparison.tsx', + () => 'mock-temperature-comparison' +) + jest.mock('services/consumption.service', () => { return jest.fn().mockImplementation(() => ({ fetchAvgTemperature: jest.fn().mockResolvedValue(25.3), @@ -90,7 +95,7 @@ describe('Comparison component', () => { }) }) - it('renders performance indicators and weather correctly', async () => { + it('renders performance indicators', async () => { const store = createMockEcolyoStore({ analysis: { ...mockAnalysisState }, global: { @@ -109,8 +114,5 @@ describe('Comparison component', () => { const indicators = await screen.findAllByRole('listitem') expect(indicators.length).toBe(mockFluidsWithData.length) - expect( - await screen.findByText('analysis.temperature_comparison.unit') - ).toBeInTheDocument() }) }) diff --git a/src/components/Analysis/Comparison/Comparison.tsx b/src/components/Analysis/Comparison/Comparison.tsx index 5e67322a75925f24894fbd64adc2cefa320f2965..c21697f59ad0d22b1132ec816b065956bf584b81 100644 --- a/src/components/Analysis/Comparison/Comparison.tsx +++ b/src/components/Analysis/Comparison/Comparison.tsx @@ -119,6 +119,7 @@ const Comparison = ({ )} <div role="list" className="performanceIndicators"> + <TemperatureComparison /> {isLoading && ( <div style={{ @@ -130,7 +131,6 @@ const Comparison = ({ <Loader /> </div> )} - {!isLoading && <TemperatureComparison />} {/* Placeholder when no data is found */} {!isLoading && fluidsWithData.length === 0 && diff --git a/src/components/Analysis/Comparison/TemperatureComparison.spec.tsx b/src/components/Analysis/Comparison/TemperatureComparison.spec.tsx index 8d3383f30fbf92a4b590a9677db2eb2d621d8408..4be5c05413861145c8ed46d2b6a3d9cdeba5d0a6 100644 --- a/src/components/Analysis/Comparison/TemperatureComparison.spec.tsx +++ b/src/components/Analysis/Comparison/TemperatureComparison.spec.tsx @@ -22,9 +22,21 @@ describe('TemperatureComparison component', () => { afterEach(() => { jest.clearAllMocks() }) - it('should be rendered correctly with hot result', async () => { - mockFetchAvgTemperature.mockResolvedValueOnce(1) - mockFetchAvgTemperature.mockResolvedValueOnce(2) + + it('should render a loader', async () => { + render( + <Provider store={store}> + <TemperatureComparison /> + </Provider> + ) + await waitFor(() => { + expect(screen.getByRole('progressbar')).toBeInTheDocument() + }) + }) + + it('should be rendered correctly with no data', async () => { + mockFetchAvgTemperature.mockResolvedValueOnce(null) + mockFetchAvgTemperature.mockResolvedValueOnce(0) const { container } = render( <Provider store={store}> <TemperatureComparison /> @@ -33,9 +45,9 @@ describe('TemperatureComparison component', () => { await waitFor(() => null, { container }) expect(container).toMatchSnapshot() }) - it('should be rendered correctly with cold result', async () => { - mockFetchAvgTemperature.mockResolvedValueOnce(2) + it('should be rendered correctly with hot result', async () => { mockFetchAvgTemperature.mockResolvedValueOnce(1) + mockFetchAvgTemperature.mockResolvedValueOnce(2) const { container } = render( <Provider store={store}> <TemperatureComparison /> @@ -43,10 +55,13 @@ describe('TemperatureComparison component', () => { ) await waitFor(() => null, { container }) expect(container).toMatchSnapshot() + expect( + await screen.findByText('analysis.temperature_comparison.unit') + ).toBeInTheDocument() }) - it('should be rendered correctly with no data', async () => { - mockFetchAvgTemperature.mockResolvedValueOnce(null) - mockFetchAvgTemperature.mockResolvedValueOnce(0) + it('should be rendered correctly with cold result', async () => { + mockFetchAvgTemperature.mockResolvedValueOnce(2) + mockFetchAvgTemperature.mockResolvedValueOnce(1) const { container } = render( <Provider store={store}> <TemperatureComparison /> diff --git a/src/components/Analysis/Comparison/TemperatureComparison.tsx b/src/components/Analysis/Comparison/TemperatureComparison.tsx index 393df4a980a3608affd5c0d06b2510daf6ea8221..23776c6ed9705a761a9972d2c696bbeb4636ca1b 100644 --- a/src/components/Analysis/Comparison/TemperatureComparison.tsx +++ b/src/components/Analysis/Comparison/TemperatureComparison.tsx @@ -1,5 +1,6 @@ import ExclamationMarkIcon from 'assets/icons/ico/exclamationMark.svg' import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton' +import Loader from 'components/Loader/Loader' import { useClient } from 'cozy-client' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import React, { useEffect, useMemo, useState } from 'react' @@ -15,14 +16,16 @@ const TemperatureComparison = () => { state => state.ecolyo.analysis ) - const [temperatureDifference, setTemperatureDifference] = useState<string>() - const [positive, setPositive] = useState<boolean>(true) - const [openTemperatureComparisonModal, setOpenTemperatureComparisonModal] = - useState<boolean>(false) + const [temperatureDifference, setTemperatureDifference] = useState<string>('') + const [openDetailsModal, setOpenDetailsModal] = useState<boolean>(false) + const [isLoading, setIsLoading] = useState<boolean>(true) + const positive = Number(temperatureDifference) >= 0 + const consumptionService = useMemo( () => new ConsumptionService(client), [client] ) + const comparisonDates = useMemo(() => { const endMonth = analysisMonth.minus({ month: 1 }).startOf('month') return { @@ -35,23 +38,22 @@ const TemperatureComparison = () => { useEffect(() => { async function handleTemperatureComparison() { - const startMonthTemperature = - await consumptionService.fetchAvgTemperature( + const [startTemperature, endTemperature] = await Promise.all([ + consumptionService.fetchAvgTemperature( comparisonDates.startMonth.year, comparisonDates.startMonth.month - ) + ), + consumptionService.fetchAvgTemperature( + comparisonDates.endMonth.year, + comparisonDates.endMonth.month + ), + ]) - const endMonthTemperature = await consumptionService.fetchAvgTemperature( - comparisonDates.endMonth.year, - comparisonDates.endMonth.month - ) - - if (startMonthTemperature !== null && endMonthTemperature !== null) { - const temperatureDifference = - endMonthTemperature - startMonthTemperature + if (startTemperature !== null && endTemperature !== null) { + const temperatureDifference = endTemperature - startTemperature setTemperatureDifference(temperatureDifference.toFixed(1)) - setPositive(temperatureDifference >= 0) } + setIsLoading(false) } handleTemperatureComparison() }, [ @@ -62,49 +64,57 @@ const TemperatureComparison = () => { comparisonDates.startMonth.year, ]) - return ( - <> - {temperatureDifference && ( - <div className={`temperatureComparison ${positive ? 'hot' : 'cold'}`}> - <div className="tc-content"> - <div> - <span className="text-28-bold"> - {positive ? '+' : ''} - {temperatureDifference} - </span> - <span className="text-18"> - {t('analysis.temperature_comparison.unit')} - </span> - </div> - <div> - <span className="tc-text text-12"> - {t('analysis.temperature_comparison.comparison')} - </span> - <span className="tc-period text-12-bold"> - - {comparisonDates.startMonth.toLocaleString({ - month: 'long', - year: 'numeric', - })} - </span> - </div> - </div> + if (isLoading) { + return ( + <div className="temperatureComparison loading"> + <Loader /> + </div> + ) + } - <StyledIconButton - icon={ExclamationMarkIcon} - sized={16} - onClick={() => setOpenTemperatureComparisonModal(true)} - aria-label={t('analysis.temperature_comparison.info_button')} - className="info-icon" - /> + if (!temperatureDifference) return null - <TemperatureComparisonModal - open={openTemperatureComparisonModal} - handleCloseClick={() => setOpenTemperatureComparisonModal(false)} - /> + return ( + <div className={`temperatureComparison ${positive ? 'hot' : 'cold'}`}> + <div className="tc-content"> + <div> + <span className="text-28-bold"> + {positive ? '+' : ''} + {temperatureDifference} + </span> + <span className="text-18"> + {t('analysis.temperature_comparison.unit')} + </span> + </div> + <div> + <span className="text-12"> + {t('analysis.temperature_comparison.comparison')} + </span> + <span className="text-12-bold"> + + {comparisonDates.startMonth.toLocaleString({ + month: 'long', + year: 'numeric', + })} + </span> </div> - )} - </> + </div> + + <div className="buttonContainer"> + <StyledIconButton + icon={ExclamationMarkIcon} + sized={16} + onClick={() => setOpenDetailsModal(true)} + aria-label={t('analysis.temperature_comparison.info_button')} + className="info-icon" + /> + </div> + + <TemperatureComparisonModal + open={openDetailsModal} + handleCloseClick={() => setOpenDetailsModal(false)} + /> + </div> ) } diff --git a/src/components/Analysis/Comparison/__snapshots__/TemperatureComparison.spec.tsx.snap b/src/components/Analysis/Comparison/__snapshots__/TemperatureComparison.spec.tsx.snap index eac3ee09c526dd84802cca03337293575eb5d0df..aaed24d5e5e9bf53c37613ee6aa0273fabe43245 100644 --- a/src/components/Analysis/Comparison/__snapshots__/TemperatureComparison.spec.tsx.snap +++ b/src/components/Analysis/Comparison/__snapshots__/TemperatureComparison.spec.tsx.snap @@ -23,39 +23,43 @@ exports[`TemperatureComparison component should be rendered correctly with cold </div> <div> <span - class="tc-text text-12" + class="text-12" > analysis.temperature_comparison.comparison </span> <span - class="tc-period text-12-bold" + class="text-12-bold" > novembre 2022 </span> </div> </div> - <button - aria-label="analysis.temperature_comparison.info_button" - class="MuiButtonBase-root MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-2 info-icon" - tabindex="0" - type="button" + <div + class="buttonContainer" > - <span - class="MuiIconButton-label" + <button + aria-label="analysis.temperature_comparison.info_button" + class="MuiButtonBase-root MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-3 info-icon" + tabindex="0" + type="button" > - <svg - aria-hidden="true" - class="styles__icon___23x3R" - height="16" - width="16" + <span + class="MuiIconButton-label" > - <use - xlink:href="#test-file-stub" - /> - </svg> - </span> - </button> + <svg + aria-hidden="true" + class="styles__icon___23x3R" + height="16" + width="16" + > + <use + xlink:href="#test-file-stub" + /> + </svg> + </span> + </button> + </div> </div> </div> `; @@ -84,39 +88,43 @@ exports[`TemperatureComparison component should be rendered correctly with hot r </div> <div> <span - class="tc-text text-12" + class="text-12" > analysis.temperature_comparison.comparison </span> <span - class="tc-period text-12-bold" + class="text-12-bold" > novembre 2022 </span> </div> </div> - <button - aria-label="analysis.temperature_comparison.info_button" - class="MuiButtonBase-root MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1 info-icon" - tabindex="0" - type="button" + <div + class="buttonContainer" > - <span - class="MuiIconButton-label" + <button + aria-label="analysis.temperature_comparison.info_button" + class="MuiButtonBase-root MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-2 info-icon" + tabindex="0" + type="button" > - <svg - aria-hidden="true" - class="styles__icon___23x3R" - height="16" - width="16" + <span + class="MuiIconButton-label" > - <use - xlink:href="#test-file-stub" - /> - </svg> - </span> - </button> + <svg + aria-hidden="true" + class="styles__icon___23x3R" + height="16" + width="16" + > + <use + xlink:href="#test-file-stub" + /> + </svg> + </span> + </button> + </div> </div> </div> `; diff --git a/src/components/Analysis/Comparison/temperatureComparison.scss b/src/components/Analysis/Comparison/temperatureComparison.scss index ce4fc3e5e665d169435eb4df2ffa3975962b3429..62e23c5de94e8335608a4d54ad8bd5d587b637f6 100644 --- a/src/components/Analysis/Comparison/temperatureComparison.scss +++ b/src/components/Analysis/Comparison/temperatureComparison.scss @@ -3,13 +3,21 @@ .temperatureComparison { display: flex; + align-items: center; border: 1px solid $grey-dark; border-radius: 4px; - padding: 4px 4px 8px 22px; + padding: 8px 4px 8px 20px; box-shadow: 0px 4px 16px 0px $black-shadow; background: linear-gradient(180deg, #323339 0%, #25262b 100%); background-position: bottom right; background-repeat: no-repeat; + height: 60px; + transition: all 0.3s ease-in-out; + + &.loading { + justify-content: center; + } + &.hot { background-image: url('../../../assets/png/temperatures/hot.svg'), linear-gradient(259deg, rgba(6, 29, 62, 0) 25.28%, #77aee0 121.36%), @@ -30,21 +38,20 @@ .tc-content { text-align: left; - padding-top: 4px; flex-grow: 1; color: $white; - .tc-text { - font-weight: 200; - } - .tc-period { - font-weight: 900; - } } - .info-icon { - padding: 0; - stroke: $white; + .buttonContainer { + display: flex; align-items: flex-start; height: 100%; + .info-icon { + align-items: flex-start; + padding: 0; + position: relative; + top: -4px; + stroke: $white; + } } }