Skip to content

Commit

Permalink
Dispaly skills in course header (#239)
Browse files Browse the repository at this point in the history
  • Loading branch information
sameenfatima78 authored Mar 24, 2021
1 parent de8f173 commit d4bc1c6
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 12 deletions.
26 changes: 14 additions & 12 deletions src/components/course/CourseHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AppContext } from '@edx/frontend-platform/react';

import { CourseContext } from './CourseContextProvider';
import CourseRunSelector from './CourseRunSelector';
import CourseSkills from './CourseSkills';
import EnrollButton from './EnrollButton';

import { ENROLLMENT_FAILED_QUERY_PARAM } from './data/constants';
Expand Down Expand Up @@ -77,18 +78,8 @@ export default function CourseHeader() {
]}
/>
)}
<div className={classNames({ 'mb-4': !course.shortDescription })}>
<h2>{course.title}</h2>
</div>
{course.shortDescription && (
<div
className="lead font-weight-normal mb-4"
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: course.shortDescription }}
/>
)}
{partners.length > 0 && (
<div className="mb-4">
<div className="mt-4 mb-2">
{partners.map(partner => (
<a
className="d-inline-block mr-4"
Expand All @@ -98,12 +89,23 @@ export default function CourseHeader() {
<img
src={partner.logoImageUrl}
alt={`${partner.name} logo`}
style={{ maxWidth: 160 }}
style={{ maxWidth: 160, maxHeight: 44 }}
/>
</a>
))}
</div>
)}
<div className={classNames({ 'mb-4': !course.shortDescription })}>
<h2>{course.title}</h2>
</div>
{course.shortDescription && (
<div
className="lead font-weight-normal mb-4"
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: course.shortDescription }}
/>
)}
{course.skillNames.length > 0 && <CourseSkills />}
{catalog.containsContentItems ? (
<>
<CourseRunSelector />
Expand Down
37 changes: 37 additions & 0 deletions src/components/course/CourseSkills.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { useContext, useState } from 'react';
import { Badge, Button } from '@edx/paragon';

import { CourseContext } from './CourseContextProvider';
import { SKILLS_BUTTON_LABEL } from './data/constants';

export const MAX_VISIBLE_SKILLS = 5;

export default function CourseSkills() {
const { state } = useContext(CourseContext);
const { skillNames } = state.course;
const [showMore, setShowMore] = useState(false);
const skillsButtonLabel = showMore ? SKILLS_BUTTON_LABEL.SHOW_LESS : SKILLS_BUTTON_LABEL.SHOW_MORE;

return (
<div className="mb-4">
<h6> Skills you&apos;ll gain</h6>
<div>
{skillNames.map((skill, index) => (
<Badge
key={skill.id}
className="course-skill"
variant="light"
style={{ display: ((index < MAX_VISIBLE_SKILLS) || showMore) ? 'inline-block' : 'none' }}
>
{ skill }
</Badge>
))}
{skillNames.length > MAX_VISIBLE_SKILLS && (
<Button className="d-inline-block" variant="link" onClick={() => { setShowMore(!showMore); }}>
{ skillsButtonLabel }
</Button>
)}
</div>
</div>
);
}
5 changes: 5 additions & 0 deletions src/components/course/data/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export const COURSE_AVAILABILITY_MAP = {
ARCHIVED: 'Archived',
};

export const SKILLS_BUTTON_LABEL = {
SHOW_MORE: 'show more',
SHOW_LESS: 'show less',
};

export const ENROLL_BUTTON_LABEL_COMING_SOON = 'Coming Soon';
export const ENROLL_BUTTON_LABEL_NOT_AVAILABLE = 'Not Currently Available';

Expand Down
7 changes: 7 additions & 0 deletions src/components/course/styles/_CourseSkills.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.course-skill {
padding: 6px;
margin-right: 7px;
margin-top: 8px;
font-size: 12.5px;
font-weight: normal;
}
1 change: 1 addition & 0 deletions src/components/course/tests/CourseHeader.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ describe('<CourseHeader />', () => {
image: {
src: 'http://test-image.url',
},
skillNames: [],
},
activeCourseRun: {
isEnrollable: true,
Expand Down
79 changes: 79 additions & 0 deletions src/components/course/tests/CourseSkills.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import { AppContext } from '@edx/frontend-platform/react';
import { screen, render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

import { CourseContextProvider } from '../CourseContextProvider';
import CourseSkills, { MAX_VISIBLE_SKILLS } from '../CourseSkills';

import { SKILLS_BUTTON_LABEL } from '../data/constants';

/* eslint-disable react/prop-types */
const CourseSkillsWithContext = ({
initialAppState = {},
initialCourseState = {},
}) => (
<AppContext.Provider value={initialAppState}>
<CourseContextProvider initialState={initialCourseState}>
<CourseSkills />
</CourseContextProvider>
</AppContext.Provider>
);
/* eslint-enable react/prop-types */

describe('<CourseSkills />', () => {
const initialAppState = {
enterpriseConfig: {
slug: 'test-enterprise-slug',
},
};
const initialCourseState = {
course: {
skillNames: ['test-skill1', 'test-skill2', 'test-skill3', 'test-skill4'],
},
};

test('renders course skills less than limit', () => {
render(
<CourseSkillsWithContext
initialAppState={initialAppState}
initialCourseState={initialCourseState}
/>,
);
initialCourseState.course.skillNames.forEach((skill) => {
expect(screen.queryByText(skill)).toBeVisible();
});
});

test('renders course skills greater than limit', () => {
const skillGreaterThanLimit = ['test-skill1', 'test-skill2', 'test-skill3', 'test-skill4', 'test-skill5', 'test-skill6'];
const courseState = {
...initialCourseState,
course: {
...initialCourseState.course,
skillNames: skillGreaterThanLimit,
},
};
render(
<CourseSkillsWithContext
initialAppState={initialAppState}
initialCourseState={courseState}
/>,
);

const shownSkills = initialCourseState.course.skillNames.slice(0, MAX_VISIBLE_SKILLS);
const hiddenSkills = initialCourseState.course.skillNames.slice(MAX_VISIBLE_SKILLS, skillGreaterThanLimit.length);

shownSkills.forEach((skill) => {
expect(screen.queryByText(skill)).toBeVisible();
});

// do not display skills greater than limit
hiddenSkills.forEach((skill) => {
expect(screen.queryByText(skill)).not.toBeVisible();
});

// display show more inline link when skills count is greater than limit
expect(screen.queryByText(SKILLS_BUTTON_LABEL.SHOW_MORE)).toBeInTheDocument();
});
});
1 change: 1 addition & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ $fa-font-path: "~font-awesome/fonts";
@import "./components/course/enrollment/styles/EnrollButton";
@import "./components/course/styles/CourseHeader";
@import "./components/course/styles/CourseSidebar";
@import "./components/course/styles/CourseSkills";
@import "./components/dashboard/main-content/course-enrollments/course-cards/styles/CourseCard";
@import "./components/dashboard/main-content/course-enrollments/styles/CourseSection";
@import "./components/dashboard/sidebar/offers/styles/Offer";
Expand Down

0 comments on commit d4bc1c6

Please sign in to comment.