-
-
Notifications
You must be signed in to change notification settings - Fork 229
/
Copy pathDataInsightsIndexPageContent.tsx
153 lines (146 loc) · 6.39 KB
/
DataInsightsIndexPageContent.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import cx from "classnames"
import {
ImageMetadata,
LinkedChart,
OwidGdocMinimalPostInterface,
merge,
LinkedAuthor,
uniqBy,
getPaginationPageNumbers,
} from "@ourworldindata/utils"
import { DataInsightBody } from "./gdocs/pages/DataInsight.js"
import { dataInsightIndexToIdMap } from "./SiteConstants.js"
import { DocumentContext } from "./gdocs/DocumentContext.js"
import { AttachmentsContext } from "./gdocs/AttachmentsContext.js"
import { DataInsightsIndexPageProps } from "./DataInsightsIndexPage.js"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
import { faArrowLeft, faArrowRight } from "@fortawesome/free-solid-svg-icons"
import DataInsightsNewsletterBanner from "./DataInsightsNewsletterBanner.js"
const Pagination = (props: { pageNumber: number; totalPageCount: number }) => {
const { pageNumber, totalPageCount } = props
if (totalPageCount <= 1) return null
// pageNumber is 0-indexed, even though the page routes are 1-indexed. Also pageNumber === 0 is a special case.
// e.g. /data-insights, /data-insights/2, /data-insights/3
const prevTarget =
pageNumber === 1
? "/data-insights"
: // pageNumber is already "one less" than the page route we're on
`/data-insights/${pageNumber}`
const isLeftArrowDisabled = pageNumber === 0
const nextTarget =
// pageNumber + 1 is the same as the route we're on, hence pageNumber + 2
pageNumber < totalPageCount - 1
? `/data-insights/${pageNumber + 2}`
: ""
const isRightArrowDisabled = pageNumber === totalPageCount - 1
// Select 5 values around the current page number
const pageNumbers = getPaginationPageNumbers(pageNumber, totalPageCount)
return (
<div className="data-insights-index-page__pagination span-cols-8 col-start-4 span-md-cols-10 col-md-start-3 span-sm-cols-12 col-sm-start-2">
<a
href={prevTarget}
aria-disabled={isLeftArrowDisabled}
className={cx("data-insights-index-page__pagination-link", {
"data-insights-index-page__pagination-link--disabled":
isLeftArrowDisabled,
})}
>
<FontAwesomeIcon icon={faArrowLeft} />
</a>
{pageNumbers.map((i) => (
<a
href={`/data-insights${i === 0 ? "" : `/${i + 1}`}`}
key={i}
className={cx("data-insights-index-page__pagination-link", {
"data-insights-index-page__pagination-link--active":
i === pageNumber,
})}
>
{i + 1}
</a>
))}
<a
href={nextTarget}
aria-disabled={isRightArrowDisabled}
className={cx("data-insights-index-page__pagination-link", {
"data-insights-index-page__pagination-link--disabled":
isRightArrowDisabled,
})}
>
<FontAwesomeIcon icon={faArrowRight} />
</a>
</div>
)
}
export const DataInsightsIndexPageContent = (
props: DataInsightsIndexPageProps
) => {
const { pageNumber, dataInsights, isPreviewing = false } = props
// Extract all attachments from the data insights and supply them to the AttachmentsContext
const { imageMetadata, linkedAuthors, linkedCharts, linkedDocuments } =
dataInsights.reduce(
(acc, di) => ({
imageMetadata: merge(acc.imageMetadata, di.imageMetadata),
linkedAuthors: di.linkedAuthors
? [...acc.linkedAuthors, ...di.linkedAuthors]
: acc.linkedAuthors,
linkedCharts: merge(acc.linkedCharts, di.linkedCharts),
linkedDocuments: merge(acc.linkedDocuments, di.linkedDocuments),
}),
{
imageMetadata: {} as Record<string, ImageMetadata>,
linkedAuthors: [] as LinkedAuthor[],
linkedCharts: {} as Record<string, LinkedChart>,
linkedDocuments: {} as Record<
string,
OwidGdocMinimalPostInterface
>,
}
)
return (
<DocumentContext.Provider value={{ isPreviewing }}>
<AttachmentsContext.Provider
value={{
imageMetadata,
linkedAuthors: uniqBy(linkedAuthors, ({ name }) => name),
linkedCharts,
linkedDocuments,
linkedIndicators: {}, // not needed for data insights
relatedCharts: [], // not needed for the index page
latestDataInsights: [], // not needed for the index page
}}
>
<header className="data-insights-index-page__header grid grid-cols-12-full-width span-cols-14">
<h2 className="span-cols-6 col-start-5 col-md-start-4 span-md-cols-10 col-sm-start-2 span-sm-cols-12 display-2-semibold ">
Daily Data Insights
</h2>
<p className="span-cols-6 col-start-5 col-md-start-4 span-md-cols-8 col-sm-start-2 span-sm-cols-12 body-1-regular">
Bite-sized insights on how the world is changing,
published every weekday.
</p>
</header>
{dataInsights.map((dataInsight, index) => {
const id =
pageNumber === 0
? dataInsightIndexToIdMap[index]
: undefined
return (
<DataInsightBody
key={dataInsight.id}
anchor={id}
shouldLinkTitle
{...dataInsight}
/>
)
})}
<Pagination
totalPageCount={props.totalPageCount}
pageNumber={props.pageNumber}
/>
<DataInsightsNewsletterBanner />
</AttachmentsContext.Provider>
</DocumentContext.Provider>
)
}
export const _OWID_DATA_INSIGHTS_INDEX_PAGE_DATA =
"_OWID_DATA_INSIGHTS_INDEX_PAGE_DATA"