Skip to content

Commit

Permalink
Merge pull request #11387 from wellcomecollection/top-stories-content…
Browse files Browse the repository at this point in the history
…-api

Stories page articles from Content API
  • Loading branch information
davidpmccormick authored Nov 18, 2024
2 parents e850f79 + 060bcaf commit 0d3e125
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 53 deletions.
60 changes: 28 additions & 32 deletions content/webapp/components/FeaturedCard/FeaturedCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ import styled from 'styled-components';
import { ImageType } from '@weco/common/model/image';
import { Label } from '@weco/common/model/labels';
import linkResolver from '@weco/common/services/prismic/link-resolver';
import { transformImage } from '@weco/common/services/prismic/transformers/images';
import { font, grid } from '@weco/common/utils/classnames';
import LabelsList from '@weco/common/views/components/LabelsList/LabelsList';
import PrismicImage from '@weco/common/views/components/PrismicImage/PrismicImage';
import Space from '@weco/common/views/components/styled/Space';
import { PaletteColor } from '@weco/common/views/themes/config';
import DateRange from '@weco/content/components/DateRange/DateRange';
import PartNumberIndicator from '@weco/content/components/PartNumberIndicator/PartNumberIndicator';
import StatusIndicator from '@weco/content/components/StatusIndicator/StatusIndicator';
import {
ArticleBasic,
getArticleColor,
getPartNumberInSeries,
} from '@weco/content/types/articles';
import { Article } from '@weco/content/services/wellcome/content/types/api';
import { ArticleBasic } from '@weco/content/types/articles';
import { BookBasic } from '@weco/content/types/books';
import { Card } from '@weco/content/types/card';
import { EventSeries } from '@weco/content/types/event-series';
Expand Down Expand Up @@ -89,44 +86,29 @@ export function convertItemToFeaturedCardProps(
}

type FeaturedCardArticleProps = {
article: ArticleBasic;
article: Article;
background: PaletteColor;
textColor: PaletteColor;
};

type FeaturedCardArticleBodyProps = {
article: ArticleBasic;
article: Article;
};

// TODO: make this e.g. just `CardArticleBody` and work it back into the existing promos/cards
const FeaturedCardArticleBody: FunctionComponent<
FeaturedCardArticleBodyProps
> = ({ article }) => {
const partNumber = getPartNumberInSeries(article);
const seriesColor = getArticleColor(article);
return (
<>
{partNumber && (
<PartNumberIndicator
number={partNumber}
backgroundColor={seriesColor}
/>
)}
<h2 className={font('wb', 2)}>{article.title}</h2>
{article.promo?.caption && (
<p className={font('intr', 5)}>{article.promo?.caption}</p>
)}
{article.series.length > 0 && (
{article.caption && <p className={font('intr', 5)}>{article.caption}</p>}
{article.seriesTitle && (
<Space $v={{ size: 'l', properties: ['margin-top'] }}>
{article.series.map(series => (
<p
key={series.title}
className={font('intb', 6)}
style={{ marginBottom: 0 }}
>
<span className={font('intr', 6)}>Part of</span> {series.title}
</p>
))}
<p className={font('intb', 6)} style={{ marginBottom: 0 }}>
<span className={font('intr', 6)}>Part of</span>{' '}
{article.seriesTitle}
</p>
</Space>
)}
</>
Expand Down Expand Up @@ -303,10 +285,24 @@ const FeaturedCard: FunctionComponent<PropsWithChildren<Props>> = ({
export const FeaturedCardArticle: FunctionComponent<
FeaturedCardArticleProps
> = ({ article, background, textColor }) => {
const props = convertItemToFeaturedCardProps(article);

const promoImage = article.image?.['16:9'] || article.image;
const image = promoImage && {
...transformImage(promoImage),
alt: '',
};
const link = {
url: linkResolver({ type: 'articles', uid: article.uid }),
text: article.title,
};
const labels = [{ text: article.format.label }];
return (
<FeaturedCard {...props} background={background} textColor={textColor}>
<FeaturedCard
image={image}
link={link}
labels={labels}
background={background}
textColor={textColor}
>
<FeaturedCardArticleBody article={article} />
</FeaturedCard>
);
Expand Down
43 changes: 22 additions & 21 deletions content/webapp/pages/stories/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { pageDescriptions } from '@weco/common/data/microcopy';
import { StoriesLandingDocument as RawStoriesLandingDocument } from '@weco/common/prismicio-types';
import { getServerData } from '@weco/common/server-data';
import { AppErrorProps } from '@weco/common/services/app';
import { transformImage } from '@weco/common/services/prismic/transformers/images';
import { serialiseProps } from '@weco/common/utils/json';
import { createPrismicLink } from '@weco/common/views/components/ApiToolbar';
import { JsonLdObj } from '@weco/common/views/components/JsonLd/JsonLd';
Expand All @@ -27,26 +28,24 @@ import { FeaturedCardArticle } from '@weco/content/components/FeaturedCard/Featu
import FeaturedText from '@weco/content/components/FeaturedText/FeaturedText';
import { defaultSerializer } from '@weco/content/components/HTMLSerializers/HTMLSerializers';
import SectionHeader from '@weco/content/components/SectionHeader/SectionHeader';
import StoryPromo from '@weco/content/components/StoryPromo/StoryPromo';
import StoryPromoContentApi from '@weco/content/components/StoryPromo/StoryPromoContentApi';
import { ArticleFormatIds } from '@weco/content/data/content-format-ids';
import { createClient } from '@weco/content/services/prismic/fetch';
import { fetchArticles } from '@weco/content/services/prismic/fetch/articles';
import { fetchStoriesLanding } from '@weco/content/services/prismic/fetch/stories-landing';
import {
transformArticle,
transformArticleToArticleBasic,
} from '@weco/content/services/prismic/transformers/articles';
import { articleLd } from '@weco/content/services/prismic/transformers/json-ld';
import { transformArticle as transformPrismicArticle } from '@weco/content/services/prismic/transformers/articles';
import { articleLdContentApi } from '@weco/content/services/prismic/transformers/json-ld';
import { transformQuery } from '@weco/content/services/prismic/transformers/paginated-results';
import { transformSeriesToSeriesBasic } from '@weco/content/services/prismic/transformers/series';
import { transformStoriesLanding } from '@weco/content/services/prismic/transformers/stories-landing';
import { ArticleBasic } from '@weco/content/types/articles';
import { getArticles } from '@weco/content/services/wellcome/content/articles';
import { Article } from '@weco/content/services/wellcome/content/types/api';
import { Series, SeriesBasic } from '@weco/content/types/series';
import { StoriesLanding } from '@weco/content/types/stories-landing';
import { setCacheControl } from '@weco/content/utils/setCacheControl';

type Props = {
articles: ArticleBasic[];
articles: Article[];
comicSeries: SeriesBasic[];
storiesLanding: StoriesLanding;
jsonLd: JsonLdObj[];
Expand Down Expand Up @@ -97,31 +96,34 @@ export const getServerSideProps: GetServerSideProps<
setCacheControl(context.res);
const serverData = await getServerData(context);
const client = createClient(context);
const articlesQueryPromise = fetchArticles(client, {
filters: prismic.filter.not('my.articles.format', ArticleFormatIds.Comic),
});

const comicsQueryPromise = fetchArticles(client, {
pageSize: 100, // we need enough comics to make sure we have at least one from three different series
filters: prismic.filter.at('my.articles.format', ArticleFormatIds.Comic),
});

const storiesLandingPromise = fetchStoriesLanding(client);
const articlesResponsePromise = getArticles({
params: {},
pageSize: 11,
toggles: serverData.toggles,
});

const [articlesQuery, storiesLandingDoc, comicsQuery] = await Promise.all([
articlesQueryPromise,
const [articlesResponse, storiesLandingDoc, comicsQuery] = await Promise.all([
articlesResponsePromise,
storiesLandingPromise,
comicsQueryPromise,
]);

const articles = transformQuery(articlesQuery, transformArticle);
const articles =
articlesResponse.type === 'ResultList' ? articlesResponse.results : [];

// In order to avoid the case where we end up with an empty comic series,
// rather than querying for the series itself we query for the individual
// comics, then group them by series and stop once we've got to three. That
// way we can be confident each of the three series that we have contains at
// least one comic.
const comics = transformQuery(comicsQuery, transformArticle);
const comics = transformQuery(comicsQuery, transformPrismicArticle);
const comicSeries = new Map<string, Series>();
for (const comic of comics.results) {
const series = comic.series[0];
Expand All @@ -137,16 +139,15 @@ export const getServerSideProps: GetServerSideProps<
transformSeriesToSeriesBasic
);

const jsonLd = articles.results.map(articleLd);
const basicArticles = articles.results.map(transformArticleToArticleBasic);
const jsonLd = articles.map(articleLdContentApi);
const storiesLanding =
storiesLandingDoc &&
transformStoriesLanding(storiesLandingDoc as RawStoriesLandingDocument);

if (articles && articles.results) {
if (articles) {
return {
props: serialiseProps({
articles: basicArticles,
articles,
comicSeries: basicComicSeries,
serverData,
jsonLd,
Expand Down Expand Up @@ -175,7 +176,7 @@ const StoriesPage: FunctionComponent<Props> = ({
jsonLd={jsonLd}
openGraphType="website"
siteSection="stories"
image={firstArticle && firstArticle.image}
image={firstArticle && transformImage(firstArticle.image)}
rssUrl="https://rss.wellcomecollection.org/stories"
apiToolbarLinks={[createPrismicLink(storiesLanding.id)]}
>
Expand Down Expand Up @@ -217,7 +218,7 @@ const StoriesPage: FunctionComponent<Props> = ({
return (
<div className="grid__cell" key={article.id}>
<Space $v={{ size: 'm', properties: ['margin-bottom'] }}>
<StoryPromo article={article} />
<StoryPromoContentApi article={article} />
</Space>
</div>
);
Expand Down

0 comments on commit 0d3e125

Please sign in to comment.