Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
221a6e6
Merge branch 'latest' of ssh://github.com/bbc/simorgh into latest
louisearchibald Sep 12, 2025
637e7a2
Merge branch 'latest' of ssh://github.com/bbc/simorgh into latest
louisearchibald Sep 12, 2025
4f2f3c4
create helper function to extract end part of mostRead id
louisearchibald Sep 12, 2025
3d916cd
find mostRead curation and then extract required part of id using helper
louisearchibald Sep 12, 2025
38764f4
pass id to HomeCuration and extend Curation type
louisearchibald Sep 12, 2025
d14d520
ensure helper is exported
louisearchibald Sep 12, 2025
28827e6
use helper to get ids of promo items and then compare against mostReadId
louisearchibald Sep 12, 2025
06d6cbb
add mostReadId to CurationGridProps type
louisearchibald Sep 12, 2025
3f13750
pass to Curation switch case
louisearchibald Sep 12, 2025
6963888
add conditional to render hardcoded text if ids match
louisearchibald Sep 12, 2025
a8d1081
extend Summary type and implement same logic for simple curation grid
louisearchibald Sep 12, 2025
04420d3
add mostReadTitle to translations type
louisearchibald Sep 26, 2025
3fc3d2c
Merge branch 'latest' into most-read-badge-on-homepages
louisearchibald Sep 26, 2025
d273fbd
Merge branch 'most-read-badge-on-homepages' of ssh://github.com/bbc/s…
louisearchibald Sep 26, 2025
1c86199
duplicate import
louisearchibald Sep 26, 2025
b4768b3
import order
louisearchibald Sep 26, 2025
8612c74
add translations for a few services for testing
louisearchibald Sep 26, 2025
1299f13
change type name
louisearchibald Sep 26, 2025
877b475
pass badge text through components and homepage and provide path to t…
louisearchibald Sep 26, 2025
d98a417
add some rough styling
louisearchibald Sep 26, 2025
b9b43a4
Merge branch 'latest' into most-read-badge-on-homepages
louisearchibald Sep 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app/components/Curation/CurationGrid/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const CurationGrid = ({
headingLevel,
eventTrackingData,
readTimeVariant,
mostReadItemId,
}: CurationGridProps) => {
const { isLite } = use(RequestContext);

Expand Down Expand Up @@ -79,6 +80,7 @@ const CurationGrid = ({
{...commonProps}
headingLevel={headingLevel}
readTimeVariant={readTimeVariant}
mostReadItemId={mostReadItemId}
/>
);
}
Expand Down
11 changes: 9 additions & 2 deletions src/app/components/Curation/CurationPromo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@
import useClickTrackerHandler from '#app/hooks/useClickTrackerHandler';
import isMediaType from '#app/lib/utilities/isMedia';
import { ReadTime } from '#app/components/ReadTime';
import { extractId } from '#app/pages/HomePage/HomePage';
import VisuallyHiddenText from '../../VisuallyHiddenText';
import { ServiceContext } from '../../../contexts/ServiceContext';
import { RequestContext } from '../../../contexts/RequestContext';

import LiveLabel from '../../LiveLabel';

import styles from './index.styles';

const CurationPromo = ({
Expand All @@ -33,6 +32,7 @@
readTime,
eventTrackingData,
readTimeVariant,
mostReadItemId,
position,
}: Summary) => {
const { isAmp, isLite } = use(RequestContext);
Expand All @@ -43,6 +43,7 @@
const photoGalleryTranslation = path(['media', 'photogallery'], translations);
const durationTranslation = path(['media', 'duration'], translations);
const duration = moment.duration(mediaDuration, 'seconds');
const mostReadBadgeTranslation = translations.mostReadBadgeText || 'Hello';

const separator = ',';

Expand All @@ -63,6 +64,9 @@
experimentVariant: readTimeVariant,
});

const getPromoItemId = extractId(id) ?? null;
const isMostReadStory = mostReadItemId && getPromoItemId === mostReadItemId;

return (
<Promo css={styles.promo} className="">
{imageUrl && (
Expand Down Expand Up @@ -95,6 +99,9 @@
</Promo.A>
) : (
<Promo.A href={link} {...clickTrackerHandler}>
{isMostReadStory ? (
<div css={styles.mostReadBadge}>{mostReadBadgeTranslation}</div>

Check failure on line 103 in src/app/components/Curation/CurationPromo/index.tsx

View workflow job for this annotation

GitHub Actions / cypress-run (22.x)

Property 'mostReadBadge' does not exist on type '{ promo: ({ isLite }: Theme) => SerializedStyles; icon: ({ isLite, spacings, mq }: Theme) => SerializedStyles; image: () => SerializedStyles; }'.

Check failure on line 103 in src/app/components/Curation/CurationPromo/index.tsx

View workflow job for this annotation

GitHub Actions / cypress-run (22.x)

Property 'mostReadBadge' does not exist on type '{ promo: ({ isLite }: Theme) => SerializedStyles; icon: ({ isLite, spacings, mq }: Theme) => SerializedStyles; image: () => SerializedStyles; }'.

Check failure on line 103 in src/app/components/Curation/CurationPromo/index.tsx

View workflow job for this annotation

GitHub Actions / build (22.x)

Property 'mostReadBadge' does not exist on type '{ promo: ({ isLite }: Theme) => SerializedStyles; icon: ({ isLite, spacings, mq }: Theme) => SerializedStyles; image: () => SerializedStyles; }'.

Check failure on line 103 in src/app/components/Curation/CurationPromo/index.tsx

View workflow job for this annotation

GitHub Actions / cypress-run (22.x)

Property 'mostReadBadge' does not exist on type '{ promo: ({ isLite }: Theme) => SerializedStyles; icon: ({ isLite, spacings, mq }: Theme) => SerializedStyles; image: () => SerializedStyles; }'.
) : null}
{isLive ? <LiveLabel>{title}</LiveLabel> : title}
</Promo.A>
)}
Expand Down
26 changes: 26 additions & 0 deletions src/app/components/Curation/HierarchicalGrid/index.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,32 @@
},
}),
}),
mostReadBadgeLarge: ({ fontSizes, fontVariants, palette, spacings }: Theme) =>
css({
position: 'relative',
display: 'inline',
verticalAlign: '0.25rem',
backgroundColor: palette.POSTBOX,
color: palette.WHITE,
borderRadius: `${spacings.HALF}rem`,
...fontSizes.pica,
...fontVariants.sansBold,
padding: `${spacings.HALF}rem`,
marginInlineEnd: `${spacings.HALF}rem`,
height: '100%',
}),
mostReadBadgeSmall: ({ fontSizes, fontVariants, palette, spacings }: Theme) =>

Check failure on line 124 in src/app/components/Curation/HierarchicalGrid/index.styles.tsx

View workflow job for this annotation

GitHub Actions / cypress-run (22.x)

'spacings' is declared but its value is never read.

Check failure on line 124 in src/app/components/Curation/HierarchicalGrid/index.styles.tsx

View workflow job for this annotation

GitHub Actions / cypress-run (22.x)

'spacings' is declared but its value is never read.

Check failure on line 124 in src/app/components/Curation/HierarchicalGrid/index.styles.tsx

View workflow job for this annotation

GitHub Actions / build (22.x)

'spacings' is declared but its value is never read.

Check failure on line 124 in src/app/components/Curation/HierarchicalGrid/index.styles.tsx

View workflow job for this annotation

GitHub Actions / cypress-run (22.x)

'spacings' is declared but its value is never read.
css({
position: 'relative',
display: 'inline-flex',
backgroundColor: palette.POSTBOX,
color: palette.WHITE,
borderRadius: pixelsToRem(4),
...fontSizes.minion,
...fontVariants.sansBold,
padding: pixelsToRem(4),
marginInlineEnd: pixelsToRem(4),
}),
};

const DesktopBigPromo = css({
Expand Down
20 changes: 20 additions & 0 deletions src/app/components/Curation/HierarchicalGrid/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import moment from 'moment';
import path from 'ramda/src/path';
import isMediaType from '#app/lib/utilities/isMedia';
import { ReadTime } from '#app/components/ReadTime';
import { extractId } from '#app/pages/HomePage/HomePage';
import useClickTrackerHandler from '#app/hooks/useClickTrackerHandler';
import VisuallyHiddenText from '../../VisuallyHiddenText';
import formatDuration from '../../../lib/utilities/formatDuration';
Expand Down Expand Up @@ -42,6 +43,7 @@ const HiearchicalGrid = ({
isFirstCuration,
eventTrackingData,
readTimeVariant,
mostReadItemId,
}: CurationGridProps) => {
const { isAmp } = use(RequestContext);
const { translations } = use(ServiceContext);
Expand All @@ -50,6 +52,9 @@ const HiearchicalGrid = ({
const videoTranslation = path(['media', 'video'], translations);
const photoGalleryTranslation = path(['media', 'photogallery'], translations);
const durationTranslation = path(['media', 'duration'], translations);
const mostReadBadgeTranslation = (
translations.mostReadBadgeText || 'Most Read'
).toUpperCase();

if (!summaries || summaries.length < 3) return null;

Expand Down Expand Up @@ -119,6 +124,10 @@ const HiearchicalGrid = ({
experimentVariant: readTimeVariant,
});

const getPromoItemid = extractId(promo.id) ?? null;
const isMostReadStory =
mostReadItemId && getPromoItemid === mostReadItemId;

return (
<li
key={promo.id}
Expand Down Expand Up @@ -169,6 +178,17 @@ const HiearchicalGrid = ({
</Promo.A>
) : (
<Promo.A href={promo.link} {...clickTrackerHandler}>
{isMostReadStory ? (
<div
css={
isFirstPromo
? styles.mostReadBadgeLarge
: styles.mostReadBadgeSmall
}
>
{mostReadBadgeTranslation}
</div>
) : null}
{isLive ? (
<LiveLabel
{...(isFirstPromo
Expand Down
3 changes: 3 additions & 0 deletions src/app/components/Curation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export default ({
renderVisuallyHiddenH2Title = false,
curationId,
readTimeVariant,
mostReadItemId,
mediaCollection,
}: Curation) => {
const componentName = getComponentName({
Expand Down Expand Up @@ -245,6 +246,7 @@ export default ({
headingLevel={3}
isFirstCuration={isFirstCuration}
eventTrackingData={eventTrackingData}
mostReadItemId={mostReadItemId}
readTimeVariant={readTimeVariant}
/>
</div>
Expand All @@ -256,6 +258,7 @@ export default ({
headingLevel={2} // if there is only one curation, all promos should be h2, and no subheading
isFirstCuration={isFirstCuration}
eventTrackingData={eventTrackingData}
mostReadItemId={mostReadItemId}
readTimeVariant={readTimeVariant}
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/app/components/Curation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export interface CurationGridProps {
headingLevel?: number;
isFirstCuration?: boolean;
eventTrackingData: EventTrackingData;
mostReadItemId?: string | null;
readTimeVariant?: string | null;
}
1 change: 1 addition & 0 deletions src/app/lib/config/services/afaanoromoo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ export const service: DefaultServiceConfig = {
linkText: 'Guutuu qabiyyee ilaaluuf fuula cufa ilaali',
},
topStoriesTitle: 'Isin hin darbiin',
mostReadBadgeText: `Baay'ee kan jaalatame`,
featuresAnalysisTitle: `Maaltu haasa'ama?`,
latestMediaTitle: 'Haaraa',
},
Expand Down
1 change: 1 addition & 0 deletions src/app/lib/config/services/mundo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ export const service: DefaultServiceConfig = {
'Ver la versión completa de la página para visualizar todo el contenido.',
},
topStoriesTitle: 'Principales noticias',
mostReadBadgeText: 'Lecturas más populares',
featuresAnalysisTitle: 'No te lo pierdas',
latestMediaTitle: 'Más videos',
ugc: {
Expand Down
1 change: 1 addition & 0 deletions src/app/lib/config/services/pidgin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ export const service: DefaultServiceConfig = {
linkText: 'View the full version of the page to see all the content.',
},
topStoriesTitle: 'Top Tori',
mostReadBadgeText: 'Di one wey dem dey read well well',
featuresAnalysisTitle: 'Informate me',
latestMediaTitle: 'New things',
},
Expand Down
3 changes: 3 additions & 0 deletions src/app/models/types/curationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface Summary extends BaseSummary {
readTime?: number;
eventTrackingData?: EventTrackingData;
visualProminence?: VisualProminence | string;
mostReadItemId?: string | null;
readTimeVariant?: string | null;
}

Expand Down Expand Up @@ -90,5 +91,7 @@ export interface Curation extends BaseCuration {
curationLength?: number;
nthCurationByStyleAndProminence?: number;
renderVisuallyHiddenH2Title?: boolean;
mostReadItemId?: string | null;
mostReadBadgeText?: string;
readTimeVariant?: string | null;
}
1 change: 1 addition & 0 deletions src/app/models/types/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ export interface Translations {
linkText: string;
};
topStoriesTitle?: string;
mostReadBadgeText?: string;
featuresAnalysisTitle?: string;
latestMediaTitle?: string;
infoBannerLabel?: string;
Expand Down
13 changes: 12 additions & 1 deletion src/app/pages/HomePage/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export interface HomePageProps {
};
}

export const extractId = (id?: string | null) => (id ?? '').split(':').pop();

const HomePage = ({ pageData }: HomePageProps) => {
const {
translations,
Expand All @@ -48,7 +50,7 @@ const HomePage = ({ pageData }: HomePageProps) => {
lang,
brandName,
} = use(ServiceContext);
const { topStoriesTitle, home } = translations;
const { topStoriesTitle, mostReadBadgeText, home } = translations;
const {
title,
description,
Expand All @@ -65,6 +67,13 @@ const HomePage = ({ pageData }: HomePageProps) => {

const itemList = getItemList({ curations, name: brandName });

const findMostReadCuration = curations.find(
curation => !!curation.mostRead?.items?.length,
);

const mostReadItemId =
extractId(findMostReadCuration?.mostRead?.items?.[0].id ?? null) ?? null;

return (
<>
<ChartbeatAnalytics title={title} />
Expand Down Expand Up @@ -131,6 +140,8 @@ const HomePage = ({ pageData }: HomePageProps) => {
}
renderVisuallyHiddenH2Title={position === 0}
curationId={curationId}
mostReadItemId={mostReadItemId}
mostReadBadgeText={mostReadBadgeText}
readTimeVariant={readTimeVariant}
{...curationProps}
/>
Expand Down
Loading