Map fixes (#1011)
* usa map: fix sizing * useSetIframeBackbroundColor * preload contracts * seo
This commit is contained in:
parent
a53fb49ec3
commit
f8ec306ee9
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user