Skip to content

Commit

Permalink
fix: APER-2852 - fit and finish categorizinator
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxFrank13 committed Sep 15, 2023
1 parent 6a13827 commit 7665126
Show file tree
Hide file tree
Showing 36 changed files with 351 additions and 165 deletions.
51 changes: 51 additions & 0 deletions src/skills-builder/ProductTool.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { useState, useContext } from 'react';
import {
Container, Stack, Form, Button,
} from '@edx/paragon';
import { VisibilityFlagsContext } from './visibility-flags-context';
import { setAllFlags } from './visibility-flags-context/data/actions';

const ProductTool = () => {
/*
This component renders a tool that contains a checkbox for each feature flag.
Setting each checkbox and then clicking the "Configure" button will trigger a rerender of the UI.
*/
const { state: visibilityFlagsState, dispatch } = useContext(VisibilityFlagsContext);
const [checkboxState, setCheckboxState] = useState(visibilityFlagsState);

// click handle for the "Configure" button
const handleClick = () => {
// sets all flags to whatever is being held in state
dispatch(setAllFlags(checkboxState));
};

const onCheckboxChange = (e) => {
// extract `checked` (boolean) and `value` (string) from the target (checkbox)
const { checked, value } = e.target;
setCheckboxState(prev => ({
...prev,
// set the key for this flag to whatever `checked` is
[value]: checked,
}));
};

return (
<Container className="py-4.5 border-top">
<Stack direction="horizontal" className="justify-content-around">
<Form.CheckboxSet
name="visibility-flags"
onChange={onCheckboxChange}
defaultValue={Object.keys(checkboxState).filter(item => checkboxState[item])}
>
{Object.keys(visibilityFlagsState).map((item, idx) => (
// eslint-disable-next-line react/no-array-index-key
<Form.Checkbox key={idx} value={item}>{item}</Form.Checkbox>
))}
</Form.CheckboxSet>
<Button onClick={handleClick}>Configure</Button>
</Stack>
</Container>
);
};

export default ProductTool;
20 changes: 11 additions & 9 deletions src/skills-builder/SkillsBuilder.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import React, { useRef } from 'react';
import React, { useContext } from 'react';
import { SkillsBuilderDefault } from './skills-builder-steps';
import { SkillsBuilderProvider } from './skills-builder-context';
import { useVisibilityFlags } from './skills-builder-steps/view-results/data/hooks';
import SkillsBuilderProgressive from './skills-builder-steps/SkillsBuilderProgressive';
import ProductTool from './ProductTool';
import { VisibilityFlagsContext } from './visibility-flags-context';

const SkillsBuilder = () => {
const visibilityFlags = useRef(useVisibilityFlags());
const { isProgressive } = visibilityFlags.current;
const { state: visibilityFlagsState } = useContext(VisibilityFlagsContext);
const { isProgressive, showProductTool } = visibilityFlagsState;

return (
<SkillsBuilderProvider>
{ isProgressive ? (
<>
{isProgressive ? (
<SkillsBuilderProgressive />
) : (
<SkillsBuilderDefault />
)}

</SkillsBuilderProvider>
{showProductTool && (
<ProductTool />
)}
</>
);
};

Expand Down
14 changes: 14 additions & 0 deletions src/skills-builder/SkillsBuilderContextWrapper.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { SkillsBuilderProvider } from './skills-builder-context';
import { VisibilityFlagsProvider } from './visibility-flags-context';
import SkillsBuilder from './SkillsBuilder';

const SkillsBuilderContextWrapper = () => (
<SkillsBuilderProvider>
<VisibilityFlagsProvider>
<SkillsBuilder />
</VisibilityFlagsProvider>
</SkillsBuilderProvider>
);

export default SkillsBuilderContextWrapper;
2 changes: 1 addition & 1 deletion src/skills-builder/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// eslint-disable-next-line import/prefer-default-export
export { default as SkillsBuilder } from './SkillsBuilder';
export { default as SkillsBuilder } from './SkillsBuilderContextWrapper';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { createContext, useReducer, useMemo } from 'react';
import PropTypes from 'prop-types';
import reducer, { skillsInitialState } from '../data/reducer';
import reducer, { skillsInitialState } from './data/reducer';
import { useAlgoliaSearch } from '../utils/search';

export const SkillsBuilderContext = createContext();
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,3 @@ export const CLEAR_ALL_CAREER_INTERESTS = 'CLEAR_ALL_CAREER_INTERESTS';
export const ADD_TO_EXPANDED_LIST = 'ADD_TO_EXPANDED_LIST';
export const REMOVE_FROM_EXPANDED_LIST = 'REMOVE_FROM_EXPANDED_LIST';
export const SET_EXPANDED_LIST = 'SET_EXPANDED_LIST';

// Stepper keys
export const STEP1 = 'select-your-preferences';
export const STEP2 = 'review-your-results';
File renamed without changes.
27 changes: 15 additions & 12 deletions src/skills-builder/skills-builder-header/SkillsBuilderHeader.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import React, { useRef } from 'react';
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Container } from '@edx/paragon';
import edXLogo from '../images/edX-logo.svg';
import { useVisibilityFlags } from '../skills-builder-steps/view-results/data/hooks';
import { VisibilityFlagsContext } from '../visibility-flags-context';
import messages from './messages';

const SkillsBuilderHeader = ({ isMedium }) => {
const { formatMessage } = useIntl();
const visibilityFlags = useRef(useVisibilityFlags());
const { showSmallHeader } = visibilityFlags.current;
const { state: visibilityFlagsState } = useContext(VisibilityFlagsContext);
const { showSmallHeader } = visibilityFlagsState;

if (showSmallHeader || isMedium) {
return (
<div className="d-flex bg-primary-500 little-hero">
<img src={edXLogo} alt="edx-logo" className="mt-2 edx-logo" />
<div className="ml-3 vertical-line" />
<div className="d-flex align-items-center w-100 ml-3">
<h1 className="h2 m-0 text-warning-300">
{formatMessage(messages.skillsBuilderHeaderTitle)}
</h1>
</div>
<div className="bg-primary-500">
<Container className="d-flex little-hero container-mw-md">
<img src={edXLogo} alt="edx-logo" className="mt-2 edx-logo" />
<div className="ml-3 vertical-line" />
<div className="d-flex align-items-center w-100 ml-3">
<h1 className="h2 m-0 text-warning-300">
{formatMessage(messages.skillsBuilderHeaderTitle)}
</h1>
</div>
</Container>
</div>

);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useIntl } from '@edx/frontend-platform/i18n';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import {
STEP1, STEP2,
} from '../data/constants';
} from './data/constants';
import messages from './messages';

import { SkillsBuilderContext } from '../skills-builder-context';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const SkillsBuilderProgressive = () => {
)}

</Form>
<Hyperlink destination={getConfig().MARKETING_SITE_SEARCH_URL} className="align-self-end">
<Hyperlink destination={getConfig().MARKETING_SITE_SEARCH_URL} className="align-self-end pt-4.5">
<Button onClick={exitButtonHandle}>
{formatMessage(messages.exitButton)}
</Button>
Expand Down
3 changes: 3 additions & 0 deletions src/skills-builder/skills-builder-steps/data/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Stepper keys
export const STEP1 = 'select-your-preferences';
export const STEP2 = 'review-your-results';
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useIntl } from '@edx/frontend-platform/i18n';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { Close } from '@edx/paragon/icons';
import { SkillsBuilderContext } from '../../skills-builder-context';
import { removeCareerInterest } from '../../data/actions';
import { removeCareerInterest } from '../../skills-builder-context/data/actions';
import messages from './messages';

const CareerInterestCard = ({ interest }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import React, { useContext, useRef } from 'react';
import React, { useContext, useState } from 'react';
import { useIntl } from '@edx/frontend-platform/i18n';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import {
Stack, Row, Col, Form, Dropdown, DropdownButton,
Stack, Row, Col, Form, Icon,
} from '@edx/paragon';
import { Verified } from '@edx/paragon/icons';
import CareerInterestCard from './CareerInterestCard';
import { addCareerInterest, clearAllCareerInterests } from '../../data/actions';
import { addCareerInterest, clearAllCareerInterests } from '../../skills-builder-context/data/actions';
import { SkillsBuilderContext } from '../../skills-builder-context';
import { useVisibilityFlags } from '../view-results/data/hooks';
import messages from './messages';
import { careerList } from '../../utils/jobsByCategory';
import { VisibilityFlagsContext } from '../../visibility-flags-context';
import { FORM_VALUES } from './data/constants';

const CareerInterestCategorizinator = () => {
const { formatMessage } = useIntl();
const { state, dispatch } = useContext(SkillsBuilderContext);
const { careerInterests } = state;
const visibilityFlags = useRef(useVisibilityFlags());
const { showCareerInterestCards, allowMultipleCareerInterests, isProgressive } = visibilityFlags.current;
const { state: visibilityFlagsState } = useContext(VisibilityFlagsContext);
const { showCareerInterestCards, allowMultipleCareerInterests, isProgressive } = visibilityFlagsState;

const handleCareerInterestSelect = (value) => {
if (!allowMultipleCareerInterests && careerInterests.length > 0) {
Expand All @@ -39,24 +41,37 @@ const CareerInterestCategorizinator = () => {
}
};

// state for controlling every dropdown menu
const [dropdownState, setDropdownState] = useState(FORM_VALUES);

const populateDropdown = (category, title = category) => {
const currentCategory = careerList[category];
const controlState = dropdownState[category];

const handleSelectChange = (e) => {
const { value } = e.target;
setDropdownState({
...FORM_VALUES,
[category]: value,
});
handleCareerInterestSelect(value);
};

return (
<DropdownButton
id={category}
title={title}
variant="light"
<Form.Control
as="select"
value={controlState}
onChange={handleSelectChange}
className="select-width"
leadingElement={controlState && (<Icon src={Verified} />)}
floatingLabel={controlState && title}
>
{currentCategory.map((job) => (
<Dropdown.Item
key={job.JobTitle}
onClick={() => handleCareerInterestSelect(job.JobTitle)}
>
{job.JobTitle}
</Dropdown.Item>
<option disabled={controlState}>{title}</option>
{currentCategory.map((job, idx) => (
// eslint-disable-next-line react/no-array-index-key
<option key={idx}>{job.JobTitle}</option>
))}
</DropdownButton>
</Form.Control>
);
};

Expand All @@ -75,15 +90,15 @@ const CareerInterestCategorizinator = () => {
</Form.Label>
<Stack
direction="horizontal"
gap={2}
gap={3}
className="flex-wrap"
>
{populateDropdown('Coding')}
{populateDropdown('Business')}
{populateDropdown('ProductManagement', 'Product Management')}
{populateDropdown('Data')}
{populateDropdown('ArtificialIntelligence', 'Artificial Intelligence')}
{populateDropdown('Business')}
{populateDropdown('Coding')}
{populateDropdown('Communications')}
{populateDropdown('Data')}
{populateDropdown('ProductManagement', 'Product Management')}
</Stack>
{ showCareerInterestCards && (
<Row>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext, useRef } from 'react';
import React, { useContext } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
Expand All @@ -8,18 +8,18 @@ import {
import { Configure, InstantSearch } from 'react-instantsearch';
import JobTitleInstantSearch from './JobTitleInstantSearch';
import CareerInterestCard from './CareerInterestCard';
import { addCareerInterest, clearAllCareerInterests } from '../../data/actions';
import { addCareerInterest, clearAllCareerInterests } from '../../skills-builder-context/data/actions';
import { SkillsBuilderContext } from '../../skills-builder-context';
import { useVisibilityFlags } from '../view-results/data/hooks';
import { VisibilityFlagsContext } from '../../visibility-flags-context';
import messages from './messages';

const CareerInterestSelect = () => {
const { formatMessage } = useIntl();
const { state, dispatch, algolia } = useContext(SkillsBuilderContext);
const { careerInterests } = state;
const { searchClient } = algolia;
const visibilityFlags = useRef(useVisibilityFlags());
const { showCareerInterestCards, allowMultipleCareerInterests } = visibilityFlags.current;
const { state: visibilityFlagsState } = useContext(VisibilityFlagsContext);
const { showCareerInterestCards, allowMultipleCareerInterests } = visibilityFlagsState;

const handleCareerInterestSelect = (value) => {
if (!allowMultipleCareerInterests && careerInterests.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
} from '@edx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { setGoal } from '../../data/actions';
import { setGoal } from '../../skills-builder-context/data/actions';
import { SkillsBuilderContext } from '../../skills-builder-context';
import messages from './messages';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import { useIntl } from '@edx/frontend-platform/i18n';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { InstantSearch } from 'react-instantsearch';
import { setCurrentJobTitle } from '../../data/actions';
import { setCurrentJobTitle } from '../../skills-builder-context/data/actions';
import { SkillsBuilderContext } from '../../skills-builder-context';
import JobTitleInstantSearch from './JobTitleInstantSearch';
import messages from './messages';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, { useRef } from 'react';
import React, { useContext } from 'react';
import {
Stack,
} from '@edx/paragon';
import { useVisibilityFlags } from '../view-results/data/hooks';
import { VisibilityFlagsContext } from '../../visibility-flags-context';
import GoalSelect from './GoalSelect';
import JobTitleSelect from './JobTitleSelect';
import CareerInterestSelect from './CareerInterestSelect';
import CareerInterestCategorizinator from './CareerInterestCategorizinator';

const SelectPreferences = () => {
const visibilityFlags = useRef(useVisibilityFlags());
const { showGoal, showCurrentJobTitle, showCategorizinator } = visibilityFlags.current;
const { state: visibilityFlagsState } = useContext(VisibilityFlagsContext);
const { showGoal, showCurrentJobTitle, showCategorizinator } = visibilityFlagsState;

return (
<Stack gap={4}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable-next-line import/prefer-default-export
export const FORM_VALUES = {
Coding: '',
Business: '',
ProductManagement: '',
Data: '',
ArtificialIntelligence: '',
Communications: '',
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ $breakpoint-medium: 992px;
overflow: scroll;
}
}

.select-width {
width: 20rem;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Stack } from '@edx/paragon';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import ProductCardGrid from './ProductCardGrid';
import ProductTypeBanner from './ProductTypeBanner';
import { addToExpandedList, removeFromExpandedList } from '../../data/actions';
import { addToExpandedList, removeFromExpandedList } from '../../skills-builder-context/data/actions';
import { SkillsBuilderContext } from '../../skills-builder-context';
import { extractProductKeys } from '../../utils/extractProductKeys';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '@edx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { addCareerInterest } from '../../data/actions';
import { addCareerInterest } from '../../skills-builder-context/data/actions';
import { SkillsBuilderContext } from '../../skills-builder-context';
import messages from './messages';

Expand Down
Loading

0 comments on commit 7665126

Please sign in to comment.