Skip to content

Commit

Permalink
Change list view (manifoldmarkets#1702)
Browse files Browse the repository at this point in the history
* adding table and list and things
  • Loading branch information
ingawei authored Apr 25, 2023
1 parent 3f10660 commit 300aead
Show file tree
Hide file tree
Showing 27 changed files with 816 additions and 403 deletions.
12 changes: 10 additions & 2 deletions web/components/answers/answer-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function AnswerItem(props: {
totalChosenProb?: number
onChoose: (answerId: string, prob: number) => void
onDeselect: (answerId: string) => void
isInModal?: boolean
}) {
const {
answer,
Expand All @@ -29,6 +30,7 @@ export function AnswerItem(props: {
totalChosenProb,
onChoose,
onDeselect,
isInModal,
} = props
const { resolution, resolutions } = contract
const { username, avatarUrl, name, number, text } = answer
Expand All @@ -43,7 +45,8 @@ export function AnswerItem(props: {
return (
<div
className={clsx(
'flex flex-col gap-4 rounded p-4 sm:flex-row',
'flex flex-col gap-4 rounded p-4',
isInModal ? '' : 'sm:flex-row',
wasResolvedTo
? resolution === 'MKT'
? 'mb-2 bg-blue-500/20'
Expand Down Expand Up @@ -72,7 +75,12 @@ export function AnswerItem(props: {
</Row>
</Col>

<Row className="items-center justify-end gap-4 self-end sm:self-start">
<Row
className={clsx(
'items-center justify-end gap-4 self-end',
isInModal ? '' : 'sm:self-start'
)}
>
{!wasResolvedTo &&
(showChoice === 'checkbox' ? (
<Input
Expand Down
127 changes: 96 additions & 31 deletions web/components/answers/answer-resolve-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,47 @@ import { removeUndefinedProps } from 'common/util/object'
import { BETTORS } from 'common/user'
import { Button } from '../buttons/button'

function getAnswerResolveButtonColor(
resolveOption: string | undefined,
answers: string[],
chosenAnswers: { [answerId: string]: number }
) {
return resolveOption === 'CANCEL'
? 'yellow'
: resolveOption === 'CHOOSE' && answers.length
? 'green'
: resolveOption === 'CHOOSE_MULTIPLE' &&
answers.length > 1 &&
answers.every((answer) => chosenAnswers[answer] > 0)
? 'blue'
: 'indigo'
}

function getAnswerResolveButtonDisabled(
resolveOption: string | undefined,
answers: string[],
chosenAnswers: { [answerId: string]: number }
) {
return (
(resolveOption === 'CHOOSE' && !answers.length) ||
(resolveOption === 'CHOOSE_MULTIPLE' &&
(!(answers.length > 1) ||
!answers.every((answer) => chosenAnswers[answer] > 0)))
)
}

function getAnswerResolveButtonLabel(
resolveOption: string | undefined,
chosenText: string,
answers: string[]
) {
return resolveOption === 'CANCEL'
? 'N/A'
: resolveOption === 'CHOOSE'
? chosenText
: `${answers.length} answers`
}

export function AnswerResolvePanel(props: {
isAdmin: boolean
isCreator: boolean
Expand All @@ -20,6 +61,7 @@ export function AnswerResolvePanel(props: {
option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined
) => void
chosenAnswers: { [answerId: string]: number }
isInModal?: boolean
}) {
const {
contract,
Expand All @@ -28,6 +70,7 @@ export function AnswerResolvePanel(props: {
chosenAnswers,
isAdmin,
isCreator,
isInModal,
} = props
const answers = Object.keys(chosenAnswers)

Expand Down Expand Up @@ -90,7 +133,8 @@ export function AnswerResolvePanel(props: {
return (
<Col className="gap-4 rounded">
<Row className="justify-between">
<div>Resolve your market</div>
{!isInModal && <div>Resolve your market</div>}
{isInModal && <div>Resolve "{contract.question}"</div>}
{isAdmin && !isCreator && (
<span className="bg-scarlet-500/20 text-scarlet-500 rounded p-1 text-xs">
ADMIN
Expand All @@ -117,36 +161,57 @@ export function AnswerResolvePanel(props: {
</Button>
)}

<ResolveConfirmationButton
color={
resolveOption === 'CANCEL'
? 'yellow'
: resolveOption === 'CHOOSE' && answers.length
? 'green'
: resolveOption === 'CHOOSE_MULTIPLE' &&
answers.length > 1 &&
answers.every((answer) => chosenAnswers[answer] > 0)
? 'blue'
: 'indigo'
}
label={
resolveOption === 'CANCEL'
? 'N/A'
: resolveOption === 'CHOOSE'
? chosenText
: `${answers.length} answers`
}
marketTitle={contract.question}
disabled={
!resolveOption ||
(resolveOption === 'CHOOSE' && !answers.length) ||
(resolveOption === 'CHOOSE_MULTIPLE' &&
(!(answers.length > 1) ||
!answers.every((answer) => chosenAnswers[answer] > 0)))
}
onResolve={onResolve}
isSubmitting={isSubmitting}
/>
{!isInModal && (
<ResolveConfirmationButton
color={getAnswerResolveButtonColor(
resolveOption,
answers,
chosenAnswers
)}
label={getAnswerResolveButtonLabel(
resolveOption,
chosenText,
answers
)}
marketTitle={contract.question}
disabled={getAnswerResolveButtonDisabled(
resolveOption,
answers,
chosenAnswers
)}
onResolve={onResolve}
isSubmitting={isSubmitting}
/>
)}
{isInModal && (
<Button
color={getAnswerResolveButtonColor(
resolveOption,
answers,
chosenAnswers
)}
disabled={
isSubmitting ||
getAnswerResolveButtonDisabled(
resolveOption,
answers,
chosenAnswers
)
}
onClick={onResolve}
>
<>
Resolve{' '}
<>
{getAnswerResolveButtonLabel(
resolveOption,
chosenText,
answers
)}
</>
</>
</Button>
)}
</Row>
</div>

Expand Down
128 changes: 75 additions & 53 deletions web/components/answers/answers-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ export function AnswersPanel(props: {
contract: FreeResponseContract | MultipleChoiceContract
onAnswerCommentClick: (answer: Answer) => void
showResolver?: boolean
isInModal?: boolean
}) {
const isAdmin = useAdmin()
const { contract, onAnswerCommentClick, showResolver } = props
const { contract, onAnswerCommentClick, showResolver, isInModal } = props
const { creatorId, resolution, resolutions, outcomeType } = contract
const [showAllAnswers, setShowAllAnswers] = useState(false)

Expand Down Expand Up @@ -135,66 +136,87 @@ export function AnswersPanel(props: {
totalChosenProb={chosenTotal}
onChoose={onChoose}
onDeselect={onDeselect}
isInModal={isInModal}
/>
))

return (
<Col className="gap-3">
{showResolver && (
<GradientContainer className="mb-4">
<AnswerResolvePanel
isAdmin={isAdmin}
isCreator={user?.id === creatorId}
contract={contract}
resolveOption={resolveOption}
setResolveOption={setResolveOption}
chosenAnswers={chosenAnswers}
/>

{!!resolveOption && (
<Col className="mt-4 gap-3">{answerItemComponents}</Col>
)}
</GradientContainer>
)}

{resolution && answerItemComponents}

{!resolveOption && (
<Col className="gap-3">
{answerItems.map((item) => (
<OpenAnswer
key={item.id}
answer={item}
// if this is in a modal
if (isInModal) {
return (
<Col className="w-full">
<AnswerResolvePanel
isAdmin={isAdmin}
isCreator={user?.id === creatorId}
contract={contract}
resolveOption={resolveOption}
setResolveOption={setResolveOption}
chosenAnswers={chosenAnswers}
isInModal={isInModal}
/>
{!!resolveOption && (
<Col className="mt-4 w-full gap-3">{answerItemComponents}</Col>
)}
</Col>
)
} else {
return (
<Col className="gap-3">
{showResolver && (
<GradientContainer className="mb-4">
<AnswerResolvePanel
isAdmin={isAdmin}
isCreator={user?.id === creatorId}
contract={contract}
onAnswerCommentClick={onAnswerCommentClick}
color={getAnswerColor(item, answersArray)}
resolveOption={resolveOption}
setResolveOption={setResolveOption}
chosenAnswers={chosenAnswers}
/>
))}
{answersToHide.length > 0 && !showAllAnswers && (
<Button
className="self-end"
color="gray-white"
onClick={() => setShowAllAnswers(true)}
size="md"
>
Show More
</Button>
)}
</Col>
)}

{answers.length === 0 && (
<div className="text-ink-500 pb-4">No answers yet...</div>
)}
{!!resolveOption && (
<Col className="mt-4 gap-3">{answerItemComponents}</Col>
)}
</GradientContainer>
)}

{resolution && answerItemComponents}

{outcomeType === 'FREE_RESPONSE' &&
tradingAllowed(contract) &&
!resolveOption &&
!privateUser?.blockedByUserIds.includes(contract.creatorId) && (
<CreateAnswerPanel contract={contract} />
{!resolveOption && (
<Col className="gap-3">
{answerItems.map((item) => (
<OpenAnswer
key={item.id}
answer={item}
contract={contract}
onAnswerCommentClick={onAnswerCommentClick}
color={getAnswerColor(item, answersArray)}
/>
))}
{answersToHide.length > 0 && !showAllAnswers && (
<Button
className="self-end"
color="gray-white"
onClick={() => setShowAllAnswers(true)}
size="md"
>
Show More
</Button>
)}
</Col>
)}
</Col>
)

{answers.length === 0 && (
<div className="text-ink-500 pb-4">No answers yet...</div>
)}

{outcomeType === 'FREE_RESPONSE' &&
tradingAllowed(contract) &&
!resolveOption &&
!privateUser?.blockedByUserIds.includes(contract.creatorId) && (
<CreateAnswerPanel contract={contract} />
)}
</Col>
)
}
}

function OpenAnswer(props: {
Expand Down
1 change: 0 additions & 1 deletion web/components/bet/quick-bet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,6 @@ export function getTextColor(contract: Contract) {
if (resolution) {
return OUTCOME_TO_COLOR_TEXT[resolution as resolution] ?? 'text-primary-200'
}

if ((contract.closeTime ?? Infinity) < Date.now()) {
return 'text-ink-600'
}
Expand Down
2 changes: 1 addition & 1 deletion web/components/bet/yes-no-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export function ChooseCancelSelector(props: {
onClick={() => onSelect('CHOOSE')}
className={btnClassName}
>
Choose an answer
Choose answer
</Button>

<Button
Expand Down
2 changes: 1 addition & 1 deletion web/components/cards/MarketCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { buildArray } from 'common/util/array'
import { Dictionary, sortBy, uniqBy } from 'lodash'
import Image from 'next/image'
import { useEffect } from 'react'
import { ContractStatusLabel } from 'web/components/contract/contracts-list-entry'
import { ContractStatusLabel } from 'web/components/contract/contracts-table'
import {
usePersistentState,
inMemoryStore,
Expand Down
4 changes: 2 additions & 2 deletions web/components/contract/contract-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { Avatar } from '../widgets/avatar'
import { UserLink } from '../widgets/user-link'
import { getLinkTarget } from 'web/components/widgets/site-link'
import { richTextToString } from 'common/util/parse'
import { ContractStatusLabel } from './contracts-list-entry'
import { ContractStatusLabel } from './contracts-table'
import { LikeButton } from './like-button'
import { CommentsButton } from '../swipe/swipe-comments'
import { BetRow } from '../bet/bet-row'
Expand Down Expand Up @@ -561,7 +561,7 @@ function ReasonChosen(props: { contract: Contract }) {
className={'z-10'}
>
<Row className={'shrink-0 items-center gap-1'}>
<UserIcon className="h-4 w-4" />
<UserIcon className={'h-4 w-4'} />
<div>{uniqueBettorCount ?? 0}</div>
</Row>
</Tooltip>
Expand Down
Loading

0 comments on commit 300aead

Please sign in to comment.