Skip to content

Commit

Permalink
Group partners by age (#2685)
Browse files Browse the repository at this point in the history
* port partners/results to TSX

* Make the change and get test coverage

* Code review issues

Remove dialog-context, pass title/setTitle around
Remove commented-out stars and count
Stop re-shuffling partners every time you view details
Use Object.keys instead of Reflect.ownKeys

* Fix tests

* Remove equity rating filter functionality
  • Loading branch information
RoyEJohnson authored Dec 9, 2024
1 parent ea3d97f commit 7b7e836
Show file tree
Hide file tree
Showing 19 changed files with 1,919 additions and 3,756 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"boxible": "^1.7.1",
"classnames": "^2.3.2",
"color": "^4.2.3",
"date-fns": "^4.1.0",
"deep-equal": "^2.2.3",
"esbuild-loader": "^3.0.1",
"js-cookie": "^3.0.5",
Expand Down
4 changes: 4 additions & 0 deletions src/app/models/reviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ const postUrl = 'salesforce/reviews/';
// calculate them anyway.
// Note: mutator
function recalculateRatings(data) {
if (!data.reviews) {
data.reviews = [];
data.averageRating = {};
}
const reviewsThatCount = data.reviews.filter((r) => r.status === 'Approved');

data.ratingCount = reviewsThatCount.length;
Expand Down
2 changes: 0 additions & 2 deletions src/app/models/salesforce-partners.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import cmsFetch from '~/helpers/cms-fetch';

export default cmsFetch('salesforce/partners');

export const tooltipText = 'Features verified by instructors who use OpenStax';
3 changes: 1 addition & 2 deletions src/app/pages/details/common/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {useState, useEffect} from 'react';
import tableOfContentsHtml from '~/models/table-of-contents-html';
import partnerFeaturePromise, {tooltipText} from '~/models/salesforce-partners';
import partnerFeaturePromise from '~/models/salesforce-partners';
import shuffle from 'lodash/shuffle';
import {camelCaseKeys} from '~/helpers/page-data-utils';
import useDetailsContext from '../context';
Expand Down Expand Up @@ -33,7 +33,6 @@ function toBlurb(partner: PartnerData) {
cost: pData.affordabilityCost,
type: pData.partnerType,
url: `/partners?${pData.partnerName}`,
verifiedFeatures: pData.verifiedByInstructor ? tooltipText : false,
rating: pData.averageRating?.ratingAvg,
ratingCount: pData.ratingCount
};
Expand Down
4 changes: 1 addition & 3 deletions src/app/pages/partners/partner-details/partner-context.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import buildContext from '~/components/jsx-helpers/build-context';
import useReviews from '~/models/reviews';
import useDialogContext from '../results/dialog-context';

// eslint-disable-next-line complexity
function useContextValue({id: partnerId, model}) {
function useContextValue({id: partnerId, model, title, setTitle}) {
const [ratings, postRating] = useReviews(partnerId);
const {title, setTitle} = useDialogContext();

if (!ratings) {
return {};
Expand Down
8 changes: 4 additions & 4 deletions src/app/pages/partners/partner-details/partner-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function RequestInfoButton({infoText='Request info'}) {
function Overview({model, icon}) {
const {
richDescription: description,
infoUrl, infoLinkText: infoText,
infoLinkText: infoText,
books, images, videos, title: partnerName
} = model;
const titles = useRealTitles(books);
Expand All @@ -84,7 +84,7 @@ function Overview({model, icon}) {
<section className="carousel">
<Carousel {...{icon, images, videos}} />
</section>
<RequestInfoButton {...{infoUrl, infoText, partnerName}} />
<RequestInfoButton {...{infoText, partnerName}} />
<hr />
<section className="overview">
<h2>Overview</h2>
Expand Down Expand Up @@ -145,9 +145,9 @@ function PartnerDetailsOrInfoRequestForm({model}) {
);
}

export default function PartnerDetailsWrapper({detailData: {id, ...model}}) {
export default function PartnerDetailsWrapper({detailData: {id, ...model}, title, setTitle}) {
return (
<PartnerContextProvider contextValueParameters={{id, model}}>
<PartnerContextProvider contextValueParameters={{id, model, title, setTitle}}>
<PartnerDetailsOrInfoRequestForm model={model} />
</PartnerContextProvider>
);
Expand Down
19 changes: 4 additions & 15 deletions src/app/pages/partners/partners.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import RawHTML from '~/components/jsx-helpers/raw-html';
import LoaderPage from '~/components/jsx-helpers/loader-page';
import Controls from './controls/controls';
import MobileControlRow from './mobile-controls/mobile-controls';
import Results, {costOptions, equityOptions} from './results/results';
import Results, {costOptions} from './results/results';
import {useLocation} from 'react-router-dom';
import {SearchContextProvider} from './search-context';
import './partners.scss';
Expand Down Expand Up @@ -67,8 +67,6 @@ function getFilterOptions(data) {
if (itemInResult) {
if (label === 'Cost per semester') {
costOptions.forEach((opt) => itemInResult.options.push(opt));
} else if (label === 'Equity Rating') {
equityOptions.forEach((opt) => itemInResult.options.push(opt));
} else {
itemInResult.options.push(entry);
}
Expand All @@ -78,22 +76,13 @@ function getFilterOptions(data) {
return result;
}

// eslint-disable-next-line complexity
function textsFromData(data) {
const linkTexts = {
websiteLinkText: data.partner_landing_page_link,
infoLinkText: (data.partner_request_info_link || 'Request info')
};
const headerTexts = {
partnerHeader: data.partner_full_partner_heading || 'Full partners',
partnerDescription: data.partner_full_partner_description ||
'Something about what Full Partners are',
allyHeader: data.partner_ally_heading || 'Brand allies',
allyDescription: data.partner_ally_description ||
'Something about what Brand Allies are'
};

return {linkTexts, headerTexts};
return {linkTexts};
}

function Partners({data}) {
Expand All @@ -114,7 +103,7 @@ function Partners({data}) {
);
const headline = data.heading;
const description = data.description;
const {linkTexts, headerTexts} = textsFromData(data);
const {linkTexts} = textsFromData(data);

return (
<React.Fragment>
Expand All @@ -134,7 +123,7 @@ function Partners({data}) {
className="padding"
data-analytics-content-list={headline}
>
<Results linkTexts={linkTexts} headerTexts={headerTexts} />
<Results linkTexts={linkTexts} />
</div>
</React.Fragment>
);
Expand Down
21 changes: 0 additions & 21 deletions src/app/pages/partners/results/dialog-context.js

This file was deleted.

126 changes: 0 additions & 126 deletions src/app/pages/partners/results/result-grid.js

This file was deleted.

61 changes: 61 additions & 0 deletions src/app/pages/partners/results/result-grid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
import {useNavigate} from 'react-router-dom';
import type {PartnerEntry} from './results';

function modelFromEntry(entry: PartnerEntry) {
return {
type: entry.type,
title: entry.title,
logoUrl: entry.logoUrl,
description: entry.blurb,
tags: entry.tags,
badgeImage: '/dist/images/partners/verified-badge.svg'
};
}

function ResultCard({entry}: {entry: PartnerEntry}) {
const {type, title, logoUrl, tags} =
modelFromEntry(entry);
const navigate = useNavigate();
const onSelect = React.useCallback(
(event: React.MouseEvent<HTMLAnchorElement>) => {
event.preventDefault();
const href = event.currentTarget.getAttribute('href');

navigate(href as string, {replace: true});
},
[navigate]
);

return (
<a
href={`?${encodeURIComponent(title)}`}
type="button"
className="card"
onClick={onSelect}
data-analytics-select-content={title}
data-content-type="Partner Profile"
data-content-tags={`,category=${type},`}
>
<div className="logo">
{logoUrl && <img src={logoUrl} alt="" />}
</div>
<div className="resource-title">{title}</div>
<div className="tags">
{tags.map(({value}) => (
<div key={value}>{value}</div>
))}
</div>
</a>
);
}

export default function ResultGrid({entries}: {entries: PartnerEntry[]}) {
return (
<div className="boxed grid">
{entries.map((entry) => (
<ResultCard key={entry.title} entry={entry} />
))}
</div>
);
}
Loading

0 comments on commit 7b7e836

Please sign in to comment.