* Split BuyAmountInput out of AmountInput * Buy and sell tabs. Compute some sell info * In progress * BuyPanel & SellPanel with banner above that shows current shares and toggle button * Remove "Remaining balance" * Bring back 'Place a trade'. Tweaks * Sell shares cloud function. * Sell all shares by default. Switch back to buy if sell all your shares. * Cache your shares in local storage so sell banner doesn't flicker. * Compute sale value of shares with binary search to keep k constant. * Update bets table to show BUY or SELL * Fixes from Stephen's review * Don't allow selling more than max shares in cloud function * Use modal for sell shares on desktop. * Handle floating point precision in max shares you can sell.
		
			
				
	
	
		
			57 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			57 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { Fragment } from 'react'
 | |
| import { Dialog, Transition } from '@headlessui/react'
 | |
| 
 | |
| // From https://tailwindui.com/components/application-ui/overlays/modals
 | |
| export function Modal(props: {
 | |
|   children: React.ReactNode
 | |
|   open: boolean
 | |
|   setOpen: (open: boolean) => void
 | |
| }) {
 | |
|   const { children, open, setOpen } = props
 | |
| 
 | |
|   return (
 | |
|     <Transition.Root show={open} as={Fragment}>
 | |
|       <Dialog
 | |
|         as="div"
 | |
|         className="fixed inset-0 z-50 overflow-y-auto"
 | |
|         onClose={setOpen}
 | |
|       >
 | |
|         <div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
 | |
|           <Transition.Child
 | |
|             as={Fragment}
 | |
|             enter="ease-out duration-300"
 | |
|             enterFrom="opacity-0"
 | |
|             enterTo="opacity-100"
 | |
|             leave="ease-in duration-200"
 | |
|             leaveFrom="opacity-100"
 | |
|             leaveTo="opacity-0"
 | |
|           >
 | |
|             <Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
 | |
|           </Transition.Child>
 | |
| 
 | |
|           {/* This element is to trick the browser into centering the modal contents. */}
 | |
|           <span
 | |
|             className="hidden sm:inline-block sm:h-screen sm:align-middle"
 | |
|             aria-hidden="true"
 | |
|           >
 | |
|             ​
 | |
|           </span>
 | |
|           <Transition.Child
 | |
|             as={Fragment}
 | |
|             enter="ease-out duration-300"
 | |
|             enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
 | |
|             enterTo="opacity-100 translate-y-0 sm:scale-100"
 | |
|             leave="ease-in duration-200"
 | |
|             leaveFrom="opacity-100 translate-y-0 sm:scale-100"
 | |
|             leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
 | |
|           >
 | |
|             <div className="inline-block transform overflow-hidden text-left align-bottom transition-all sm:my-8 sm:w-full sm:max-w-md sm:p-6 sm:align-middle">
 | |
|               {children}
 | |
|             </div>
 | |
|           </Transition.Child>
 | |
|         </div>
 | |
|       </Dialog>
 | |
|     </Transition.Root>
 | |
|   )
 | |
| }
 |