Skip to content

Commit

Permalink
feat: skills quiz v2 enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
mahamakifdar19 committed Jan 11, 2024
1 parent c46feda commit 112aef2
Show file tree
Hide file tree
Showing 14 changed files with 200 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,11 @@ describe('sortAssignmentsByAssignmentStatus', () => {

expect(sortedAssignments).toEqual(expectedSortedAssignments);
});

it('returns empty array for null assignments', () => {
const assignments = null;
const expectedAssignments = [];
const sortedAssignments = sortAssignmentsByAssignmentStatus(assignments);
expect(sortedAssignments).toEqual(expectedAssignments);
});
});
18 changes: 18 additions & 0 deletions src/components/enterprise-user-subsidy/data/hooks/hooks.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { renderHook } from '@testing-library/react-hooks';
import * as logging from '@edx/frontend-platform/logging';
import { camelCaseObject } from '@edx/frontend-platform/utils';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { logError } from '@edx/frontend-platform/logging';

import {
useCouponCodes,
Expand Down Expand Up @@ -349,6 +350,9 @@ describe('useCustomerAgreementData', () => {
});

it('handles no customer agreement data for enterprise', async () => {
jest.mock('@edx/frontend-platform/logging', () => ({
logError: jest.fn(),
}));
fetchCustomerAgreementData.mockResolvedValueOnce({
data: { results: [] },
});
Expand All @@ -363,6 +367,20 @@ describe('useCustomerAgreementData', () => {
false, // isLoading
]);
});

it('handles errors in fetching customer agreement data', async () => {
const mockError = new Error('error');
fetchCustomerAgreementData.mockRejectedValueOnce(mockError);

const { result, waitForNextUpdate } = renderHook(() => useCustomerAgreementData(TEST_ENTERPRISE_UUID));

expect(result.current).toEqual([undefined, true]);

await waitForNextUpdate();

expect(result.current).toEqual([null, false]);
expect(logError).toHaveBeenCalledWith(new Error(mockError));
});
});

const Wrapper = ({ children }) => (
Expand Down
56 changes: 45 additions & 11 deletions src/components/skills-quiz-v2/JobCardComponent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,76 @@ import React, { useContext, useState, useEffect } from 'react';
import {
SelectableBox, Chip, Spinner, Stack, Button,
} from '@edx/paragon';
import { camelCaseObject } from '@edx/frontend-platform/utils';
import { logError } from '@edx/frontend-platform/logging';
import PropTypes from 'prop-types';
import { SkillsContext } from '../skills-quiz/SkillsContextProvider';
import { SET_KEY_VALUE } from '../skills-quiz/data/constants';
import { DROPDOWN_OPTION_IMPROVE_CURRENT_ROLE } from '../skills-quiz/constants';
import TopSkillsOverview from '../skills-quiz/TopSkillsOverview';
import SearchCourseCard from '../skills-quiz/SearchCourseCard';
import SearchProgramCard from '../skills-quiz/SearchProgramCard';
import SearchPathways from '../skills-quiz/SearchPathways';
import SkillsCourses from '../skills-quiz/SkillsCourses';
import { fetchCourseEnrollments } from '../skills-quiz/data/service';
import { saveSkillsGoalsAndJobsUserSelected } from '../skills-quiz/data/utils';

const JobCardComponent = ({
jobs, isLoading, jobIndex, courseIndex,
}) => {
const { dispatch, state } = useContext(SkillsContext);
const { goal } = state;
const { goal, currentJobRole, interestedJobs } = state;
const [jobSelected, setJobSelected] = useState(undefined);
const [showMoreRecommendedCourses, setShowMoreRecommendedCourses] = useState(false);

useEffect(() => {
if (jobs?.length === 1) {
if (jobs?.length > 0) {
setJobSelected(jobs[0]?.name);
dispatch({ type: SET_KEY_VALUE, key: 'selectedJob', value: jobSelected });
} else if (jobs?.length === 0) {
setJobSelected(undefined);
dispatch({ type: SET_KEY_VALUE, key: 'selectedJob', value: undefined });
dispatch({
type: SET_KEY_VALUE,
key: 'selectedJob',
value: jobs[0]?.name,
});
}
}, [jobs, dispatch, jobSelected]);
}, [jobs, dispatch]);

useEffect(() => {
if (goal && (currentJobRole || interestedJobs)) {
saveSkillsGoalsAndJobsUserSelected(goal, currentJobRole, interestedJobs);
}
}, [goal, currentJobRole, interestedJobs]);

useEffect(() => {
const fetchLearnerCourseEnrollments = async () => {
try {
const response = await fetchCourseEnrollments();
const enrolledCourses = camelCaseObject(response.data);
const enrolledCourseIds = enrolledCourses.map(
(course) => course.courseDetails.courseId,
);
dispatch({
type: SET_KEY_VALUE,
key: 'enrolledCourseIds',
value: enrolledCourseIds,
});
} catch (error) {
logError(error);
}
};

if (jobs?.length > 0) {
fetchLearnerCourseEnrollments();
}
}, [dispatch, jobs]);

const handleChange = (e) => {
e.preventDefault();
setJobSelected(e.target.value);
dispatch({ type: SET_KEY_VALUE, key: 'selectedJob', value: e.target.value });
setShowMoreRecommendedCourses(false);
};

return !isLoading ? (
<>
<div className="skills-quiz-v2-job-card">
<SelectableBox.Set
type="radio"
value={jobSelected}
Expand Down Expand Up @@ -68,7 +102,7 @@ const JobCardComponent = ({
</SelectableBox>
))}
</SelectableBox.Set>
{(jobSelected || goal === DROPDOWN_OPTION_IMPROVE_CURRENT_ROLE) && (
{jobs?.length > 0 && (
<>
<TopSkillsOverview index={jobIndex} />
<Stack gap={4}>
Expand All @@ -89,7 +123,7 @@ const JobCardComponent = ({
{ showMoreRecommendedCourses && <SkillsCourses index={courseIndex} />}
</>
)}
</>
</div>
) : (
<Spinner
animation="border"
Expand Down
35 changes: 0 additions & 35 deletions src/components/skills-quiz-v2/ProgramCard.jsx

This file was deleted.

33 changes: 17 additions & 16 deletions src/components/skills-quiz-v2/SkillsQuiz.jsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
import { Helmet } from 'react-helmet';
import './styles/index.scss';
import { AppContext } from '@edx/frontend-platform/react';
import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils';
import PropTypes from 'prop-types';
import {
ModalDialog, useToggle, ActionRow, Button,
} from '@edx/paragon';
import { useNavigate } from 'react-router-dom';
import { useContext } from 'react';
import { useContext, useEffect } from 'react';
import {
SKILL_BUILDER_TITLE,
text,
webTechBootCamps,
closeModalText,
} from './constants';
import ProgramCard from './ProgramCard';
import SkillsQuizHeader from './SkillsQuizHeader';
import SkillQuizForm from './SkillsQuizForm';
import headerImage from '../skills-quiz/images/headerImage.png';

const SkillsQuizV2 = ({ isStyleAutoSuggest }) => {
const { enterpriseConfig } = useContext(AppContext);
const { enterpriseConfig, authenticatedUser: { userId } } = useContext(AppContext);
const navigate = useNavigate();
const [isOpen, open, close] = useToggle(false);

const handleExit = () => {
navigate(`/${enterpriseConfig.slug}/search`);
sendEnterpriseTrackEvent(
enterpriseConfig.uuid,
'edx.ui.enterprise.learner_portal.skills_quiz.done.clicked',
{ userId, enterprise: enterpriseConfig.slug },
);
};

useEffect(() => {
sendEnterpriseTrackEvent(
enterpriseConfig.uuid,
'edx.ui.enterprise.learner_portal.skills_quiz.started',
{ userId, enterprise: enterpriseConfig.slug },
);
}, [enterpriseConfig.slug, enterpriseConfig.uuid, userId]);

const TITLE = `edx - ${SKILL_BUILDER_TITLE}`;
return (
<>
Expand Down Expand Up @@ -58,7 +69,7 @@ const SkillsQuizV2 = ({ isStyleAutoSuggest }) => {
<ModalDialog
title="Skills Quiz"
size="fullscreen"
className="bg-light-200 skills-quiz-modal"
className="bg-light-200 skills-quiz-modal skills-quiz-v2"
isOpen
onClose={open}
>
Expand All @@ -74,16 +85,6 @@ const SkillsQuizV2 = ({ isStyleAutoSuggest }) => {
<p className="text-gray-600 text-justify">{text}</p>
</div>
<SkillQuizForm isStyleAutoSuggest={isStyleAutoSuggest} />
<div className="cards-display">
<p className="pgn__form-label">
Boot camps for a web technology specialist
</p>
<div className="card-container">
{webTechBootCamps.map((bootcamp) => (
<ProgramCard {...bootcamp} />
))}
</div>
</div>
</div>
</ModalDialog.Body>
</ModalDialog>
Expand Down
3 changes: 1 addition & 2 deletions src/components/skills-quiz-v2/SkillsQuizForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ const SkillQuizForm = ({ isStyleAutoSuggest }) => {
<SearchJobDropdown key="search" isStyleSearchBox isChip />
<Button
variant="link"
size="inline"
className="mb-2 mb-sm-0 btn"
className="mb-2 mb-sm-0 advanced-options-btn my-2 mx-n3"
onClick={() => setHide(!hide)}
>
{!hide ? 'Hide advanced options' : 'Show advanced options'}
Expand Down
18 changes: 0 additions & 18 deletions src/components/skills-quiz-v2/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,4 @@ export const SKILL_BUILDER_TITLE = 'Skill Builder';

export const text = 'We combine the educational expertise with labor market data to help you reach your learning and professional goals. Whether you are looking to grow in your career, change careers, or just learn new skills, this tool can help you find a relevant course. Your role selection and recommendations are private and are not visible to your edX administrator';

export const webTechBootCamps = [
{
mainImg:
'https://prod-discovery.edx-cdn.org/media/course/image/8e119d15-b484-4de6-a795-b6d9be101233-19d5867a8db3.small.png',
logoImg:
'https://prod-discovery.edx-cdn.org/organization/logos/eac96c61-1462-4084-a0b2-12525b74a9e1-8377159ff774.png',
title: 'Engineering for Your Classroom K – 3',
subtitle: 'University of British Columbia',
},
{
mainImg:
'https://prod-discovery.edx-cdn.org/media/course/image/7868fb19-176b-4d98-b1a0-4d1e2029fdb8-b302dd3a98d1.jpg',
logoImg:
'https://prod-discovery.edx-cdn.org/organization/logos/eac96c61-1462-4084-a0b2-12525b74a9e1-8377159ff774.png',
title: 'Software Engineering : Introduction',
subtitle: 'University of British Columbia',
},
];
export const closeModalText = 'Learners who enroll in courses that align with their career goals are more likely to complete the course';
69 changes: 37 additions & 32 deletions src/components/skills-quiz-v2/styles/_Body.scss
Original file line number Diff line number Diff line change
@@ -1,37 +1,42 @@
$gray-500: #707070;
$max-sm-modal-width: 28rem !important;
$min-sm-modal-height: 16rem !important;

.page-body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.form {
width: 65%;
}
.pgn__form-group {
width: 101%;
}
.text {
width: 65%;
}
.pgn__form-label {
font-weight: bold;
}
.skills-quiz-v2 {
$max-sm-modal-width: 28rem !important;
$min-sm-modal-height: 16rem !important;

.btn {
margin: 7px -5px;
}
.page-body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

.form-auto-suggest {
.form-control {
color: $gray-500;
.form {
width: 65%;
}

.pgn__form-group {
width: 101%;
}
}

.modal-small {
max-width: $max-sm-modal-width;
min-height: $min-sm-modal-height;
.text {
width: 65%;
}

.pgn__form-label {
font-weight: bold;
}

.advanced-options-btn {
text-decoration: none;
}

.form-auto-suggest {
.form-control {
color: $gray-500;
}
}

.modal-small {
max-width: $max-sm-modal-width;
min-height: $min-sm-modal-height;
}
}
Loading

0 comments on commit 112aef2

Please sign in to comment.