Revert "Turn on no unused variables linting, kill dead code (#484)"
This reverts commit 515928a69a
.
This commit is contained in:
parent
4ad04869a1
commit
5beda1ded7
|
@ -8,15 +8,8 @@ module.exports = {
|
|||
],
|
||||
rules: {
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_',
|
||||
caughtErrorsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
'@next/next/no-img-element': 'off',
|
||||
'@next/next/no-typos': 'off',
|
||||
'lodash/import-scope': [2, 'member'],
|
||||
|
|
|
@ -116,7 +116,7 @@ export function AnswersPanel(props: { contract: FreeResponseContract }) {
|
|||
{!resolveOption && (
|
||||
<div className={clsx('flow-root pr-2 md:pr-0')}>
|
||||
<div className={clsx(tradingAllowed(contract) ? '' : '-mb-6')}>
|
||||
{answerItems.map((item) => (
|
||||
{answerItems.map((item, activityItemIdx) => (
|
||||
<div key={item.id} className={'relative pb-2'}>
|
||||
<div className="relative flex items-start space-x-3">
|
||||
<OpenAnswer {...item} />
|
||||
|
|
|
@ -138,8 +138,9 @@ export function BetsList(props: { user: User; hideBetsBefore?: number }) {
|
|||
return !hasSoldAll
|
||||
})
|
||||
|
||||
const unsettled = contracts.filter(
|
||||
(c) => !c.isResolved && contractsMetrics[c.id].invested !== 0
|
||||
const [settled, unsettled] = partition(
|
||||
contracts,
|
||||
(c) => c.isResolved || contractsMetrics[c.id].invested === 0
|
||||
)
|
||||
|
||||
const currentInvested = sumBy(
|
||||
|
@ -260,7 +261,7 @@ function ContractBets(props: {
|
|||
|
||||
const isBinary = outcomeType === 'BINARY'
|
||||
|
||||
const { payout, profit, profitPercent } = getContractBetMetrics(
|
||||
const { payout, profit, profitPercent, invested } = getContractBetMetrics(
|
||||
contract,
|
||||
bets
|
||||
)
|
||||
|
@ -656,6 +657,7 @@ function SellButton(props: { contract: Contract; bet: Bet }) {
|
|||
|
||||
return (
|
||||
<ConfirmationButton
|
||||
id={`sell-${bet.id}`}
|
||||
openModalBtn={{
|
||||
className: clsx('btn-sm', isSubmitting && 'btn-disabled loading'),
|
||||
label: 'Sell',
|
||||
|
|
|
@ -8,7 +8,7 @@ import { manaToUSD } from '../../../common/util/format'
|
|||
import { Row } from '../layout/row'
|
||||
|
||||
export function CharityCard(props: { charity: Charity }) {
|
||||
const { slug, photo, preview, id, tags } = props.charity
|
||||
const { name, slug, photo, preview, id, tags } = props.charity
|
||||
|
||||
const txns = useCharityTxns(id)
|
||||
const raised = sumBy(txns, (txn) => txn.amount)
|
||||
|
|
|
@ -24,12 +24,13 @@ export function ChoicesToggleGroup(props: {
|
|||
<RadioGroup
|
||||
className={clsx(className, 'flex flex-row flex-wrap items-center gap-3')}
|
||||
value={currentChoice.toString()}
|
||||
onChange={setChoice}
|
||||
onChange={(str) => null}
|
||||
>
|
||||
{Object.keys(choicesMap).map((choiceKey) => (
|
||||
<RadioGroup.Option
|
||||
key={choiceKey}
|
||||
value={choicesMap[choiceKey]}
|
||||
onClick={() => setChoice(choicesMap[choiceKey])}
|
||||
className={({ active }) =>
|
||||
clsx(
|
||||
active ? 'ring-2 ring-indigo-500 ring-offset-2' : '',
|
||||
|
|
|
@ -5,6 +5,7 @@ import { Modal } from './layout/modal'
|
|||
import { Row } from './layout/row'
|
||||
|
||||
export function ConfirmationButton(props: {
|
||||
id: string
|
||||
openModalBtn: {
|
||||
label: string
|
||||
icon?: JSX.Element
|
||||
|
@ -21,7 +22,7 @@ export function ConfirmationButton(props: {
|
|||
onSubmit: () => void
|
||||
children: ReactNode
|
||||
}) {
|
||||
const { openModalBtn, cancelBtn, submitBtn, onSubmit, children } = props
|
||||
const { id, openModalBtn, cancelBtn, submitBtn, onSubmit, children } = props
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
|
@ -66,6 +67,7 @@ export function ResolveConfirmationButton(props: {
|
|||
props
|
||||
return (
|
||||
<ConfirmationButton
|
||||
id="resolution-modal"
|
||||
openModalBtn={{
|
||||
className: clsx(
|
||||
'border-none self-start',
|
||||
|
|
|
@ -140,7 +140,7 @@ export function QuickBet(props: { contract: Contract; user: User }) {
|
|||
}
|
||||
}
|
||||
|
||||
const textColor = `text-${getColor(contract)}`
|
||||
const textColor = `text-${getColor(contract, previewProb)}`
|
||||
|
||||
return (
|
||||
<Col
|
||||
|
@ -223,7 +223,7 @@ export function QuickBet(props: { contract: Contract; user: User }) {
|
|||
|
||||
export function ProbBar(props: { contract: Contract; previewProb?: number }) {
|
||||
const { contract, previewProb } = props
|
||||
const color = getColor(contract)
|
||||
const color = getColor(contract, previewProb)
|
||||
const prob = previewProb ?? getProb(contract)
|
||||
return (
|
||||
<>
|
||||
|
@ -257,7 +257,7 @@ function QuickOutcomeView(props: {
|
|||
// If there's a preview prob, display that instead of the current prob
|
||||
const override =
|
||||
previewProb === undefined ? undefined : formatPercent(previewProb)
|
||||
const textColor = `text-${getColor(contract)}`
|
||||
const textColor = `text-${getColor(contract, previewProb)}`
|
||||
|
||||
let display: string | undefined
|
||||
switch (outcomeType) {
|
||||
|
@ -306,7 +306,7 @@ function getNumericScale(contract: NumericContract) {
|
|||
return (ev - min) / (max - min)
|
||||
}
|
||||
|
||||
export function getColor(contract: Contract) {
|
||||
export function getColor(contract: Contract, previewProb?: number) {
|
||||
// TODO: Try injecting a gradient here
|
||||
// return 'primary'
|
||||
const { resolution } = contract
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
import { SparklesIcon } from '@heroicons/react/solid'
|
||||
import { sample } from 'lodash'
|
||||
import { SparklesIcon, XIcon } from '@heroicons/react/solid'
|
||||
import { Avatar } from './avatar'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Spacer } from './layout/spacer'
|
||||
import { firebaseLogin } from 'web/lib/firebase/users'
|
||||
import { NewContract } from '../pages/create'
|
||||
import { firebaseLogin, User } from 'web/lib/firebase/users'
|
||||
import { ContractsGrid } from './contract/contracts-list'
|
||||
import { Contract } from 'common/contract'
|
||||
import { Contract, MAX_QUESTION_LENGTH } from 'common/contract'
|
||||
import { Col } from './layout/col'
|
||||
import clsx from 'clsx'
|
||||
import { Row } from './layout/row'
|
||||
import { ENV_CONFIG } from '../../common/envs/constants'
|
||||
import { SiteLink } from './site-link'
|
||||
import { formatMoney } from 'common/util/format'
|
||||
|
||||
|
@ -61,3 +67,90 @@ export function FeedPromo(props: { hotContracts: Contract[] }) {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function FeedCreate(props: {
|
||||
user?: User
|
||||
tag?: string
|
||||
placeholder?: string
|
||||
className?: string
|
||||
}) {
|
||||
const { user, tag, className } = props
|
||||
const [question, setQuestion] = useState('')
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
const inputRef = useRef<HTMLTextAreaElement | null>()
|
||||
|
||||
// Rotate through a new placeholder each day
|
||||
// Easter egg idea: click your own name to shuffle the placeholder
|
||||
// const daysSinceEpoch = Math.floor(Date.now() / 1000 / 60 / 60 / 24)
|
||||
|
||||
// Take care not to produce a different placeholder on the server and client
|
||||
const [defaultPlaceholder, setDefaultPlaceholder] = useState('')
|
||||
useEffect(() => {
|
||||
setDefaultPlaceholder(`e.g. ${sample(ENV_CONFIG.newQuestionPlaceholders)}`)
|
||||
}, [])
|
||||
|
||||
const placeholder = props.placeholder ?? defaultPlaceholder
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'w-full cursor-text rounded bg-white p-4 shadow-md',
|
||||
isExpanded ? 'ring-2 ring-indigo-300' : '',
|
||||
className
|
||||
)}
|
||||
onClick={() => {
|
||||
!isExpanded && inputRef.current?.focus()
|
||||
}}
|
||||
>
|
||||
<div className="relative flex items-start space-x-3">
|
||||
<Avatar username={user?.username} avatarUrl={user?.avatarUrl} noLink />
|
||||
|
||||
<div className="min-w-0 flex-1">
|
||||
<Row className="justify-between">
|
||||
<p className="my-0.5 text-sm">Ask a question... </p>
|
||||
{isExpanded && (
|
||||
<button
|
||||
className="btn btn-xs btn-circle btn-ghost rounded"
|
||||
onClick={() => setIsExpanded(false)}
|
||||
>
|
||||
<XIcon
|
||||
className="mx-auto h-6 w-6 text-gray-500"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
</Row>
|
||||
<textarea
|
||||
ref={inputRef as any}
|
||||
className={clsx(
|
||||
'w-full resize-none appearance-none border-transparent bg-transparent p-0 text-indigo-700 placeholder:text-gray-400 focus:border-transparent focus:ring-transparent',
|
||||
question && 'text-lg sm:text-xl',
|
||||
!question && 'text-base sm:text-lg'
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
value={question}
|
||||
rows={question.length > 68 ? 4 : 2}
|
||||
maxLength={MAX_QUESTION_LENGTH}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onChange={(e) => setQuestion(e.target.value.replace('\n', ''))}
|
||||
onFocus={() => setIsExpanded(true)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Hide component instead of deleting, so edits to NewContract don't get lost */}
|
||||
<div className={isExpanded ? '' : 'hidden'}>
|
||||
<NewContract question={question} tag={tag} />
|
||||
</div>
|
||||
|
||||
{/* Show a fake "Create Market" button, which gets replaced with the NewContract one*/}
|
||||
{!isExpanded && (
|
||||
<div className="flex justify-end sm:-mt-4">
|
||||
<button className="btn btn-sm capitalize" disabled>
|
||||
Create Market
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Answer } from 'common/answer'
|
|||
import { Bet } from 'common/bet'
|
||||
import { Comment } from 'common/comment'
|
||||
import { formatPercent } from 'common/util/format'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import { Col } from 'web/components/layout/col'
|
||||
import { Modal } from 'web/components/layout/modal'
|
||||
import { AnswerBetPanel } from 'web/components/answers/answer-bet-panel'
|
||||
|
|
|
@ -3,6 +3,7 @@ import React, { useState } from 'react'
|
|||
import {
|
||||
BanIcon,
|
||||
CheckIcon,
|
||||
DotsVerticalIcon,
|
||||
LockClosedIcon,
|
||||
XIcon,
|
||||
} from '@heroicons/react/solid'
|
||||
|
@ -273,3 +274,30 @@ function FeedClose(props: { contract: Contract }) {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Should highlight the entire Feed segment
|
||||
function FeedExpand(props: { setExpanded: (expanded: boolean) => void }) {
|
||||
const { setExpanded } = props
|
||||
return (
|
||||
<>
|
||||
<button onClick={() => setExpanded(true)}>
|
||||
<div className="relative px-1">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-gray-200 hover:bg-gray-300">
|
||||
<DotsVerticalIcon
|
||||
className="h-5 w-5 text-gray-500"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button onClick={() => setExpanded(true)}>
|
||||
<div className="min-w-0 flex-1 py-1.5">
|
||||
<div className="text-sm text-gray-500 hover:text-gray-700">
|
||||
<span>Show all activity</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ export function CreateFoldButton() {
|
|||
|
||||
return (
|
||||
<ConfirmationButton
|
||||
id="create-fold"
|
||||
openModalBtn={{
|
||||
label: 'New',
|
||||
icon: <PlusCircleIcon className="mr-2 h-5 w-5" />,
|
||||
|
|
|
@ -98,7 +98,7 @@ function AddLiquidityPanel(props: { contract: CPMMContract }) {
|
|||
setError('Server error')
|
||||
}
|
||||
})
|
||||
.catch((_) => setError('Server error'))
|
||||
.catch((e) => setError('Server error'))
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -162,7 +162,7 @@ function WithdrawLiquidityPanel(props: {
|
|||
const { contract, lpShares } = props
|
||||
const { YES: yesShares, NO: noShares } = lpShares
|
||||
|
||||
const [_error, setError] = useState<string | undefined>(undefined)
|
||||
const [error, setError] = useState<string | undefined>(undefined)
|
||||
const [isSuccess, setIsSuccess] = useState(false)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
|
@ -171,12 +171,12 @@ function WithdrawLiquidityPanel(props: {
|
|||
setIsSuccess(false)
|
||||
|
||||
withdrawLiquidity({ contractId: contract.id })
|
||||
.then((_) => {
|
||||
.then((r) => {
|
||||
setIsSuccess(true)
|
||||
setError(undefined)
|
||||
setIsLoading(false)
|
||||
})
|
||||
.catch((_) => setError('Server error'))
|
||||
.catch((e) => setError('Server error'))
|
||||
}
|
||||
|
||||
if (isSuccess)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import Link from 'next/link'
|
||||
import { User } from 'web/lib/firebase/users'
|
||||
import { firebaseLogout, User } from 'web/lib/firebase/users'
|
||||
import { formatMoney } from 'common/util/format'
|
||||
import { Avatar } from '../avatar'
|
||||
import { IS_PRIVATE_MANIFOLD } from 'common/envs/constants'
|
||||
|
||||
export function ProfileSummary(props: { user: User }) {
|
||||
const { user } = props
|
||||
|
|
|
@ -7,12 +7,15 @@ import {
|
|||
CashIcon,
|
||||
HeartIcon,
|
||||
PresentationChartLineIcon,
|
||||
ChatAltIcon,
|
||||
SparklesIcon,
|
||||
NewspaperIcon,
|
||||
} from '@heroicons/react/outline'
|
||||
import clsx from 'clsx'
|
||||
import { sortBy } from 'lodash'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useFollowedFolds } from 'web/hooks/use-fold'
|
||||
import { useUser } from 'web/hooks/use-user'
|
||||
import { firebaseLogin, firebaseLogout, User } from 'web/lib/firebase/users'
|
||||
import { ManifoldLogo } from './manifold-logo'
|
||||
|
@ -176,6 +179,8 @@ export default function Sidebar(props: { className?: string }) {
|
|||
}, [])
|
||||
|
||||
const user = useUser()
|
||||
let folds = useFollowedFolds(user) || []
|
||||
folds = sortBy(folds, 'followCount').reverse()
|
||||
const mustWaitForFreeMarketStatus = useHasCreatedContractToday(user)
|
||||
const navigationOptions =
|
||||
user === null
|
||||
|
|
|
@ -53,6 +53,7 @@ function NumericBuyPanel(props: {
|
|||
|
||||
const [betAmount, setBetAmount] = useState<number | undefined>(undefined)
|
||||
|
||||
const [valueError, setValueError] = useState<string | undefined>()
|
||||
const [error, setError] = useState<string | undefined>()
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
const [wasSubmitted, setWasSubmitted] = useState(false)
|
||||
|
|
|
@ -6,11 +6,12 @@ import { Toaster } from 'react-hot-toast'
|
|||
|
||||
export function Page(props: {
|
||||
margin?: boolean
|
||||
assertUser?: 'signed-in' | 'signed-out'
|
||||
rightSidebar?: ReactNode
|
||||
suspend?: boolean
|
||||
children?: ReactNode
|
||||
}) {
|
||||
const { margin, children, rightSidebar, suspend } = props
|
||||
const { margin, assertUser, children, rightSidebar, suspend } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { isEqual, sortBy } from 'lodash'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Fold } from 'common/fold'
|
||||
import { User } from 'common/user'
|
||||
import {
|
||||
listAllFolds,
|
||||
listenForFold,
|
||||
listenForFolds,
|
||||
listenForFoldsWithTags,
|
||||
|
@ -78,3 +80,38 @@ export const useFollowedFoldIds = (user: User | null | undefined) => {
|
|||
|
||||
return followedFoldIds
|
||||
}
|
||||
|
||||
// We also cache followedFolds directly in JSON.
|
||||
// TODO: Extract out localStorage caches to a utility
|
||||
export const useFollowedFolds = (user: User | null | undefined) => {
|
||||
const [followedFolds, setFollowedFolds] = useState<Fold[] | undefined>()
|
||||
const ids = useFollowedFoldIds(user)
|
||||
|
||||
useEffect(() => {
|
||||
if (user && ids) {
|
||||
const key = `followed-full-folds-${user.id}`
|
||||
const followedFoldJson = localStorage.getItem(key)
|
||||
if (followedFoldJson) {
|
||||
setFollowedFolds(JSON.parse(followedFoldJson))
|
||||
// Exit early if ids and followedFoldIds have all the same elements.
|
||||
if (
|
||||
isEqual(
|
||||
sortBy(ids),
|
||||
sortBy(JSON.parse(followedFoldJson).map((f: Fold) => f.id))
|
||||
)
|
||||
) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, fetch the full contents of all folds
|
||||
listAllFolds().then((folds) => {
|
||||
const followedFolds = folds.filter((fold) => ids.includes(fold.id))
|
||||
setFollowedFolds(followedFolds)
|
||||
localStorage.setItem(key, JSON.stringify(followedFolds))
|
||||
})
|
||||
}
|
||||
}, [user, ids])
|
||||
|
||||
return followedFolds
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { collection, query, where } from 'firebase/firestore'
|
||||
import { Notification } from 'common/notification'
|
||||
import { db } from 'web/lib/firebase/init'
|
||||
import { listenForValues } from 'web/lib/firebase/utils'
|
||||
import { getValues, listenForValues } from 'web/lib/firebase/utils'
|
||||
|
||||
function getNotificationsQuery(userId: string, unseenOnly?: boolean) {
|
||||
const notifsCollection = collection(db, `/users/${userId}/notifications`)
|
||||
|
|
|
@ -37,7 +37,7 @@ export default function Activity() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Page suspend={!!contract}>
|
||||
<Page assertUser="signed-in" suspend={!!contract}>
|
||||
<Col className="mx-auto w-full max-w-[700px]">
|
||||
<CategorySelector category={category} setCategory={setCategory} />
|
||||
<Spacer h={1} />
|
||||
|
|
|
@ -19,7 +19,6 @@ export default async function handler(
|
|||
listAllComments(contractId),
|
||||
])
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const bets = allBets.map(({ userId, ...bet }) => bet) as Exclude<
|
||||
Bet,
|
||||
'userId'
|
||||
|
|
|
@ -24,7 +24,6 @@ export default async function handler(
|
|||
listAllComments(contract.id),
|
||||
])
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const bets = allBets.map(({ userId, ...bet }) => bet) as Exclude<
|
||||
Bet,
|
||||
'userId'
|
||||
|
|
|
@ -56,8 +56,8 @@ export default function Create() {
|
|||
}
|
||||
|
||||
// Allow user to create a new contract
|
||||
export function NewContract(props: { question: string }) {
|
||||
const { question } = props
|
||||
export function NewContract(props: { question: string; tag?: string }) {
|
||||
const { question, tag } = props
|
||||
const creator = useUser()
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -74,7 +74,7 @@ export function NewContract(props: { question: string }) {
|
|||
// const [tagText, setTagText] = useState<string>(tag ?? '')
|
||||
// const tags = parseWordsAsTags(tagText)
|
||||
|
||||
const [ante, _setAnte] = useState(FIXED_ANTE)
|
||||
const [ante, setAnte] = useState(FIXED_ANTE)
|
||||
|
||||
const mustWaitForDailyFreeMarketStatus = useHasCreatedContractToday(creator)
|
||||
|
||||
|
|
|
@ -27,8 +27,10 @@ import { EditFoldButton } from 'web/components/folds/edit-fold-button'
|
|||
import Custom404 from '../../404'
|
||||
import { FollowFoldButton } from 'web/components/folds/follow-fold-button'
|
||||
import { SEO } from 'web/components/SEO'
|
||||
import { useTaggedContracts } from 'web/hooks/use-contracts'
|
||||
import { Linkify } from 'web/components/linkify'
|
||||
import { fromPropz, usePropz } from 'web/hooks/use-propz'
|
||||
import { filterDefined } from 'common/util/array'
|
||||
import { findActiveContracts } from 'web/components/feed/find-active-contracts'
|
||||
import { Tabs } from 'web/components/layout/tabs'
|
||||
|
||||
|
@ -131,6 +133,15 @@ export default function FoldPage(props: {
|
|||
const user = useUser()
|
||||
const isCurator = user && fold && user.id === fold.curatorId
|
||||
|
||||
const taggedContracts = useTaggedContracts(fold?.tags) ?? props.contracts
|
||||
const contractsMap = Object.fromEntries(
|
||||
taggedContracts.map((contract) => [contract.id, contract])
|
||||
)
|
||||
|
||||
const contracts = filterDefined(
|
||||
props.contracts.map((contract) => contractsMap[contract.id])
|
||||
)
|
||||
|
||||
if (fold === null || !foldSubpages.includes(page) || slugs[2]) {
|
||||
return <Custom404 />
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ const Home = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Page suspend={!!contract}>
|
||||
<Page assertUser="signed-in" suspend={!!contract}>
|
||||
<Col className="mx-auto w-full p-2">
|
||||
<ContractSearch
|
||||
querySortOptions={{
|
||||
|
|
|
@ -40,7 +40,7 @@ const Home = (props: { hotContracts: Contract[] }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<Page assertUser="signed-out">
|
||||
<div className="px-4 pt-2 md:mt-0 lg:hidden">
|
||||
<ManifoldLogo />
|
||||
</div>
|
||||
|
|
|
@ -8,14 +8,19 @@ import {
|
|||
} from '@heroicons/react/outline'
|
||||
|
||||
import { firebaseLogin } from 'web/lib/firebase/users'
|
||||
import { ContractsGrid } from 'web/components/contract/contracts-list'
|
||||
import { Col } from 'web/components/layout/col'
|
||||
import Link from 'next/link'
|
||||
import { Contract } from 'web/lib/firebase/contracts'
|
||||
|
||||
export default function LandingPage(props: { hotContracts: Contract[] }) {
|
||||
const { hotContracts } = props
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<div>
|
||||
<Hero />
|
||||
<FeaturesSection />
|
||||
{/* <ExploreMarketsSection hotContracts={hotContracts} /> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -144,3 +149,20 @@ function FeaturesSection() {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ExploreMarketsSection(props: { hotContracts: Contract[] }) {
|
||||
const { hotContracts } = props
|
||||
return (
|
||||
<div className="mx-auto max-w-4xl px-4 py-8">
|
||||
<p className="my-12 text-3xl font-extrabold leading-8 tracking-tight text-indigo-700 sm:text-4xl">
|
||||
Today's top markets
|
||||
</p>
|
||||
|
||||
<ContractsGrid
|
||||
contracts={hotContracts}
|
||||
loadMore={() => {}}
|
||||
hasMore={false}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import { fromPropz, usePropz } from 'web/hooks/use-propz'
|
|||
export const getStaticProps = fromPropz(getStaticPropz)
|
||||
export async function getStaticPropz() {
|
||||
const [topTraders, topCreators] = await Promise.all([
|
||||
getTopTraders().catch(() => {}),
|
||||
getTopCreators().catch(() => {}),
|
||||
getTopTraders().catch((_) => {}),
|
||||
getTopCreators().catch((_) => {}),
|
||||
])
|
||||
|
||||
return {
|
||||
|
|
|
@ -290,3 +290,13 @@ ${TEST_VALUE}
|
|||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
// Given a date string like '2022-04-02',
|
||||
// return the time just before midnight on that date (in the user's local time), as millis since epoch
|
||||
function dateToMillis(date: string) {
|
||||
return dayjs(date)
|
||||
.set('hour', 23)
|
||||
.set('minute', 59)
|
||||
.set('second', 59)
|
||||
.valueOf()
|
||||
}
|
||||
|
|
|
@ -31,7 +31,9 @@ import { Linkify } from 'web/components/linkify'
|
|||
import {
|
||||
BinaryOutcomeLabel,
|
||||
CancelLabel,
|
||||
FreeResponseOutcomeLabel,
|
||||
MultiLabel,
|
||||
OutcomeLabel,
|
||||
ProbPercentLabel,
|
||||
} from 'web/components/outcome-label'
|
||||
import {
|
||||
|
@ -42,7 +44,7 @@ import {
|
|||
import { getContractFromId } from 'web/lib/firebase/contracts'
|
||||
import { CheckIcon, XIcon } from '@heroicons/react/outline'
|
||||
import toast from 'react-hot-toast'
|
||||
import { formatMoney } from 'common/util/format'
|
||||
import { formatMoney, formatPercent } from 'common/util/format'
|
||||
|
||||
export default function Notifications() {
|
||||
const user = useUser()
|
||||
|
@ -182,7 +184,7 @@ function NotificationGroupItem(props: {
|
|||
className?: string
|
||||
}) {
|
||||
const { notificationGroup, className } = props
|
||||
const { sourceContractId, notifications } = notificationGroup
|
||||
const { sourceContractId, notifications, timePeriod } = notificationGroup
|
||||
const {
|
||||
sourceContractTitle,
|
||||
sourceContractSlug,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import dayjs from 'dayjs'
|
||||
import { zip, uniq, sumBy, concat, countBy, sortBy, sum } from 'lodash'
|
||||
import { IS_PRIVATE_MANIFOLD } from 'common/envs/constants'
|
||||
import {
|
||||
DailyCountChart,
|
||||
DailyPercentChart,
|
||||
|
|
Loading…
Reference in New Issue
Block a user