From f944b9a72d95730e213275193b032f3da320c687 Mon Sep 17 00:00:00 2001 From: Vasilica Olariu Date: Tue, 30 Aug 2022 11:51:04 +0300 Subject: [PATCH] TCA-376 - refetch course progress data when user opens sidebar nav --- .../learn/free-code-camp/FreeCodeCamp.tsx | 6 ++- .../collapsible-pane/CollapsiblePane.tsx | 8 ++- ...tification-progress-provider-data.model.ts | 1 + .../user-certification-progress.provider.tsx | 51 +++++++++++-------- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src-ts/tools/learn/free-code-camp/FreeCodeCamp.tsx b/src-ts/tools/learn/free-code-camp/FreeCodeCamp.tsx index b335e8a77..3051c38e8 100644 --- a/src-ts/tools/learn/free-code-camp/FreeCodeCamp.tsx +++ b/src-ts/tools/learn/free-code-camp/FreeCodeCamp.tsx @@ -62,6 +62,7 @@ const FreeCodeCamp: FC<{}> = () => { certificationProgress: certificateProgress, setCertificateProgress, ready: progressReady, + refetch: refetchProgress, }: UserCertificationProgressProviderData = useUserCertificationProgress( profile?.userId, routeParams.provider, @@ -336,7 +337,10 @@ const FreeCodeCamp: FC<{}> = () => { {lesson && (
- + isOpen && refetchProgress()} + >
{courseData?.title} diff --git a/src-ts/tools/learn/learn-lib/collapsible-pane/CollapsiblePane.tsx b/src-ts/tools/learn/learn-lib/collapsible-pane/CollapsiblePane.tsx index 3742fecb0..e73399a51 100644 --- a/src-ts/tools/learn/learn-lib/collapsible-pane/CollapsiblePane.tsx +++ b/src-ts/tools/learn/learn-lib/collapsible-pane/CollapsiblePane.tsx @@ -1,4 +1,5 @@ import classNames from 'classnames' +import { noop } from 'lodash' import { Dispatch, FC, ReactNode, SetStateAction, useCallback, useState } from 'react' import { IconSolid } from '../../../../lib' @@ -7,16 +8,19 @@ import styles from './CollapsiblePane.module.scss' interface CollapsiblePaneProps { children: ReactNode + onToggle?: (isOpen: boolean) => void position?: 'to-left'|'to-right' title: string } const CollapsiblePane: FC = (props: CollapsiblePaneProps) => { + const {onToggle = noop}: CollapsiblePaneProps = props const [isOpen, setIsOpen]: [boolean, Dispatch>] = useState(false) const toggle: () => void = useCallback(() => { - setIsOpen(open => !open) - }, []) + setIsOpen(!isOpen) + onToggle(!isOpen) + }, [isOpen, onToggle]) return (
void, setCertificateProgress: (progess: LearnUserCertificationProgress) => void, } diff --git a/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certification-progress.provider.tsx b/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certification-progress.provider.tsx index 2b0991b04..8a951e979 100644 --- a/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certification-progress.provider.tsx +++ b/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certification-progress.provider.tsx @@ -1,49 +1,60 @@ -import { Dispatch, SetStateAction, useEffect, useState } from 'react' +import { Dispatch, MutableRefObject, SetStateAction, useCallback, useEffect, useRef, useState } from 'react' import { UserCertificationProgressProviderData } from './user-certification-progress-provider-data.model' import { LearnUserCertificationProgress, userCertificationProgressGetAsync } from './user-certifications-functions' export function useUserCertificationProgress(userId?: number, provider?: string, certification?: string): UserCertificationProgressProviderData { + const callCounter: MutableRefObject = useRef(0) function setCertificateProgress(progress: LearnUserCertificationProgress): void { setState((prevState) => ({ ...prevState, certificationProgress: progress })) + callCounter.current++ } + const fetchProgress: () => void = useCallback(() => { + if (!userId) { + return + } + + const currentCallCounter: number = ++callCounter.current + + userCertificationProgressGetAsync(userId, provider, certification) + .then((myCertifications) => { + // if another call to fetchProgress or to setCertificateProgress + // was made before we got the api response + // return, and do not update state + if (callCounter.current !== currentCallCounter) { + return + } + + setState((prevState) => ({ + ...prevState, + certificationProgress: myCertifications.find(c => c.certification === certification), + loading: false, + ready: true, + })) + }) + }, [certification, provider, userId]) + const [state, setState]: [UserCertificationProgressProviderData, Dispatch>] = useState({ certificationProgress: undefined, loading: false, ready: false, + refetch: fetchProgress, setCertificateProgress, }) useEffect(() => { - setState((prevState) => ({ ...prevState, loading: true, })) - if (!userId) { - return - } - - userCertificationProgressGetAsync(userId, provider, certification) - .then((myCertifications) => { - setState((prevState) => ({ - ...prevState, - certificationProgress: myCertifications.find(c => c.certification === certification), - loading: false, - ready: true, - })) - }) - }, [ - certification, - provider, - userId, - ]) + fetchProgress() + }, [certification, fetchProgress]) return state }