diff --git a/web/pages/tournament/index.tsx b/web/pages/tournament/index.tsx new file mode 100644 index 00000000..5cd85b06 --- /dev/null +++ b/web/pages/tournament/index.tsx @@ -0,0 +1,209 @@ +import { ClockIcon } from '@heroicons/react/outline' +import { + ChevronLeftIcon, + ChevronRightIcon, + UsersIcon, +} from '@heroicons/react/solid' +import clsx from 'clsx' +import { Contract } from 'common/contract' +import { formatLargeNumber } from 'common/util/format' +import dayjs, { Dayjs } from 'dayjs' +import customParseFormat from 'dayjs/plugin/customParseFormat' +import { throttle } from 'lodash' +import { ReactNode, useEffect, useRef, useState } from 'react' +import { ContractCard } from 'web/components/contract/contract-card' +import { DateTimeTooltip } from 'web/components/datetime-tooltip' +import { Col } from 'web/components/layout/col' +import { Row } from 'web/components/layout/row' +import { Page } from 'web/components/page' +import { SEO } from 'web/components/SEO' +import { useContracts } from 'web/hooks/use-contracts' +import { useGroup } from 'web/hooks/use-group' +import utc from 'dayjs/plugin/utc' +import timezone from 'dayjs/plugin/timezone' + +dayjs.extend(utc) +dayjs.extend(timezone) +dayjs.extend(customParseFormat) +const toDate = (d: string) => dayjs(d, 'MMM D, YYYY').tz('America/Los_Angeles') + +type Tourney = { + title: string + url?: string + blurb: string // actual description in the click-through + award?: number + endTime?: Dayjs + // TODO: somehow get the markets + groupId?: string +} + +const tourneys: Tourney[] = [ + { + title: 'CSPI/Salem Tournament', + blurb: + 'Forecasting contest - top 5 can become Salem Center’s next research fellow.', + url: 'https://salemcenter.manifold.markets/', + award: 25_000, + }, + { + title: 'Fantasy Football Stock Exchange', + blurb: 'How many points will each NFL player score?', + url: 'https://manifold.markets/group/fantasy-football-stock-exchange', + award: 500, + endTime: toDate('Jan 6, 2023'), + groupId: 'SxGRqXRpV3RAQKudbcNb', + }, + { + title: 'Cause Exploration Prize', + blurb: + 'Which new charity ideas will Open Philanthropy find most promising?', + award: 100_000, + endTime: toDate('Sep 9, 2022'), + }, + { + title: 'Clearer Thinking Regrant Project', + blurb: 'Something amazing', + award: 1_000_000, + endTime: toDate('Sep 22, 2022'), + }, +] + +export default function TournamentPage() { + const ffsx = useGroup('SxGRqXRpV3RAQKudbcNb') + const markets = useContracts() ?? [] + const ffsxMarkets = markets + .filter((m) => (ffsx?.contractIds ?? []).includes(m.id)) + .slice(0, 50) + + const ffsxLength = ffsx?.memberIds.length + + useEffect(() => console.log(tourneys), []) + + return ( + + + +

Tournaments

+ {tourneys.map(({ groupId, ...data }) => ( +
+ ))} + + + ) +} + +function Section(props: { + title: string + url?: string + blurb: string + award?: number + endTime?: Dayjs + markets: Contract[] +}) { + const { title, url, blurb, award, endTime, markets } = props + + return ( +
+ +

+ {url ? {title} : title} +

+ + {!!award && ( + + 🏆 ${formatLargeNumber(award)} + + )} + + + 400 + + {endTime && ( + + + + {endTime.format('MMM D')} + + + )} + +
+ {blurb} + +
+ {markets.length ? ( + markets.map((m) => ( + + )) + ) : ( +
+ Coming Soon... +
+ )} + +
+ ) +} + +function Carousel(props: { children: ReactNode; className?: string }) { + const { children, className } = props + + const ref = useRef(null) + + const th = (f: () => any) => throttle(f, 500, { trailing: false }) + const scrollLeft = th(() => + ref.current?.scrollBy({ left: -ref.current.clientWidth }) + ) + const scrollRight = th(() => + ref.current?.scrollBy({ left: ref.current.clientWidth }) + ) + + const [atFront, setAtFront] = useState(true) + const [atBack, setAtBack] = useState(false) + const onScroll = throttle(() => { + if (ref.current) { + const { scrollLeft, clientWidth, scrollWidth } = ref.current + setAtFront(scrollLeft < 80) + setAtBack(scrollWidth - (clientWidth + scrollLeft) < 80) + } + }, 500) + + // eslint-disable-next-line react-hooks/exhaustive-deps + useEffect(onScroll, []) + + return ( +
+ + {children} + + {!atFront && ( +
+ +
+ )} + {!atBack && ( +
+ +
+ )} +
+ ) +}