import { useEffect, useMemo, useState, useCallback } from 'react' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import useMangoStore from '../stores/useMangoStore' import { mangoCacheSelector, mangoGroupConfigSelector, mangoGroupSelector, } from '../stores/selectors' import Button, { IconButton } from '../components/Button' import { abbreviateAddress, copyToClipboard, formatUsdValue, usdFormatter, } from '../utils' import { notify } from '../utils/notifications' import { getMarketIndexBySymbol, ReferrerIdRecord, } from '@blockworks-foundation/mango-client' import { useTranslation } from 'next-i18next' import EmptyState from '../components/EmptyState' import { CheckIcon, CurrencyDollarIcon, DuplicateIcon, LinkIcon, } from '@heroicons/react/solid' import { MngoMonoIcon } from '../components/icons' import Link from 'next/link' import { Table, TableDateDisplay, Td, Th, TrBody, TrHead, } from '../components/TableElements' import AccountsModal from '../components/AccountsModal' import { useViewport } from '../hooks/useViewport' import { breakpoints } from '../components/TradePageGrid' import { ExpandableRow } from '../components/TableElements' import MobileTableHeader from '../components/mobile/MobileTableHeader' import Input, { Label } from '../components/Input' import InlineNotification from '../components/InlineNotification' import useMangoAccount from '../hooks/useMangoAccount' import { handleWalletConnect } from 'components/ConnectWalletButton' import { useWallet } from '@solana/wallet-adapter-react' export async function getStaticProps({ locale }) { return { props: { ...(await serverSideTranslations(locale, [ 'common', 'delegate', 'referrals', 'profile', ])), // Will be passed to the page component as props }, } } export default function Referral() { const { t } = useTranslation(['common', 'referrals']) const mangoGroup = useMangoStore(mangoGroupSelector) const mangoCache = useMangoStore(mangoCacheSelector) const { mangoAccount } = useMangoAccount() const groupConfig = useMangoStore(mangoGroupConfigSelector) const actions = useMangoStore((s) => s.actions) const { wallet, connected } = useWallet() const referralHistory = useMangoStore((s) => s.referrals.history) const referralTotalAmount = useMangoStore((s) => s.referrals.total) const hasReferrals = referralHistory.length > 0 const [customRefLinkInput, setCustomRefLinkInput] = useState('') const [existingCustomRefLinks, setexistingCustomRefLinks] = useState< ReferrerIdRecord[] >([]) const [hasCopied, setHasCopied] = useState(null) const [showAccountsModal, setShowAccountsModal] = useState(false) // const [hasReferrals] = useState(false) // Placeholder to show/hide users referral stats const [loading, setLoading] = useState(false) const [inputError, setInputError] = useState('') const { width } = useViewport() const isMobile = width ? width < breakpoints.sm : false const fetchCustomReferralLinks = useCallback(async () => { if (!mangoAccount) return setLoading(true) const mangoClient = useMangoStore.getState().connection.client const referrerIds = await mangoClient.getReferrerIdsForMangoAccount( mangoAccount ) setexistingCustomRefLinks(referrerIds) setLoading(false) }, [mangoAccount]) const uniqueReferrals = useMemo( () => hasReferrals ? referralHistory.reduce( (resultSet, item) => resultSet.add(item['referree_mango_account']), new Set() ).size : 0, [hasReferrals] ) useEffect(() => { if (mangoAccount) { fetchCustomReferralLinks() } }, [mangoAccount]) useEffect(() => { let timer if (hasCopied) { timer = setTimeout(() => setHasCopied(null), 1000) } return () => { clearTimeout(timer) } }, [hasCopied]) useEffect(() => { if (mangoAccount) { actions.loadReferralData() } }, [mangoAccount]) const onChangeRefIdInput = (value) => { const id = value.replace(/ /g, '') setCustomRefLinkInput(id) if (id.length > 32) { setInputError(t('referrals:too-long-error')) } else { setInputError('') } } const validateRefIdInput = () => { if (customRefLinkInput.length >= 33) { setInputError(t('referrals:too-long-error')) } if (customRefLinkInput.length === 0) { setInputError(t('referrals:enter-referral-id')) } } const handleConnect = useCallback(() => { if (wallet) { handleWalletConnect(wallet) } }, [wallet]) const submitRefLink = async () => { let encodedRefLink: string try { encodedRefLink = encodeURIComponent(customRefLinkInput) } catch (e) { notify({ type: 'error', title: 'Invalid custom referral link', }) return } if (!inputError && mangoGroup && mangoAccount && wallet) { try { const mangoClient = useMangoStore.getState().connection.client const txid = await mangoClient.registerReferrerId( mangoGroup, mangoAccount, wallet.adapter, encodedRefLink ) notify({ txid, title: t('referrals:link-created'), }) fetchCustomReferralLinks() } catch (e) { notify({ type: 'error', title: t('referrals:link-not-created'), description: e.message, txid: e.txid, }) } } else return } const handleCopyLink = (link, index) => { copyToClipboard(link) setHasCopied(index) } const mngoIndex = getMarketIndexBySymbol(groupConfig, 'MNGO') const hasRequiredMngo = mangoGroup && mangoAccount && mangoCache ? mangoAccount .getUiDeposit( mangoCache.rootBankCache[mngoIndex], mangoGroup, mngoIndex ) .toNumber() >= 10000 : false const hasCustomRefLinks = existingCustomRefLinks && existingCustomRefLinks.length > 0 return (

{t('referrals:sow-seed')}

  • {t('referrals:earn-16')}
  • {t('referrals:program-details-1')}
  • {t('referrals:program-details-4')}
{connected ? ( mangoAccount ? ( <> {hasReferrals ? (

{t('referrals:your-referrals')}

{t('referrals:total-earnings')}
{formatUsdValue(referralTotalAmount)}
{t('referrals:total-referrals')}
{uniqueReferrals}
) : null}
{hasRequiredMngo ? (

{t('referrals:your-links')}

{!loading ? ( !hasCustomRefLinks ? (
{t('referrlals:link')} {t('referrlals:copy-link')}
{!isMobile ? ( ) : null}

{isMobile ? abbreviateAddress( mangoAccount.publicKey ) : `https://trade.mango.markets?ref=${mangoAccount.publicKey.toString()}`}

handleCopyLink( `https://trade.mango.markets?ref=${mangoAccount.publicKey.toString()}`, 1 ) } > {hasCopied === 1 ? ( ) : ( )}
) : ( {existingCustomRefLinks.map( (customRefs, index) => ( ) )}
{t('referrals:link')}
{t('referrals:copy-link')}
{!isMobile ? ( ) : null}

{isMobile ? customRefs.referrerId : `https://trade.mango.markets?ref=${customRefs.referrerId}`}

handleCopyLink( `https://trade.mango.markets?ref=${customRefs.referrerId}`, index + 1 ) } > {hasCopied === index + 1 ? ( ) : ( )}
) ) : (
)}
) : (

{t('referrals:10k-mngo')}

{t('referrals:buy-mngo')}
)}
{hasRequiredMngo ? (

{t('referrals:custom-links')}

{t('referrals:custom-links-limit')}

onChangeRefIdInput(e.target.value)} value={customRefLinkInput} disabled={existingCustomRefLinks.length === 5} /> {inputError ? (
) : null}
) : null}
{referralHistory.length > 0 ? (

{t('referrals:earnings-history')}

{!isMobile ? ( {referralHistory.map((ref) => { const pk = ref.referree_mango_account const acct = pk.slice(0, 5) + '…' + pk.slice(-5) return ( ) })}
{t('date')} {t('referrals:referee')}
{t('referrals:fee-earned')}
{acct} {usdFormatter(ref.referral_fee_accrual, 4)}
) : (
{referralHistory.map((ref, index) => (
{usdFormatter(ref.referral_fee_accrual, 4)}
} key={`${ref.referral_fee_accrual + index}`} panelTemplate={ <> } /> ))}
)}
) : null} ) : (
} onClickButton={() => setShowAccountsModal(true)} title={t('no-account-found')} disabled={!wallet || !mangoGroup} />
) ) : (
} onClickButton={handleConnect} title={t('connect-wallet')} />
)}
{showAccountsModal ? ( setShowAccountsModal(false)} isOpen={showAccountsModal} /> ) : null}
) }