From fc8f988f484236a7702621d70939991ccfc7cc5f Mon Sep 17 00:00:00 2001 From: John Williams Date: Thu, 19 Sep 2024 13:17:13 -0400 Subject: [PATCH] feat(website): add mica sustainability indicator route and table --- .../components/MicaComplianceTable.tsx | 237 ++++++++++++++++++ apps/website/config/routes.ts | 4 + apps/website/config/siteMap.ts | 4 + apps/website/content/mica.ts | 30 +++ apps/website/pages/mica-indicators/index.tsx | 72 ++++++ .../pages/mica-indicators/methodology.tsx | 66 +++++ libs/units/src/time.ts | 4 + 7 files changed, 417 insertions(+) create mode 100644 apps/website/components/MicaComplianceTable.tsx create mode 100644 apps/website/content/mica.ts create mode 100644 apps/website/pages/mica-indicators/index.tsx create mode 100644 apps/website/pages/mica-indicators/methodology.tsx diff --git a/apps/website/components/MicaComplianceTable.tsx b/apps/website/components/MicaComplianceTable.tsx new file mode 100644 index 000000000..74191d2ce --- /dev/null +++ b/apps/website/components/MicaComplianceTable.tsx @@ -0,0 +1,237 @@ +import { Panel, Text, Tooltip } from '@siafoundation/design-system' +import { MicaIndicatorObject } from '../content/mica' +import { + CloudUpload32, + Earth32, + Flash32, + Information16, + TrashCan32, +} from '@carbon/icons-react' +import { cx } from 'class-variance-authority' + +type MicaComplianceTableCellGroupLayoutProps = { + indicatorData: { + title: string + description: string + unit: string + result: { + value: number + year: number + } + } + displayValue: string + customTitle?: string + last?: boolean +} + +function MicaComplianceTableCellGroupLayout({ + indicatorData, + displayValue, + customTitle, + last, +}: MicaComplianceTableCellGroupLayoutProps) { + const { title, description } = indicatorData + return ( + <> + + + {customTitle || title} + + + +
+ + {displayValue} + + + + +
+ + + ) +} + +type MicaComplianceTableProps = { + micaIndicators: MicaIndicatorObject + lastUpdated: string +} + +export function MicaComplianceTable({ + micaIndicators, + lastUpdated, +}: MicaComplianceTableProps) { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + Domain + + + + Sustainability Indicator + +
+
+ + + Energy + +
+
+
+ + + GHG Emissions + +
+
+
+ + + Waste Production + +
+
+
+ + + Natural resources + +
+
+
+
+ + Last updated {lastUpdated.slice(0, lastUpdated.indexOf('T'))} + +
+ + ) +} diff --git a/apps/website/config/routes.ts b/apps/website/config/routes.ts index 6f57b6203..262288154 100644 --- a/apps/website/config/routes.ts +++ b/apps/website/config/routes.ts @@ -78,4 +78,8 @@ export const routes = { letter: { index: '/letter', }, + micaIndicators: { + index: '/mica-indicators', + methodology: '/mica-indicators/methodology', + }, } diff --git a/apps/website/config/siteMap.ts b/apps/website/config/siteMap.ts index 94ae4188e..66d45bf84 100644 --- a/apps/website/config/siteMap.ts +++ b/apps/website/config/siteMap.ts @@ -65,6 +65,10 @@ export const menuSections = [ title: 'Whitepaper', newTab: true, }, + { + link: routes.micaIndicators.index, + title: 'MiCA Indicators', + }, ], }, { diff --git a/apps/website/content/mica.ts b/apps/website/content/mica.ts new file mode 100644 index 000000000..42308ae58 --- /dev/null +++ b/apps/website/content/mica.ts @@ -0,0 +1,30 @@ +import { to } from '@siafoundation/request' +import axios from 'axios' +import * as dotenv from 'dotenv' + +dotenv.config() + +export type MicaIndicator = { + indicator: number + title: string + description: string + unit: string + result: { + value: number + year: number + } +} + +export type MicaIndicatorObject = { [key: string]: MicaIndicator } + +export async function getMicaIndicators() { + const [indicators, indicatorsError] = await to( + axios( + `https://ccri.sia.tools/mica/overview/sia?responseType=recent&key=${process.env['CCRI_TOKEN']}` + ) + ) + + if (indicatorsError) throw indicatorsError + + return indicators +} diff --git a/apps/website/pages/mica-indicators/index.tsx b/apps/website/pages/mica-indicators/index.tsx new file mode 100644 index 000000000..d66d17e50 --- /dev/null +++ b/apps/website/pages/mica-indicators/index.tsx @@ -0,0 +1,72 @@ +import { Layout } from '../../components/Layout' +import { textContent } from '../../lib/utils' +import { routes } from '../../config/routes' +import { SectionTransparent } from '../../components/SectionTransparent' +import { Link, SiteHeading } from '@siafoundation/design-system' +import { SectionGradient } from '../../components/SectionGradient' +import { backgrounds, previews } from '../../content/assets' +import { MicaComplianceTable } from '../../components/MicaComplianceTable' +import { hoursInSeconds } from '@siafoundation/units' +import { AsyncReturnType } from '../../lib/types' +import { getMicaIndicators } from '../../content/mica' + +type Props = AsyncReturnType['props'] + +export default function MicaIndicators({ micaIndicators, lastUpdated }: Props) { + const title = 'MiCA Indicators' + const description = ( + <> + The EU Markets in Crypto-Assets ( + + MiCA) + {' '} + regulation requires token issuers and crypto-asset service providers + (CASPs) to disclose sustainability data. This following data is maintained + in partnership with the Crypto Carbon Ratings Institute ( + CCRI). You can find their + methodology here. + + ) + + return ( + + + + } + backgroundImage={backgrounds.waterfall} + previewImage={previews.waterfall} + > + + + + + ) +} + +export async function getStaticProps() { + const micaIndicators = await getMicaIndicators() + const lastUpdated = new Date().toISOString() + + const props = { + micaIndicators, + lastUpdated, + } + + return { + props, + revalidate: hoursInSeconds(24), + } +} diff --git a/apps/website/pages/mica-indicators/methodology.tsx b/apps/website/pages/mica-indicators/methodology.tsx new file mode 100644 index 000000000..d3d9fe2ad --- /dev/null +++ b/apps/website/pages/mica-indicators/methodology.tsx @@ -0,0 +1,66 @@ +import { Layout } from '../../components/Layout' +import { getStats } from '../../content/stats' +import { AsyncReturnType } from '../../lib/types' +import { getNotionPage } from '@siafoundation/data-sources' +import { minutesInSeconds } from '@siafoundation/units' +import { SectionTransparent } from '../../components/SectionTransparent' +import { SiteHeading, Text, Link } from '@siafoundation/design-system' +import { SectionSolid } from '../../components/SectionSolid' +import { MDXRemote } from 'next-mdx-remote' +import { components } from '../../config/mdx' +import { backgrounds, previews } from '../../content/assets' +import { routes } from '../../config/routes' + +type Props = AsyncReturnType['props'] + +const description = '' + +export default function MicaMethodology({ title, source }: Props) { + return ( + + + + } + backgroundImage={backgrounds.nateBridge} + previewImage={previews.nateBridge} + > + + + + See the MiCA Indicators for the Sia Network{' '} + here. + + + + ) +} + +const databaseId = '123632e3aeaf80759d9bf096a45665c3' + +export async function getStaticProps() { + const stats = await getStats() + + const { title, date, source } = await getNotionPage(databaseId) + + return { + props: { + title, + date, + source, + fallback: { + '/api/stats': stats, + }, + }, + revalidate: minutesInSeconds(5), + } +} diff --git a/libs/units/src/time.ts b/libs/units/src/time.ts index 74531862a..4da525414 100644 --- a/libs/units/src/time.ts +++ b/libs/units/src/time.ts @@ -2,6 +2,10 @@ export function minutesInMilliseconds(minutes: number) { return 1000 * 60 * minutes } +export function hoursInSeconds(hours: number) { + return 60 * 60 * hours +} + export function hoursInMilliseconds(hours: number) { return 1000 * 60 * 60 * hours }