Rename Header to NavBar. Split profile menu and mantic logo out.
This commit is contained in:
parent
28a2199ec7
commit
702c0af33e
|
@ -1,172 +0,0 @@
|
|||
import clsx from 'clsx'
|
||||
import Link from 'next/link'
|
||||
import Image from 'next/image'
|
||||
|
||||
import { useUser } from '../hooks/use-user'
|
||||
import { formatMoney } from '../lib/util/format'
|
||||
import { Row } from './layout/row'
|
||||
import { firebaseLogin, firebaseLogout, User } from '../lib/firebase/users'
|
||||
import { MenuButton } from './menu'
|
||||
|
||||
const hoverClasses =
|
||||
'hover:underline hover:decoration-indigo-400 hover:decoration-2'
|
||||
|
||||
function getNavigationOptions(user: User, options: { mobile: boolean }) {
|
||||
const { mobile } = options
|
||||
return [
|
||||
{
|
||||
name: 'Home',
|
||||
href: '/',
|
||||
},
|
||||
...(mobile
|
||||
? [
|
||||
{ name: 'About', href: '/about' },
|
||||
{
|
||||
name: 'Create a market',
|
||||
href: '/create',
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
name: 'Your bets',
|
||||
href: '/bets',
|
||||
},
|
||||
{
|
||||
name: 'Your markets',
|
||||
href: `/${user.username}`,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Sign out',
|
||||
href: '#',
|
||||
onClick: () => firebaseLogout(),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
function ProfileSummary(props: { user: User }) {
|
||||
const { user } = props
|
||||
return (
|
||||
<Row className="avatar items-center">
|
||||
<div className="rounded-full w-10 h-10 mr-4">
|
||||
<Image src={user.avatarUrl} width={40} height={40} />
|
||||
</div>
|
||||
<div className="truncate" style={{ maxWidth: 175 }}>
|
||||
{user.name}
|
||||
<div className="text-gray-700 text-sm">{formatMoney(user.balance)}</div>
|
||||
</div>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
function SignedInHeaders(props: { user: User; themeClasses?: string }) {
|
||||
const { user, themeClasses } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<Link href="/about">
|
||||
<a
|
||||
className={clsx(
|
||||
'text-base hidden md:block whitespace-nowrap',
|
||||
themeClasses
|
||||
)}
|
||||
>
|
||||
About
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<Link href="/create">
|
||||
<a
|
||||
className={clsx(
|
||||
'text-base hidden md:block whitespace-nowrap',
|
||||
themeClasses
|
||||
)}
|
||||
>
|
||||
Create a market
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<MenuButton
|
||||
className="hidden md:block"
|
||||
menuItems={getNavigationOptions(user, { mobile: false })}
|
||||
buttonContent={<ProfileSummary user={user} />}
|
||||
/>
|
||||
|
||||
<MenuButton
|
||||
className="md:hidden"
|
||||
menuItems={getNavigationOptions(user, { mobile: true })}
|
||||
buttonContent={<ProfileSummary 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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function Header(props: {
|
||||
darkBackground?: boolean
|
||||
className?: string
|
||||
children?: any
|
||||
}) {
|
||||
const { darkBackground, className, children } = props
|
||||
|
||||
const user = useUser()
|
||||
|
||||
const themeClasses = clsx(darkBackground && 'text-white', hoverClasses)
|
||||
|
||||
return (
|
||||
<nav
|
||||
className={clsx(
|
||||
'max-w-7xl w-full flex flex-row justify-between md:justify-start pt-5 pb-4',
|
||||
className
|
||||
)}
|
||||
aria-label="Global"
|
||||
>
|
||||
<Link href="/">
|
||||
<a className="flex flex-row gap-3">
|
||||
<img
|
||||
className="sm:h-10 sm:w-10 hover:rotate-12 transition-all"
|
||||
src="/logo-icon.svg"
|
||||
width={40}
|
||||
height={40}
|
||||
/>
|
||||
<div
|
||||
className={clsx(
|
||||
'font-major-mono lowercase mt-1 sm:text-2xl md:whitespace-nowrap',
|
||||
darkBackground && 'text-white'
|
||||
)}
|
||||
style={{ fontFamily: 'Major Mono Display,monospace' }}
|
||||
>
|
||||
Mantic Markets
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<Row className="gap-6 sm:gap-8 mt-1 md:ml-16">
|
||||
{children}
|
||||
|
||||
{user ? (
|
||||
<SignedInHeaders user={user} themeClasses={themeClasses} />
|
||||
) : (
|
||||
<SignedOutHeaders themeClasses={themeClasses} />
|
||||
)}
|
||||
</Row>
|
||||
</nav>
|
||||
)
|
||||
}
|
27
web/components/mantic-logo.tsx
Normal file
27
web/components/mantic-logo.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
import Link from 'next/link'
|
||||
import clsx from 'clsx'
|
||||
|
||||
export function ManticLogo(props: { darkBackground?: boolean }) {
|
||||
const { darkBackground } = props
|
||||
return (
|
||||
<Link href="/">
|
||||
<a className="flex flex-row gap-3">
|
||||
<img
|
||||
className="sm:h-10 sm:w-10 hover:rotate-12 transition-all"
|
||||
src="/logo-icon.svg"
|
||||
width={40}
|
||||
height={40}
|
||||
/>
|
||||
<div
|
||||
className={clsx(
|
||||
'font-major-mono lowercase mt-1 sm:text-2xl md:whitespace-nowrap',
|
||||
darkBackground && 'text-white'
|
||||
)}
|
||||
style={{ fontFamily: 'Major Mono Display,monospace' }}
|
||||
>
|
||||
Mantic Markets
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
}
|
95
web/components/nav-bar.tsx
Normal file
95
web/components/nav-bar.tsx
Normal file
|
@ -0,0 +1,95 @@
|
|||
import clsx from 'clsx'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { useUser } from '../hooks/use-user'
|
||||
import { Row } from './layout/row'
|
||||
import { firebaseLogin, User } from '../lib/firebase/users'
|
||||
import { ManticLogo } from './mantic-logo'
|
||||
import { ProfileMenu } from './profile-menu'
|
||||
|
||||
const hoverClasses =
|
||||
'hover:underline hover:decoration-indigo-400 hover:decoration-2'
|
||||
|
||||
export function NavBar(props: {
|
||||
darkBackground?: boolean
|
||||
className?: string
|
||||
children?: any
|
||||
}) {
|
||||
const { darkBackground, className, children } = props
|
||||
|
||||
const user = useUser()
|
||||
|
||||
const themeClasses = clsx(darkBackground && 'text-white', hoverClasses)
|
||||
|
||||
return (
|
||||
<nav
|
||||
className={clsx(
|
||||
'w-full flex flex-row justify-between md:justify-start pt-5 pb-4',
|
||||
className
|
||||
)}
|
||||
aria-label="Global"
|
||||
>
|
||||
<ManticLogo darkBackground={darkBackground} />
|
||||
|
||||
<Row className="gap-6 sm:gap-8 mt-1 md:ml-16">
|
||||
{children}
|
||||
|
||||
{user ? (
|
||||
<SignedInHeaders user={user} themeClasses={themeClasses} />
|
||||
) : (
|
||||
<SignedOutHeaders themeClasses={themeClasses} />
|
||||
)}
|
||||
</Row>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
function SignedInHeaders(props: { user: User; themeClasses?: string }) {
|
||||
const { user, themeClasses } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<Link href="/about">
|
||||
<a
|
||||
className={clsx(
|
||||
'text-base hidden md:block whitespace-nowrap',
|
||||
themeClasses
|
||||
)}
|
||||
>
|
||||
About
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<Link href="/create">
|
||||
<a
|
||||
className={clsx(
|
||||
'text-base hidden md:block whitespace-nowrap',
|
||||
themeClasses
|
||||
)}
|
||||
>
|
||||
Create a market
|
||||
</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>
|
||||
</>
|
||||
)
|
||||
}
|
73
web/components/profile-menu.tsx
Normal file
73
web/components/profile-menu.tsx
Normal file
|
@ -0,0 +1,73 @@
|
|||
import Image from 'next/image'
|
||||
import { firebaseLogout, User } from '../lib/firebase/users'
|
||||
import { formatMoney } from '../lib/util/format'
|
||||
import { Row } from './layout/row'
|
||||
import { MenuButton } from './menu'
|
||||
|
||||
export function ProfileMenu(props: { user: User }) {
|
||||
const { user } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuButton
|
||||
className="hidden md:block"
|
||||
menuItems={getNavigationOptions(user, { mobile: false })}
|
||||
buttonContent={<ProfileSummary user={user} />}
|
||||
/>
|
||||
|
||||
<MenuButton
|
||||
className="md:hidden"
|
||||
menuItems={getNavigationOptions(user, { mobile: true })}
|
||||
buttonContent={<ProfileSummary user={user} />}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function getNavigationOptions(user: User, options: { mobile: boolean }) {
|
||||
const { mobile } = options
|
||||
return [
|
||||
{
|
||||
name: 'Home',
|
||||
href: '/',
|
||||
},
|
||||
...(mobile
|
||||
? [
|
||||
{ name: 'About', href: '/about' },
|
||||
{
|
||||
name: 'Create a market',
|
||||
href: '/create',
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
name: 'Your bets',
|
||||
href: '/bets',
|
||||
},
|
||||
{
|
||||
name: 'Your markets',
|
||||
href: `/${user.username}`,
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Sign out',
|
||||
href: '#',
|
||||
onClick: () => firebaseLogout(),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
function ProfileSummary(props: { user: User }) {
|
||||
const { user } = props
|
||||
return (
|
||||
<Row className="avatar items-center">
|
||||
<div className="rounded-full w-10 h-10 mr-4">
|
||||
<Image src={user.avatarUrl} width={40} height={40} />
|
||||
</div>
|
||||
<div className="truncate" style={{ maxWidth: 175 }}>
|
||||
{user.name}
|
||||
<div className="text-gray-700 text-sm">{formatMoney(user.balance)}</div>
|
||||
</div>
|
||||
</Row>
|
||||
)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { firebaseLogout, User } from '../lib/firebase/users'
|
||||
import { Header } from './header'
|
||||
import { NavBar } from './nav-bar'
|
||||
import { ContractsList } from './contracts-list'
|
||||
import { Title } from './title'
|
||||
import { Row } from './layout/row'
|
||||
|
@ -77,7 +77,7 @@ export function UserPage(props: { user: User; currentUser?: User }) {
|
|||
url={`/@${user.username}`}
|
||||
/>
|
||||
|
||||
<Header />
|
||||
<NavBar />
|
||||
|
||||
{/* <UserCard user={user} showPrivateInfo={isCurrentUser} /> */}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
|||
import clsx from 'clsx'
|
||||
|
||||
import { useContractWithPreload } from '../../hooks/use-contract'
|
||||
import { Header } from '../../components/header'
|
||||
import { NavBar } from '../../components/nav-bar'
|
||||
import { ContractOverview } from '../../components/contract-overview'
|
||||
import { BetPanel } from '../../components/bet-panel'
|
||||
import { Col } from '../../components/layout/col'
|
||||
|
@ -64,7 +64,7 @@ export default function ContractPage(props: {
|
|||
url={`/${props.username}/${props.slug}`}
|
||||
/>
|
||||
|
||||
<Header />
|
||||
<NavBar />
|
||||
|
||||
<Col className="w-full md:flex-row justify-between mt-6">
|
||||
<div className="flex-[3]">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { cloneElement } from 'react'
|
||||
import { Header } from '../components/header'
|
||||
import { NavBar } from '../components/nav-bar'
|
||||
import { SEO } from '../components/SEO'
|
||||
import styles from './about.module.css'
|
||||
|
||||
|
@ -7,7 +7,7 @@ export default function About() {
|
|||
return (
|
||||
<div className="max-w-3xl px-4 mx-auto">
|
||||
<SEO title="About" description="About" url="/about" />
|
||||
<Header />
|
||||
<NavBar />
|
||||
<Contents />
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { Header } from '../components/header'
|
||||
import { NavBar } from '../components/nav-bar'
|
||||
import { UserPage } from '../components/user-page'
|
||||
import { useUser } from '../hooks/use-user'
|
||||
import { firebaseLogin } from '../lib/firebase/users'
|
||||
|
@ -35,7 +35,7 @@ export default function Account() {
|
|||
<UserPage user={user} currentUser={user} />
|
||||
) : (
|
||||
<div className="max-w-4xl px-4 pb-8 mx-auto">
|
||||
<Header />
|
||||
<NavBar />
|
||||
<SignInCard />
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { BetsList } from '../components/bets-list'
|
||||
import { Header } from '../components/header'
|
||||
import { NavBar } from '../components/nav-bar'
|
||||
import { SEO } from '../components/SEO'
|
||||
import { Title } from '../components/title'
|
||||
import { useUser } from '../hooks/use-user'
|
||||
|
@ -10,7 +10,7 @@ export default function BetsPage() {
|
|||
return (
|
||||
<div className="max-w-4xl px-4 pb-8 mx-auto">
|
||||
<SEO title="Your bets" description="Your bets" url="/bets" />
|
||||
<Header />
|
||||
<NavBar />
|
||||
<Title text="Your bets" />
|
||||
{user && <BetsList user={user} />}
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@ import router from 'next/router'
|
|||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { ContractsList } from '../components/contracts-list'
|
||||
import { Header } from '../components/header'
|
||||
import { NavBar } from '../components/nav-bar'
|
||||
import { Spacer } from '../components/layout/spacer'
|
||||
import { Title } from '../components/title'
|
||||
import { useUser } from '../hooks/use-user'
|
||||
|
@ -43,7 +43,7 @@ export default function NewContract() {
|
|||
|
||||
return (
|
||||
<div className="max-w-4xl px-4 pb-8 mx-auto">
|
||||
<Header />
|
||||
<NavBar />
|
||||
|
||||
<Title text="Create a new prediction market" />
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { firebaseLogin } from '../lib/firebase/users'
|
|||
import { useContracts } from '../hooks/use-contracts'
|
||||
import { SearchableGrid } from '../components/contracts-list'
|
||||
import { Col } from '../components/layout/col'
|
||||
import { Header } from '../components/header'
|
||||
import { NavBar } from '../components/nav-bar'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function LandingPage() {
|
||||
|
@ -33,14 +33,14 @@ function Hero() {
|
|||
return (
|
||||
<div className="overflow-hidden h-screen bg-world-trading bg-cover bg-gray-900 bg-center lg:bg-left">
|
||||
<div className="max-w-7xl w-full mx-auto">
|
||||
<Header className="px-6 sm:px-8" darkBackground>
|
||||
<NavBar className="px-6 sm:px-8" darkBackground>
|
||||
<div
|
||||
className="text-base font-medium text-white cursor-pointer hover:underline hover:decoration-teal-500 hover:decoration-2"
|
||||
onClick={scrollToAbout}
|
||||
>
|
||||
About
|
||||
</div>
|
||||
</Header>
|
||||
</NavBar>
|
||||
</div>
|
||||
<main>
|
||||
<div className="pt-32 sm:pt-8 lg:pt-0 lg:pb-14 lg:overflow-hidden">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { SearchableGrid } from '../components/contracts-list'
|
||||
import { Header } from '../components/header'
|
||||
import { NavBar } from '../components/nav-bar'
|
||||
import { useContracts } from '../hooks/use-contracts'
|
||||
import { Contract, listAllContracts } from '../lib/firebase/contracts'
|
||||
|
||||
|
@ -20,7 +20,7 @@ export default function Markets(props: { contracts: Contract[] }) {
|
|||
|
||||
return (
|
||||
<div className="max-w-4xl px-4 pb-8 mx-auto">
|
||||
<Header />
|
||||
<NavBar />
|
||||
{(props.contracts || contracts !== 'loading') && (
|
||||
<SearchableGrid
|
||||
contracts={contracts === 'loading' ? props.contracts : contracts}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { DatumValue } from '@nivo/core'
|
|||
import { ResponsiveLine } from '@nivo/line'
|
||||
|
||||
import { Entry, makeEntries } from '../lib/simulator/entries'
|
||||
import { Header } from '../components/header'
|
||||
import { NavBar } from '../components/nav-bar'
|
||||
import { Col } from '../components/layout/col'
|
||||
|
||||
function TableBody(props: { entries: Entry[] }) {
|
||||
|
@ -149,9 +149,7 @@ function NewBidTable(props: {
|
|||
|
||||
function randomBid() {
|
||||
const bidType = Math.random() < 0.5 ? 'YES' : 'NO'
|
||||
const p = bidType === 'YES'
|
||||
? nextEntry.prob
|
||||
: 1 - nextEntry.prob
|
||||
const p = bidType === 'YES' ? nextEntry.prob : 1 - nextEntry.prob
|
||||
|
||||
const amount = Math.round(p * Math.random() * 300) + 1
|
||||
const bid = makeBid(bidType, amount)
|
||||
|
@ -256,7 +254,7 @@ export default function Simulator() {
|
|||
|
||||
return (
|
||||
<Col>
|
||||
<Header />
|
||||
<NavBar />
|
||||
<div className="grid grid-cols-1 xl:grid-cols-2 gap-4 w-full mt-8 p-2 mx-auto text-center">
|
||||
{/* Left column */}
|
||||
<div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import { SearchableGrid } from '../../components/contracts-list'
|
||||
import { Header } from '../../components/header'
|
||||
import { NavBar } from '../../components/nav-bar'
|
||||
import { Title } from '../../components/title'
|
||||
import { useContracts } from '../../hooks/use-contracts'
|
||||
|
||||
|
@ -20,7 +20,7 @@ export default function TagPage() {
|
|||
|
||||
return (
|
||||
<div className="max-w-4xl px-4 pb-8 mx-auto">
|
||||
<Header />
|
||||
<NavBar />
|
||||
<Title text={`#${tag}`} />
|
||||
<SearchableGrid contracts={contracts === 'loading' ? [] : contracts} />
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue
Block a user