Create common card component (#1012)
* Create common card component * lint
This commit is contained in:
parent
7ce09ae39d
commit
94624c5387
16
web/components/card.tsx
Normal file
16
web/components/card.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user