diff --git a/packages/@ourworldindata/types/src/domainTypes/Various.ts b/packages/@ourworldindata/types/src/domainTypes/Various.ts
index 85e1e6cbacf..fd601e16449 100644
--- a/packages/@ourworldindata/types/src/domainTypes/Various.ts
+++ b/packages/@ourworldindata/types/src/domainTypes/Various.ts
@@ -34,6 +34,7 @@ export enum SiteFooterContext {
multiDimDataPage = "multiDimDataPage",
dynamicCollectionPage = "dynamicCollectionPage",
explorerPage = "explorerPage",
+ explorerIndexPage = "explorerIndexPage",
default = "default",
dataInsightsIndexPage = "data-insights-index-page",
dataCatalogPage = "data-catalog-page",
diff --git a/site/ExplorerIndex.tsx b/site/ExplorerIndex.tsx
new file mode 100644
index 00000000000..f71adbad07b
--- /dev/null
+++ b/site/ExplorerIndex.tsx
@@ -0,0 +1,86 @@
+import React from "react"
+import ReactDOM from "react-dom"
+import { MinimalExplorerInfo } from "@ourworldindata/types"
+import { EXPLORER_DYNAMIC_THUMBNAIL_URL } from "../settings/clientSettings.js"
+import { faHeartBroken } from "@fortawesome/free-solid-svg-icons"
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
+import { EXPLORERS_ROUTE_FOLDER } from "@ourworldindata/explorer"
+
+function ExplorerIndexPageCard(props: {
+ baseUrl: string
+ explorer: MinimalExplorerInfo
+}) {
+ const { baseUrl, explorer } = props
+ const [hasError, setHasError] = React.useState(false)
+ return (
+
+
+ {!hasError ? (
+ setHasError(true)}
+ src={`${EXPLORER_DYNAMIC_THUMBNAIL_URL}/${explorer.slug}.png`}
+ />
+ ) : (
+
+
+ Explorer preview not available
+
+ )}
+ {explorer.title}
+ {explorer.subtitle}
+
+
+ )
+}
+
+export interface ExplorerIndexPageProps {
+ baseUrl: string
+ explorers: MinimalExplorerInfo[]
+}
+
+export function ExplorerIndex(props: ExplorerIndexPageProps) {
+ const { baseUrl, explorers } = props
+ return (
+ <>
+
+
+ {explorers.map((explorer) => (
+
+ ))}
+
+ >
+ )
+}
+
+export const __OWID_EXPLORER_INDEX_PAGE_PROPS =
+ "__OWID_EXPLORER_INDEX_PAGE_PROPS"
+
+export function hydrateExplorerIndex() {
+ const explorerIndexPageProps = (window as any)[
+ __OWID_EXPLORER_INDEX_PAGE_PROPS
+ ]
+
+ if (!explorerIndexPageProps) return
+ ReactDOM.hydrate(
+ ,
+ document.querySelector(".explorer-index-page")
+ )
+}
diff --git a/site/ExplorerIndexPage.scss b/site/ExplorerIndexPage.scss
index 84945e1976a..0c2a486db6d 100644
--- a/site/ExplorerIndexPage.scss
+++ b/site/ExplorerIndexPage.scss
@@ -39,6 +39,7 @@
}
}
img {
+ background: $gray-5;
transition: 150ms;
box-shadow: 0px 0px 12px 0px rgba(49, 37, 2, 0.05);
}
@@ -55,4 +56,30 @@
}
}
}
+ @keyframes fadein {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+ }
+ .explorer-index-page__card-error {
+ width: 100%;
+ aspect-ratio: 850/600;
+ background-color: $gray-5;
+ color: $grey-text-color;
+ font-size: 1rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ svg {
+ margin-bottom: 16px;
+ }
+ svg,
+ p {
+ animation: fadein ease 0.3s;
+ }
+ }
}
diff --git a/site/ExplorerIndexPage.tsx b/site/ExplorerIndexPage.tsx
index 8acfa1bbc21..2ddaf4a61cf 100644
--- a/site/ExplorerIndexPage.tsx
+++ b/site/ExplorerIndexPage.tsx
@@ -4,18 +4,23 @@ import { Html } from "./Html.js"
import { EXPLORERS_ROUTE_FOLDER } from "@ourworldindata/explorer"
import { SiteHeader } from "./SiteHeader.js"
import { SiteFooter } from "./SiteFooter.js"
-import { MinimalExplorerInfo } from "@ourworldindata/types"
-import { EXPLORER_DYNAMIC_THUMBNAIL_URL } from "../settings/clientSettings.js"
-
-interface ExplorerIndexPageProps {
- baseUrl: string
- explorers: MinimalExplorerInfo[]
-}
+import { SiteFooterContext } from "@ourworldindata/types"
+import {
+ __OWID_EXPLORER_INDEX_PAGE_PROPS,
+ ExplorerIndex,
+ ExplorerIndexPageProps,
+} from "./ExplorerIndex.js"
export const ExplorerIndexPage = ({
baseUrl,
explorers,
}: ExplorerIndexPageProps) => {
+ const inlineJs = `window.${__OWID_EXPLORER_INDEX_PAGE_PROPS} = ${JSON.stringify(
+ {
+ baseUrl,
+ explorers,
+ }
+ )}`
return (
-
-
+
-
+
+
)
diff --git a/site/runSiteFooterScripts.ts b/site/runSiteFooterScripts.ts
index 31ca9f2ae72..a5c540e4266 100644
--- a/site/runSiteFooterScripts.ts
+++ b/site/runSiteFooterScripts.ts
@@ -22,6 +22,7 @@ import {
import { runAllGraphersLoadedListener } from "./runAllGraphersLoadedListener.js"
import { hydrateMultiDimDataPageContent } from "./multiDim/MultiDimDataPageContent.js"
import { hydrateDataCatalogPage } from "./DataCatalog/DataCatalog.js"
+import { hydrateExplorerIndex } from "./ExplorerIndex.js"
export const runSiteFooterScripts = (
args:
@@ -66,6 +67,12 @@ export const runSiteFooterScripts = (
runCookiePreferencesManager()
void runDetailsOnDemand()
break
+ case SiteFooterContext.explorerIndexPage:
+ hydrateExplorerIndex()
+ runSiteNavigation(BAKED_BASE_URL)
+ runCookiePreferencesManager()
+ runSiteTools()
+ break
case SiteFooterContext.gdocsDocument:
hydrateOwidGdoc(debug, isPreviewing)
runAllGraphersLoadedListener()