import React, { FunctionComponent, useEffect, useState } from 'react' import { PublicKey } from '@solana/web3.js' import { RadioGroup } from '@headlessui/react' import { CheckCircleIcon, DuplicateIcon, ExclamationIcon, InformationCircleIcon, } from '@heroicons/react/outline' import PhoneInput from 'react-phone-input-2' import 'react-phone-input-2/lib/plain.css' import Button from './Button' import Input from './Input' import { ElementTitle } from './styles' import useMangoStore from '../stores/useMangoStore' import useAlertsStore from '../stores/useAlertsStore' import { notify } from '../utils/notifications' import { copyToClipboard } from '../utils' import Modal from './Modal' import Loading from './Loading' import MarginAccountSelect from './MarginAccountSelect' import Tooltip from './Tooltip' import Select from './Select' interface AlertsModalProps { marginAccount?: { publicKey: PublicKey } alert?: { alertProvider: string collateralRatioThresh: number acc: PublicKey } isOpen: boolean onClose: () => void } const AlertsModal: FunctionComponent = ({ isOpen, onClose, alert, marginAccount, }) => { const connected = useMangoStore((s) => s.wallet.connected) const marginAccounts = useMangoStore((s) => s.marginAccounts) const selectedMangoGroup = useMangoStore((s) => s.selectedMangoGroup.current) const actions = useAlertsStore((s) => s.actions) const submitting = useAlertsStore((s) => s.submitting) const success = useAlertsStore((s) => s.success) const set = useAlertsStore((s) => s.set) const tgCode = useAlertsStore((s) => s.tgCode) // select by default: // 1. margin account passed in directly (from the margin account info on the trade page) // 2. previous alert's margin account (when re-activating from the alerts page) // 3, the first margin account const [selectedMarginAccount, setSelectedMarginAccount] = useState( marginAccount || alert?.acc || marginAccounts[0] ) const [collateralRatioPreset, setCollateralRatioPreset] = useState('113') const [customCollateralRatio, setCustomCollateralRatio] = useState('') const [alertProvider, setAlertProvider] = useState('sms') const [phoneNumber, setPhoneNumber] = useState({ phone: null }) const [email, setEmail] = useState('') const [showTgCode, setShowTgCode] = useState(false) const [isCopied, setIsCopied] = useState(false) const ratioPresets = ['Custom', '113', '115', '120', '130', '150', '200'] const collateralRatioThresh = collateralRatioPreset !== 'Custom' ? parseInt(collateralRatioPreset) : parseInt(customCollateralRatio) useEffect(() => { if (isCopied) { const timer = setTimeout(() => { setIsCopied(false) }, 2000) return () => clearTimeout(timer) } }, [isCopied]) useEffect(() => { if (tgCode) { setShowTgCode(true) } }, [tgCode]) useEffect(() => { if (alert) { const isPreset = ratioPresets.find( (preset) => preset === alert.collateralRatioThresh.toString() ) if (isPreset) { setCollateralRatioPreset(alert.collateralRatioThresh.toString()) } else { setCollateralRatioPreset('Custom') setCustomCollateralRatio(alert.collateralRatioThresh.toString()) } setAlertProvider(alert.alertProvider) const alertAccount = marginAccounts.find( (account) => account.publicKey.toString() === alert.acc.toString() ) setSelectedMarginAccount(alertAccount) } }, [alert]) const handleCopyTgCode = (code) => { setIsCopied(true) copyToClipboard(code) } const handleNewFromTgCode = () => { set((s) => { s.tgCode = null }) resetForm() } const handleCloseModal = () => { set((s) => { s.success = '' s.tgCode = null }) resetForm() onClose() } const handleNewFromSuccess = () => { resetForm() set((s) => { s.success = '' }) } const resetForm = () => { setAlertProvider('sms') setPhoneNumber({ phone: null }) setEmail('') setCollateralRatioPreset('113') setCustomCollateralRatio('') } async function onSubmit() { if (!connected) { notify({ message: 'Please connect wallet', type: 'error', }) return } else if (!selectedMarginAccount) { notify({ message: 'Please select a margin account', type: 'error', }) return } else if (alertProvider === 'sms' && !phoneNumber.phone) { notify({ message: 'Please provide phone number', type: 'error', }) return } else if (alertProvider === 'mail' && !email) { notify({ message: 'Please provide e-mail', type: 'error', }) return } const body = { mangoGroupPk: selectedMangoGroup.publicKey.toString(), marginAccountPk: selectedMarginAccount.publicKey.toString(), collateralRatioThresh, alertProvider, phoneNumber, email, } actions.createAlert(body) } return ( {tgCode && showTgCode ? ( ) : success ? (
{success}

{"We'll let you know if it's triggered."}

) : ( <>
X
Create Liquidation Alert{' '}
{marginAccounts.length > 0 ? ( <> {marginAccounts.length > 1 ? (
Margin Account
) : null}
Alert me when my collateral ratio is below:
{collateralRatioPreset === 'Custom' ? (
Custom collateral ratio
setCustomCollateralRatio(e.target.value)} suffix="%" />
) : null}
Alert me via:
setAlertProvider(val)} className="flex border border-th-fgd-4 rounded" > {({ checked }) => ( )} {({ checked }) => ( )} {({ checked }) => ( )}
{alertProvider === 'sms' ? ( <>
Mobile Number
setPhoneNumber({ phone: val, code: '' }) } /> ) : null} {alertProvider === 'mail' ? ( <>
Email
setEmail(e.target.value)} /> ) : null}
) : ( <>
No Margin Accounts Found

Make a deposit to initialize a margin account.

)} )}
) } export default AlertsModal const TelegramModal = ({ handleCloseModal, handleCopyToClipboard, handleNewFromTgCode, isCopied, tgCode, }) => { return (
Claim Your Alert in Telegram

This code will expire in 15 minutes

{tgCode}{' '}
handleCopyToClipboard(tgCode)} > {isCopied ? 'Copied!' : 'Copy'}
  1. Copy the code above
  2. Go to{' '} https://t.me/mango_alerts_bot
  3. Paste the code and send message
) }