Skip to content

Commit ac38212

Browse files
authored
Merge pull request #947 from topcoder-platform/dev
November Prod Release
2 parents 10e7a66 + fc095a7 commit ac38212

File tree

202 files changed

+3096
-3476
lines changed

Some content is hidden

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

202 files changed

+3096
-3476
lines changed

.circleci/config.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,7 @@ workflows:
257257
branches:
258258
only:
259259
- dev
260-
- justin_fixes
261-
- talent_search_fixes
262-
- feature/standardized-skills
260+
- MP-356_member-stats-and-history
263261

264262
- deployQa:
265263
context: org-global

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
"react-responsive-modal": "^6.2.0",
9393
"react-router-dom": "^6.4.2",
9494
"react-scripts": "5.0.1",
95-
"react-select": "^5.5.0",
95+
"react-select": "^5.8.0",
9696
"react-spinners": "^0.13.6",
9797
"react-stickynode": "^1.4.1",
9898
"react-toastify": "^9.0.8",

src/apps/learn/src/certification-details/CertificationDetailsPage.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const CertificationDetailsPage: FC<{}> = () => {
4343
const {
4444
certification,
4545
ready: certificationReady,
46+
mutate: reloadCertification,
4647
}: TCACertificationProviderData = useGetTCACertification(dashedName as string)
4748

4849
// Fetch Enrollment status & progress
@@ -130,6 +131,8 @@ const CertificationDetailsPage: FC<{}> = () => {
130131
certification={certification}
131132
enrolled={isEnrolled}
132133
certProgress={progress}
134+
profile={profile}
135+
reloadCertification={reloadCertification}
133136
/>
134137
)
135138
}

src/apps/learn/src/certification-details/certification-details-sidebar/CertificationDetailsSidebar.module.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
.section-header {
55
margin-top: $sp-6;
6+
display: flex;
7+
align-items: center;
68
}
79

810
.certificate-placeholder {

src/apps/learn/src/certification-details/certification-details-sidebar/CertificationDetailsSidebar.tsx

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
import { FC, ReactNode } from 'react'
1+
import { Dispatch, FC, ReactNode, SetStateAction, useMemo, useState } from 'react'
2+
import { KeyedMutator } from 'swr'
23
import classNames from 'classnames'
34

45
import { EnvironmentConfig } from '~/config'
56
import { IconOutline, IconSolid, Tooltip } from '~/libs/ui'
7+
import { UserProfile, UserRole } from '~/libs/core'
68

79
import {
810
CompletionTimeRange,
11+
EditSkillsBtn,
912
LearnLevelIcon,
13+
ModifySkillsModal,
1014
ProvidersLogoList,
1115
SkillTags,
1216
StickySidebar,
@@ -24,6 +28,8 @@ interface CertificationDetailsSidebarProps {
2428
certification: TCACertification
2529
enrolled: boolean
2630
certProgress?: TCACertificationProgress
31+
profile: UserProfile | undefined
32+
reloadCertification: KeyedMutator<any>
2733
}
2834

2935
function renderTooltipContents(icon: ReactNode, text: Array<string>): ReactNode {
@@ -57,6 +63,26 @@ const CertificationDetailsSidebar: FC<CertificationDetailsSidebarProps> = (props
5763

5864
const suggestedRetailPrice: string = product?.metadata?.estimatedRetailPrice || '20'
5965

66+
const canEdit: boolean = useMemo(() => !!props.profile?.roles?.includes(UserRole.tcaAdmin), [props.profile])
67+
68+
const [isEditMode, setIsEditMode]: [boolean, Dispatch<SetStateAction<boolean>>]
69+
= useState<boolean>(false)
70+
71+
function handleModyfSkillsModalClose(): void {
72+
setIsEditMode(false)
73+
}
74+
75+
function handleModyfSkillsSave(): void {
76+
setTimeout(() => {
77+
setIsEditMode(false)
78+
props.reloadCertification()
79+
}, 1500)
80+
}
81+
82+
function handleEditSkillsClick(): void {
83+
setIsEditMode(true)
84+
}
85+
6086
return (
6187
<StickySidebar>
6288
<div className={styles['certificate-placeholder']}>
@@ -140,10 +166,17 @@ const CertificationDetailsSidebar: FC<CertificationDetailsSidebarProps> = (props
140166
</ul>
141167

142168
<div className={classNames('body-small-medium', styles['section-header'])}>
143-
Skills Covered
169+
<span>Skills Covered</span>
170+
{
171+
canEdit && (
172+
<EditSkillsBtn
173+
onClick={handleEditSkillsClick}
174+
className={styles.editTCABtn}
175+
/>
176+
)
177+
}
144178
</div>
145179
<SkillTags
146-
emsiSkills={props.certification.emsiSkills}
147180
skills={props.certification.skills}
148181
courseKey={props.certification.dashedName}
149182
theme='gray'
@@ -173,6 +206,16 @@ const CertificationDetailsSidebar: FC<CertificationDetailsSidebarProps> = (props
173206
<EnrollCtaBtn certification={props.certification.dashedName} />
174207
)}
175208
</div>
209+
210+
{
211+
isEditMode && (
212+
<ModifySkillsModal
213+
onClose={handleModyfSkillsModalClose}
214+
onSave={handleModyfSkillsSave}
215+
certification={props.certification}
216+
/>
217+
)
218+
}
176219
</StickySidebar>
177220
)
178221
}

src/apps/learn/src/course-details/CourseDetailsPage.module.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
@extend .body-main;
4343
margin-top: $sp-8;
4444
}
45+
.skills-section-header {
46+
margin-top: $sp-8;
47+
}
4548
}
4649

4750
.description {

src/apps/learn/src/course-details/CourseDetailsPage.tsx

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
/* eslint-disable complexity */
12
/* eslint-disable react/no-danger */
2-
import { FC, ReactNode, useContext, useMemo } from 'react'
3+
import { Dispatch, FC, ReactNode, SetStateAction, useContext, useMemo, useState } from 'react'
34
import { Params, useParams } from 'react-router-dom'
5+
import classNames from 'classnames'
46

57
import {
68
Breadcrumb,
@@ -10,14 +12,17 @@ import {
1012
LoadingSpinner,
1113
} from '~/libs/ui'
1214
import { textFormatGetSafeString } from '~/libs/shared'
13-
import { profileContext, ProfileContextData } from '~/libs/core'
15+
import { profileContext, ProfileContextData, UserRole } from '~/libs/core'
1416

1517
import {
1618
AllCertificationsProviderData,
1719
CoursesProviderData,
1820
CourseTitle,
21+
EditSkillsBtn,
22+
ModifySkillsModal,
1923
PageTitle,
2024
ResourceProviderData,
25+
SkillTags,
2126
TCACertificationProgressBox,
2227
useGetCertification,
2328
useGetCourses,
@@ -44,6 +49,7 @@ const CourseDetailsPage: FC<{}> = () => {
4449
const {
4550
course,
4651
ready: courseReady,
52+
mutate: reloadCourse,
4753
}: CoursesProviderData = useGetCourses(textFormatGetSafeString(routeParams.provider), routeParams.certification)
4854

4955
const {
@@ -79,6 +85,11 @@ const CourseDetailsPage: FC<{}> = () => {
7985
routeParams.provider,
8086
])
8187

88+
const canEdit: boolean = useMemo(() => !!profile?.roles?.includes(UserRole.tcaAdmin), [profile])
89+
90+
const [isEditMode, setIsEditMode]: [boolean, Dispatch<SetStateAction<boolean>>]
91+
= useState<boolean>(false)
92+
8293
function getDescription(): ReactNode {
8394

8495
if (!course) {
@@ -178,6 +189,21 @@ const CourseDetailsPage: FC<{}> = () => {
178189
)
179190
}
180191

192+
function handleEditSkillsClick(): void {
193+
setIsEditMode(true)
194+
}
195+
196+
function handleModyfSkillsModalClose(): void {
197+
setIsEditMode(false)
198+
}
199+
200+
function handleModyfSkillsSave(): void {
201+
setTimeout(() => {
202+
setIsEditMode(false)
203+
reloadCourse()
204+
}, 1500)
205+
}
206+
181207
return (
182208
<ContentLayout>
183209
<PageTitle>{course?.title ?? 'Course Details'}</PageTitle>
@@ -199,6 +225,24 @@ const CourseDetailsPage: FC<{}> = () => {
199225
trackType={certificate?.certificationCategory.track}
200226
/>
201227

228+
<div className={classNames('body-small-medium', styles['skills-section-header'])}>
229+
<span>Skills Covered</span>
230+
{
231+
canEdit && (
232+
<EditSkillsBtn
233+
onClick={handleEditSkillsClick}
234+
className={styles.editTCABtn}
235+
/>
236+
)
237+
}
238+
</div>
239+
<SkillTags
240+
skills={course.skills || []}
241+
courseKey={course.id}
242+
theme='gray'
243+
expandCount={9}
244+
/>
245+
202246
<TCACertificationProgressBox
203247
userId={profile?.userId}
204248
className={styles.tcaCertBanner}
@@ -229,6 +273,16 @@ const CourseDetailsPage: FC<{}> = () => {
229273
/>
230274
</div>
231275
</div>
276+
277+
{
278+
isEditMode && (
279+
<ModifySkillsModal
280+
onClose={handleModyfSkillsModalClose}
281+
onSave={handleModyfSkillsSave}
282+
course={course}
283+
/>
284+
)
285+
}
232286
</>
233287
)}
234288
</ContentLayout>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@import "@libs/ui/styles/includes";
2+
3+
.editSkillsBtn {
4+
padding: 0 !important;
5+
padding-left: $sp-4 !important;
6+
color: $black-100;
7+
8+
svg {
9+
width: 16px;
10+
height: 16px;
11+
}
12+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { FC } from 'react'
2+
import classNames from 'classnames'
3+
4+
import { Button, IconOutline } from '~/libs/ui'
5+
6+
import styles from './EditSkillsBtn.module.scss'
7+
8+
interface EditSkillsBtnProps {
9+
className?: string
10+
onClick: () => void
11+
}
12+
13+
const EditSkillsBtn: FC<EditSkillsBtnProps> = (props: EditSkillsBtnProps) => (
14+
<Button
15+
icon={IconOutline.PencilIcon}
16+
onClick={props.onClick}
17+
className={classNames(styles.editSkillsBtn, props.className)}
18+
size='md'
19+
/>
20+
)
21+
22+
export default EditSkillsBtn
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as EditSkillsBtn } from './EditSkillsBtn'

0 commit comments

Comments
 (0)