Create common card component (#1012)

* Create common card component

* lint
This commit is contained in:
Sinclair Chen 2022-10-05 18:02:24 -07:00 committed by GitHub
parent 7ce09ae39d
commit 94624c5387
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 86 deletions

16
web/components/card.tsx Normal file
View File

@ -0,0 +1,16 @@
import clsx from 'clsx'
export function Card(props: JSX.IntrinsicElements['div']) {
const { children, className, ...rest } = props
return (
<div
className={clsx(
'cursor-pointer rounded-lg border-2 bg-white transition-shadow hover:shadow-md focus:shadow-md',
className
)}
{...rest}
>
{children}
</div>
)
}

View File

@ -6,6 +6,8 @@ import { Charity } from 'common/charity'
import { useCharityTxns } from 'web/hooks/use-charity-txns' import { useCharityTxns } from 'web/hooks/use-charity-txns'
import { manaToUSD } from '../../../common/util/format' import { manaToUSD } from '../../../common/util/format'
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { Col } from '../layout/col'
import { Card } from '../card'
export function CharityCard(props: { charity: Charity; match?: number }) { export function CharityCard(props: { charity: Charity; match?: number }) {
const { charity } = props const { charity } = props
@ -15,8 +17,9 @@ export function CharityCard(props: { charity: Charity; match?: number }) {
const raised = sumBy(txns, (txn) => txn.amount) const raised = sumBy(txns, (txn) => txn.amount)
return ( return (
<Link href={`/charity/${slug}`} passHref> <Link href={`/charity/${slug}`}>
<div className="card card-compact transition:shadow flex-1 cursor-pointer border-2 bg-white hover:shadow-md"> <a className="flex-1">
<Card className="!rounded-2xl">
<Row className="mt-6 mb-2"> <Row className="mt-6 mb-2">
{tags?.includes('Featured') && <FeaturedBadge />} {tags?.includes('Featured') && <FeaturedBadge />}
</Row> </Row>
@ -29,8 +32,7 @@ export function CharityCard(props: { charity: Charity; match?: number }) {
)} )}
</figure> </figure>
</div> </div>
<div className="card-body"> <Col className="p-8">
{/* <h3 className="card-title line-clamp-3">{name}</h3> */}
<div className="line-clamp-4 text-sm">{preview}</div> <div className="line-clamp-4 text-sm">{preview}</div>
{raised > 0 && ( {raised > 0 && (
<> <>
@ -50,8 +52,9 @@ export function CharityCard(props: { charity: Charity; match?: number }) {
</Row> </Row>
</> </>
)} )}
</div> </Col>
</div> </Card>
</a>
</Link> </Link>
) )
} }

View File

@ -8,6 +8,7 @@ import {
BinaryContract, BinaryContract,
Contract, Contract,
CPMMBinaryContract, CPMMBinaryContract,
CPMMContract,
FreeResponseContract, FreeResponseContract,
MultipleChoiceContract, MultipleChoiceContract,
NumericContract, NumericContract,
@ -35,6 +36,7 @@ import { getMappedValue } from 'common/pseudo-numeric'
import { Tooltip } from '../tooltip' import { Tooltip } from '../tooltip'
import { SiteLink } from '../site-link' import { SiteLink } from '../site-link'
import { ProbChange } from './prob-change-table' import { ProbChange } from './prob-change-table'
import { Card } from '../card'
export function ContractCard(props: { export function ContractCard(props: {
contract: Contract contract: Contract
@ -75,12 +77,7 @@ export function ContractCard(props: {
!hideQuickBet !hideQuickBet
return ( return (
<Row <Card className={clsx('group relative flex gap-3', className)}>
className={clsx(
'group relative gap-3 rounded-lg bg-white shadow-md hover:cursor-pointer hover:bg-gray-100',
className
)}
>
<Col className="relative flex-1 gap-3 py-4 pb-12 pl-6"> <Col className="relative flex-1 gap-3 py-4 pb-12 pl-6">
<AvatarDetails <AvatarDetails
contract={contract} contract={contract}
@ -195,7 +192,7 @@ export function ContractCard(props: {
/> />
</Link> </Link>
)} )}
</Row> </Card>
) )
} }
@ -391,7 +388,7 @@ export function PseudoNumericResolutionOrExpectation(props: {
} }
export function ContractCardProbChange(props: { export function ContractCardProbChange(props: {
contract: CPMMBinaryContract contract: CPMMContract
noLinkAvatar?: boolean noLinkAvatar?: boolean
className?: string className?: string
}) { }) {
@ -399,12 +396,7 @@ export function ContractCardProbChange(props: {
const contract = useContractWithPreload(props.contract) as CPMMBinaryContract const contract = useContractWithPreload(props.contract) as CPMMBinaryContract
return ( return (
<Col <Card className={clsx(className, 'mb-4')}>
className={clsx(
className,
'mb-4 rounded-lg bg-white shadow hover:bg-gray-100 hover:shadow-lg'
)}
>
<AvatarDetails <AvatarDetails
contract={contract} contract={contract}
className={'px-6 pt-4'} className={'px-6 pt-4'}
@ -419,6 +411,6 @@ export function ContractCardProbChange(props: {
</SiteLink> </SiteLink>
<ProbChange className="py-2 pr-4" contract={contract} /> <ProbChange className="py-2 pr-4" contract={contract} />
</Row> </Row>
</Col> </Card>
) )
} }

View File

@ -1,13 +1,10 @@
import { sortBy } from 'lodash'
import clsx from 'clsx' import clsx from 'clsx'
import { contractPath } from 'web/lib/firebase/contracts'
import { CPMMContract } from 'common/contract' import { CPMMContract } from 'common/contract'
import { formatPercent } from 'common/util/format' import { formatPercent } from 'common/util/format'
import { SiteLink } from '../site-link' import { sortBy } from 'lodash'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { Row } from '../layout/row'
import { LoadingIndicator } from '../loading-indicator' import { LoadingIndicator } from '../loading-indicator'
import { useContractWithPreload } from 'web/hooks/use-contract' import { ContractCardProbChange } from './contract-card'
export function ProbChangeTable(props: { export function ProbChangeTable(props: {
changes: CPMMContract[] | undefined changes: CPMMContract[] | undefined
@ -39,46 +36,21 @@ export function ProbChangeTable(props: {
if (rows === 0) return <div className="px-4 text-gray-500">None</div> if (rows === 0) return <div className="px-4 text-gray-500">None</div>
return ( return (
<Col className="mb-4 w-full divide-x-2 divide-y rounded-lg bg-white shadow-md md:flex-row md:divide-y-0"> <Col className="mb-4 w-full gap-4 rounded-lg md:flex-row">
<Col className="flex-1 divide-y"> <Col className="flex-1 gap-4">
{filteredPositiveChanges.map((contract) => ( {filteredPositiveChanges.map((contract) => (
<ProbChangeRow key={contract.id} contract={contract} /> <ContractCardProbChange key={contract.id} contract={contract} />
))} ))}
</Col> </Col>
<Col className="flex-1 divide-y"> <Col className="flex-1 gap-4">
{filteredNegativeChanges.map((contract) => ( {filteredNegativeChanges.map((contract) => (
<ProbChangeRow key={contract.id} contract={contract} /> <ContractCardProbChange key={contract.id} contract={contract} />
))} ))}
</Col> </Col>
</Col> </Col>
) )
} }
export function ProbChangeRow(props: {
contract: CPMMContract
className?: string
}) {
const { className } = props
const contract =
(useContractWithPreload(props.contract) as CPMMContract) ?? props.contract
return (
<Row
className={clsx(
'items-center justify-between gap-4 hover:bg-gray-100',
className
)}
>
<SiteLink
className="p-4 pr-0 font-semibold text-indigo-700"
href={contractPath(contract)}
>
<span className="line-clamp-2">{contract.question}</span>
</SiteLink>
<ProbChange className="py-2 pr-4 text-xl" contract={contract} />
</Row>
)
}
export function ProbChange(props: { export function ProbChange(props: {
contract: CPMMContract contract: CPMMContract
className?: string className?: string

View File

@ -7,8 +7,8 @@ import { useUserById } from 'web/hooks/use-user'
import { postPath } from 'web/lib/firebase/posts' import { postPath } from 'web/lib/firebase/posts'
import { fromNow } from 'web/lib/util/time' import { fromNow } from 'web/lib/util/time'
import { Avatar } from './avatar' import { Avatar } from './avatar'
import { Card } from './card'
import { CardHighlightOptions } from './contract/contracts-grid' import { CardHighlightOptions } from './contract/contracts-grid'
import { Row } from './layout/row'
import { UserLink } from './user-link' import { UserLink } from './user-link'
export function PostCard(props: { export function PostCard(props: {
@ -26,9 +26,9 @@ export function PostCard(props: {
return ( return (
<div className="relative py-1"> <div className="relative py-1">
<Row <Card
className={clsx( className={clsx(
'relative gap-3 rounded-lg bg-white py-2 px-3 shadow-md hover:cursor-pointer hover:bg-gray-100', 'relative flex gap-3 py-2 px-3',
itemIds?.includes(post.id) && highlightClassName itemIds?.includes(post.id) && highlightClassName
)} )}
> >
@ -58,7 +58,7 @@ export function PostCard(props: {
Post Post
</span> </span>
</div> </div>
</Row> </Card>
{onPostClick ? ( {onPostClick ? (
<a <a
className="absolute top-0 left-0 right-0 bottom-0" className="absolute top-0 left-0 right-0 bottom-0"