Merge remote-tracking branch 'origin/alerts-modal' into main

This commit is contained in:
Tyler Shipe 2021-05-02 00:39:20 -04:00
commit 3de58a6f31
2 changed files with 178 additions and 122 deletions

View File

@ -1,6 +1,10 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { RadioGroup } from '@headlessui/react' import { RadioGroup } from '@headlessui/react'
import { InformationCircleIcon, DuplicateIcon } from '@heroicons/react/outline' import {
InformationCircleIcon,
DuplicateIcon,
ExclamationIcon,
} from '@heroicons/react/outline'
import PhoneInput from 'react-phone-input-2' import PhoneInput from 'react-phone-input-2'
import 'react-phone-input-2/lib/plain.css' import 'react-phone-input-2/lib/plain.css'
import Button from './Button' import Button from './Button'
@ -13,6 +17,7 @@ import Modal from './Modal'
import Loading from './Loading' import Loading from './Loading'
import MarginAccountSelect from './MarginAccountSelect' import MarginAccountSelect from './MarginAccountSelect'
import Tooltip from './Tooltip' import Tooltip from './Tooltip'
import Select from './Select'
export default function AlertsModal({ isOpen, onClose }) { export default function AlertsModal({ isOpen, onClose }) {
const connected = useMangoStore((s) => s.wallet.connected) const connected = useMangoStore((s) => s.wallet.connected)
@ -29,6 +34,7 @@ export default function AlertsModal({ isOpen, onClose }) {
const [tgCode, setTgCode] = useState<string>('') const [tgCode, setTgCode] = useState<string>('')
const [submitting, setSubmitting] = useState(false) const [submitting, setSubmitting] = useState(false)
const [isCopied, setIsCopied] = useState(false) const [isCopied, setIsCopied] = useState(false)
const [useCustomRatio, setUseCustomRatio] = useState(false)
useEffect(() => { useEffect(() => {
if (isCopied) { if (isCopied) {
@ -131,6 +137,8 @@ export default function AlertsModal({ isOpen, onClose }) {
}) })
} }
const ratioPresets = [113, 115, 120, 130, 150, 200]
return ( return (
<Modal isOpen={isOpen} onClose={onClose}> <Modal isOpen={isOpen} onClose={onClose}>
{tgCode !== '' ? ( {tgCode !== '' ? (
@ -159,125 +167,168 @@ export default function AlertsModal({ isOpen, onClose }) {
</Tooltip> </Tooltip>
</ElementTitle> </ElementTitle>
</Modal.Header> </Modal.Header>
<div className="pb-4"> {marginAccounts.length > 0 ? (
<div className={`text-th-fgd-1 pb-2`}>Margin Account</div> <>
<MarginAccountSelect {marginAccounts.length > 1 ? (
value={marginAccounts[0]} <div className="pb-4">
onChange={setSelectedMarginAccount} <div className={`text-th-fgd-1 pb-2`}>Margin Account</div>
/> <MarginAccountSelect
</div> value={marginAccounts[0]}
<div className="pb-4"> onChange={setSelectedMarginAccount}
<div className={`text-th-fgd-1 pb-2`}> />
Alert me when my collateral ratio is below: </div>
</div> ) : null}
<Input <div className="pb-4">
type="number" <div className={`text-th-fgd-1 pb-2`}>
value={collateralRatioThresh} Alert me when my collateral ratio is below:
onChange={(e) => setCollateralRatioThresh(e.target.value)} </div>
suffix="%" {useCustomRatio ? (
/> <Input
</div> type="number"
<div className="pb-4"> value={collateralRatioThresh}
<div className={`text-th-fgd-1 pb-2`}>Alert me via:</div> onChange={(e) => setCollateralRatioThresh(e.target.value)}
<RadioGroup suffix="%"
value={alertProvider} />
onChange={(val) => setAlertProvider(val)}
className="flex border border-th-fgd-4 rounded"
>
<RadioGroup.Option
value="sms"
className="flex-1 focus:outline-none"
>
{({ checked }) => (
<button
className={`${
checked ? 'bg-th-bkg-3 rounded-l' : ''
} font-normal text-th-fgd-1 text-center py-1.5 w-full rounded-none border-r border-th-fgd-4 hover:bg-th-bkg-3 focus:outline-none`}
>
SMS
</button>
)}
</RadioGroup.Option>
<RadioGroup.Option
value="mail"
className="focus:outline-none flex-1"
>
{({ checked }) => (
<button
className={`${
checked ? 'bg-th-bkg-3' : ''
} font-normal text-th-fgd-1 text-center py-1.5 w-full rounded-none border-r border-th-fgd-4 hover:bg-th-bkg-3 focus:outline-none`}
>
E-mail
</button>
)}
</RadioGroup.Option>
<RadioGroup.Option
value="tg"
className="focus:outline-none flex-1"
>
{({ checked }) => (
<button
className={`${
checked ? 'bg-th-bkg-3 rounded-r' : ''
} font-normal text-th-fgd-1 text-center py-1.5 w-full rounded-none hover:bg-th-bkg-3 focus:outline-none`}
>
Telegram
</button>
)}
</RadioGroup.Option>
</RadioGroup>
</div>
<div className="pb-4">
{alertProvider === 'sms' ? (
<>
<div className={`text-th-fgd-1 pb-2`}>Mobile Number</div>
<PhoneInput
containerClass="w-full"
inputClass="!w-full !bg-th-bkg-1 !rounded !h-10 !text-th-fgd-1
!border !border-th-fgd-4 !border-l hover:!border-th-primary focus:!border-th-primary default-transition"
buttonClass="!bg-th-bkg-2 !border !border-th-fgd-4 !pl-1 hover:!bg-th-bkg-3 focus:!bg-th-primary !rounded-l default-transition"
dropdownClass="!bg-th-bkg-1 !border-0 !pl-1 !text-th-fgd-1 !rounded !mt-2 !max-h-40 thin-scroll"
country="us"
inputProps={{
name: 'phone',
required: true,
// autoFocus: true,
}}
onChange={(val) => setPhoneNumber({ phone: val, code: '' })}
/>
</>
) : null}
{alertProvider === 'mail' ? (
<>
<div className={`text-th-fgd-1 pb-2`}>Email</div>
<Input
value={email}
type="mail"
onChange={(e) => setEmail(e.target.value)}
/>
</>
) : null}
</div>
<Button
disabled={!connected}
onClick={onSubmit}
className="w-full mb-2"
>
{connected ? (
<div className="flex justify-center">
{submitting ? (
<Loading />
) : alertProvider === 'tg' ? (
'Generate Telegram Bot Code'
) : ( ) : (
'Save Alert' <Select
value={collateralRatioThresh + '%'}
onChange={(v) => setCollateralRatioThresh(v)}
>
{ratioPresets.map((option, index) => (
<Select.Option key={index} value={option}>
{option}%
</Select.Option>
))}
</Select>
)} )}
<Button
className="px-0 py-0 mt-2 border-0 font-normal text-th-fgd-3 text-xs hover:bg-transparent hover:opacity-60"
onClick={() => setUseCustomRatio(!useCustomRatio)}
>
{useCustomRatio
? 'Choose a suggested collateral ratio threshold'
: 'Enter a custom collateral ratio threshold'}
</Button>
</div> </div>
) : ( <div className="pb-4">
'Connect Wallet To Save' <div className={`text-th-fgd-1 pb-2`}>Alert me via:</div>
)} <RadioGroup
</Button> value={alertProvider}
onChange={(val) => setAlertProvider(val)}
className="flex border border-th-fgd-4 rounded"
>
<RadioGroup.Option
value="sms"
className="flex-1 focus:outline-none"
>
{({ checked }) => (
<button
className={`${
checked ? 'bg-th-bkg-3 rounded-l' : ''
} font-normal text-th-fgd-1 text-center py-1.5 w-full rounded-none border-r border-th-fgd-4 hover:bg-th-bkg-3 focus:outline-none`}
>
SMS
</button>
)}
</RadioGroup.Option>
<RadioGroup.Option
value="mail"
className="focus:outline-none flex-1"
>
{({ checked }) => (
<button
className={`${
checked ? 'bg-th-bkg-3' : ''
} font-normal text-th-fgd-1 text-center py-1.5 w-full rounded-none border-r border-th-fgd-4 hover:bg-th-bkg-3 focus:outline-none`}
>
E-mail
</button>
)}
</RadioGroup.Option>
<RadioGroup.Option
value="tg"
className="focus:outline-none flex-1"
>
{({ checked }) => (
<button
className={`${
checked ? 'bg-th-bkg-3 rounded-r' : ''
} font-normal text-th-fgd-1 text-center py-1.5 w-full rounded-none hover:bg-th-bkg-3 focus:outline-none`}
>
Telegram
</button>
)}
</RadioGroup.Option>
</RadioGroup>
</div>
<div className="pb-4">
{alertProvider === 'sms' ? (
<>
<div className={`text-th-fgd-1 pb-2`}>Mobile Number</div>
<PhoneInput
containerClass="w-full"
inputClass="!w-full !bg-th-bkg-1 !rounded !h-10 !text-th-fgd-1
!border !border-th-fgd-4 !border-l hover:!border-th-primary focus:!border-th-primary default-transition"
buttonClass="!bg-th-bkg-2 !border !border-th-fgd-4 !pl-1 hover:!bg-th-bkg-3 focus:!bg-th-primary !rounded-l default-transition"
dropdownClass="!bg-th-bkg-1 !border-0 !pl-1 !text-th-fgd-1 !rounded !mt-2 !max-h-40 thin-scroll"
country="us"
inputProps={{
name: 'phone',
required: true,
}}
onChange={(val) =>
setPhoneNumber({ phone: val, code: '' })
}
/>
</>
) : null}
{alertProvider === 'mail' ? (
<>
<div className={`text-th-fgd-1 pb-2`}>Email</div>
<Input
value={email}
type="mail"
onChange={(e) => setEmail(e.target.value)}
/>
</>
) : null}
</div>
<Button
disabled={!connected}
onClick={onSubmit}
className="w-full mb-2"
>
{connected ? (
<div className="flex justify-center">
{submitting ? (
<Loading />
) : alertProvider === 'tg' ? (
'Generate Telegram Bot Code'
) : (
'Save Alert'
)}
</div>
) : (
'Connect Wallet To Save'
)}
</Button>
</>
) : (
<>
<div className="flex flex-col items-center text-th-fgd-1 p-4 mb-4 rounded-lg border border-th-fgd-4">
<ExclamationIcon className="w-8 h-8 text-th-red" />
<div className="font-bold text-base pb-1">
No Margin Accounts Found
</div>
<p className="mb-0">
Make a deposit to initialize a margin account.
</p>
</div>
<Button onClick={onClose} className="w-full">
Okay, Got It
</Button>
</>
)}
</> </>
)} )}
</Modal> </Modal>

View File

@ -1,6 +1,11 @@
import { Listbox } from '@headlessui/react' import { Listbox } from '@headlessui/react'
import styled from '@emotion/styled'
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid' import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid'
const StyledDiv = styled.div`
min-height: 2.5rem;
`
const Select = ({ const Select = ({
value, value,
onChange, onChange,
@ -15,10 +20,10 @@ const Select = ({
{({ open }) => ( {({ open }) => (
<> <>
<Listbox.Button <Listbox.Button
className={`h-full w-full font-normal bg-th-bkg-1 border border-th-fgd-4 rounded hover:border-th-primary focus:outline-none focus:border-th-primary`} className={`h-full w-full font-normal bg-th-bkg-1 ring-1 ring-th-fgd-4 ring-inset rounded hover:ring-th-primary focus:outline-none focus:border-th-primary`}
> >
<div <StyledDiv
className={`flex items-center justify-between space-x-4 p-3`} className={`flex items-center justify-between space-x-4 p-2`}
> >
<span className="text-th-fgd-1"> <span className="text-th-fgd-1">
{value ? value : placeholder} {value ? value : placeholder}
@ -28,12 +33,12 @@ const Select = ({
) : ( ) : (
<ChevronDownIcon className={`h-5 w-5 mr-1 text-th-primary`} /> <ChevronDownIcon className={`h-5 w-5 mr-1 text-th-primary`} />
)} )}
</div> </StyledDiv>
</Listbox.Button> </Listbox.Button>
{open ? ( {open ? (
<Listbox.Options <Listbox.Options
static static
className={`text-th-fgd-1 z-20 w-full p-1 absolute left-0 mt-1 bg-th-bkg-1 origin-top-left divide-y divide-th-bkg-3 shadow-lg outline-none rounded-md`} className={`text-th-fgd-1 max-h-40 overflow-auto z-20 w-full p-1 absolute left-0 mt-1 bg-th-bkg-1 origin-top-left divide-y divide-th-bkg-3 shadow-lg outline-none rounded-md thin-scroll`}
> >
{children} {children}
</Listbox.Options> </Listbox.Options>