Skip to content

Commit 94628e3

Browse files
authored
Merge pull request #470 from topcoder-platform/TCA-870-cert-generation
TCA-870-cert-generation -> TCA-792_tc-certifications-epic
2 parents 1c83cdc + 107260b commit 94628e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1061
-119
lines changed

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

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { FC, MutableRefObject, useCallback, useEffect, useMemo, useRef } from 'react'
22
import { NavigateFunction, useNavigate } from 'react-router-dom'
33
import classNames from 'classnames'
4-
import html2canvas from 'html2canvas'
54

65
import {
76
FacebookSocialShareBtn,
@@ -13,18 +12,20 @@ import {
1312
UserProfile,
1413
} from '../../../../lib'
1514
import {
15+
ActionButton,
1616
AllCertificationsProviderData,
1717
CoursesProviderData,
18+
useCertificateCanvas,
19+
useCertificatePrint,
20+
useCertificateScaling,
1821
useGetCertification,
1922
useGetCourses,
2023
useGetUserCompletedCertifications,
2124
UserCompletedCertificationsProviderData,
2225
} from '../../learn-lib'
2326
import { getCoursePath, getUserCertificateSsr } from '../../learn.routes'
2427

25-
import { ActionButton } from './action-button'
2628
import { Certificate } from './certificate'
27-
import { useCertificateScaling } from './use-certificate-scaling.hook'
2829
import styles from './CertificateView.module.scss'
2930

3031
export type CertificateViewStyle = 'large-container' | undefined
@@ -102,27 +103,7 @@ const CertificateView: FC<CertificateViewProps> = (props: CertificateViewProps)
102103
navigate(coursePath)
103104
}, [coursePath, navigate])
104105

105-
const getCertificateCanvas: () => Promise<HTMLCanvasElement | void> = useCallback(async () => {
106-
107-
if (!certificateElRef.current) {
108-
return undefined
109-
}
110-
111-
return html2canvas(certificateElRef.current, {
112-
// when canvas iframe is ready, remove text gradients
113-
// as they're not supported in html2canvas
114-
onclone: (doc: Document) => {
115-
[].forEach.call(doc.querySelectorAll('.grad'), (el: HTMLDivElement) => {
116-
el.classList.remove('grad')
117-
})
118-
},
119-
// scale (pixelRatio) doesn't matter for the final ceriticate, use 1
120-
scale: 1,
121-
// use the same (ideal) window size when rendering the certificate
122-
windowHeight: 700,
123-
windowWidth: 1024,
124-
})
125-
}, [])
106+
const getCertificateCanvas: () => Promise<HTMLCanvasElement | void> = useCertificateCanvas(certificateElRef)
126107

127108
const handleDownload: () => Promise<void> = useCallback(async () => {
128109

@@ -133,23 +114,7 @@ const CertificateView: FC<CertificateViewProps> = (props: CertificateViewProps)
133114

134115
}, [certificationTitle, getCertificateCanvas])
135116

136-
const handlePrint: () => Promise<void> = useCallback(async () => {
137-
138-
const canvas: HTMLCanvasElement | void = await getCertificateCanvas()
139-
if (!canvas) {
140-
return
141-
}
142-
143-
const printWindow: Window | null = window.open('')
144-
if (!printWindow) {
145-
return
146-
}
147-
148-
printWindow.document.body.appendChild(canvas)
149-
printWindow.document.title = certificationTitle
150-
printWindow.focus()
151-
printWindow.print()
152-
}, [certificationTitle, getCertificateCanvas])
117+
const handlePrint: () => Promise<void> = useCertificatePrint(certificateElRef, certificationTitle)
153118

154119
useEffect(() => {
155120
if (ready && !hasCompletedTheCertification) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import '../../../../../lib/styles/includes';
1+
@import '../../../../lib/styles/includes';
22

33
.wrap {
44
@include icon-mxx;

src-ts/tools/learn/learn-lib/data-providers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export * from './lesson-provider'
44
export * from './resource-provider-provider'
55
export * from './user-certifications-provider'
66
export * from './user-completed-certifications-provider'
7+
export * from './user-completed-tca-certifications-provider'
78
export * from './tca-certifications-provider'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface TCACertificationCategory {
2+
id: number
3+
category: string
4+
track: string
5+
createdAt: Date
6+
updatedAt: Date
7+
}
Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
import { TCACertificationLearnLevel } from './tca-certificate-level-type'
22
import { TCACertificationStatus } from './tca-certificate-status-type'
3+
import { TCACertificationCategory } from './tca-certification-category.model'
34
import { TcaProviderType } from './tca-provider-type'
45

56
export interface TCACertification {
7+
id: number
8+
title: string
69
certificationCategoryId: string
710
coursesCount: number
811
dashedName: string
912
description: string
10-
estimatedCompletionTime: number
11-
id: number
1213
introText: string
14+
estimatedCompletionTime: number
1315
learnerLevel: TCACertificationLearnLevel
14-
learningOutcomes: Array<string>
15-
prerequisites: Array<string>
16+
certificationCategory: TCACertificationCategory
17+
stripeProductId?: string
18+
skills: string[]
19+
learningOutcomes: string[]
20+
prerequisites: string[]
21+
createdAt: Date
22+
updatedAt: Date
1623
providers: Array<TcaProviderType>
1724
sequentialCourses: boolean
18-
skills: string[]
1925
status: TCACertificationStatus
20-
stripeProductId?: string
21-
title: string
2226
}

src-ts/tools/learn/learn-lib/data-providers/tca-certifications-provider/tca-certifications-provider-data.model.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,10 @@ export interface TCACertificationsProviderData {
66
loading: boolean
77
ready: boolean
88
}
9+
10+
export interface TCACertificationProviderData {
11+
certification: TCACertification
12+
error: boolean
13+
loading: boolean
14+
ready: boolean
15+
}
Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,51 @@
11
/* eslint-disable max-len */
22
/* eslint-disable sort-keys */
33
/* eslint-disable default-param-last */
4+
import { find } from 'lodash'
45
import useSWR, { SWRConfiguration, SWRResponse } from 'swr'
56

7+
import { LEARN_PATHS } from '../../../learn.routes'
68
import { learnUrlGet } from '../../functions'
79
import { useSwrCache } from '../../learn-swr'
810

9-
import { TCACertificationsProviderData } from './tca-certifications-provider-data.model'
11+
import { TCACertificationProviderData, TCACertificationsProviderData } from './tca-certifications-provider-data.model'
1012
import { TCACertification } from './tca-certification.model'
1113

1214
interface TCACertificationsAllProviderOptions {
1315
enabled?: boolean
1416
}
1517

18+
const TCACertificationMock: TCACertification[] = [{
19+
id: 1,
20+
title: 'Web Development Fundamentals',
21+
dashedName: 'web-development-fundamentals',
22+
description: 'The Web Developer Fundamentals certification will teach you the basics of HTML, CSS, javascript, front end libraries and will also introduce you to backend development.',
23+
estimatedCompletionTime: 4,
24+
learnerLevel: 'Beginner',
25+
sequentialCourses: false,
26+
status: 'active',
27+
certificationCategoryId: '',
28+
skills: ['HTML', 'CSS', 'JavaScript', 'HTML', 'CSS', 'JavaScript', 'HTML', 'CSS', 'JavaScript', 'HTML', 'CSS', 'JavaScript', 'HTML', 'CSS', 'JavaScript'],
29+
},
30+
{
31+
id: 2,
32+
title: 'Data Science Fundamentals',
33+
dashedName: 'data-science-fundamentals',
34+
description: 'The Data Science Fundamentals certification will teach you the basics of scientific computing, Data Analysis and machine learning while using Python. Additionally, you will learn about data visualization.',
35+
estimatedCompletionTime: 14,
36+
status: 'active',
37+
sequentialCourses: false,
38+
learnerLevel: 'Expert',
39+
certificationCategoryId: '',
40+
skills: ['Python', 'TensorFlow', 'JSON'],
41+
}]
42+
1643
export function useGetAllTCACertifications(
1744
options?: TCACertificationsAllProviderOptions,
1845
): TCACertificationsProviderData {
1946

2047
const url: string = learnUrlGet(
21-
'topcoder-certifications',
48+
LEARN_PATHS.tcaCertifications,
2249
)
2350
const swrCacheConfig: SWRConfiguration = useSwrCache(url)
2451

@@ -38,10 +65,10 @@ export function useGetAllTCACertifications(
3865
export function useGetTCACertification(
3966
certification: string,
4067
options?: TCACertificationsAllProviderOptions,
41-
): TCACertificationsProviderData {
68+
): TCACertificationProviderData {
4269

4370
const url: string = learnUrlGet(
44-
'topcoder-certifications',
71+
LEARN_PATHS.tcaCertifications,
4572
certification,
4673
)
4774
const swrCacheConfig: SWRConfiguration = useSwrCache(url)
@@ -52,89 +79,34 @@ export function useGetTCACertification(
5279
})
5380

5481
return {
55-
certifications: data ?? [],
82+
certification: data,
5683
error: !!error,
5784
loading: !data,
5885
ready: !!data,
5986
}
6087
}
6188

6289
// TODO: remove when integrated with API
63-
export function useGetAllTCACertificationsMOCK(): TCACertificationsProviderData {
64-
const data: TCACertification[] = [{
65-
id: 1,
66-
title: 'Web Development Fundamentals',
67-
dashedName: 'web-developmnt-fundamentals',
68-
description: 'The Web Developer Fundamentals certification will teach you the basics of HTML, CSS, javascript, front end libraries and will also introduce you to backend development.',
69-
introText: 'Introducing our Web Development fundamentals certification! Start your certification journey with Topcoder.',
70-
estimatedCompletionTime: 4,
71-
learnerLevel: 'Beginner',
72-
sequentialCourses: false,
73-
status: 'active',
74-
certificationCategoryId: '',
75-
skills: ['HTML', 'CSS', 'JavaScript', 'HTML1', 'CSS2', 'JavaScript2', 'HTML3', 'CSS3', 'JavaScript3', 'HTML4', 'CSS4', 'JavaScript4'],
76-
prerequisites: [],
77-
coursesCount: 4,
78-
providers: ['freecodecamp', 'topcoder'],
79-
learningOutcomes: [],
80-
},
81-
{
82-
id: 2,
83-
title: 'Data Science Fundamentals',
84-
dashedName: 'data-science-fundamentals',
85-
description: 'The Data Science Fundamentals certification will teach you the basics of scientific computing, Data Analysis and machine learning while using Python. Additionally, you will learn about data visualization.',
86-
introText: '',
87-
estimatedCompletionTime: 14,
88-
status: 'active',
89-
sequentialCourses: false,
90-
learnerLevel: 'Expert',
91-
certificationCategoryId: '',
92-
skills: ['Python', 'TensorFlow', 'JSON'],
93-
prerequisites: [],
94-
coursesCount: 4,
95-
providers: ['freecodecamp', 'topcoder'],
96-
learningOutcomes: [],
97-
}]
90+
export function useGetTCACertificationMOCK(
91+
certification: string,
92+
): TCACertificationProviderData {
93+
94+
const data: TCACertification | undefined = find(TCACertificationMock, { dashedName: certification })
9895

9996
return {
100-
certifications: data ?? [],
97+
certification: data,
10198
error: false,
10299
loading: !data,
103100
ready: !!data,
104101
}
105102
}
106103

107104
// TODO: remove when integrated with API
108-
export function useGetTCACertificationMOCK(
109-
certification: string,
110-
): TCACertificationsProviderData {
111-
const data: TCACertification[] = [{
112-
id: 1,
113-
title: 'Web Development Fundamentals',
114-
dashedName: 'web-developmnt-fundamentals',
115-
description: 'The Web Developer Fundamentals certification will teach you the basics of HTML, CSS, javascript, front end libraries and will also introduce you to backend development.',
116-
introText: 'Introducing our Web Development fundamentals certification! Start your certification journey with Topcoder.',
117-
estimatedCompletionTime: 4,
118-
learnerLevel: 'Beginner',
119-
sequentialCourses: false,
120-
status: 'active',
121-
certificationCategoryId: '',
122-
skills: ['HTML', 'CSS', 'JavaScript', 'HTML1', 'CSS2', 'JavaScript2', 'HTML3', 'CSS3', 'JavaScript3', 'HTML4', 'CSS4', 'JavaScript4'],
123-
prerequisites: [],
124-
coursesCount: 4,
125-
providers: ['freecodecamp', 'topcoder'],
126-
learningOutcomes: [
127-
'Fundamental skills required to begin a career in web development',
128-
'Introduction to React and other front end libraries - a jumping off point to build awesome websites',
129-
'Introduction to Java Script - one of the languages every web developer should know for web development and building basic algorithms and data structures',
130-
'Introduction to backend development with Node and APIs',
131-
],
132-
}]
133-
105+
export function useGetAllTCACertificationsMOCK(): TCACertificationsProviderData {
134106
return {
135-
certifications: data ?? [],
107+
certifications: TCACertificationMock ?? [],
136108
error: false,
137-
loading: !data,
138-
ready: !!data,
109+
loading: !TCACertificationMock,
110+
ready: !!TCACertificationMock,
139111
}
140112
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './user-completed-tca-certifications-provider-data.model'
2+
export * from './user-completed-tca-certifications.provider'
3+
export * from './user-completed-tca-certification.model'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface UserCompletedTCACertification {
2+
status: string
3+
completedDate: string
4+
trackType: string
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { UserCompletedTCACertification } from './user-completed-tca-certification.model'
2+
3+
export interface UserCompletedTCACertificationsProviderData {
4+
certifications: ReadonlyArray<UserCompletedTCACertification>
5+
loading: boolean
6+
ready: boolean
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import useSWR, { SWRResponse } from 'swr'
2+
3+
import { learnUrlGet } from '../../functions'
4+
5+
import { UserCompletedTCACertification } from './user-completed-tca-certification.model'
6+
import { UserCompletedTCACertificationsProviderData } from './user-completed-tca-certifications-provider-data.model'
7+
8+
const COMPLETED_CERTS_MOCK = [
9+
{ status: 'comleted', trackType: 'web dev', completedDate: 'Dec 19, 2022' },
10+
]
11+
12+
export function useGetUserTCACompletedCertifications(
13+
userId?: number,
14+
certification?: string,
15+
): UserCompletedTCACertificationsProviderData {
16+
17+
// TODO: update to actual API endpoint URL when ready
18+
const url: string = learnUrlGet('completed-certifications', `${userId}`)
19+
20+
const { data, error }: SWRResponse<ReadonlyArray<UserCompletedTCACertification>> = useSWR(url)
21+
22+
let certifications: ReadonlyArray<UserCompletedTCACertification> = data ?? []
23+
24+
if (certification) {
25+
certifications = certifications
26+
.filter(c => (!certification || c.certification === certification))
27+
}
28+
29+
return {
30+
certifications,
31+
loading: !data && !error,
32+
ready: !!data || !!error,
33+
}
34+
}
35+
36+
// TODO: remove when API ready
37+
export function useGetUserTCACompletedCertificationsMOCK(
38+
userId?: number,
39+
certification?: string,
40+
): UserCompletedTCACertificationsProviderData {
41+
const data = COMPLETED_CERTS_MOCK
42+
43+
return {
44+
certifications: data,
45+
loading: !data,
46+
ready: !!data,
47+
}
48+
}

src-ts/tools/learn/learn-lib/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from './action-button'
12
export * from './collapsible-pane'
23
export * from './course-badge'
34
export * from './course-outline'
@@ -9,4 +10,7 @@ export * from './learn-level-icon'
910
export * from './learn-swr'
1011
export * from './my-course-card'
1112
export * from './svgs'
13+
export * from './use-certificate-canvas-hook'
14+
export * from './use-certificate-print-hook'
15+
export * from './use-certificate-scaling-hook'
1216
export * from './wave-hero'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './useCertificateCanvas.hook'

0 commit comments

Comments
 (0)