From 5152be57ba8816f360ca6ce3f08be7966995f30d Mon Sep 17 00:00:00 2001 From: James Grugett Date: Sat, 4 Jun 2022 19:00:13 -0500 Subject: [PATCH] Quick back from clicking contract card on home! Preserves search state. --- web/components/contract-search.tsx | 8 ++- web/components/contract/contract-card.tsx | 16 +++-- web/components/contract/contracts-list.tsx | 4 +- web/pages/home.tsx | 68 ++++++++++++++++++---- 4 files changed, 79 insertions(+), 17 deletions(-) diff --git a/web/components/contract-search.tsx b/web/components/contract-search.tsx index 6371064e..ee1dae6e 100644 --- a/web/components/contract-search.tsx +++ b/web/components/contract-search.tsx @@ -56,8 +56,9 @@ export function ContractSearch(props: { category?: string } showCategorySelector: boolean + onContractClick?: (contract: Contract) => void }) { - const { querySortOptions, additionalFilter, showCategorySelector } = props + const { querySortOptions, additionalFilter, showCategorySelector, onContractClick } = props const user = useUser() const follows = useFollows(user?.id) @@ -151,6 +152,7 @@ export function ContractSearch(props: { category: category === 'following' ? 'all' : category, ...additionalFilter, }} + onContractClick={onContractClick} /> )} @@ -168,8 +170,9 @@ export function ContractSearchInner(props: { tag?: string category?: string } + onContractClick?: (contract: Contract) => void }) { - const { querySortOptions, filter, additionalFilter } = props + const { querySortOptions, filter, additionalFilter, onContractClick } = props const { initialQuery } = useInitialQueryAndSort(querySortOptions) const { query, setQuery, setSort } = useUpdateQueryAndSort({ @@ -235,6 +238,7 @@ export function ContractSearchInner(props: { loadMore={showMore} hasMore={!isLastPage} showCloseTime={index.endsWith('close-date')} + onContractClick={onContractClick} /> ) } diff --git a/web/components/contract/contract-card.tsx b/web/components/contract/contract-card.tsx index 1a492c8b..6e87438e 100644 --- a/web/components/contract/contract-card.tsx +++ b/web/components/contract/contract-card.tsx @@ -28,8 +28,9 @@ export function ContractCard(props: { showHotVolume?: boolean showCloseTime?: boolean className?: string + onClick?: () => void }) { - const { showHotVolume, showCloseTime, className } = props + const { showHotVolume, showCloseTime, className, onClick } = props const contract = useContractWithPreload(props.contract) ?? props.contract const { question, outcomeType } = contract const { resolution } = contract @@ -61,9 +62,16 @@ export function ContractCard(props: { 'peer absolute -left-6 -top-4 -bottom-4 right-0 z-10' )} > - - - + {onClick ? ( + + ) : ( + + + + )}

void hasMore: boolean showCloseTime?: boolean + onContractClick?: (contract: Contract) => void }) { - const { contracts, showCloseTime, hasMore, loadMore } = props + const { contracts, showCloseTime, hasMore, loadMore, onContractClick } = props const [elem, setElem] = useState(null) const isBottomVisible = useIsVisible(elem) @@ -43,6 +44,7 @@ export function ContractsGrid(props: { contract={contract} key={contract.id} showCloseTime={showCloseTime} + onClick={() => onContractClick?.(contract)} /> ))} diff --git a/web/pages/home.tsx b/web/pages/home.tsx index 7ffa4f3e..07f2a552 100644 --- a/web/pages/home.tsx +++ b/web/pages/home.tsx @@ -1,31 +1,79 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import Router from 'next/router' import { Page } from 'web/components/page' import { Col } from 'web/components/layout/col' import { useUser } from 'web/hooks/use-user' import { ContractSearch } from 'web/components/contract-search' +import { Contract } from 'common/contract' +import { ContractPageContent } from './[username]/[contractSlug]' +import { getContractFromSlug } from 'web/lib/firebase/contracts' const Home = () => { const user = useUser() + const [contract, setContract] = useState() + + useEffect(() => { + const onBack = () => { + const path = location.pathname.split('/').slice(1) + if (path[0] === 'home') setContract(undefined) + else { + const [username, contractSlug] = path + if (!username || !contractSlug) setContract(undefined) + else { + // Show contract if route is to a contract: '/[username]/[contractSlug]'. + getContractFromSlug(contractSlug).then((c) => { + setContract(c) + window.scrollTo(0, 0) + }) + } + } + } + + window.addEventListener('popstate', onBack) + return () => window.removeEventListener('popstate', onBack) + }, []) + if (user === null) { Router.replace('/') return <> } return ( - - - + + + { + // Show contract without navigating to contract page. + setContract(c) + // Update the url without switching pages in Nextjs. + history.pushState(null, '', `/${c.creatorUsername}/${c.slug}`) + window.scrollTo(0, 0) + }} + /> + + + + {contract && ( + { + history.back() }} - showCategorySelector /> - - + )} + ) }