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 { useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { getProbability } from 'common/calculate'
|
import { getProbability } from 'common/calculate'
|
||||||
import { Contract, CPMMBinaryContract } from 'common/contract'
|
import { CPMMBinaryContract } from 'common/contract'
|
||||||
import { Customize, USAMap } from './usa-map'
|
import { Customize, USAMap } from './usa-map'
|
||||||
import {
|
import { listenForContract } from 'web/lib/firebase/contracts'
|
||||||
getContractFromSlug,
|
|
||||||
listenForContract,
|
|
||||||
} from 'web/lib/firebase/contracts'
|
|
||||||
import { interpolateColor } from 'common/util/color'
|
import { interpolateColor } from 'common/util/color'
|
||||||
|
|
||||||
export interface StateElectionMarket {
|
export interface StateElectionMarket {
|
||||||
|
@ -18,10 +15,14 @@ export interface StateElectionMarket {
|
||||||
state: string
|
state: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function StateElectionMap(props: { markets: StateElectionMarket[] }) {
|
export function StateElectionMap(props: {
|
||||||
|
markets: StateElectionMarket[]
|
||||||
|
contracts: CPMMBinaryContract[]
|
||||||
|
}) {
|
||||||
const { markets } = props
|
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) =>
|
const probs = contracts.map((c) =>
|
||||||
c ? getProbability(c as CPMMBinaryContract) : 0.5
|
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)
|
return interpolateColor('#ebe4ec', color, Math.abs(p - 0.5) * 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
const useContracts = (slugs: string[]) => {
|
const useUpdateContracts = (
|
||||||
const [contracts, setContracts] = useState<(Contract | undefined)[]>(
|
contracts: CPMMBinaryContract[],
|
||||||
slugs.map(() => undefined)
|
setContracts: (newContracts: CPMMBinaryContract[]) => void
|
||||||
)
|
) => {
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
Promise.all(slugs.map((slug) => getContractFromSlug(slug))).then(
|
|
||||||
(contracts) => setContracts(contracts)
|
|
||||||
)
|
|
||||||
}, [slugs])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (contracts.some((c) => c === undefined)) return
|
if (contracts.some((c) => c === undefined)) return
|
||||||
|
|
||||||
// listen to contract updates
|
// listen to contract updates
|
||||||
const unsubs = (contracts as Contract[]).map((c, i) =>
|
const unsubs = contracts.map((c, i) =>
|
||||||
listenForContract(
|
listenForContract(
|
||||||
c.id,
|
c.id,
|
||||||
(newC) => newC && setContracts(setAt(contracts, i, newC))
|
(newC) =>
|
||||||
|
newC && setContracts(setAt(contracts, i, newC as CPMMBinaryContract))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return () => unsubs.forEach((u) => u())
|
return () => unsubs.forEach((u) => u())
|
||||||
}, [contracts])
|
}, [contracts, setContracts])
|
||||||
|
|
||||||
return contracts
|
return contracts
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// https://github.com/jb-1980/usa-map-react
|
// https://github.com/jb-1980/usa-map-react
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
|
import clsx from 'clsx'
|
||||||
import { DATA } from './data'
|
import { DATA } from './data'
|
||||||
import { USAState } from './usa-state'
|
import { USAState } from './usa-state'
|
||||||
|
|
||||||
|
@ -65,40 +66,38 @@ export const USAMap = ({
|
||||||
const stateClickHandler = (state: string) => customize?.[state]?.clickHandler
|
const stateClickHandler = (state: string) => customize?.[state]?.clickHandler
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full">
|
<svg
|
||||||
<svg
|
className={clsx('flex h-96 w-full sm:h-full', className)}
|
||||||
className={className}
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
viewBox="0 0 959 593"
|
||||||
viewBox="0 0 959 593"
|
>
|
||||||
>
|
<title>{title}</title>
|
||||||
<title>{title}</title>
|
<g className="outlines">
|
||||||
<g className="outlines">
|
{States({
|
||||||
{States({
|
hideStateTitle,
|
||||||
hideStateTitle,
|
fillStateColor,
|
||||||
fillStateColor,
|
stateClickHandler,
|
||||||
stateClickHandler,
|
})}
|
||||||
})}
|
<g className="DC state">
|
||||||
<g className="DC state">
|
<path
|
||||||
<path
|
className="DC1"
|
||||||
className="DC1"
|
fill={fillStateColor('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"
|
||||||
d="M801.8,253.8 l-1.1-1.6 -1-0.8 1.1-1.6 2.2,1.5z"
|
/>
|
||||||
/>
|
<circle
|
||||||
<circle
|
className="DC2"
|
||||||
className="DC2"
|
onClick={onClick}
|
||||||
onClick={onClick}
|
data-name={'DC'}
|
||||||
data-name={'DC'}
|
fill={fillStateColor('DC2')}
|
||||||
fill={fillStateColor('DC2')}
|
stroke="#FFFFFF"
|
||||||
stroke="#FFFFFF"
|
strokeWidth="1.5"
|
||||||
strokeWidth="1.5"
|
cx="801.3"
|
||||||
cx="801.3"
|
cy="251.8"
|
||||||
cy="251.8"
|
r="5"
|
||||||
r="5"
|
opacity="1"
|
||||||
opacity="1"
|
/>
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</g>
|
||||||
</div>
|
</svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
|
import { CPMMBinaryContract } from 'common/contract'
|
||||||
|
import { useEffect } from 'react'
|
||||||
import { Col } from 'web/components/layout/col'
|
import { Col } from 'web/components/layout/col'
|
||||||
import { Spacer } from 'web/components/layout/spacer'
|
import { Spacer } from 'web/components/layout/spacer'
|
||||||
import { Page } from 'web/components/page'
|
import { Page } from 'web/components/page'
|
||||||
|
import { SEO } from 'web/components/SEO'
|
||||||
import { Title } from 'web/components/title'
|
import { Title } from 'web/components/title'
|
||||||
import {
|
import {
|
||||||
StateElectionMarket,
|
StateElectionMarket,
|
||||||
StateElectionMap,
|
StateElectionMap,
|
||||||
} from 'web/components/usa-map/state-election-map'
|
} from 'web/components/usa-map/state-election-map'
|
||||||
|
import { getContractFromSlug } from 'web/lib/firebase/contracts'
|
||||||
|
|
||||||
const senateMidterms: StateElectionMarket[] = [
|
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 (
|
return (
|
||||||
<Page className="">
|
<Page className="">
|
||||||
<Col className="items-center justify-center">
|
<Col className="items-center justify-center">
|
||||||
<Title text="2022 US Midterm Elections" className="mt-2" />
|
<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>
|
<div className="mt-2 text-2xl">Senate</div>
|
||||||
<StateElectionMap markets={senateMidterms} />
|
<StateElectionMap
|
||||||
|
markets={senateMidterms}
|
||||||
|
contracts={senateContracts}
|
||||||
|
/>
|
||||||
<iframe
|
<iframe
|
||||||
src="https://manifold.markets/TomShlomi/will-the-gop-control-the-us-senate"
|
src="https://manifold.markets/TomShlomi/will-the-gop-control-the-us-senate"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
className="mt-8 flex h-96 w-full"
|
className="mt-8 flex h-96 w-full"
|
||||||
></iframe>
|
></iframe>
|
||||||
<Spacer h={8} />
|
<Spacer h={8} />
|
||||||
|
|
||||||
<div className="mt-8 text-2xl">Governors</div>
|
<div className="mt-8 text-2xl">Governors</div>
|
||||||
<StateElectionMap markets={governorMidterms} />
|
<StateElectionMap
|
||||||
|
markets={governorMidterms}
|
||||||
|
contracts={governorContracts}
|
||||||
|
/>
|
||||||
<iframe
|
<iframe
|
||||||
src="https://manifold.markets/ManifoldMarkets/democrats-go-down-at-least-one-gove"
|
src="https://manifold.markets/ManifoldMarkets/democrats-go-down-at-least-one-gove"
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
className="mt-8 flex h-96 w-full"
|
className="mt-8 flex h-96 w-full"
|
||||||
></iframe>
|
></iframe>
|
||||||
<Spacer h={8} />
|
<Spacer h={8} />
|
||||||
|
|
||||||
<div className="mt-8 text-2xl">House</div>
|
<div className="mt-8 text-2xl">House</div>
|
||||||
<iframe
|
<iframe
|
||||||
src="https://manifold.markets/BoltonBailey/will-democrats-maintain-control-of"
|
src="https://manifold.markets/BoltonBailey/will-democrats-maintain-control-of"
|
||||||
|
@ -203,6 +240,7 @@ const App = () => {
|
||||||
className="mt-8 flex h-96 w-full"
|
className="mt-8 flex h-96 w-full"
|
||||||
></iframe>
|
></iframe>
|
||||||
<Spacer h={8} />
|
<Spacer h={8} />
|
||||||
|
|
||||||
<div className="mt-8 text-2xl">Related markets</div>
|
<div className="mt-8 text-2xl">Related markets</div>
|
||||||
<iframe
|
<iframe
|
||||||
src="https://manifold.markets/BoltonBailey/balance-of-power-in-us-congress-aft"
|
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
|
export default App
|
||||||
|
|
Loading…
Reference in New Issue
Block a user