import { gql } from '@apollo/client'; import AutoSizer from 'react-virtualized-auto-sizer'; import classNames from 'classnames'; import { useRouter } from 'next/router'; import React, { Children, isValidElement, ReactNode, useEffect, useState, } from 'react'; import debounce from 'lodash/debounce'; import { Market, MarketVariables, Market_market } from './__generated__/Market'; import { PageQueryContainer } from '../../components/page-query-container'; // Top level page query const MARKET_QUERY = gql` query Market($marketId: ID!) { market(id: $marketId) { id name trades { id price size createdAt } } } `; const MarketPage = () => { const { query } = useRouter(); const { w } = useWindowSize(); return ( query={MARKET_QUERY} options={{ variables: { marketId: query.marketId as string }, skip: !query.marketId, }} > {(data) => w > 1050 ? ( ) : ( ) } {} ); }; export default MarketPage; interface TradeGridProps { market: Market_market; } const TradeGrid = ({ market }: TradeGridProps) => { const wrapperClasses = classNames( 'h-full max-h-full', 'grid gap-[1px] grid-cols-[1fr_325px_325px] grid-rows-[min-content_1fr_200px]', 'bg-neutral-200', 'text-ui' ); return (

Market: {market.name}

{JSON.stringify(market.trades, null, 2)}
); }; interface TradeGridChildProps { children: ReactNode; className?: string; } const TradeGridChild = ({ children, className }: TradeGridChildProps) => { const gridChildClasses = classNames('bg-white', className); return (
{({ width, height }) => (
{children}
)}
); }; interface GridTabsProps { children: ReactNode; group: string; } const GridTabs = ({ children, group }: GridTabsProps) => { const { query, asPath, replace } = useRouter(); return (
{/* the tabs */}
{Children.map(children, (child) => { if (!isValidElement(child)) return null; const isActive = query[group] === child.props.name; const buttonClass = classNames( 'py-4', 'px-12', 'border-t border-neutral-200', 'capitalize', { 'text-vega-pink': isActive, 'bg-white': isActive, } ); return ( ); })}
{/* the content */}
{Children.map(children, (child) => { if (isValidElement(child) && query[group] === child.props.name) { return (
{child.props.children}
); } return null; })}
); }; interface GridTabProps { children: ReactNode; name: string; } const GridTab = ({ children }: GridTabProps) => { return
{children}
; }; ///// SMALL SCREENS /////// type View = keyof typeof Views; interface TradePanelsProps { market: Market_market; } const TradePanels = ({ market }: TradePanelsProps) => { const [view, setView] = React.useState('chart'); const renderView = () => { const Component = Views[view]; if (!Component) { throw new Error(`No component for view: ${view}`); } return ; }; return (

Market: {market.name}

{({ width, height }) => (
{renderView()}
)}
{Object.keys(Views).map((key: View) => { const className = classNames( 'p-8', 'border-t', 'border-neutral-200', 'capitalize', { 'text-vega-pink': view === key, 'bg-white': view === key, } ); return ( ); })}
); }; const Chart = () =>
TODO: Chart
; const Ticket = () =>
TODO: Ticket
; const Orderbook = () =>
TODO: Orderbook
; const Orders = () =>
TODO: Orders
; const Positions = () =>
TODO: Positions
; const Collateral = () =>
TODO: Collateral
; const Views = { chart: Chart, ticket: Ticket, orderbook: Orderbook, orders: Orders, positions: Positions, collateral: Collateral, }; const useWindowSize = () => { const [windowSize, setWindowSize] = useState(() => { if (typeof window !== 'undefined') { return { w: window.innerWidth, h: window.innerHeight, }; } // Something sensible for server rendered page return { w: 1200, h: 900, }; }); useEffect(() => { const handleResize = debounce((event) => { setWindowSize({ w: event.target.innerWidth, h: event.target.innerHeight, }); }, 300); window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, []); return windowSize; };