Merge branch 'main' into new-dpm

This commit is contained in:
mantikoros 2022-01-11 12:05:06 -06:00
commit dc45c29604
21 changed files with 161 additions and 131 deletions

View File

@ -18,7 +18,7 @@ export function AddFundsButton(props: { className?: string }) {
<label
htmlFor="add-funds"
className={clsx(
'btn btn-sm normal-case modal-button bg-gradient-to-r from-teal-500 to-green-500 hover:from-teal-600 hover:to-green-600 font-normal border-none',
'btn btn-xs normal-case modal-button bg-gradient-to-r from-teal-500 to-green-500 hover:from-teal-600 hover:to-green-600 font-normal border-none',
className
)}
>

View File

@ -0,0 +1,79 @@
import clsx from 'clsx'
import { useUser } from '../hooks/use-user'
import { formatMoney } from '../lib/util/format'
import { AddFundsButton } from './add-funds-button'
import { Col } from './layout/col'
import { Row } from './layout/row'
export function AmountInput(props: {
amount: number | undefined
onChange: (newAmount: number | undefined) => void
error: string | undefined
setError: (error: string | undefined) => void
disabled?: boolean
className?: string
inputClassName?: string
}) {
const {
amount,
onChange,
error,
setError,
disabled,
className,
inputClassName,
} = props
const user = useUser()
const onAmountChange = (str: string) => {
const amount = parseInt(str.replace(/[^\d]/, ''))
if (str && isNaN(amount)) return
onChange(str ? amount : undefined)
if (user && user.balance < amount) setError('Insufficient balance')
else setError(undefined)
}
const remainingBalance = (user?.balance ?? 0) - (amount ?? 0)
return (
<Col className={className}>
<label className="input-group">
<span className="text-sm bg-gray-200">M$</span>
<input
className={clsx(
'input input-bordered',
error && 'input-error',
inputClassName
)}
type="text"
placeholder="0"
maxLength={9}
value={amount ?? ''}
disabled={disabled}
onChange={(e) => onAmountChange(e.target.value)}
/>
</label>
{user && (
<Row className="text-sm text-gray-500 justify-between mt-3 gap-4 items-end">
{error ? (
<div className="font-medium tracking-wide text-red-500 text-xs whitespace-nowrap mr-auto self-center">
{error}
</div>
) : (
<Col>
<div className="whitespace-nowrap">Remaining balance</div>
<div className="text-neutral mt-1">
{formatMoney(Math.floor(remainingBalance))}
</div>
</Col>
)}
{user.balance !== 1000 && <AddFundsButton className="mt-1" />}
</Row>
)}
</Col>
)
}

View File

@ -20,11 +20,11 @@ import {
calculatePayoutAfterCorrectBet,
} from '../../common/calculate'
import { firebaseLogin } from '../lib/firebase/users'
import { AddFundsButton } from './add-funds-button'
import { OutcomeLabel } from './outcome-label'
import { AdvancedPanel } from './advanced-panel'
import { Bet } from '../../common/bet'
import { placeBet } from '../lib/firebase/api-call'
import { AmountInput } from './amount-input'
export function BetPanel(props: { contract: Contract; className?: string }) {
useEffect(() => {
@ -48,17 +48,9 @@ export function BetPanel(props: { contract: Contract; className?: string }) {
setWasSubmitted(false)
}
function onBetChange(str: string) {
function onBetChange(newAmount: number | undefined) {
setWasSubmitted(false)
const amount = parseInt(str.replace(/[^\d]/, ''))
if (str && isNaN(amount)) return
setBetAmount(str ? amount : undefined)
if (user && user.balance < amount) setError('Insufficient balance')
else setError(undefined)
setBetAmount(newAmount)
}
async function submitBet() {
@ -106,8 +98,6 @@ export function BetPanel(props: { contract: Contract; className?: string }) {
: 0
const estimatedReturnPercent = (estimatedReturn * 100).toFixed() + '%'
const remainingBalance = (user?.balance || 0) - (betAmount || 0)
return (
<Col
className={clsx('bg-gray-100 shadow-md px-8 py-6 rounded-md', className)}
@ -121,41 +111,17 @@ export function BetPanel(props: { contract: Contract; className?: string }) {
onSelect={(choice) => onBetChoice(choice)}
/>
<div className="mt-3 mb-1 text-sm text-gray-500">
Amount{' '}
{user && (
<span className="float-right">
{formatMoney(
remainingBalance > 0 ? Math.floor(remainingBalance) : 0
)}{' '}
left
</span>
)}
</div>
<Col className="my-2">
<label className="input-group">
<span className="text-sm bg-gray-200">M$</span>
<input
className={clsx(
'input input-bordered w-full',
error && 'input-error'
)}
type="text"
placeholder="0"
maxLength={9}
value={betAmount ?? ''}
onChange={(e) => onBetChange(e.target.value)}
/>
</label>
{error && (
<div className="font-medium tracking-wide text-red-500 text-xs mt-3">
{error}
</div>
)}
{user && user.balance !== 1000 && (
<AddFundsButton className="self-end mt-3" />
)}
</Col>
<div className="my-3 text-sm text-gray-500">Amount </div>
<AmountInput
inputClassName="w-full"
amount={betAmount}
onChange={onBetChange}
error={error}
setError={setError}
disabled={isSubmitting}
/>
<Spacer h={4} />
<div className="mt-2 mb-1 text-sm text-gray-500">Implied probability</div>
<Row>

View File

@ -0,0 +1,37 @@
import Link from 'next/link'
import clsx from 'clsx'
export function ManifoldLogo(props: { darkBackground?: boolean }) {
const { darkBackground } = props
return (
<Link href="/">
<a className="flex flex-row gap-4">
<img
className="hover:rotate-12 transition-all"
src={darkBackground ? '/logo-white.svg' : '/logo.svg'}
width={45}
height={45}
/>
<div
className={clsx(
'sm:hidden font-major-mono lowercase mt-1 text-lg',
darkBackground && 'text-white'
)}
>
Manifold
<br />
Markets
</div>
<div
className={clsx(
'hidden sm:flex font-major-mono lowercase mt-1 sm:text-2xl md:whitespace-nowrap',
darkBackground && 'text-white'
)}
>
Manifold Markets
</div>
</a>
</Link>
)
}

View File

@ -1,26 +0,0 @@
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(
'hidden sm:flex font-major-mono lowercase mt-1 sm:text-2xl md:whitespace-nowrap',
darkBackground && 'text-white'
)}
>
Manifold Markets
</div>
</a>
</Link>
)
}

View File

@ -4,16 +4,17 @@ 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 { ManifoldLogo } from './manifold-logo'
import { ProfileMenu } from './profile-menu'
export function NavBar(props: {
darkBackground?: boolean
wide?: boolean
isLandingPage?: boolean
className?: string
children?: any
}) {
const { darkBackground, wide, className, children } = props
const { darkBackground, wide, isLandingPage, className, children } = props
const user = useUser()
@ -26,10 +27,10 @@ export function NavBar(props: {
<Row
className={clsx(
'justify-between items-center mx-auto sm:px-4',
wide ? 'max-w-6xl' : 'max-w-4xl'
isLandingPage ? 'max-w-7xl' : wide ? 'max-w-6xl' : 'max-w-4xl'
)}
>
<ManticLogo darkBackground={darkBackground} />
<ManifoldLogo darkBackground={darkBackground} />
<Row className="items-center gap-6 sm:gap-8 md:ml-16 lg:ml-40">
{children}

View File

@ -1,7 +1,7 @@
import Image from 'next/image'
import { firebaseLogout, User } from '../lib/firebase/users'
import { formatMoney } from '../lib/util/format'
import { Row } from './layout/row'
import { Col } from './layout/col'
import { MenuButton } from './menu'
export function ProfileMenu(props: { user: User }) {
@ -67,16 +67,16 @@ function getNavigationOptions(user: User, options: { mobile: boolean }) {
function ProfileSummary(props: { user: User }) {
const { user } = props
return (
<Row className="avatar items-center">
<div className="rounded-full w-10 h-10 mr-4">
<Col className="avatar items-center sm:flex-row gap-2 sm:gap-0">
<div className="rounded-full w-10 h-10 sm:mr-4">
<Image src={user.avatarUrl} width={40} height={40} />
</div>
<div className="truncate text-left" style={{ maxWidth: 170 }}>
{user.name}
<div className="hidden sm:flex">{user.name}</div>
<div className="text-gray-700 text-sm">
{formatMoney(Math.floor(user.balance))}
</div>
</div>
</Row>
</Col>
)
}

View File

@ -35,7 +35,7 @@ function MyApp({ Component, pageProps }: AppProps) {
/>
<meta
name="twitter:image"
content="https://manifold.markets/logo-bg.png"
content="https://manifold.markets/logo-bg-white.png"
key="image2"
/>
</Head>

View File

@ -9,7 +9,7 @@ function SignInCard() {
<div className="card glass sm:card-side shadow-xl hover:shadow-xl text-neutral-content bg-green-600 hover:bg-green-600 transition-all max-w-sm mx-4 sm:mx-auto my-12">
<div className="p-4">
<img
src="/logo-icon-white-bg.png"
src="/logo-bg-white.png"
className="rounded-lg shadow-lg w-20 h-20"
/>
</div>

View File

@ -10,10 +10,10 @@ import { Title } from '../components/title'
import { useUser } from '../hooks/use-user'
import { Contract, path } from '../lib/firebase/contracts'
import { Page } from '../components/page'
import { formatMoney } from '../lib/util/format'
import { AdvancedPanel } from '../components/advanced-panel'
import { createContract } from '../lib/firebase/api-call'
import { Row } from '../components/layout/row'
import { AmountInput } from '../components/amount-input'
// Allow user to create a new contract
export default function NewContract() {
@ -33,7 +33,7 @@ export default function NewContract() {
const [description, setDescription] = useState('')
const [ante, setAnte] = useState<number | undefined>(0)
const [anteError, setAnteError] = useState('')
const [anteError, setAnteError] = useState<string | undefined>()
const [closeDate, setCloseDate] = useState('')
const [isSubmitting, setIsSubmitting] = useState(false)
@ -75,17 +75,6 @@ export default function NewContract() {
await router.push(path(result.contract as Contract))
}
function onAnteChange(str: string) {
const amount = parseInt(str.replace(/[^\d]/, ''))
if (str && isNaN(amount)) return
setAnte(str ? amount : undefined)
if (user && user.balance < amount) setAnteError('Insufficient balance')
else setAnteError('')
}
const descriptionPlaceholder = `e.g. This market will resolve to “Yes” if, by June 2, 2021, 11:59:59 PM ET, Paxlovid (also known under PF-07321332)...`
if (!creator) return <></>
@ -166,33 +155,19 @@ export default function NewContract() {
<label className="label">
<span className="mb-1">Subsidize your market</span>
</label>
<label className="input-group">
<span className="text-sm ">M$</span>
<input
className={clsx(
'input input-bordered',
anteError && 'input-error'
)}
type="text"
placeholder="0"
maxLength={9}
value={ante ?? ''}
disabled={isSubmitting}
onChange={(e) => onAnteChange(e.target.value)}
/>
</label>
<label>
<span className="label-text text-gray-500 ml-1">
Remaining balance:{' '}
{formatMoney(remainingBalance > 0 ? remainingBalance : 0)}
</span>
</label>
<AmountInput
className="items-start"
amount={ante}
onChange={setAnte}
error={anteError}
setError={setAnteError}
disabled={isSubmitting}
/>
</div>
<Spacer h={4} />
<div className="form-control">
<div className="form-control items-start mb-1">
<label className="label">
<span className="mb-1">Close date</span>
</label>
@ -208,8 +183,8 @@ export default function NewContract() {
</div>
<label>
<span className="label-text text-gray-500 ml-1">
No new trades will be allowed after{' '}
{closeDate ? formattedCloseTime : 'this time'}
No trades allowed after this date
{/* {closeDate ? formattedCloseTime : 'this date'} */}
</span>
</label>
</AdvancedPanel>

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 wide darkBackground>
<NavBar isLandingPage darkBackground>
<div
className="text-base font-medium text-white ml-8 cursor-pointer hover:underline hover:decoration-teal-500 hover:decoration-2"
onClick={scrollToAbout}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 69.218 70.506" xmlns="http://www.w3.org/2000/svg" fill="none">
<g data-v-fde0c5aa="" id="5c4df6fb-50cb-4581-b5fd-961d2467c672" stroke="none" fill="#11b981" transform="matrix(0.801904, 0, 0, 0.801904, 7.879115, 8.276814)">
<path d="M29.347 10.688A16.012 16.012 0 0 1 34 10c1.604 0 3.168.238 4.652.688C41.374 3.578 47.976 0 58 0a2 2 0 1 1 0 4c-8.574 0-13.645 2.759-15.688 8.325a16.03 16.03 0 0 1 4.399 3.956C49.892 17.358 52 21.399 52 26c0 4.672-2.173 8.766-5.437 9.767C43.11 40.917 37.801 45 34 45s-9.11-4.083-12.563-9.233C18.173 34.767 16 30.672 16 26c0-4.6 2.108-8.642 5.29-9.72a16.03 16.03 0 0 1 4.398-3.955C23.645 6.76 18.573 4 9.999 4a2 2 0 1 1 0-4c10.024 0 16.627 3.578 19.348 10.688zM34 41c1.894 0 5.359-2.493 8.068-5.87C39.58 33.547 38 29.984 38 26c0-3.898 1.513-7.394 3.91-9.026A11.966 11.966 0 0 0 34 14c-2.972 0-5.76 1.087-7.91 2.974C28.488 18.606 30 22.102 30 26c0 3.983-1.58 7.546-4.068 9.13C28.642 38.508 32.106 41 34 41zm-11-9c1.408 0 3-2.547 3-6s-1.592-6-3-6-3 2.547-3 6 1.592 6 3 6zm22 0c1.408 0 3-2.547 3-6s-1.592-6-3-6-3 2.547-3 6 1.592 6 3 6zM6.883 66.673a2 2 0 0 1-3.297.741C1.13 64.96 0 60.813 0 55c0-6.052 3.982-12.206 11.734-18.548a2 2 0 0 1 3.029.604l15 28a2 2 0 1 1-3.526 1.888l-8.755-16.342c-4.18 2.733-7.74 8.065-10.599 16.07zm5.526-25.54C6.75 46.174 4 50.818 4 55c0 2.566.243 4.666.7 6.304 2.934-6.756 6.547-11.518 10.887-14.24l-3.178-5.932zm48.708 25.54c-2.86-8.006-6.418-13.338-10.599-16.071l-8.755 16.342a2 2 0 1 1-3.526-1.888l15-28a2 2 0 0 1 3.03-.604C64.018 42.794 68 48.948 68 55c0 5.813-1.13 9.96-3.585 12.414a2 2 0 0 1-3.298-.741zm-5.526-25.54l-3.178 5.932c4.34 2.721 7.954 7.483 10.887 14.24.457-1.639.7-3.739.7-6.305 0-4.18-2.75-8.825-8.409-13.868z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="master-artboard" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500" width="500px" height="500px"><rect id="ee-background" x="0" y="0" width="500" height="500" style="fill: white; fill-opacity: 0; pointer-events: none;"/><g transform="matrix(0.4310344457626343, 0, 0, 0.4310344457626343, -49.559356689453125, 43.23752975463867)"><g transform="matrix(-1, 0, 0, 1, 1398.2724346748023, 1.4210854715202004e-14)"><g transform="matrix(-0.8166666626930236, 0, 0, 0.8166666626930236, 1188.272278324478, 1.4210854715202004e-14)"><path d="m1200 723.75c-1.875-7.5-9.375-13.125-16.875-13.125l-266.25-18.75 196.88-444.38c3.75-7.5 1.875-16.875-5.625-22.5s-15-5.625-22.5 0l-401.25 288.75-60-371.25c-1.875-7.5-7.5-15-16.875-15-7.5 0-16.875 3.75-18.75 11.25l-157.5 384.38-243.75-285h-1.875-1.875c-1.875-1.875-1.875-1.875-3.75-1.875h-1.875-5.625-1.875c-1.875 0-3.75 0-5.625 1.875h-1.875c-1.875 0-3.75 1.875-3.75 3.75l-157.5 170.62c-5.625 3.75-5.625 11.25-1.875 18.75 3.75 5.625 9.375 9.375 16.875 9.375h1.875l146.25-22.5 30 459.38v1.875c0 1.875 0 3.75 1.875 5.625 0 1.875 1.875 3.75 3.75 3.75l1.875 1.875c1.875 1.875 1.875 1.875 3.75 1.875h1.875l521.25 178.12c1.875 0 3.75 1.875 5.625 1.875h5.625 1.875c1.875 0 1.875-1.875 3.75-1.875l446.25-326.25c5.625-5.625 9.375-13.125 7.5-20.625zm-1134.4-328.12 91.875-99.375 5.625 84.375zm1063.1 348.75-7.5 5.625-341.25 249.38 65.625-148.12 54.375-123.75zm-605.62 217.5 146.25-161.25c7.5-7.5 5.625-18.75-1.875-26.25s-18.75-5.625-26.25 1.875l-157.5 174.38-230.62-78.75 796.88-575.62-324.38 735zm75-748.12 52.5 324.38-129.38 93.75-63.75-75zm-106.88 438.75-118.12 86.25-142.5 103.12-33.75-525v-11.25z" style="fill-opacity: 1; fill: rgb(255, 255, 255);"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 98 KiB

2
web/public/logo.svg Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<svg id="master-artboard" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500" width="500px" height="500px"><rect id="ee-background" x="0" y="0" width="500" height="500" style="fill: white; fill-opacity: 0; pointer-events: none;"/><g transform="matrix(0.4310344457626343, 0, 0, 0.4310344457626343, -49.559356689453125, 43.23752975463867)"><g transform="matrix(-1, 0, 0, 1, 1398.2724346748023, 1.4210854715202004e-14)"><g transform="matrix(-0.8166666626930236, 0, 0, 0.8166666626930236, 1188.272278324478, 1.4210854715202004e-14)"><path d="m1200 723.75c-1.875-7.5-9.375-13.125-16.875-13.125l-266.25-18.75 196.88-444.38c3.75-7.5 1.875-16.875-5.625-22.5s-15-5.625-22.5 0l-401.25 288.75-60-371.25c-1.875-7.5-7.5-15-16.875-15-7.5 0-16.875 3.75-18.75 11.25l-157.5 384.38-243.75-285h-1.875-1.875c-1.875-1.875-1.875-1.875-3.75-1.875h-1.875-5.625-1.875c-1.875 0-3.75 0-5.625 1.875h-1.875c-1.875 0-3.75 1.875-3.75 3.75l-157.5 170.62c-5.625 3.75-5.625 11.25-1.875 18.75 3.75 5.625 9.375 9.375 16.875 9.375h1.875l146.25-22.5 30 459.38v1.875c0 1.875 0 3.75 1.875 5.625 0 1.875 1.875 3.75 3.75 3.75l1.875 1.875c1.875 1.875 1.875 1.875 3.75 1.875h1.875l521.25 178.12c1.875 0 3.75 1.875 5.625 1.875h5.625 1.875c1.875 0 1.875-1.875 3.75-1.875l446.25-326.25c5.625-5.625 9.375-13.125 7.5-20.625zm-1134.4-328.12 91.875-99.375 5.625 84.375zm1063.1 348.75-7.5 5.625-341.25 249.38 65.625-148.12 54.375-123.75zm-605.62 217.5 146.25-161.25c7.5-7.5 5.625-18.75-1.875-26.25s-18.75-5.625-26.25 1.875l-157.5 174.38-230.62-78.75 796.88-575.62-324.38 735zm75-748.12 52.5 324.38-129.38 93.75-63.75-75zm-106.88 438.75-118.12 86.25-142.5 103.12-33.75-525v-11.25z" style="fill-opacity: 1; fill: rgb(67, 55, 201);"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB