diff --git a/web/components/bet-panel.tsx b/web/components/bet-panel.tsx index 1309e9b2..0fa026d3 100644 --- a/web/components/bet-panel.tsx +++ b/web/components/bet-panel.tsx @@ -115,7 +115,10 @@ export function BetPanel(props: { contract: Contract; className?: string }) { - + <Title + className="mt-0 whitespace-nowrap text-neutral" + text={`Buy ${betChoice}`} + /> <div className="mt-2 mb-1 text-sm text-gray-500">Outcome</div> <YesNoSelector diff --git a/web/components/bets-list.tsx b/web/components/bets-list.tsx index 8a9f816c..1ca7b38a 100644 --- a/web/components/bets-list.tsx +++ b/web/components/bets-list.tsx @@ -151,9 +151,10 @@ function MyContractBets(props: { contract: Contract; bets: Bet[] }) { </Row> <Row className="gap-2 text-gray-500 text-sm"> - <div> - <UserLink username={contract.creatorUsername} /> - </div> + <UserLink + name={contract.creatorName} + username={contract.creatorUsername} + /> {resolution && ( <> <div>•</div> diff --git a/web/components/contract-card.tsx b/web/components/contract-card.tsx index 9fc08526..cbaf1c12 100644 --- a/web/components/contract-card.tsx +++ b/web/components/contract-card.tsx @@ -24,8 +24,8 @@ export function ContractCard(props: { return ( <Link href={contractPath(contract)}> - <a> - <li className="col-span-1 bg-white hover:bg-gray-100 shadow-md rounded-lg divide-y divide-gray-200"> + <a className="col-span-1"> + <li className="bg-white hover:bg-gray-100 shadow-md rounded-lg divide-y divide-gray-200"> <div className="card"> <div className="card-body p-6"> <Row className="justify-between gap-4 mb-2"> @@ -102,15 +102,17 @@ export function AbbrContractDetails(props: { showHotVolume?: boolean }) { const { contract, showHotVolume } = props - const { volume24Hours } = contract + const { volume24Hours, creatorName, creatorUsername } = contract const { truePool } = contractMetrics(contract) return ( <Col className={clsx('text-sm text-gray-500 gap-2')}> <Row className="gap-2 flex-wrap"> - <div className="whitespace-nowrap"> - <UserLink username={contract.creatorUsername} /> - </div> + <UserLink + className="whitespace-nowrap" + name={creatorName} + username={creatorUsername} + /> <div>•</div> {showHotVolume ? ( <div className="whitespace-nowrap"> @@ -127,7 +129,8 @@ export function AbbrContractDetails(props: { export function ContractDetails(props: { contract: Contract }) { const { contract } = props - const { question, description, closeTime } = contract + const { question, description, closeTime, creatorName, creatorUsername } = + contract const { truePool, createdDate, resolvedDate } = contractMetrics(contract) const tags = parseTags(`${question} ${description}`).map((tag) => `#${tag}`) @@ -135,9 +138,11 @@ export function ContractDetails(props: { contract: Contract }) { return ( <Col className="text-sm text-gray-500 gap-2 sm:flex-row sm:flex-wrap"> <Row className="gap-2 flex-wrap"> - <div className="whitespace-nowrap"> - <UserLink username={contract.creatorUsername} /> - </div> + <UserLink + className="whitespace-nowrap" + name={creatorName} + username={creatorUsername} + /> <div className="">•</div> <div className="whitespace-nowrap"> {resolvedDate ? `${createdDate} - ${resolvedDate}` : createdDate} diff --git a/web/components/contract-feed.tsx b/web/components/contract-feed.tsx index 572f7bc5..d50c9edb 100644 --- a/web/components/contract-feed.tsx +++ b/web/components/contract-feed.tsx @@ -31,6 +31,7 @@ import { formatMoney } from '../lib/util/format' import { ResolutionOrChance } from './contract-card' import { SiteLink } from './site-link' import { Col } from './layout/col' +import { UserLink } from './user-page' dayjs.extend(relativeTime) function FeedComment(props: { activityItem: any }) { @@ -38,7 +39,7 @@ function FeedComment(props: { activityItem: any }) { const { person, text, amount, outcome, createdTime } = activityItem return ( <> - <div className="relative"> + <SiteLink className="relative" href={`/${person.username}`}> <img className="h-10 w-10 rounded-full bg-gray-400 flex items-center justify-center ring-8 ring-gray-50" src={person.avatarUrl} @@ -48,13 +49,15 @@ function FeedComment(props: { activityItem: any }) { <span className="absolute -bottom-3 -right-2 bg-gray-50 rounded-tl px-0.5 py-px"> <ChatAltIcon className="h-5 w-5 text-gray-400" aria-hidden="true" /> </span> - </div> + </SiteLink> <div className="min-w-0 flex-1"> <div> <p className="mt-0.5 text-sm text-gray-500"> - <a href={person.href} className="font-medium text-gray-900"> - {person.name} - </a>{' '} + <UserLink + className="text-gray-500" + username={person.username} + name={person.name} + />{' '} placed {formatMoney(amount)} on <OutcomeLabel outcome={outcome} />{' '} <Timestamp time={createdTime} /> </p> @@ -205,6 +208,8 @@ export function ContractDescription(props: { function FeedQuestion(props: { contract: Contract }) { const { contract } = props + const { creatorName, creatorUsername, createdTime, question, resolution } = + contract const { probPercent } = contractMetrics(contract) return ( @@ -218,19 +223,23 @@ function FeedQuestion(props: { contract: Contract }) { </div> <div className="min-w-0 flex-1 py-1.5"> <div className="text-sm text-gray-500 mb-2"> - <span className="text-gray-900">{contract.creatorName}</span> asked{' '} - <Timestamp time={contract.createdTime} /> + <UserLink + className="text-gray-900" + name={creatorName} + username={creatorUsername} + />{' '} + asked <Timestamp time={createdTime} /> </div> <Col className="items-start sm:flex-row justify-between gap-2 sm:gap-4 mb-4 mr-2"> <SiteLink href={contractPath(contract)} className="text-lg sm:text-xl text-indigo-700" > - {contract.question} + {question} </SiteLink> <ResolutionOrChance className="items-center" - resolution={contract.resolution} + resolution={resolution} probPercent={probPercent} /> </Col> @@ -242,6 +251,7 @@ function FeedQuestion(props: { contract: Contract }) { function FeedDescription(props: { contract: Contract }) { const { contract } = props + const { creatorName, creatorUsername } = contract const user = useUser() const isCreator = user?.id === contract.creatorId @@ -256,8 +266,12 @@ function FeedDescription(props: { contract: Contract }) { </div> <div className="min-w-0 flex-1 py-1.5"> <div className="text-sm text-gray-500"> - <span className="text-gray-900">{contract.creatorName}</span> created - this market <Timestamp time={contract.createdTime} /> + <UserLink + className="text-gray-900" + name={creatorName} + username={creatorUsername} + />{' '} + created this market <Timestamp time={contract.createdTime} /> </div> <ContractDescription contract={contract} isCreator={isCreator} /> </div> @@ -280,6 +294,7 @@ function OutcomeIcon(props: { outcome?: 'YES' | 'NO' | 'CANCEL' }) { function FeedResolve(props: { contract: Contract }) { const { contract } = props + const { creatorName, creatorUsername } = contract const resolution = contract.resolution || 'CANCEL' return ( @@ -293,8 +308,12 @@ function FeedResolve(props: { contract: Contract }) { </div> <div className="min-w-0 flex-1 py-1.5"> <div className="text-sm text-gray-500"> - <span className="text-gray-900">{contract.creatorName}</span> resolved - this market to <OutcomeLabel outcome={resolution} />{' '} + <UserLink + className="text-gray-900" + name={creatorName} + username={creatorUsername} + />{' '} + resolved this market to <OutcomeLabel outcome={resolution} />{' '} <Timestamp time={contract.resolutionTime || 0} /> </div> </div> @@ -354,7 +373,7 @@ function toFeedComment(bet: Bet, comment: Comment) { // Invariant: bet.comment exists text: comment.text, person: { - href: `/${comment.userUsername}`, + username: comment.userUsername, name: comment.userName, avatarUrl: comment.userAvatarUrl, }, diff --git a/web/components/contract-overview.tsx b/web/components/contract-overview.tsx index 0574aad9..964f70f0 100644 --- a/web/components/contract-overview.tsx +++ b/web/components/contract-overview.tsx @@ -40,7 +40,7 @@ export const ContractOverview = (props: { return ( <Col className={clsx('mb-6', className)}> - <Row className="justify-between gap-4"> + <Row className="justify-between gap-4 px-2"> <Col className="gap-4"> <div className="text-2xl md:text-3xl text-indigo-700"> <Linkify text={contract.question} /> diff --git a/web/components/contracts-list.tsx b/web/components/contracts-list.tsx index c76fa72d..8759fe8b 100644 --- a/web/components/contracts-list.tsx +++ b/web/components/contracts-list.tsx @@ -42,7 +42,7 @@ export function ContractsGrid(props: { } return ( - <ul role="list" className="grid grid-cols-1 gap-6 lg:grid-cols-2"> + <ul className="w-full grid grid-cols-1 gap-6 md:grid-cols-2"> {contracts.map((contract) => ( <ContractCard contract={contract} diff --git a/web/components/manifold-logo.tsx b/web/components/manifold-logo.tsx index 545093e5..a36ae712 100644 --- a/web/components/manifold-logo.tsx +++ b/web/components/manifold-logo.tsx @@ -1,4 +1,5 @@ import Link from 'next/link' +import Image from 'next/image' import clsx from 'clsx' export function ManifoldLogo(props: { darkBackground?: boolean }) { @@ -6,8 +7,8 @@ export function ManifoldLogo(props: { darkBackground?: boolean }) { return ( <Link href="/"> - <a className="flex flex-row gap-4"> - <img + <a className="flex flex-row gap-4 flex-shrink-0"> + <Image className="hover:rotate-12 transition-all" src={darkBackground ? '/logo-white.svg' : '/logo.svg'} width={45} diff --git a/web/components/menu.tsx b/web/components/menu.tsx index 5b8ffd86..2274afc0 100644 --- a/web/components/menu.tsx +++ b/web/components/menu.tsx @@ -9,10 +9,7 @@ export function MenuButton(props: { }) { const { buttonContent, menuItems, className } = props return ( - <Menu - as="div" - className={clsx('flex-shrink-0 relative ml-4 z-10', className)} - > + <Menu as="div" className={clsx('flex-shrink-0 relative z-10', className)}> <div> <Menu.Button className="rounded-full flex"> <span className="sr-only">Open user menu</span> diff --git a/web/components/nav-bar.tsx b/web/components/nav-bar.tsx index 216a626a..d4abd801 100644 --- a/web/components/nav-bar.tsx +++ b/web/components/nav-bar.tsx @@ -10,11 +10,9 @@ import { ProfileMenu } from './profile-menu' export function NavBar(props: { darkBackground?: boolean wide?: boolean - isLandingPage?: boolean className?: string - children?: any }) { - const { darkBackground, wide, isLandingPage, className, children } = props + const { darkBackground, wide, className } = props const user = useUser() @@ -27,44 +25,14 @@ export function NavBar(props: { <Row className={clsx( 'justify-between items-center mx-auto sm:px-4', - isLandingPage ? 'max-w-7xl' : wide ? 'max-w-6xl' : 'max-w-4xl' + wide ? 'max-w-6xl' : 'max-w-4xl' )} > <ManifoldLogo darkBackground={darkBackground} /> - <Row className="items-center gap-6 sm:gap-8 md:ml-16 lg:ml-40"> - {children} - - {!user && ( - <Link href="/about"> - <a - className={clsx( - 'text-base hidden md:block whitespace-nowrap', - themeClasses - )} - > - About - </a> - </Link> - )} - - {!isLandingPage && ( - <Link href="/markets"> - <a - className={clsx( - 'text-base hidden md:block whitespace-nowrap', - themeClasses - )} - > - All markets - </a> - </Link> - )} - - {user ? ( - <SignedInHeaders user={user} themeClasses={themeClasses} /> - ) : ( - <SignedOutHeaders themeClasses={themeClasses} /> + <Row className="items-center gap-6 sm:gap-8 ml-6"> + {(user || user === null) && ( + <NavOptions user={user} themeClasses={themeClasses} /> )} </Row> </Row> @@ -72,41 +40,62 @@ export function NavBar(props: { ) } -function SignedInHeaders(props: { user: User; themeClasses?: string }) { +function NavOptions(props: { user: User | null; themeClasses: string }) { const { user, themeClasses } = props - return ( <> - <Link href="/create"> + {user === null && ( + <Link href="/about"> + <a + className={clsx( + 'text-base hidden md:block whitespace-nowrap', + themeClasses + )} + > + About + </a> + </Link> + )} + + <Link href="/markets"> <a className={clsx( 'text-base hidden md:block whitespace-nowrap', themeClasses )} > - Create a market + All markets </a> </Link> - <ProfileMenu user={user} /> - </> - ) -} - -function SignedOutHeaders(props: { themeClasses?: string }) { - const { themeClasses } = props - - return ( - <> - <div - className={clsx( - 'text-base font-medium cursor-pointer whitespace-nowrap', - themeClasses - )} - onClick={firebaseLogin} - > - Sign in - </div> + {user === null ? ( + <> + <div + className={clsx( + 'text-base font-medium cursor-pointer whitespace-nowrap', + themeClasses + )} + onClick={firebaseLogin} + > + Sign in + </div> + </> + ) : ( + <> + <Link href="/create"> + <a + className={clsx( + 'text-base hidden md:block whitespace-nowrap', + themeClasses + )} + > + Create a market + </a> + </Link> + + <ProfileMenu user={user} /> + </> + )} </> ) } diff --git a/web/components/profile-menu.tsx b/web/components/profile-menu.tsx index 4f20a1a5..4bbe48c4 100644 --- a/web/components/profile-menu.tsx +++ b/web/components/profile-menu.tsx @@ -51,10 +51,6 @@ function getNavigationOptions(user: User, options: { mobile: boolean }) { name: 'Your markets', href: `/${user.username}`, }, - // { - // name: 'Add funds', - // href: '/add-funds', - // }, { name: 'Discord', href: 'https://discord.gg/eHQBNBqXuh', diff --git a/web/components/resolution-panel.tsx b/web/components/resolution-panel.tsx index 3c540e0a..dec0d436 100644 --- a/web/components/resolution-panel.tsx +++ b/web/components/resolution-panel.tsx @@ -60,7 +60,7 @@ export function ResolutionPanel(props: { <Col className={clsx('bg-gray-100 shadow-md px-8 py-6 rounded-md', className)} > - <Title className="mt-0" text="Your market" /> + <Title className="mt-0 text-neutral" text="Your market" /> <div className="pt-2 pb-1 text-sm text-gray-500">Resolve outcome</div> diff --git a/web/components/user-page.tsx b/web/components/user-page.tsx index 3bf207b2..0a27fae6 100644 --- a/web/components/user-page.tsx +++ b/web/components/user-page.tsx @@ -7,12 +7,18 @@ import { SEO } from './SEO' import { Page } from './page' import { SiteLink } from './site-link' -export function UserLink(props: { username: string; className?: string }) { - const { username, className } = props +export function UserLink(props: { + name: string + username: string + showUsername?: boolean + className?: string +}) { + const { name, username, showUsername, className } = props return ( <SiteLink href={`/${username}`} className={className}> - @{username} + {name} + {showUsername && ` (@${username})`} </SiteLink> ) } diff --git a/web/pages/[username]/[contractSlug].tsx b/web/pages/[username]/[contractSlug].tsx index 30092509..57ceb4f0 100644 --- a/web/pages/[username]/[contractSlug].tsx +++ b/web/pages/[username]/[contractSlug].tsx @@ -119,8 +119,13 @@ function BetsSection(props: { contract: Contract; user: User | null }) { return ( <div> - <Title text="Your trades" /> - <MyBetsSummary contract={contract} bets={userBets} showMKT /> + <Title className="px-2" text="Your trades" /> + <MyBetsSummary + className="px-2" + contract={contract} + bets={userBets} + showMKT + /> <Spacer h={6} /> <ContractBetsTable contract={contract} bets={userBets} /> <Spacer h={12} /> diff --git a/web/pages/index.tsx b/web/pages/index.tsx index a641b6b9..d644a3f6 100644 --- a/web/pages/index.tsx +++ b/web/pages/index.tsx @@ -1,12 +1,10 @@ import React from 'react' import _ from 'lodash' -import { useUser } from '../hooks/use-user' import { Contract, getHotContracts, listAllContracts, } from '../lib/firebase/contracts' -import LandingPage from './landing-page' import { ContractsGrid } from '../components/contracts-list' import { Spacer } from '../components/layout/spacer' import { Page } from '../components/page' @@ -37,16 +35,8 @@ const Home = (props: { hotContracts: Contract[] recentComments: Comment[] }) => { - const user = useUser() - - if (user === undefined) return <></> - const { contracts, hotContracts, recentComments } = props - if (user === null) { - return <LandingPage hotContracts={hotContracts} /> - } - return ( <Page> <div className="w-full bg-indigo-50 border-2 border-indigo-100 p-6 rounded-lg shadow-md"> diff --git a/web/pages/landing-page.tsx b/web/pages/landing-page.tsx index 12f2e675..b4c6aa5b 100644 --- a/web/pages/landing-page.tsx +++ b/web/pages/landing-page.tsx @@ -34,7 +34,7 @@ const scrollToAbout = () => { function Hero() { return ( <div className="overflow-hidden h-screen bg-world-trading bg-cover bg-gray-900 bg-center lg:bg-left"> - <NavBar isLandingPage darkBackground /> + <NavBar darkBackground /> <main> <div className="pt-32 sm:pt-8 lg:pt-0 lg:pb-14 lg:overflow-hidden"> <div className="mx-auto max-w-7xl lg:px-8 xl:px-0">