Skip to content

Commit 1dacb5e

Browse files
committed
TCA-996 - implement certificate not found error pages for tca certifications and FCC courses
1 parent 1697222 commit 1dacb5e

File tree

32 files changed

+551
-133
lines changed

32 files changed

+551
-133
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
$tca-certif-aspect-ratio: 1.25715;
1+
$tca-certif-aspect-ratio: 1.2571;

src-ts/lib/svgs/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ReactComponent as SocialIconYoutube } from './social-yt-icon.svg'
2121
import { ReactComponent as TooltipArrowIcon } from './tooltip-arrow.svg'
2222
import { ReactComponent as TcAcademyLogoSvg } from './tc-academy-logo.svg'
2323
import { ReactComponent as TCAcademyLogoWhiteSvg } from './tc-academy-logo-white.svg'
24+
import { ReactComponent as TCAcademyLogoMixedSvg } from './tc-academy-logo-mixed.svg'
2425
import { ReactComponent as TcLogoSvg } from './tc-logo.svg'
2526
import { ReactComponent as TCLogoSvg } from './tc-logo-white.svg'
2627
import { ReactComponent as FccLogoSvg } from './vendor-fcc-logo.svg'
@@ -49,6 +50,7 @@ export {
4950
IconCheck,
5051
TcAcademyLogoSvg,
5152
TCAcademyLogoWhiteSvg,
53+
TCAcademyLogoMixedSvg,
5254
TcLogoSvg,
5355
TCLogoSvg,
5456
FccLogoSvg,

src-ts/lib/svgs/tc-academy-logo-mixed.svg

Lines changed: 24 additions & 0 deletions
Loading
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
@import '../../../../lib/styles/includes';
2+
3+
.wrap {
4+
display: flex;
5+
height: 100%;
6+
z-index: 1;
7+
overflow: hidden;
8+
9+
@include ltemd {
10+
border: 1px dashed $blue-25;
11+
border-radius: 8px;
12+
}
13+
> svg {
14+
position: absolute;
15+
top: 50%;
16+
left: 0;
17+
width: 100%;
18+
height: auto;
19+
display: block;
20+
z-index: -1;
21+
transform: translateY(-50%);
22+
23+
@include ltemd {
24+
:global(.rect-border) {
25+
display: none;
26+
}
27+
}
28+
}
29+
}
30+
31+
.details {
32+
width: 55%;
33+
padding: calc($space-mx + $space-lg);
34+
display: flex;
35+
flex-direction: column;
36+
flex: 1;
37+
38+
&Inner {
39+
max-width: 385px;
40+
flex: 1;
41+
display: flex;
42+
flex-direction: column;
43+
}
44+
45+
h2 {
46+
color: $blue-25;
47+
}
48+
49+
h3 {
50+
font-size: 48px;
51+
line-height: 50px;
52+
font-weight: 500;
53+
color: $tc-white;
54+
margin-top: $space-sm;
55+
56+
:global(.nw) {
57+
white-space: nowrap;
58+
}
59+
}
60+
}
61+
62+
.logos {
63+
margin-top: auto;
64+
display: flex;
65+
}
66+
67+
.logo {
68+
display: flex;
69+
align-items: center;
70+
height: 52px;
71+
72+
svg {
73+
width: auto;
74+
75+
}
76+
&.whiteLogo svg > path {
77+
fill: $tc-white;
78+
}
79+
}
80+
81+
.divider {
82+
width: $border;
83+
background: $black-10;
84+
margin: 0 $space-lg;
85+
flex: 0 0 auto;
86+
}
87+
88+
.rightSide {
89+
width: 45%;
90+
91+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { FC } from 'react'
2+
import classNames from 'classnames'
3+
4+
import { TCAcademyLogoMixedSvg, TcLogoSvg } from '../../../../lib'
5+
import { CertificateNotFoundContent } from '../../learn-lib'
6+
7+
import { ReactComponent as BackgroundSvg } from './bg.svg'
8+
import styles from './CertificateNotFound.module.scss'
9+
10+
const CertificateNotFound: FC<{}> = () => (
11+
<div className={styles.wrap}>
12+
<BackgroundSvg />
13+
<div className={styles.details}>
14+
<div className={styles.detailsInner}>
15+
<h2 className='details'>Topcoder Academy</h2>
16+
<h3>
17+
Certificate
18+
{' '}
19+
<span className='nw'>not found</span>
20+
</h3>
21+
<CertificateNotFoundContent className='mobile-hide' />
22+
<div className={styles.logos}>
23+
<div className={classNames(styles.logo, styles.whiteLogo)}>
24+
<TcLogoSvg />
25+
</div>
26+
<div className={styles.divider} />
27+
<div className={styles.logo}>
28+
<TCAcademyLogoMixedSvg />
29+
</div>
30+
</div>
31+
</div>
32+
</div>
33+
<div className={styles.rightSide} />
34+
</div>
35+
)
36+
37+
export default CertificateNotFound
Lines changed: 38 additions & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as CertificateNotFound } from './CertificateNotFound'

src-ts/tools/learn/course-certificate/certificate-view/CertificateView.tsx

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import {
22
FC,
33
MutableRefObject,
4-
useEffect,
4+
ReactNode,
55
useMemo,
66
useRef,
77
} from 'react'
88

99
import {
1010
AllCertificationsProviderData,
11+
CertificateNotFoundContent,
1112
CertificatePageLayout,
1213
CoursesProviderData,
1314
useGetCertification,
@@ -20,13 +21,13 @@ import {
2021
getUserCertificateSsr,
2122
} from '../../learn.routes'
2223
import { UserProfile } from '../../../../lib'
24+
import { CertificateNotFound } from '../certificate-not-found'
2325

2426
import Certificate from './certificate/Certificate'
2527

2628
interface CertificateViewProps {
2729
certification: string
2830
fullScreenCertLayout?: boolean
29-
onCertificationNotCompleted: () => void
3031
profile: UserProfile
3132
provider: string
3233
}
@@ -81,23 +82,14 @@ const CertificateView: FC<CertificateViewProps> = (props: CertificateViewProps)
8182
const ready: boolean = useMemo(() => (
8283
completedCertificateReady && courseReady && certificateReady
8384
), [certificateReady, completedCertificateReady, courseReady])
85+
const certificateNotFoundError: boolean = ready && !hasCompletedTheCertification
8486

85-
useEffect(() => {
87+
function renderCertificate(): ReactNode {
8688
if (ready && !hasCompletedTheCertification) {
87-
props.onCertificationNotCompleted()
89+
return <CertificateNotFound />
8890
}
89-
}, [coursePath, hasCompletedTheCertification, props, ready])
9091

91-
return (
92-
<CertificatePageLayout
93-
certificateElRef={certificateElRef}
94-
fallbackBackUrl={coursePath}
95-
fullScreenCertLayout={props.fullScreenCertLayout}
96-
isCertificateCompleted={hasCompletedTheCertification}
97-
isReady={ready}
98-
ssrUrl={certUrl}
99-
title={certificationTitle}
100-
>
92+
return (
10193
<Certificate
10294
completedDate={completedCertificate?.completedDate ?? ''}
10395
course={course?.title}
@@ -107,6 +99,25 @@ const CertificateView: FC<CertificateViewProps> = (props: CertificateViewProps)
10799
type={certificate?.certificationCategory.track}
108100
userName={userName}
109101
/>
102+
)
103+
}
104+
105+
return (
106+
<CertificatePageLayout
107+
certificateElRef={certificateElRef}
108+
fallbackBackUrl={coursePath}
109+
fullScreenCertLayout={!certificateNotFoundError && props.fullScreenCertLayout}
110+
isCertificateCompleted={hasCompletedTheCertification}
111+
isReady={ready}
112+
ssrUrl={certUrl}
113+
title={certificationTitle}
114+
disableActions={ready && !hasCompletedTheCertification}
115+
className={certificateNotFoundError ? 'cert-not-found-layout' : ''}
116+
afterContent={certificateNotFoundError && (
117+
<CertificateNotFoundContent className='desktop-hide' />
118+
)}
119+
>
120+
{renderCertificate()}
110121
</CertificatePageLayout>
111122
)
112123
}

src-ts/tools/learn/course-certificate/certificate-view/certificate/Certificate.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
.wrap {
44
display: flex;
55
height: 100%;
6+
background: $tc-white;
67
}
78

89
.details {

src-ts/tools/learn/course-certificate/my-certificate/MyCertificate.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ const MyCertificate: FC<{}> = () => {
3737
certification={certificationParam}
3838
profile={profile}
3939
provider={providerParam}
40-
onCertificationNotCompleted={navigateToCourse}
4140
/>
4241
)}
4342
</>

0 commit comments

Comments
 (0)