* usa map: fix sizing

* useSetIframeBackbroundColor

* preload contracts

* seo
This commit is contained in:
mantikoros 2022-10-05 18:20:40 -05:00 committed by GitHub
parent a53fb49ec3
commit f8ec306ee9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 99 additions and 58 deletions

View File

@ -3,12 +3,9 @@ import Router from 'next/router'
import { useEffect, useState } from 'react'
import { getProbability } from 'common/calculate'
import { Contract, CPMMBinaryContract } from 'common/contract'
import { CPMMBinaryContract } from 'common/contract'
import { Customize, USAMap } from './usa-map'
import {
getContractFromSlug,
listenForContract,
} from 'web/lib/firebase/contracts'
import { listenForContract } from 'web/lib/firebase/contracts'
import { interpolateColor } from 'common/util/color'
export interface StateElectionMarket {
@ -18,10 +15,14 @@ export interface StateElectionMarket {
state: string
}
export function StateElectionMap(props: { markets: StateElectionMarket[] }) {
export function StateElectionMap(props: {
markets: StateElectionMarket[]
contracts: CPMMBinaryContract[]
}) {
const { markets } = props
const [contracts, setContracts] = useState(props.contracts)
useUpdateContracts(contracts, setContracts)
const contracts = useContracts(markets.map((m) => m.slug))
const probs = contracts.map((c) =>
c ? getProbability(c as CPMMBinaryContract) : 0.5
)
@ -50,29 +51,23 @@ const probToColor = (prob: number, isWinRepublican: boolean) => {
return interpolateColor('#ebe4ec', color, Math.abs(p - 0.5) * 2)
}
const useContracts = (slugs: string[]) => {
const [contracts, setContracts] = useState<(Contract | undefined)[]>(
slugs.map(() => undefined)
)
useEffect(() => {
Promise.all(slugs.map((slug) => getContractFromSlug(slug))).then(
(contracts) => setContracts(contracts)
)
}, [slugs])
const useUpdateContracts = (
contracts: CPMMBinaryContract[],
setContracts: (newContracts: CPMMBinaryContract[]) => void
) => {
useEffect(() => {
if (contracts.some((c) => c === undefined)) return
// listen to contract updates
const unsubs = (contracts as Contract[]).map((c, i) =>
const unsubs = contracts.map((c, i) =>
listenForContract(
c.id,
(newC) => newC && setContracts(setAt(contracts, i, newC))
(newC) =>
newC && setContracts(setAt(contracts, i, newC as CPMMBinaryContract))
)
)
return () => unsubs.forEach((u) => u())
}, [contracts])
}, [contracts, setContracts])
return contracts
}

View File

@ -1,6 +1,7 @@
// https://github.com/jb-1980/usa-map-react
// MIT License
import clsx from 'clsx'
import { DATA } from './data'
import { USAState } from './usa-state'
@ -65,40 +66,38 @@ export const USAMap = ({
const stateClickHandler = (state: string) => customize?.[state]?.clickHandler
return (
<div className="flex w-full">
<svg
className={className}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 959 593"
>
<title>{title}</title>
<g className="outlines">
{States({
hideStateTitle,
fillStateColor,
stateClickHandler,
})}
<g className="DC state">
<path
className="DC1"
fill={fillStateColor('DC1')}
d="M801.8,253.8 l-1.1-1.6 -1-0.8 1.1-1.6 2.2,1.5z"
/>
<circle
className="DC2"
onClick={onClick}
data-name={'DC'}
fill={fillStateColor('DC2')}
stroke="#FFFFFF"
strokeWidth="1.5"
cx="801.3"
cy="251.8"
r="5"
opacity="1"
/>
</g>
<svg
className={clsx('flex h-96 w-full sm:h-full', className)}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 959 593"
>
<title>{title}</title>
<g className="outlines">
{States({
hideStateTitle,
fillStateColor,
stateClickHandler,
})}
<g className="DC state">
<path
className="DC1"
fill={fillStateColor('DC1')}
d="M801.8,253.8 l-1.1-1.6 -1-0.8 1.1-1.6 2.2,1.5z"
/>
<circle
className="DC2"
onClick={onClick}
data-name={'DC'}
fill={fillStateColor('DC2')}
stroke="#FFFFFF"
strokeWidth="1.5"
cx="801.3"
cy="251.8"
r="5"
opacity="1"
/>
</g>
</svg>
</div>
</g>
</svg>
)
}

View File

@ -1,11 +1,15 @@
import { CPMMBinaryContract } from 'common/contract'
import { useEffect } from 'react'
import { Col } from 'web/components/layout/col'
import { Spacer } from 'web/components/layout/spacer'
import { Page } from 'web/components/page'
import { SEO } from 'web/components/SEO'
import { Title } from 'web/components/title'
import {
StateElectionMarket,
StateElectionMap,
} from 'web/components/usa-map/state-election-map'
import { getContractFromSlug } from 'web/lib/firebase/contracts'
const senateMidterms: StateElectionMarket[] = [
{
@ -175,27 +179,60 @@ const governorMidterms: StateElectionMarket[] = [
},
]
const App = () => {
export async function getStaticProps() {
const senateContracts = await Promise.all(
senateMidterms.map((m) => getContractFromSlug(m.slug))
)
const governorContracts = await Promise.all(
governorMidterms.map((m) => getContractFromSlug(m.slug))
)
return {
props: { senateContracts, governorContracts },
revalidate: 60, // regenerate after a minute
}
}
const App = (props: {
senateContracts: CPMMBinaryContract[]
governorContracts: CPMMBinaryContract[]
}) => {
useSetIframeBackbroundColor()
const { senateContracts, governorContracts } = props
return (
<Page className="">
<Col className="items-center justify-center">
<Title text="2022 US Midterm Elections" className="mt-2" />
<SEO
title="2022 US Midterm Elections"
description="Bet on the midterm elections using prediction markets. See Manifold's state-by-state breakdown of senate and governor races."
/>
<div className="mt-2 text-2xl">Senate</div>
<StateElectionMap markets={senateMidterms} />
<StateElectionMap
markets={senateMidterms}
contracts={senateContracts}
/>
<iframe
src="https://manifold.markets/TomShlomi/will-the-gop-control-the-us-senate"
frameBorder="0"
className="mt-8 flex h-96 w-full"
></iframe>
<Spacer h={8} />
<div className="mt-8 text-2xl">Governors</div>
<StateElectionMap markets={governorMidterms} />
<StateElectionMap
markets={governorMidterms}
contracts={governorContracts}
/>
<iframe
src="https://manifold.markets/ManifoldMarkets/democrats-go-down-at-least-one-gove"
frameBorder="0"
className="mt-8 flex h-96 w-full"
></iframe>
<Spacer h={8} />
<div className="mt-8 text-2xl">House</div>
<iframe
src="https://manifold.markets/BoltonBailey/will-democrats-maintain-control-of"
@ -203,6 +240,7 @@ const App = () => {
className="mt-8 flex h-96 w-full"
></iframe>
<Spacer h={8} />
<div className="mt-8 text-2xl">Related markets</div>
<iframe
src="https://manifold.markets/BoltonBailey/balance-of-power-in-us-congress-aft"
@ -232,4 +270,13 @@ const App = () => {
)
}
const useSetIframeBackbroundColor = () => {
useEffect(() => {
if (window.location.host !== 'manifold.markets') return
for (let i = 0; i < self.frames.length; i++) {
self.frames[i].document.body.style.backgroundColor = '#f9fafb'
}
}, [])
}
export default App