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 { manaToUSD } from '../../../common/util/format'
import { Row } from '../layout/row'
import { Col } from '../layout/col'
import { Card } from '../card'
export function CharityCard(props: { charity: Charity; match?: number }) {
const { charity } = props
@ -15,43 +17,44 @@ export function CharityCard(props: { charity: Charity; match?: number }) {
const raised = sumBy(txns, (txn) => txn.amount)
return (
<Link href={`/charity/${slug}`} passHref>
<div className="card card-compact transition:shadow flex-1 cursor-pointer border-2 bg-white hover:shadow-md">
<Row className="mt-6 mb-2">
{tags?.includes('Featured') && <FeaturedBadge />}
</Row>
<div className="px-8">
<figure className="relative h-32">
{photo ? (
<Image src={photo} alt="" layout="fill" objectFit="contain" />
) : (
<div className="h-full w-full bg-gradient-to-r from-slate-300 to-indigo-200" />
)}
</figure>
</div>
<div className="card-body">
{/* <h3 className="card-title line-clamp-3">{name}</h3> */}
<div className="line-clamp-4 text-sm">{preview}</div>
{raised > 0 && (
<>
<Row className="mt-4 flex-1 items-end justify-center gap-6 text-gray-900">
<Row className="items-baseline gap-1">
<span className="text-3xl font-semibold">
{formatUsd(raised)}
</span>
raised
</Row>
{/* {match && (
<Link href={`/charity/${slug}`}>
<a className="flex-1">
<Card className="!rounded-2xl">
<Row className="mt-6 mb-2">
{tags?.includes('Featured') && <FeaturedBadge />}
</Row>
<div className="px-8">
<figure className="relative h-32">
{photo ? (
<Image src={photo} alt="" layout="fill" objectFit="contain" />
) : (
<div className="h-full w-full bg-gradient-to-r from-slate-300 to-indigo-200" />
)}
</figure>
</div>
<Col className="p-8">
<div className="line-clamp-4 text-sm">{preview}</div>
{raised > 0 && (
<>
<Row className="mt-4 flex-1 items-end justify-center gap-6 text-gray-900">
<Row className="items-baseline gap-1">
<span className="text-3xl font-semibold">
{formatUsd(raised)}
</span>
raised
</Row>
{/* {match && (
<Col className="text-gray-500">
<span className="text-xl">+{formatUsd(match)}</span>
<span className="">match</span>
</Col>
)} */}
</Row>
</>
)}
</div>
</div>
</Row>
</>
)}
</Col>
</Card>
</a>
</Link>
)
}

View File

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

View File

@ -1,13 +1,10 @@
import { sortBy } from 'lodash'
import clsx from 'clsx'
import { contractPath } from 'web/lib/firebase/contracts'
import { CPMMContract } from 'common/contract'
import { formatPercent } from 'common/util/format'
import { SiteLink } from '../site-link'
import { sortBy } from 'lodash'
import { Col } from '../layout/col'
import { Row } from '../layout/row'
import { LoadingIndicator } from '../loading-indicator'
import { useContractWithPreload } from 'web/hooks/use-contract'
import { ContractCardProbChange } from './contract-card'
export function ProbChangeTable(props: {
changes: CPMMContract[] | undefined
@ -39,46 +36,21 @@ export function ProbChangeTable(props: {
if (rows === 0) return <div className="px-4 text-gray-500">None</div>
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="flex-1 divide-y">
<Col className="mb-4 w-full gap-4 rounded-lg md:flex-row">
<Col className="flex-1 gap-4">
{filteredPositiveChanges.map((contract) => (
<ProbChangeRow key={contract.id} contract={contract} />
<ContractCardProbChange key={contract.id} contract={contract} />
))}
</Col>
<Col className="flex-1 divide-y">
<Col className="flex-1 gap-4">
{filteredNegativeChanges.map((contract) => (
<ProbChangeRow key={contract.id} contract={contract} />
<ContractCardProbChange key={contract.id} contract={contract} />
))}
</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: {
contract: CPMMContract
className?: string

View File

@ -7,8 +7,8 @@ import { useUserById } from 'web/hooks/use-user'
import { postPath } from 'web/lib/firebase/posts'
import { fromNow } from 'web/lib/util/time'
import { Avatar } from './avatar'
import { Card } from './card'
import { CardHighlightOptions } from './contract/contracts-grid'
import { Row } from './layout/row'
import { UserLink } from './user-link'
export function PostCard(props: {
@ -26,9 +26,9 @@ export function PostCard(props: {
return (
<div className="relative py-1">
<Row
<Card
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
)}
>
@ -58,7 +58,7 @@ export function PostCard(props: {
Post
</span>
</div>
</Row>
</Card>
{onPostClick ? (
<a
className="absolute top-0 left-0 right-0 bottom-0"