diff --git a/src-ts/tools/learn/course-certificate/certificate-view/certificate/Certificate.tsx b/src-ts/tools/learn/course-certificate/certificate-view/certificate/Certificate.tsx index af4d8ca5b..be076dec3 100644 --- a/src-ts/tools/learn/course-certificate/certificate-view/certificate/Certificate.tsx +++ b/src-ts/tools/learn/course-certificate/certificate-view/certificate/Certificate.tsx @@ -1,6 +1,7 @@ import classNames from 'classnames' import { FC, MutableRefObject } from 'react' +import { LearnConfig } from '../../../learn-config' import { LearnCertificateTrackType } from '../../../learn-lib' import { CertificateBgPattern } from './certificate-bg-pattern' @@ -13,7 +14,7 @@ import { ReactComponent as FccLogoSvg } from './vendor-fcc-logo.svg' interface CertificateProps { completedDate?: string course?: string - elRef?: MutableRefObject + elRef?: MutableRefObject provider?: string tcHandle?: string type?: LearnCertificateTrackType @@ -21,10 +22,19 @@ interface CertificateProps { } const Certificate: FC = (props: CertificateProps) => { + const certificateType: LearnCertificateTrackType = props.type ?? 'DEV' + const elementSelector: { [attr: string]: string } = { + [LearnConfig.CERT_ELEMENT_SELECTOR.attribute]: LearnConfig.CERT_ELEMENT_SELECTOR.value, + } + return ( -
+

Topcoder Academy

Certificate of Course Completion

diff --git a/src-ts/tools/learn/free-code-camp/FreeCodeCamp.tsx b/src-ts/tools/learn/free-code-camp/FreeCodeCamp.tsx index 43b519f83..11268128f 100644 --- a/src-ts/tools/learn/free-code-camp/FreeCodeCamp.tsx +++ b/src-ts/tools/learn/free-code-camp/FreeCodeCamp.tsx @@ -27,6 +27,7 @@ import { useCourses, useLearnBreadcrumb, useLessonProvider, + userCertificationProgressCompleteCourseAsync, UserCertificationProgressProviderData, userCertificationProgressStartAsync, UserCertificationProgressStatus, @@ -257,26 +258,34 @@ const FreeCodeCamp: FC<{}> = () => { } useEffect(() => { + + // if we don't yet have the user's handle, + // or if the cert isn't complete, + // or the cert isn't in progress, + // there's nothing to do if ( - certificateProgress && - certificateProgress.certificationProgressPercentage === 100 && - certificateProgress.status === UserCertificationProgressStatus.inProgress + !profile?.handle + || certificateProgress?.certificationProgressPercentage !== 100 + || certificateProgress?.status !== UserCertificationProgressStatus.inProgress ) { - userCertificationProgressUpdateAsync( - certificateProgress.id, - UserCertificationUpdateProgressActions.completeCertificate, - {} - ) - .then(setCertificateProgress) - .then(() => { - const completedPath: string = getCertificationCompletedPath( - providerParam, - certificationParam - ) - - navigate(completedPath) - }) + return } + + // it's safe to complete the course + userCertificationProgressCompleteCourseAsync( + certificateProgress.id, + certificationParam, + profile.handle, + providerParam, + ) + .then(setCertificateProgress) + .then(() => { + const completedPath: string = getCertificationCompletedPath( + providerParam, + certificationParam + ) + navigate(completedPath) + }) }, [ certificateProgress, certificationParam, diff --git a/src-ts/tools/learn/learn-config/learn-config.model.ts b/src-ts/tools/learn/learn-config/learn-config.model.ts index 783fe51ff..a4c546c7c 100644 --- a/src-ts/tools/learn/learn-config/learn-config.model.ts +++ b/src-ts/tools/learn/learn-config/learn-config.model.ts @@ -1,4 +1,8 @@ export interface LearnConfigModel { API: string + CERT_ELEMENT_SELECTOR: { + attribute: string, + value: string, + } CLIENT: string } diff --git a/src-ts/tools/learn/learn-config/learn.default.config.ts b/src-ts/tools/learn/learn-config/learn.default.config.ts index 36ca36697..a29a695a1 100644 --- a/src-ts/tools/learn/learn-config/learn.default.config.ts +++ b/src-ts/tools/learn/learn-config/learn.default.config.ts @@ -2,5 +2,9 @@ import { LearnConfigModel } from './learn-config.model' export const LearnConfigDefault: LearnConfigModel = { API: 'http://localhost:3001/v5/learning-paths', + CERT_ELEMENT_SELECTOR: { + attribute: 'data-id', + value: 'certificate-container', + }, CLIENT: 'https://fcc.topcoder-dev.com:4431', } diff --git a/src-ts/tools/learn/learn-config/learn.dev.config.ts b/src-ts/tools/learn/learn-config/learn.dev.config.ts index 8ee03c5fe..60c00ef28 100644 --- a/src-ts/tools/learn/learn-config/learn.dev.config.ts +++ b/src-ts/tools/learn/learn-config/learn.dev.config.ts @@ -1,6 +1,8 @@ import { LearnConfigModel } from './learn-config.model' +import { LearnConfigDefault } from './learn.default.config' export const LearnConfigDev: LearnConfigModel = { + ...LearnConfigDefault, API: 'https://api.topcoder-dev.com/v5/learning-paths', CLIENT: 'https://freecodecamp.topcoder-dev.com', } diff --git a/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certifications-functions/index.ts b/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certifications-functions/index.ts index 507435d3c..9b8dd3889 100755 --- a/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certifications-functions/index.ts +++ b/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certifications-functions/index.ts @@ -3,6 +3,7 @@ export * from './learn-module-progress.model' export * from './user-certification-progress-status.enum' export * from './user-certification-update-progress-actions.enum' export { + completeCourse as userCertificationProgressCompleteCourseAsync, getAsync as userCertificationProgressGetAsync, startAsync as userCertificationProgressStartAsync, updateAsync as userCertificationProgressUpdateAsync diff --git a/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certifications-functions/user-certification-progress.store.ts b/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certifications-functions/user-certification-progress.store.ts index f570da701..52a78321e 100755 --- a/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certifications-functions/user-certification-progress.store.ts +++ b/src-ts/tools/learn/learn-lib/user-certifications-provider/user-certifications-functions/user-certification-progress.store.ts @@ -1,3 +1,5 @@ +import { LearnConfig } from '../../../learn-config' +import { getUserCertificatePath } from '../../../learn.routes' import { learnUrlGet, learnXhrGetAsync, learnXhrPostAsync, learnXhrPutAsync } from '../../functions' import { LearnUserCertificationProgress } from './learn-user-certification-progress.model' @@ -5,6 +7,27 @@ import { UserCertificationUpdateProgressActions } from './user-certification-upd const certProgressPath: string = 'certification-progresses' +export function completeCourse( + certificationProgressId: string, + certification: string, + handle: string, + provider: string, +): Promise { + + // construct the certificate params + const certificateElement: string = `[${LearnConfig.CERT_ELEMENT_SELECTOR.attribute}=${LearnConfig.CERT_ELEMENT_SELECTOR.value}]` + const certificateUrl: string = getUserCertificatePath(provider, certification, handle) + + return updateAsync( + certificationProgressId, + UserCertificationUpdateProgressActions.completeCertificate, + { + certificateElement, + certificateUrl, + } + ) +} + export function getAsync(userId: number, provider?: string, certification?: string): Promise> { const params: string = [ diff --git a/src-ts/tools/learn/learn.routes.tsx b/src-ts/tools/learn/learn.routes.tsx index a2ecb9342..3a3f8060d 100644 --- a/src-ts/tools/learn/learn.routes.tsx +++ b/src-ts/tools/learn/learn.routes.tsx @@ -8,12 +8,16 @@ import { default as Learn, toolTitle } from './Learn' import { MyLearning } from './my-learning' import { WelcomePage } from './welcome' +export function getAuthenticateAndStartCourseRoute(): string { + return `${authUrlLogin()}${encodeURIComponent(`?${LEARN_PATHS.startCourseRouteFlag}`)}` +} + export function getCoursePath(provider: string, certification: string): string { return `${rootRoute}/${provider}/${certification}` } export function getCertificatePath(provider: string, certification: string): string { - return `${getCoursePath(provider, certification)}/certificate` + return `${getCoursePath(provider, certification)}${LEARN_PATHS.certificate}` } export function getCertificationCompletedPath(provider: string, certification: string): string { @@ -40,7 +44,12 @@ export function getLessonPathFromModule( return `${getCoursePath(provider, certification)}/${module}/${lesson}` } +export function getUserCertificatePath(provider: string, certification: string, handle: string): string { + return `${window.location.origin}${getCoursePath(provider, certification)}/${handle}${LEARN_PATHS.certificate}` +} + export enum LEARN_PATHS { + certificate = '/certificate', completed = '/learn/completed', myCertificate = '/learn/my-certificate', myLearning = '/learn/my-learning', @@ -49,10 +58,6 @@ export enum LEARN_PATHS { startCourseRouteFlag = 'start-course', } -export function getAuthenticateAndStartCourseRoute(): string { - return `${authUrlLogin()}${encodeURIComponent(`?${LEARN_PATHS.startCourseRouteFlag}`)}` -} - export const rootRoute: string = LEARN_PATHS.root export const absoluteRootRoute: string = `${window.location.origin}${LEARN_PATHS.root}`