diff --git a/src-ts/lib/loading-spinner/LoadingSpinner.tsx b/src-ts/lib/loading-spinner/LoadingSpinner.tsx index 56d5ba5ab..e8fe9684a 100644 --- a/src-ts/lib/loading-spinner/LoadingSpinner.tsx +++ b/src-ts/lib/loading-spinner/LoadingSpinner.tsx @@ -3,7 +3,7 @@ * * Centered Loading Spinner with back overlay */ -import { FC } from 'react' +import { FC, forwardRef, RefAttributes } from 'react' import { PuffLoader } from 'react-spinners' import classNames from 'classnames' @@ -19,7 +19,8 @@ export interface LoadingSpinnerProps { type?: LoadingSpinnerType } -const LoadingSpinner: FC = (props: LoadingSpinnerProps) => { +const LoadingSpinner: FC> += forwardRef((props, ref) => { if (!!props.hide) { return <> } @@ -27,6 +28,7 @@ const LoadingSpinner: FC = (props: LoadingSpinnerProps) => const isOverlay: boolean = props.type === 'Overlay' return (
= (props: LoadingSpinnerProps) =>
) -} +}) export default LoadingSpinner diff --git a/src-ts/tools/learn/certification-details/CertificationDetailsPage.tsx b/src-ts/tools/learn/certification-details/CertificationDetailsPage.tsx index ce60512db..c3fa16ea0 100644 --- a/src-ts/tools/learn/certification-details/CertificationDetailsPage.tsx +++ b/src-ts/tools/learn/certification-details/CertificationDetailsPage.tsx @@ -118,7 +118,7 @@ const CertificationDetailsPage: FC<{}> = () => { /> ) - ) : <> + ) : undefined } function renderSidebar(): ReactNode { diff --git a/src-ts/tools/learn/course-certificate/certificate-view/CertificateView.tsx b/src-ts/tools/learn/course-certificate/certificate-view/CertificateView.tsx index 1ba5ba28b..435bed0b1 100644 --- a/src-ts/tools/learn/course-certificate/certificate-view/CertificateView.tsx +++ b/src-ts/tools/learn/course-certificate/certificate-view/CertificateView.tsx @@ -1,7 +1,9 @@ import { FC, + forwardRef, MutableRefObject, ReactNode, + RefAttributes, useMemo, useRef, } from 'react' @@ -33,7 +35,8 @@ interface CertificateViewProps { provider: string } -const CertificateView: FC = (props: CertificateViewProps) => { +const CertificateView: FC> += forwardRef((props, ref) => { const coursePath: string = getCoursePath(props.provider, props.certification) const certificateElRef: MutableRefObject = useRef() @@ -110,6 +113,7 @@ const CertificateView: FC = (props: CertificateViewProps) = (props: CertificateViewProps) ) -} +}) export default CertificateView diff --git a/src-ts/tools/learn/course-certificate/user-certificate/UserCertificate.tsx b/src-ts/tools/learn/course-certificate/user-certificate/UserCertificate.tsx index 7218dc738..2582f521e 100644 --- a/src-ts/tools/learn/course-certificate/user-certificate/UserCertificate.tsx +++ b/src-ts/tools/learn/course-certificate/user-certificate/UserCertificate.tsx @@ -1,4 +1,13 @@ -import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react' +import { + Dispatch, + FC, + MutableRefObject, + SetStateAction, + useEffect, + useLayoutEffect, + useRef, + useState, +} from 'react' import { Params, useParams } from 'react-router-dom' import { @@ -7,8 +16,10 @@ import { UserProfile, } from '../../../../lib' import { CertificateView } from '../certificate-view' +import { hideSiblings } from '../../learn-lib' const UserCertificate: FC<{}> = () => { + const elRef: MutableRefObject = useRef() const routeParams: Params = useParams() @@ -31,9 +42,19 @@ const UserCertificate: FC<{}> = () => { } }, [routeParams.memberHandle, setProfileReady]) + useLayoutEffect(() => { + const el: HTMLElement = elRef.current + if (!el) { + return + } + + hideSiblings(el) + hideSiblings(el.parentElement as HTMLElement) + }, []) + return ( <> - + {profileReady && profile && ( = () => { profile={profile} provider={providerParam} fullScreenCertLayout + ref={elRef} /> )} diff --git a/src-ts/tools/learn/learn-lib/certificate-page-layout/CertificatePageLayout.tsx b/src-ts/tools/learn/learn-lib/certificate-page-layout/CertificatePageLayout.tsx index 6be17a21c..e2c7cc9c8 100644 --- a/src-ts/tools/learn/learn-lib/certificate-page-layout/CertificatePageLayout.tsx +++ b/src-ts/tools/learn/learn-lib/certificate-page-layout/CertificatePageLayout.tsx @@ -1,7 +1,9 @@ import { FC, + forwardRef, MutableRefObject, ReactNode, + RefAttributes, useCallback, useLayoutEffect, useRef, @@ -42,7 +44,8 @@ interface CertificatePageLayoutProps { title?: string } -const CertificatePageLayout: FC = (props: CertificatePageLayoutProps) => { +const CertificatePageLayout: FC> += forwardRef((props, ref) => { const [queryParams]: [URLSearchParams, any] = useSearchParams() const viewStyle: CertificatePageLayoutStyle = queryParams.get(getViewStyleParamKey()) as CertificatePageLayoutStyle @@ -78,6 +81,12 @@ const CertificatePageLayout: FC = (props: Certificat const handlePrint: () => Promise = useCertificatePrint(props.certificateElRef, props.title ?? '') + if (typeof ref === 'function') { + ref(wrapElRef.current) + } else if (ref && Object.prototype.hasOwnProperty.call(ref, 'current')) { + ref.current = wrapElRef.current + } + useLayoutEffect(() => { const el: HTMLElement = wrapElRef.current if (props.fullScreenCertLayout !== true || !el) { @@ -93,57 +102,59 @@ const CertificatePageLayout: FC = (props: Certificat <> - {props.isReady && ( -
-
- {!props.fullScreenCertLayout && ( -
- } - onClick={handleBackBtnClick} - /> -
- )} -
-
- {props.children} -
-
- {!props.fullScreenCertLayout && ( +
+ {props.isReady && ( + <> +
+ {!props.fullScreenCertLayout && ( +
+ } + onClick={handleBackBtnClick} + /> +
+ )}
- } - onClick={handlePrint} - /> - } - onClick={handleDownload} - /> - } - onClick={shareModal.show} - > - Share certificate - +
+ {props.children} +
- )} -
- {props.afterContent} - {shareModal.modal} -
- )} + {!props.fullScreenCertLayout && ( +
+ } + onClick={handlePrint} + /> + } + onClick={handleDownload} + /> + } + onClick={shareModal.show} + > + Share certificate + +
+ )} +
+ {props.afterContent} + {shareModal.modal} + + )} +
) -} +}) export default CertificatePageLayout