Clean up rendering of user bets list (#694)
* Clean up crufty markup in bets list * Don't render bet tables in bets list until expanded * Don't look up unfilled bets for every sell button
This commit is contained in:
		
							parent
							
								
									7e4f4b9a87
								
							
						
					
					
						commit
						ad46a60c4f
					
				|  | @ -3,6 +3,7 @@ import { groupBy, mapValues, sortBy, partition, sumBy } from 'lodash' | ||||||
| import dayjs from 'dayjs' | import dayjs from 'dayjs' | ||||||
| import { useEffect, useMemo, useState } from 'react' | import { useEffect, useMemo, useState } from 'react' | ||||||
| import clsx from 'clsx' | import clsx from 'clsx' | ||||||
|  | import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid' | ||||||
| 
 | 
 | ||||||
| import { Bet } from 'web/lib/firebase/bets' | import { Bet } from 'web/lib/firebase/bets' | ||||||
| import { User } from 'web/lib/firebase/users' | import { User } from 'web/lib/firebase/users' | ||||||
|  | @ -277,13 +278,7 @@ function ContractBets(props: { | ||||||
|     bets |     bets | ||||||
|   ) |   ) | ||||||
|   return ( |   return ( | ||||||
|     <div |     <div tabIndex={0} className="relative bg-white p-4 pr-6"> | ||||||
|       tabIndex={0} |  | ||||||
|       className={clsx( |  | ||||||
|         'collapse collapse-arrow relative bg-white p-4 pr-6', |  | ||||||
|         collapsed ? 'collapse-close' : 'collapse-open pb-2' |  | ||||||
|       )} |  | ||||||
|     > |  | ||||||
|       <Row |       <Row | ||||||
|         className="cursor-pointer flex-wrap gap-2" |         className="cursor-pointer flex-wrap gap-2" | ||||||
|         onClick={() => setCollapsed((collapsed) => !collapsed)} |         onClick={() => setCollapsed((collapsed) => !collapsed)} | ||||||
|  | @ -300,10 +295,11 @@ function ContractBets(props: { | ||||||
|             </Link> |             </Link> | ||||||
| 
 | 
 | ||||||
|             {/* Show carrot for collapsing. Hack the positioning. */} |             {/* Show carrot for collapsing. Hack the positioning. */} | ||||||
|             <div |             {collapsed ? ( | ||||||
|               className="collapse-title absolute h-0 min-h-0 w-0 p-0" |               <ChevronDownIcon className="absolute top-5 right-4 h-6 w-6" /> | ||||||
|               style={{ top: -10, right: 0 }} |             ) : ( | ||||||
|             /> |               <ChevronUpIcon className="absolute top-5 right-4 h-6 w-6" /> | ||||||
|  |             )} | ||||||
|           </Row> |           </Row> | ||||||
| 
 | 
 | ||||||
|           <Row className="flex-1 items-center gap-2 text-sm text-gray-500"> |           <Row className="flex-1 items-center gap-2 text-sm text-gray-500"> | ||||||
|  | @ -335,55 +331,42 @@ function ContractBets(props: { | ||||||
|           </Row> |           </Row> | ||||||
|         </Col> |         </Col> | ||||||
| 
 | 
 | ||||||
|         <Row className="mr-5 justify-end sm:mr-8"> |         <Col className="mr-5 sm:mr-8"> | ||||||
|           <Col> |           <div className="whitespace-nowrap text-right text-lg"> | ||||||
|             <div className="whitespace-nowrap text-right text-lg"> |             {formatMoney(metric === 'profit' ? profit : payout)} | ||||||
|               {formatMoney(metric === 'profit' ? profit : payout)} |           </div> | ||||||
|             </div> |           <ProfitBadge className="text-right" profitPercent={profitPercent} /> | ||||||
|             <div className="text-right"> |         </Col> | ||||||
|               <ProfitBadge profitPercent={profitPercent} /> |  | ||||||
|             </div> |  | ||||||
|           </Col> |  | ||||||
|         </Row> |  | ||||||
|       </Row> |       </Row> | ||||||
| 
 | 
 | ||||||
|       <div |       {!collapsed && ( | ||||||
|         className="collapse-content !px-0" |         <div className="bg-white"> | ||||||
|         style={{ backgroundColor: 'white' }} |           <BetsSummary | ||||||
|       > |             className="mt-8 mr-5 flex-1 sm:mr-8" | ||||||
|         <Spacer h={8} /> |             contract={contract} | ||||||
|  |             bets={bets} | ||||||
|  |             isYourBets={isYourBets} | ||||||
|  |           /> | ||||||
| 
 | 
 | ||||||
|         <BetsSummary |           {contract.mechanism === 'cpmm-1' && limitBets.length > 0 && ( | ||||||
|           className="mr-5 flex-1 sm:mr-8" |  | ||||||
|           contract={contract} |  | ||||||
|           bets={bets} |  | ||||||
|           isYourBets={isYourBets} |  | ||||||
|         /> |  | ||||||
| 
 |  | ||||||
|         <Spacer h={4} /> |  | ||||||
| 
 |  | ||||||
|         {contract.mechanism === 'cpmm-1' && limitBets.length > 0 && ( |  | ||||||
|           <> |  | ||||||
|             <div className="max-w-md"> |             <div className="max-w-md"> | ||||||
|               <div className="bg-gray-50 px-4 py-2">Limit orders</div> |               <div className="mt-4 bg-gray-50 px-4 py-2">Limit orders</div> | ||||||
|               <LimitOrderTable |               <LimitOrderTable | ||||||
|                 contract={contract} |                 contract={contract} | ||||||
|                 limitBets={limitBets} |                 limitBets={limitBets} | ||||||
|                 isYou={true} |                 isYou={true} | ||||||
|               /> |               /> | ||||||
|             </div> |             </div> | ||||||
|           </> |           )} | ||||||
|         )} |  | ||||||
| 
 | 
 | ||||||
|         <Spacer h={4} /> |           <div className="mt-4 bg-gray-50 px-4 py-2">Bets</div> | ||||||
| 
 |           <ContractBetsTable | ||||||
|         <div className="bg-gray-50 px-4 py-2">Bets</div> |             contract={contract} | ||||||
|         <ContractBetsTable |             bets={bets} | ||||||
|           contract={contract} |             isYourBets={isYourBets} | ||||||
|           bets={bets} |           /> | ||||||
|           isYourBets={isYourBets} |         </div> | ||||||
|         /> |       )} | ||||||
|       </div> |  | ||||||
|     </div> |     </div> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | @ -427,107 +410,92 @@ export function BetsSummary(props: { | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Row className={clsx('flex-wrap gap-4 sm:flex-nowrap sm:gap-6', className)}> |     <Row className={clsx('flex-wrap gap-4 sm:flex-nowrap sm:gap-6', className)}> | ||||||
|       <Row className="flex-wrap gap-4 sm:gap-6"> |       {!isCpmm && ( | ||||||
|         {!isCpmm && ( |  | ||||||
|           <Col> |  | ||||||
|             <div className="whitespace-nowrap text-sm text-gray-500"> |  | ||||||
|               Invested |  | ||||||
|             </div> |  | ||||||
|             <div className="whitespace-nowrap">{formatMoney(invested)}</div> |  | ||||||
|           </Col> |  | ||||||
|         )} |  | ||||||
|         {resolution ? ( |  | ||||||
|           <Col> |  | ||||||
|             <div className="text-sm text-gray-500">Payout</div> |  | ||||||
|             <div className="whitespace-nowrap"> |  | ||||||
|               {formatMoney(payout)}{' '} |  | ||||||
|               <ProfitBadge profitPercent={profitPercent} /> |  | ||||||
|             </div> |  | ||||||
|           </Col> |  | ||||||
|         ) : ( |  | ||||||
|           <> |  | ||||||
|             {isBinary ? ( |  | ||||||
|               <> |  | ||||||
|                 <Col> |  | ||||||
|                   <div className="whitespace-nowrap text-sm text-gray-500"> |  | ||||||
|                     Payout if <YesLabel /> |  | ||||||
|                   </div> |  | ||||||
|                   <div className="whitespace-nowrap"> |  | ||||||
|                     {formatMoney(yesWinnings)} |  | ||||||
|                   </div> |  | ||||||
|                 </Col> |  | ||||||
|                 <Col> |  | ||||||
|                   <div className="whitespace-nowrap text-sm text-gray-500"> |  | ||||||
|                     Payout if <NoLabel /> |  | ||||||
|                   </div> |  | ||||||
|                   <div className="whitespace-nowrap"> |  | ||||||
|                     {formatMoney(noWinnings)} |  | ||||||
|                   </div> |  | ||||||
|                 </Col> |  | ||||||
|               </> |  | ||||||
|             ) : isPseudoNumeric ? ( |  | ||||||
|               <> |  | ||||||
|                 <Col> |  | ||||||
|                   <div className="whitespace-nowrap text-sm text-gray-500"> |  | ||||||
|                     Payout if {'>='} {formatLargeNumber(contract.max)} |  | ||||||
|                   </div> |  | ||||||
|                   <div className="whitespace-nowrap"> |  | ||||||
|                     {formatMoney(yesWinnings)} |  | ||||||
|                   </div> |  | ||||||
|                 </Col> |  | ||||||
|                 <Col> |  | ||||||
|                   <div className="whitespace-nowrap text-sm text-gray-500"> |  | ||||||
|                     Payout if {'<='} {formatLargeNumber(contract.min)} |  | ||||||
|                   </div> |  | ||||||
|                   <div className="whitespace-nowrap"> |  | ||||||
|                     {formatMoney(noWinnings)} |  | ||||||
|                   </div> |  | ||||||
|                 </Col> |  | ||||||
|               </> |  | ||||||
|             ) : ( |  | ||||||
|               <Col> |  | ||||||
|                 <div className="whitespace-nowrap text-sm text-gray-500"> |  | ||||||
|                   Current value |  | ||||||
|                 </div> |  | ||||||
|                 <div className="whitespace-nowrap">{formatMoney(payout)}</div> |  | ||||||
|               </Col> |  | ||||||
|             )} |  | ||||||
|           </> |  | ||||||
|         )} |  | ||||||
|         <Col> |         <Col> | ||||||
|           <div className="whitespace-nowrap text-sm text-gray-500">Profit</div> |           <div className="whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |             Invested | ||||||
|  |           </div> | ||||||
|  |           <div className="whitespace-nowrap">{formatMoney(invested)}</div> | ||||||
|  |         </Col> | ||||||
|  |       )} | ||||||
|  |       {resolution ? ( | ||||||
|  |         <Col> | ||||||
|  |           <div className="text-sm text-gray-500">Payout</div> | ||||||
|           <div className="whitespace-nowrap"> |           <div className="whitespace-nowrap"> | ||||||
|             {formatMoney(profit)} <ProfitBadge profitPercent={profitPercent} /> |             {formatMoney(payout)} <ProfitBadge profitPercent={profitPercent} /> | ||||||
|             {isYourBets && |  | ||||||
|               isCpmm && |  | ||||||
|               (isBinary || isPseudoNumeric) && |  | ||||||
|               !isClosed && |  | ||||||
|               !resolution && |  | ||||||
|               hasShares && |  | ||||||
|               sharesOutcome && |  | ||||||
|               user && ( |  | ||||||
|                 <> |  | ||||||
|                   <button |  | ||||||
|                     className="btn btn-sm ml-2" |  | ||||||
|                     onClick={() => setShowSellModal(true)} |  | ||||||
|                   > |  | ||||||
|                     Sell |  | ||||||
|                   </button> |  | ||||||
|                   {showSellModal && ( |  | ||||||
|                     <SellSharesModal |  | ||||||
|                       contract={contract} |  | ||||||
|                       user={user} |  | ||||||
|                       userBets={bets} |  | ||||||
|                       shares={totalShares[sharesOutcome]} |  | ||||||
|                       sharesOutcome={sharesOutcome} |  | ||||||
|                       setOpen={setShowSellModal} |  | ||||||
|                     /> |  | ||||||
|                   )} |  | ||||||
|                 </> |  | ||||||
|               )} |  | ||||||
|           </div> |           </div> | ||||||
|         </Col> |         </Col> | ||||||
|       </Row> |       ) : isBinary ? ( | ||||||
|  |         <> | ||||||
|  |           <Col> | ||||||
|  |             <div className="whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |               Payout if <YesLabel /> | ||||||
|  |             </div> | ||||||
|  |             <div className="whitespace-nowrap">{formatMoney(yesWinnings)}</div> | ||||||
|  |           </Col> | ||||||
|  |           <Col> | ||||||
|  |             <div className="whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |               Payout if <NoLabel /> | ||||||
|  |             </div> | ||||||
|  |             <div className="whitespace-nowrap">{formatMoney(noWinnings)}</div> | ||||||
|  |           </Col> | ||||||
|  |         </> | ||||||
|  |       ) : isPseudoNumeric ? ( | ||||||
|  |         <> | ||||||
|  |           <Col> | ||||||
|  |             <div className="whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |               Payout if {'>='} {formatLargeNumber(contract.max)} | ||||||
|  |             </div> | ||||||
|  |             <div className="whitespace-nowrap">{formatMoney(yesWinnings)}</div> | ||||||
|  |           </Col> | ||||||
|  |           <Col> | ||||||
|  |             <div className="whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |               Payout if {'<='} {formatLargeNumber(contract.min)} | ||||||
|  |             </div> | ||||||
|  |             <div className="whitespace-nowrap">{formatMoney(noWinnings)}</div> | ||||||
|  |           </Col> | ||||||
|  |         </> | ||||||
|  |       ) : ( | ||||||
|  |         <Col> | ||||||
|  |           <div className="whitespace-nowrap text-sm text-gray-500"> | ||||||
|  |             Current value | ||||||
|  |           </div> | ||||||
|  |           <div className="whitespace-nowrap">{formatMoney(payout)}</div> | ||||||
|  |         </Col> | ||||||
|  |       )} | ||||||
|  |       <Col> | ||||||
|  |         <div className="whitespace-nowrap text-sm text-gray-500">Profit</div> | ||||||
|  |         <div className="whitespace-nowrap"> | ||||||
|  |           {formatMoney(profit)} <ProfitBadge profitPercent={profitPercent} /> | ||||||
|  |           {isYourBets && | ||||||
|  |             isCpmm && | ||||||
|  |             (isBinary || isPseudoNumeric) && | ||||||
|  |             !isClosed && | ||||||
|  |             !resolution && | ||||||
|  |             hasShares && | ||||||
|  |             sharesOutcome && | ||||||
|  |             user && ( | ||||||
|  |               <> | ||||||
|  |                 <button | ||||||
|  |                   className="btn btn-sm ml-2" | ||||||
|  |                   onClick={() => setShowSellModal(true)} | ||||||
|  |                 > | ||||||
|  |                   Sell | ||||||
|  |                 </button> | ||||||
|  |                 {showSellModal && ( | ||||||
|  |                   <SellSharesModal | ||||||
|  |                     contract={contract} | ||||||
|  |                     user={user} | ||||||
|  |                     userBets={bets} | ||||||
|  |                     shares={totalShares[sharesOutcome]} | ||||||
|  |                     sharesOutcome={sharesOutcome} | ||||||
|  |                     setOpen={setShowSellModal} | ||||||
|  |                   /> | ||||||
|  |                 )} | ||||||
|  |               </> | ||||||
|  |             )} | ||||||
|  |         </div> | ||||||
|  |       </Col> | ||||||
|     </Row> |     </Row> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | @ -689,7 +657,13 @@ function BetRow(props: { | ||||||
|           !isClosed && |           !isClosed && | ||||||
|           !isSold && |           !isSold && | ||||||
|           !isAnte && |           !isAnte && | ||||||
|           !isNumeric && <SellButton contract={contract} bet={bet} />} |           !isNumeric && ( | ||||||
|  |             <SellButton | ||||||
|  |               contract={contract} | ||||||
|  |               bet={bet} | ||||||
|  |               unfilledBets={unfilledBets} | ||||||
|  |             /> | ||||||
|  |           )} | ||||||
|       </td> |       </td> | ||||||
|       {isCPMM && <td>{shares >= 0 ? 'BUY' : 'SELL'}</td>} |       {isCPMM && <td>{shares >= 0 ? 'BUY' : 'SELL'}</td>} | ||||||
|       <td> |       <td> | ||||||
|  | @ -729,8 +703,12 @@ function BetRow(props: { | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function SellButton(props: { contract: Contract; bet: Bet }) { | function SellButton(props: { | ||||||
|   const { contract, bet } = props |   contract: Contract | ||||||
|  |   bet: Bet | ||||||
|  |   unfilledBets: LimitBet[] | ||||||
|  | }) { | ||||||
|  |   const { contract, bet, unfilledBets } = props | ||||||
|   const { outcome, shares, loanAmount } = bet |   const { outcome, shares, loanAmount } = bet | ||||||
| 
 | 
 | ||||||
|   const [isSubmitting, setIsSubmitting] = useState(false) |   const [isSubmitting, setIsSubmitting] = useState(false) | ||||||
|  | @ -740,8 +718,6 @@ function SellButton(props: { contract: Contract; bet: Bet }) { | ||||||
|     outcome === 'NO' ? 'YES' : outcome |     outcome === 'NO' ? 'YES' : outcome | ||||||
|   ) |   ) | ||||||
| 
 | 
 | ||||||
|   const unfilledBets = useUnfilledBets(contract.id) ?? [] |  | ||||||
| 
 |  | ||||||
|   const outcomeProb = getProbabilityAfterSale( |   const outcomeProb = getProbabilityAfterSale( | ||||||
|     contract, |     contract, | ||||||
|     outcome, |     outcome, | ||||||
|  | @ -787,8 +763,8 @@ function SellButton(props: { contract: Contract; bet: Bet }) { | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function ProfitBadge(props: { profitPercent: number }) { | function ProfitBadge(props: { profitPercent: number; className?: string }) { | ||||||
|   const { profitPercent } = props |   const { profitPercent, className } = props | ||||||
|   if (!profitPercent) return null |   if (!profitPercent) return null | ||||||
|   const colors = |   const colors = | ||||||
|     profitPercent > 0 |     profitPercent > 0 | ||||||
|  | @ -799,7 +775,8 @@ function ProfitBadge(props: { profitPercent: number }) { | ||||||
|     <span |     <span | ||||||
|       className={clsx( |       className={clsx( | ||||||
|         'ml-1 inline-flex items-center rounded-full px-3 py-0.5 text-sm font-medium', |         'ml-1 inline-flex items-center rounded-full px-3 py-0.5 text-sm font-medium', | ||||||
|         colors |         colors, | ||||||
|  |         className | ||||||
|       )} |       )} | ||||||
|     > |     > | ||||||
|       {(profitPercent > 0 ? '+' : '') + profitPercent.toFixed(1) + '%'} |       {(profitPercent > 0 ? '+' : '') + profitPercent.toFixed(1) + '%'} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user