From 9df78a4963624683beec262647eb1e9c54d5d0e2 Mon Sep 17 00:00:00 2001 From: Austin Chen Date: Wed, 15 Dec 2021 17:34:36 -0800 Subject: [PATCH] Support user profiles on `/[username]` Currently all bets are also shown --- web/components/contracts-list.tsx | 6 +++--- web/lib/firebase/users.ts | 14 ++++++++++++++ web/pages/[username]/index.tsx | 27 ++++++++++++++++----------- web/pages/account.tsx | 30 +++++++++++++++--------------- web/pages/contract/index.tsx | 2 +- 5 files changed, 49 insertions(+), 30 deletions(-) diff --git a/web/components/contracts-list.tsx b/web/components/contracts-list.tsx index 52a2c0e5..11450e4f 100644 --- a/web/components/contracts-list.tsx +++ b/web/components/contracts-list.tsx @@ -10,6 +10,7 @@ import { path, } from '../lib/firebase/contracts' import { formatMoney } from '../lib/util/format' +import { User } from '../lib/firebase/users' export function ContractDetails(props: { contract: Contract }) { const { contract } = props @@ -95,9 +96,8 @@ export function ContractsGrid(props: { contracts: Contract[] }) { ) } -export function ContractsList(props: {}) { - const creator = useUser() - +export function ContractsList(props: { creator: User }) { + const { creator } = props const [contracts, setContracts] = useState([]) useEffect(() => { diff --git a/web/lib/firebase/users.ts b/web/lib/firebase/users.ts index 03088bda..b54df11d 100644 --- a/web/lib/firebase/users.ts +++ b/web/lib/firebase/users.ts @@ -5,6 +5,11 @@ import { setDoc, getDoc, onSnapshot, + collection, + query, + where, + limit, + getDocs, } from 'firebase/firestore' import { getAuth } from 'firebase/auth' import { ref, getStorage, uploadBytes, getDownloadURL } from 'firebase/storage' @@ -35,6 +40,15 @@ export async function getUser(userId: string) { return docSnap.data() as User } +export async function getUserByUsername(username: string) { + // Find a user whose username matches the given username, or null if no such user exists. + const userCollection = collection(db, 'users') + const q = query(userCollection, where('username', '==', username), limit(1)) + const docs = await getDocs(q) + const users = docs.docs.map((doc) => doc.data() as User) + return users[0] || null +} + export async function setUser(userId: string, user: User) { await setDoc(doc(db, 'users', userId), user) } diff --git a/web/pages/[username]/index.tsx b/web/pages/[username]/index.tsx index c2676800..93f05109 100644 --- a/web/pages/[username]/index.tsx +++ b/web/pages/[username]/index.tsx @@ -1,18 +1,23 @@ import { useRouter } from 'next/router' -import React from 'react' -import { Header } from '../../components/header' -import { Col } from '../../components/layout/col' -import { Title } from '../../components/title' +import React, { useEffect, useState } from 'react' +import { getUserByUsername, User } from '../../lib/firebase/users' +import { UserPage } from '../account' +import Error from 'next/error' -// For now, render a placeholder page -export default function ContractPage() { +export default function UserProfile() { const router = useRouter() + const [user, setUser] = useState(null) const { username } = router.query as { username: string } + useEffect(() => { + if (username) { + getUserByUsername(username).then(setUser) + } + }, [username]) - return ( - -
- - </Col> + const errorMessage = `Who is this "${username}" you speak of..` + return user ? ( + <UserPage user={user} /> + ) : ( + <Error statusCode={404} title={errorMessage} /> ) } diff --git a/web/pages/account.tsx b/web/pages/account.tsx index 4f278ae1..c1f2a0db 100644 --- a/web/pages/account.tsx +++ b/web/pages/account.tsx @@ -64,29 +64,29 @@ function SignInCard() { ) } -export default function Account() { - const user = useUser() - +export function UserPage(props: { user: User }) { + const { user } = props return ( <div> <Header /> <div className="max-w-4xl pt-8 pb-0 sm:pb-8 mx-auto"> - {user ? ( - <div> - <UserCard user={user} /> + <div> + <UserCard user={user} /> - <Title className="px-2" text="Your markets" /> - <ContractsList /> + <Title className="px-2" text="Your markets" /> + <ContractsList creator={user} /> - <Spacer h={4} /> + <Spacer h={4} /> - <Title className="px-2" text="Your bets" /> - <BetsList user={user} /> - </div> - ) : ( - <SignInCard /> - )} + <Title className="px-2" text="Your bets" /> + <BetsList user={user} /> + </div> </div> </div> ) } + +export default function Account() { + const user = useUser() + return user ? <UserPage user={user} /> : <SignInCard /> +} diff --git a/web/pages/contract/index.tsx b/web/pages/contract/index.tsx index 2bbf4b81..1d4c5264 100644 --- a/web/pages/contract/index.tsx +++ b/web/pages/contract/index.tsx @@ -115,7 +115,7 @@ export default function NewContract() { <Title text="Your markets" /> - <ContractsList /> + <ContractsList creator={creator} /> </div> </div> )