From 39870dd933c3a35fc0567abbdf0145e52e8de969 Mon Sep 17 00:00:00 2001 From: Austin Chen Date: Wed, 18 May 2022 11:52:12 -0400 Subject: [PATCH] Bets on profile, again (#251) * Revert "Revert "Show every user's bets on their profile (#170)"" This reverts commit 142206b79a20126ed0d4a9eb8529e590755ecb22. * Fix typo * Delete portfolio page --- web/components/contract/contracts-list.tsx | 1 - web/components/nav/nav-bar.tsx | 2 +- web/components/nav/sidebar.tsx | 23 ++++--- web/components/user-page.tsx | 71 ++++++++++++++++++---- web/hooks/use-sort-and-query-params.tsx | 1 - web/lib/firebase/bets.ts | 6 ++ web/pages/[username]/bets.tsx | 5 ++ web/pages/[username]/comments.tsx | 5 ++ web/pages/[username]/index.tsx | 8 ++- web/pages/portfolio.tsx | 24 -------- 10 files changed, 96 insertions(+), 50 deletions(-) create mode 100644 web/pages/[username]/bets.tsx create mode 100644 web/pages/[username]/comments.tsx delete mode 100644 web/pages/portfolio.tsx diff --git a/web/components/contract/contracts-list.tsx b/web/components/contract/contracts-list.tsx index 9d74064d..28fae7da 100644 --- a/web/components/contract/contracts-list.tsx +++ b/web/components/contract/contracts-list.tsx @@ -19,7 +19,6 @@ export function ContractsGrid(props: { const isBottomVisible = useIsVisible(elem) useEffect(() => { - console.log({ isBottomVisible, hasMore }) if (isBottomVisible) { loadMore() } diff --git a/web/components/nav/nav-bar.tsx b/web/components/nav/nav-bar.tsx index 04c8e891..987e3142 100644 --- a/web/components/nav/nav-bar.tsx +++ b/web/components/nav/nav-bar.tsx @@ -47,7 +47,7 @@ export function BottomNavBar() { )} {user !== null && ( - + { } } -const navigation = [ - { name: 'Home', href: '/home', icon: HomeIcon }, - { name: 'Activity', href: '/activity', icon: ChatAltIcon }, - { name: 'Portfolio', href: '/portfolio', icon: PresentationChartLineIcon }, - { name: 'Charity', href: '/charity', icon: HeartIcon }, -] +function getNavigation(username: string) { + return [ + { name: 'Home', href: '/home', icon: HomeIcon }, + { name: 'Activity', href: '/activity', icon: ChatAltIcon }, + { + name: 'Portfolio', + href: `/${username}/bets`, + icon: PresentationChartLineIcon, + }, + { name: 'Charity', href: '/charity', icon: HeartIcon }, + ] +} const signedOutNavigation = [ { name: 'Home', href: '/home', icon: HomeIcon }, @@ -119,7 +125,10 @@ export default function Sidebar(props: { className?: string }) { folds = _.sortBy(folds, 'followCount').reverse() const deservesDailyFreeMarket = !useHasCreatedContractToday(user) - const navigationOptions = user === null ? signedOutNavigation : navigation + const navigationOptions = + user === null + ? signedOutNavigation + : getNavigation(user?.username || 'error') const mobileNavigationOptions = user === null ? signedOutMobileNavigation : mobileNavigation diff --git a/web/components/user-page.tsx b/web/components/user-page.tsx index 89750b28..9f78165c 100644 --- a/web/components/user-page.tsx +++ b/web/components/user-page.tsx @@ -21,6 +21,9 @@ import { getContractFromId, listContracts } from 'web/lib/firebase/contracts' import { LoadingIndicator } from './loading-indicator' import { useRouter } from 'next/router' import _ from 'lodash' +import { BetsList } from './bets-list' +import { Bet } from 'common/bet' +import { getUserBets } from 'web/lib/firebase/bets' export function UserLink(props: { name: string @@ -38,12 +41,13 @@ export function UserLink(props: { ) } +export const TAB_IDS = ['markets', 'comments', 'bets'] + export function UserPage(props: { user: User currentUser?: User - defaultTabTitle?: string + defaultTabTitle?: 'markets' | 'comments' | 'bets' }) { - const router = useRouter() const { user, currentUser, defaultTabTitle } = props const isCurrentUser = user.id === currentUser?.id const bannerUrl = user.bannerUrl ?? defaultBannerUrl(user.id) @@ -51,6 +55,7 @@ export function UserPage(props: { const [usersContracts, setUsersContracts] = useState( 'loading' ) + const [usersBets, setUsersBets] = useState('loading') const [commentsByContract, setCommentsByContract] = useState< Map | 'loading' >('loading') @@ -59,6 +64,7 @@ export function UserPage(props: { if (!user) return getUsersComments(user.id).then(setUsersComments) listContracts(user.id).then(setUsersContracts) + getUserBets(user.id).then(setUsersBets) }, [user]) useEffect(() => { @@ -187,17 +193,14 @@ export function UserPage(props: { {usersContracts !== 'loading' && commentsByContract != 'loading' ? ( - router.push( - { - pathname: `/${user.username}`, - query: { tab: tabName }, - }, - undefined, - { shallow: true } - ) - } + defaultIndex={TAB_IDS.indexOf(defaultTabTitle || 'markets')} + onClick={(tabName) => { + const tabId = tabName.toLowerCase() + const subpath = tabId === 'markets' ? '' : '/' + tabId + // BUG: if you start on `/Bob/bets`, then click on Markets, use-query-and-sort-params + // rewrites the url incorrectly to `/Bob/bets` instead of `/Bob` + window.history.replaceState('', '', `/${user.username}${subpath}`) + }} tabs={[ { title: 'Markets', @@ -220,6 +223,24 @@ export function UserPage(props: {
{usersComments.length}
), }, + { + title: 'Bets', + content: ( +
+ + {isCurrentUser && } +
+ ), + tabIcon: ( +
{usersBets.length}
+ ), + }, ]} /> ) : ( @@ -242,3 +263,27 @@ export function defaultBannerUrl(userId: string) { ] return defaultBanner[genHash(userId)() % defaultBanner.length] } + +import { ExclamationIcon } from '@heroicons/react/solid' + +function AlertBox(props: { title: string; text: string }) { + const { title, text } = props + return ( +
+
+
+
+
+

{title}

+
+ +
+
+
+
+ ) +} diff --git a/web/hooks/use-sort-and-query-params.tsx b/web/hooks/use-sort-and-query-params.tsx index 7a9abb85..776bcd4d 100644 --- a/web/hooks/use-sort-and-query-params.tsx +++ b/web/hooks/use-sort-and-query-params.tsx @@ -47,7 +47,6 @@ export function useInitialQueryAndSort(options?: { } setInitialSort(localSort ?? defaultSort) } else { - console.log('ready setting to ', sort ?? defaultSort) setInitialSort(sort ?? defaultSort) } } diff --git a/web/lib/firebase/bets.ts b/web/lib/firebase/bets.ts index b55b0027..c3ca8508 100644 --- a/web/lib/firebase/bets.ts +++ b/web/lib/firebase/bets.ts @@ -60,6 +60,12 @@ export function listenForBets( }) } +export async function getUserBets(userId: string) { + return getValues( + query(collectionGroup(db, 'bets'), where('userId', '==', userId)) + ) +} + export function listenForUserBets( userId: string, setBets: (bets: Bet[]) => void diff --git a/web/pages/[username]/bets.tsx b/web/pages/[username]/bets.tsx new file mode 100644 index 00000000..0403d263 --- /dev/null +++ b/web/pages/[username]/bets.tsx @@ -0,0 +1,5 @@ +import UserProfile from '.' + +export default function UserBets() { + return +} diff --git a/web/pages/[username]/comments.tsx b/web/pages/[username]/comments.tsx new file mode 100644 index 00000000..65a53028 --- /dev/null +++ b/web/pages/[username]/comments.tsx @@ -0,0 +1,5 @@ +import UserProfile from '.' + +export default function UserBets() { + return +} diff --git a/web/pages/[username]/index.tsx b/web/pages/[username]/index.tsx index cbc53235..eaef8471 100644 --- a/web/pages/[username]/index.tsx +++ b/web/pages/[username]/index.tsx @@ -6,10 +6,12 @@ import { UserPage } from 'web/components/user-page' import { useUser } from 'web/hooks/use-user' import Custom404 from '../404' -export default function UserProfile() { +export default function UserProfile(props: { + tab?: 'markets' | 'comments' | 'bets' +}) { const router = useRouter() const [user, setUser] = useState('loading') - const { username, tab } = router.query as { username: string; tab: string } + const { username } = router.query as { username: string } useEffect(() => { if (username) { getUserByUsername(username).then(setUser) @@ -24,7 +26,7 @@ export default function UserProfile() { ) : ( diff --git a/web/pages/portfolio.tsx b/web/pages/portfolio.tsx deleted file mode 100644 index 8b1f07ad..00000000 --- a/web/pages/portfolio.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import Router from 'next/router' -import { useEffect } from 'react' - -import { BetsList } from 'web/components/bets-list' -import { Page } from 'web/components/page' -import { SEO } from 'web/components/SEO' -import { Title } from 'web/components/title' -import { useUser } from 'web/hooks/use-user' - -export default function PortfolioPage() { - const user = useUser() - - useEffect(() => { - if (user === null) Router.replace('/') - }) - - return ( - - - - {user && <BetsList user={user} />} - </Page> - ) -}