From 4bb757d0ae98a79d6616c12f54a26974d7f078ea Mon Sep 17 00:00:00 2001 From: majakomel Date: Thu, 30 Jul 2026 15:46:59 +0200 Subject: [PATCH] Replace reports with findings on homepage --- components/landing/HighlightBox.js | 4 +- pages/index.tsx | 132 +++++++++++++++++++++-------- 2 files changed, 100 insertions(+), 36 deletions(-) diff --git a/components/landing/HighlightBox.js b/components/landing/HighlightBox.js index d90fb3da..5635ac06 100644 --- a/components/landing/HighlightBox.js +++ b/components/landing/HighlightBox.js @@ -11,7 +11,7 @@ const HighlightBox = ({ countryCode, title, text, dates, footer }) => { const intl = useIntl() return ( -
+
{countryCode && (
@@ -38,7 +38,7 @@ const HighlightBox = ({ countryCode, title, text, dates, footer }) => {
-
{footer}
+ {footer &&
{footer}
}
) } diff --git a/pages/index.tsx b/pages/index.tsx index 2d5db72c..91b650a5 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -2,13 +2,76 @@ import axios from 'axios' import Link from 'next/link' import { colors } from 'ooni-components' -import { FormattedMessage } from 'react-intl' +import { FormattedMessage, useIntl } from 'react-intl' import { twMerge } from 'tailwind-merge' +import FindingsSection from 'components/FindingsSection' import FormattedMarkdown from 'components/FormattedMarkdown' -import HighlightSection from 'components/landing/HighlightsSection' import CoverageChart from 'components/landing/Stats' -import highlightContent from 'components/landing/highlights.json' +import { convertDatesData, sortData } from 'hooks/useFindings' +import { getFindings } from 'lib/api' import { toCompactNumberUnit } from 'utils' + +const FINDINGS_THEMES = [ + 'social_media', + 'news_media', + 'human_rights', + 'circumvention', +] as const + +type FindingTheme = (typeof FINDINGS_THEMES)[number] + +type FindingSummary = { + id: string + title: string + author: string + start_time: string + end_time?: string + short_description: string + CCs: string[] +} + +const toFindingSummary = (finding: { + id: string + title: string + reported_by?: string + start_time: Date | string + end_time?: Date | string + short_description: string + CCs: string[] +}): FindingSummary => ({ + id: finding.id, + title: finding.title, + author: finding.reported_by ?? '', + start_time: + finding.start_time instanceof Date + ? finding.start_time.toISOString() + : finding.start_time, + ...(finding.end_time && { + end_time: + finding.end_time instanceof Date + ? finding.end_time.toISOString() + : finding.end_time, + }), + short_description: finding.short_description, + CCs: finding.CCs ?? [finding.CCs?.[0]], +}) + +const groupFindingsByTheme = ( + incidents: { id: string; themes?: string[] }[], +): Record => { + const sorted = sortData(convertDatesData(incidents)) + + return FINDINGS_THEMES.reduce( + (acc, theme) => { + acc[theme] = sorted + .filter((f: { themes?: string[] }) => f.themes?.includes(theme)) + .slice(0, 5) + .map(toFindingSummary) + return acc + }, + {} as Record, + ) +} interface StatsItemProps { label: React.ReactNode unit?: string @@ -69,15 +132,19 @@ const FeatureBoxTitle = ({ export async function getStaticProps() { const client = axios.create({ baseURL: process.env.NEXT_PUBLIC_OONI_API }) - const result = await client.get('/api/_/global_overview') + const [result, incidents] = await Promise.all([ + client.get('/api/_/global_overview'), + getFindings().catch(() => []), + ]) return { props: { measurementCount: result.data.measurement_count, asnCount: result.data.network_count, countryCount: result.data.country_count, + findings: groupFindingsByTheme(incidents), }, - revalidate: 60 * 60 * 12, // 12 hours + revalidate: 60 * 60 * 1, // 1 hours } } @@ -85,13 +152,16 @@ interface LandingPageProps { measurementCount: number asnCount: number countryCount: number + findings: Record } const LandingPage = ({ measurementCount, asnCount, countryCount, + findings, }: LandingPageProps) => { + const intl = useIntl() const compactMeasurementCount = toCompactNumberUnit(measurementCount) const compactAsnCount = toCompactNumberUnit(asnCount) @@ -114,7 +184,7 @@ const LandingPage = ({
@@ -220,37 +290,31 @@ const LandingPage = ({
- {/* Political Events */} - } - description={ - - } - highlights={highlightContent.political} + - {/* Media */} - } - description={ - - } - highlights={highlightContent.media} + - {/* LGBTQI sites */} - } - description={ - - } - highlights={highlightContent.lgbtqi} + - {/* Censorship changes */} - } - description={ - - } - highlights={highlightContent.changes} +