Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ interface InputSelectProps {
readonly label?: string
readonly name: string
readonly onChange: (event: ChangeEvent<HTMLInputElement>) => void
readonly options: Array<InputSelectOption>
readonly options: ReadonlyArray<InputSelectOption>
readonly tabIndex?: number
readonly value?: string
}
Expand Down Expand Up @@ -68,7 +68,7 @@ const InputSelect: FC<InputSelectProps> = (props: InputSelectProps) => {
hideInlineErrors={props.hideInlineErrors}
ref={triggerRef}
>
<div className={styles['selected']} onClick={toggleMenu}>
<div className={styles['selected']} onClick={() => !props.disabled && toggleMenu}>
<span className='body-small'>{selectedOption ? label(selectedOption) : ''}</span>
<span className={styles['selected-icon']}>
<IconOutline.ChevronDownIcon />
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './InputSelect'
export { default as InputSelect } from './InputSelect'
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ $error-line-height: 14px;
background-color: $black-10;
background: $black-10;
border-color: $black-40;
pointer-events: none;
}

&.input-error {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import classNames from 'classnames'
import { FC } from 'react'

import { Button, textFormatDateLocaleShortString } from '../../../../../lib'
Expand All @@ -18,7 +19,7 @@ const Completed: FC<CompletedProps> = (props: CompletedProps) => {
}

return (
<div className={styles['wrap']}>
<div className={classNames(styles['wrap'], 'course-card-wrap', 'completed')}>
<div className={styles['line']}>
<CourseTitle
title={props.certification.title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const InProgress: FC<InProgressProps> = (props: InProgressProps) => {
}

return (
<div className={classNames(styles['wrap'], styles['large'])}>
<div className={classNames(styles['wrap'], styles['large'], 'course-card-wrap', 'in-progress')}>
<div className={styles['inner']}>
<div className={styles['line']}>
<CourseTitle
Expand Down
53 changes: 4 additions & 49 deletions src-ts/tools/learn/my-learning/MyLearning.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
.wrap {
flex: 1 1 auto;
position: relative;
}

.content-layout {
background: $black-5;
margin-top: $space-xxxxl;
display: flex;
flex-direction: column;
}

.hero-wrap {
Expand All @@ -21,50 +20,6 @@
}
}

.title-line {
display: flex;
align-items: center;

svg {
@include icon-size(60);
margin-right: $space-sm;
@include ltemd {
@include icon-size(38);
}
}
}

.courses-area {
padding: $space-xxxxl 0;
gap: $space-lg;
display: flex;
flex-direction: column;
position: relative;
&:empty {
display: none;
}

@include ltemd {
gap: $space-xxl;
}
}

.cards-wrap {
display: flex;
gap: $space-xxl;
flex-wrap: wrap;

> * {
flex: 0 1 calc(50% - calc($space-xxl / 2));
}

@include ltemd {
> * {
flex: 1 1 0;
}
}
}

.loading-spinner {
background: none;
}
}
68 changes: 29 additions & 39 deletions src-ts/tools/learn/my-learning/MyLearning.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { FC, useContext, useMemo } from 'react'
import { Dispatch, FC, ReactNode, SetStateAction, useContext, useMemo, useState } from 'react'

import { Breadcrumb, BreadcrumbItemModel, ContentLayout, LoadingSpinner, Portal, profileContext, ProfileContextData } from '../../../lib'
import {
AllCertificationsProviderData,
LearnCertification,
LearningHat,
MyCourseCompletedCard,
MyCourseInProgressCard,
useAllCertifications,
useLearnBreadcrumb,
UserCertificationsProviderData,
Expand All @@ -15,7 +12,10 @@ import {
} from '../learn-lib'
import { LEARN_PATHS } from '../learn.routes'

import { CompletedTab } from './completed-tab'
import { HeroCard } from './hero-card'
import { InProgressTab } from './in-progress-tab'
import { MyTabsNavbar, MyTabsViews } from './my-tabs-navbar'
import styles from './MyLearning.module.scss'

interface CertificatesByIdType {
Expand All @@ -27,6 +27,7 @@ const MyLearning: FC<{}> = () => {
const { profile, initialized: profileReady }: ProfileContextData = useContext(profileContext)
const { completed, inProgress, ready: coursesReady }: UserCertificationsProviderData = useUserCertifications()
const { certifications, ready: certificatesReady }: AllCertificationsProviderData = useAllCertifications()
const [activeTab, setActiveTab]: [MyTabsViews|undefined, Dispatch<SetStateAction<MyTabsViews|undefined>>] = useState()

const ready: boolean = profileReady && coursesReady && certificatesReady

Expand All @@ -44,6 +45,28 @@ const MyLearning: FC<{}> = () => {
},
])

const renderTabs: () => ReactNode = () => (
<MyTabsNavbar
inProgress={inProgress.length}
completed={completed.length}
onTabChange={setActiveTab}
>
{activeTab === MyTabsViews.completed ? (
<CompletedTab
allCertificates={certifications}
certificatesById={certificatesById}
certifications={completed}
/>
) : (
<InProgressTab
allCertificates={certifications}
certificatesById={certificatesById}
certifications={inProgress}
/>
)}
</MyTabsNavbar>
)

return (
<ContentLayout contentClass={styles['content-layout']}>
<Breadcrumb items={breadcrumb} />
Expand All @@ -54,6 +77,7 @@ const MyLearning: FC<{}> = () => {
<div className={styles['hero-wrap']}>
<WaveHero
title='my learning'
theme='light'
text={`
This is your very own page to keep track of your professional education and skill building.
From here you can resume your courses in progress or review past accomplishments.
Expand All @@ -64,41 +88,7 @@ const MyLearning: FC<{}> = () => {
</div>
</Portal>

{ready && (
<>
<div className={styles['courses-area']}>
{inProgress.map((certif) => (
<MyCourseInProgressCard
certification={certificatesById[certif.certificationId]}
key={certif.certificationId}
theme='detailed'
currentLesson={certif.currentLesson}
completedPercentage={certif.courseProgressPercentage / 100}
startDate={certif.startDate}
/>
))}
</div>

{!!completed.length && (
<div className={styles['courses-area']}>
<div className={styles['title-line']}>
<LearningHat />
<h2 className='details'>Completed Courses</h2>
</div>

<div className={styles['cards-wrap']}>
{completed.map((certif) => (
<MyCourseCompletedCard
certification={certificatesById[certif.certificationId]}
key={certif.certificationId}
completed={certif.completedDate}
/>
))}
</div>
</div>
)}
</>
)}
{ready && renderTabs()}
</div>
</ContentLayout>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@import '../../../../lib/styles/includes';

.cards-wrap {
display: flex;
gap: $space-xxl;
flex-wrap: wrap;

> * {
flex: 0 1 calc(50% - calc($space-xxl / 2));
}

> :global(.course-card-wrap) {
background: $black-5;
}

@include ltemd {
> * {
flex: 1 1 0;
}
}
}

.placeholder-wrap {
flex: 1 1 auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: $space-xxl;
}
72 changes: 72 additions & 0 deletions src-ts/tools/learn/my-learning/completed-tab/CompletedTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { FC, ReactNode } from 'react'

import { Button } from '../../../../lib'
import { LearnCertification, MyCourseCompletedCard, UserCertificationCompleted } from '../../learn-lib'
import { LEARN_PATHS } from '../../learn.routes'
import { sortOptions } from '../my-learning-sort-options'
import { MyTabsViews } from '../my-tabs-navbar'
import { TabContentLayout } from '../tab-content-layout'
import { useSortAndFilter, UseSortAndFilterValue } from '../use-sort-and-filter'

import styles from './CompletedTab.module.scss'

interface CompletedTabProps {
allCertificates: ReadonlyArray<LearnCertification>
certificatesById: {[key: string]: LearnCertification}
certifications: ReadonlyArray<UserCertificationCompleted>
}

const CompletedTab: FC<CompletedTabProps> = (props: CompletedTabProps) => {

const {
handleCategoryChange,
certifications,
handleSortChange,
}: UseSortAndFilterValue = useSortAndFilter(
props.allCertificates,
props.certifications
)

const hasCertifications: boolean = certifications.length >= 1

const renderPlaceholder: () => ReactNode = () => (
<div className={styles['placeholder-wrap']}>
<div className='body-medium-bold'>
Your Completed courses will live here. Let’s go!
</div>
<Button
route={LEARN_PATHS.root}
buttonStyle='primary'
size='md'
label='Start a course'
/>
</div>
)

const renderCertificationsList: () => ReactNode = () => (
hasCertifications ? certifications.map((certif) => (
<MyCourseCompletedCard
certification={props.certificatesById[certif.certificationId]}
key={certif.certificationId}
completed={certif.completedDate}
/>
)) : renderPlaceholder()
)

return (
<TabContentLayout
certifications={props.allCertificates}
title={MyTabsViews.completed}
sortOptions={sortOptions.completed}
onSortChange={handleSortChange}
onCategoryChange={handleCategoryChange}
disableFilters={!hasCertifications}
>
<div className={styles['cards-wrap']}>
{renderCertificationsList()}
</div>
</TabContentLayout>
)
}

export default CompletedTab
1 change: 1 addition & 0 deletions src-ts/tools/learn/my-learning/completed-tab/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as CompletedTab } from './CompletedTab'
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@import '../../../../lib/styles/includes';

.wrap {
gap: $space-lg;
display: flex;
flex-direction: column;
position: relative;

@include ltemd {
gap: $space-xxl;
}

> :global(.course-card-wrap) {
background: $black-5;
}
}

.placeholder-wrap {
flex: 1 1 auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: $space-xxl;
}
Loading