* Line clamp question in prob change table * Tweaks * Expand option for daily movers * Snap scrolling for carousel * Add arrows to section headers * Remove carousel from experimental/home * React querify fetching your groups * Edit home is its own page * Add daily profit and balance * Merge branch 'main' into new-home * Make experimental search by your followed groups/creators * Just submit, allow xs on pills * Weigh in * Use next/future/image component to optimize avatar images * Inga/challenge icon (#857) * changed challenge icon to custom icon * fixed tip button alignment * weighing in and trading "weigh in" for "trade" Co-authored-by: Ian Philips <iansphilips@gmail.com> Co-authored-by: Austin Chen <akrolsmir@gmail.com> Co-authored-by: ingawei <46611122+ingawei@users.noreply.github.com> Co-authored-by: mantikoros <sgrugett@gmail.com>
		
			
				
	
	
		
			99 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import clsx from 'clsx'
 | 
						|
import { contractPath } from 'web/lib/firebase/contracts'
 | 
						|
import { CPMMContract } from 'common/contract'
 | 
						|
import { formatPercent } from 'common/util/format'
 | 
						|
import { useProbChanges } from 'web/hooks/use-prob-changes'
 | 
						|
import { linkClass, SiteLink } from '../site-link'
 | 
						|
import { Col } from '../layout/col'
 | 
						|
import { Row } from '../layout/row'
 | 
						|
import { useState } from 'react'
 | 
						|
 | 
						|
export function ProbChangeTable(props: { userId: string | undefined }) {
 | 
						|
  const { userId } = props
 | 
						|
 | 
						|
  const changes = useProbChanges(userId ?? '')
 | 
						|
  const [expanded, setExpanded] = useState(false)
 | 
						|
 | 
						|
  if (!changes) {
 | 
						|
    return null
 | 
						|
  }
 | 
						|
 | 
						|
  const count = expanded ? 16 : 4
 | 
						|
 | 
						|
  const { positiveChanges, negativeChanges } = changes
 | 
						|
  const filteredPositiveChanges = positiveChanges.slice(0, count / 2)
 | 
						|
  const filteredNegativeChanges = negativeChanges.slice(0, count / 2)
 | 
						|
  const filteredChanges = [
 | 
						|
    ...filteredPositiveChanges,
 | 
						|
    ...filteredNegativeChanges,
 | 
						|
  ]
 | 
						|
 | 
						|
  return (
 | 
						|
    <Col>
 | 
						|
      <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">
 | 
						|
          {filteredChanges.slice(0, count / 2).map((contract) => (
 | 
						|
            <Row className="items-center hover:bg-gray-100">
 | 
						|
              <ProbChange
 | 
						|
                className="p-4 text-right text-xl"
 | 
						|
                contract={contract}
 | 
						|
              />
 | 
						|
              <SiteLink
 | 
						|
                className="p-4 pl-2 font-semibold text-indigo-700"
 | 
						|
                href={contractPath(contract)}
 | 
						|
              >
 | 
						|
                <span className="line-clamp-2">{contract.question}</span>
 | 
						|
              </SiteLink>
 | 
						|
            </Row>
 | 
						|
          ))}
 | 
						|
        </Col>
 | 
						|
        <Col className="flex-1 divide-y">
 | 
						|
          {filteredChanges.slice(count / 2).map((contract) => (
 | 
						|
            <Row className="items-center hover:bg-gray-100">
 | 
						|
              <ProbChange
 | 
						|
                className="p-4 text-right text-xl"
 | 
						|
                contract={contract}
 | 
						|
              />
 | 
						|
              <SiteLink
 | 
						|
                className="p-4 pl-2 font-semibold text-indigo-700"
 | 
						|
                href={contractPath(contract)}
 | 
						|
              >
 | 
						|
                <span className="line-clamp-2">{contract.question}</span>
 | 
						|
              </SiteLink>
 | 
						|
            </Row>
 | 
						|
          ))}
 | 
						|
        </Col>
 | 
						|
      </Col>
 | 
						|
      <div
 | 
						|
        className={clsx(linkClass, 'cursor-pointer self-end')}
 | 
						|
        onClick={() => setExpanded(!expanded)}
 | 
						|
      >
 | 
						|
        {expanded ? 'Show less' : 'Show more'}
 | 
						|
      </div>
 | 
						|
    </Col>
 | 
						|
  )
 | 
						|
}
 | 
						|
 | 
						|
export function ProbChange(props: {
 | 
						|
  contract: CPMMContract
 | 
						|
  className?: string
 | 
						|
}) {
 | 
						|
  const { contract, className } = props
 | 
						|
  const {
 | 
						|
    probChanges: { day: change },
 | 
						|
  } = contract
 | 
						|
 | 
						|
  const color =
 | 
						|
    change > 0
 | 
						|
      ? 'text-green-500'
 | 
						|
      : change < 0
 | 
						|
      ? 'text-red-500'
 | 
						|
      : 'text-gray-600'
 | 
						|
 | 
						|
  const str =
 | 
						|
    change === 0
 | 
						|
      ? '+0%'
 | 
						|
      : `${change > 0 ? '+' : '-'}${formatPercent(Math.abs(change))}`
 | 
						|
  return <div className={clsx(className, color)}>{str}</div>
 | 
						|
}
 |