This commit is contained in:
mantikoros 2022-01-13 20:52:11 -06:00
commit 41b24d415d
15 changed files with 129 additions and 117 deletions

View File

@ -115,7 +115,10 @@ export function BetPanel(props: { contract: Contract; className?: string }) {
<Col
className={clsx('bg-gray-100 shadow-md px-8 py-6 rounded-md', className)}
>
<Title className="!mt-0 whitespace-nowrap" text={`Buy ${betChoice}`} />
<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

View File

@ -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>

View File

@ -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}

View File

@ -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,
},

View File

@ -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} />

View File

@ -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}

View File

@ -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}

View File

@ -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>

View File

@ -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} />
</>
)}
</>
)
}

View File

@ -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',

View File

@ -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>

View File

@ -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>
)
}

View File

@ -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} />

View File

@ -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">

View File

@ -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">