Merge remote-tracking branch 'origin/alerts-modal' into main
This commit is contained in:
commit
3de58a6f31
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue