Skip to content

Commit

Permalink
feat: Academy tags chips connected to Algolia search
Browse files Browse the repository at this point in the history
  • Loading branch information
IrfanUddinAhmad committed Jan 18, 2024
1 parent 0cd16cf commit dbef203
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 17 deletions.
14 changes: 4 additions & 10 deletions src/components/academies/AcademyDetailPage.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useContext, useMemo } from 'react';
import {
Container, Chip, Breadcrumb,
Container, Breadcrumb,
Skeleton, Spinner,
} from '@edx/paragon';
import {
Expand All @@ -13,14 +13,15 @@ import { useAcademyMetadata } from './data/hooks';
import CourseCard from './CourseCard';
import NotFoundPage from '../NotFoundPage';
import { ACADEMY_NOT_FOUND_TITLE } from './data/constants';
import './styles/Academy.scss';

const AcademyDetailPage = () => {
const config = getConfig();
const { enterpriseConfig } = useContext(AppContext);
const { academyUUID } = useParams();
const [academy, isAcademyAPILoading, academyAPIError] = useAcademyMetadata(academyUUID);
const academyURL = `/${enterpriseConfig.slug}/academy/${academyUUID}`;

Check failure on line 24 in src/components/academies/AcademyDetailPage.jsx

View workflow job for this annotation

GitHub Actions / tests

Trailing spaces not allowed
// init algolia index
const courseIndex = useMemo(
() => {
Expand Down Expand Up @@ -67,14 +68,6 @@ const AcademyDetailPage = () => {
? <Skeleton height={30} count={3} data-testid="academy-description-loading" />
: <p data-testid="academy-description">{academy?.longDescription}</p>
}
{isAcademyAPILoading ? <Skeleton height={40} className="mt-4 mb-4" data-testid="academy-tags-loading" />
: (
<div className="academy-tags mb-3">
{academy?.tags.map(tag => (
<Chip data-testid="academy-tag" key={tag.id} variant="light">{tag.title}</Chip>
))}
</div>
)}

{isAcademyAPILoading
? (
Expand All @@ -88,6 +81,7 @@ const AcademyDetailPage = () => {
academyUUID={academyUUID}
academyTitle={academy?.title}
academyURL={academyURL}
tags={academy?.tags}
/>
)}
</div>
Expand Down
64 changes: 57 additions & 7 deletions src/components/academies/CourseCard.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import React, { useEffect, useState } from 'react';
import { CardGrid, Spinner } from '@edx/paragon';
import {
Badge,
Button,
CardGrid,
Spinner

Check failure on line 6 in src/components/academies/CourseCard.jsx

View workflow job for this annotation

GitHub Actions / tests

Missing trailing comma
} from '@edx/paragon';
import { camelCaseObject } from '@edx/frontend-platform/utils';
import { v4 as uuidv4 } from 'uuid';
import PropTypes from 'prop-types';
Expand All @@ -10,35 +15,79 @@ import {
} from './data/constants';

const CourseCard = ({
courseIndex, academyUUID, academyTitle, academyURL,
courseIndex, academyUUID, academyTitle, academyURL, tags,
}) => {
const [isAlgoliaLoading, setIsAlgoliaLoading] = useState(true);
const [courses, setCourses] = useState([]);

const [selectedTag, setSelectedTag] = useState();

useEffect(
() => {
function contentIntersect(academyContent, tagContent) {
const intersect = [];
for (const content of tagContent) {

Check failure on line 29 in src/components/academies/CourseCard.jsx

View workflow job for this annotation

GitHub Actions / tests

iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations
if (academyContent.some(o => o.aggregation_key === content.aggregation_key)) {
intersect.push(content);
}
}
return intersect;
}

async function fetchCourses() {
setIsAlgoliaLoading(true);

const { hits, nbHits } = await courseIndex.search('', {
const { hits: academyHits, nbHits: nbAcademyHits } = await courseIndex.search('', {
filters: `content_type:course AND academy_uuids:${academyUUID}`, // eslint-disable-line object-shorthand
});

if (nbHits > 0) {
const hitsCamelCased = camelCaseObject(hits);
setCourses(hitsCamelCased);
let tagHits;
let nbTagHits;
if (selectedTag) {
const response = await courseIndex.search('', {
facetFilters: ['content_type:course', `academy_tags:${selectedTag}`]

Check failure on line 48 in src/components/academies/CourseCard.jsx

View workflow job for this annotation

GitHub Actions / tests

Missing trailing comma
});
({ hits: tagHits, nbHits: nbTagHits } = response);

Check failure on line 50 in src/components/academies/CourseCard.jsx

View workflow job for this annotation

GitHub Actions / tests

'nbTagHits' is assigned a value but never used
}

if (nbAcademyHits > 0) {
let allHits;
const academyHitsCamelCased = camelCaseObject(academyHits);

if (selectedTag) {
const tagHitsCamelCased = camelCaseObject(tagHits);
allHits = contentIntersect(academyHitsCamelCased, tagHitsCamelCased);
} else {
allHits = academyHitsCamelCased;
}

setCourses(allHits);
setIsAlgoliaLoading(false);
} else {
setIsAlgoliaLoading(false);
}
}
fetchCourses();
},
[courseIndex, academyUUID],
[courseIndex, academyUUID, selectedTag],
);

return (
<>
<div className="academy-tags mb-3">
{tags.map(tag => (

Check failure on line 78 in src/components/academies/CourseCard.jsx

View workflow job for this annotation

GitHub Actions / tests

'tags.map' is missing in props validation
<Badge
as={Button}
className="academy-tag"
data-testid="academy-tag"
key={tag.id}
onClick={() => setSelectedTag(tag.title)}
>
{tag.title}
</Badge>
))}
</div>

<div className="academy-exec-ed-courses-container my-4">
<h3 data-testid="academy-exec-ed-courses-title">{EXECUTIVE_EDUCATION_SECTION.title}</h3>
<p data-testid="academy-exec-ed-courses-subtitle">{EXECUTIVE_EDUCATION_SECTION.subtitle}</p>
Expand Down Expand Up @@ -109,6 +158,7 @@ CourseCard.propTypes = {
academyUUID: PropTypes.string.isRequired,
academyTitle: PropTypes.string.isRequired,
academyURL: PropTypes.string.isRequired,
tags: PropTypes.shape({}).isRequired,
};

export default CourseCard;
13 changes: 13 additions & 0 deletions src/components/academies/styles/Academy.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,16 @@
right: 1em;
}
}
.academy-tag {
padding: 6px;
margin-right: 7px;
margin-top: 8px;
font-size: .875rem;
font-weight: normal;
color: #454545 !important;
background-color: #E1DDDB !important;
border-color: #E1DDDB !important;
}



1 change: 1 addition & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@
@import "./components/executive-education-2u/styles/ExecutiveEducation2UPage";
@import "./components/executive-education-2u/styles/ExecutiveEducation2UErrorPage";
@import "./components/skills-quiz-v2/styles";
@import "./components/academies/styles/Academy"

0 comments on commit dbef203

Please sign in to comment.