-
-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: payouts in funding cycle history (#4356)
- Loading branch information
1 parent
9bafdf1
commit af95cb4
Showing
6 changed files
with
212 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 14 additions & 2 deletions
16
...rojectDashboard/components/CyclesPayoutsPanel/components/HistoricalConfigurationPanel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,30 @@ | ||
import { V2V3CurrencyOption } from 'models/v2v3/currencyOption' | ||
import { | ||
V2V3FundingCycle, | ||
V2V3FundingCycleMetadata, | ||
} from 'models/v2v3/fundingCycle' | ||
import { useHistoricalConfigurationPanel } from '../hooks/useConfigurationPanel/useHistoricalConfigurationPanel' | ||
import { ConfigurationPanel } from './ConfigurationPanel' | ||
import { HistoricalPayoutsData } from './HistoricalPayoutsData' | ||
|
||
type HistoricalConfigurationPanelProps = { | ||
export type HistoricalConfigurationPanelProps = { | ||
fundingCycle: V2V3FundingCycle | ||
metadata: V2V3FundingCycleMetadata | ||
withdrawnAmountAndCurrency: { | ||
amount: number | ||
currency: V2V3CurrencyOption | ||
} | ||
} | ||
|
||
export const HistoricalConfigurationPanel: React.FC< | ||
HistoricalConfigurationPanelProps | ||
> = p => { | ||
const props = useHistoricalConfigurationPanel(p) | ||
return <ConfigurationPanel {...props} /> | ||
|
||
return ( | ||
<div className="flex flex-col gap-8"> | ||
<ConfigurationPanel {...props} /> | ||
<HistoricalPayoutsData {...p} /> | ||
</div> | ||
) | ||
} |
115 changes: 115 additions & 0 deletions
115
...V2V3Project/ProjectDashboard/components/CyclesPayoutsPanel/components/HistoricalCycle.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { Disclosure, Transition } from '@headlessui/react' | ||
import { ChevronDownIcon } from '@heroicons/react/24/outline' | ||
import { useProjectMetadataContext } from 'contexts/shared/ProjectMetadataContext' | ||
import { BigNumber } from 'ethers' | ||
import { FundingCyclesQuery } from 'generated/graphql' | ||
import useProjectDistributionLimit from 'hooks/v2v3/contractReader/useProjectDistributionLimit' | ||
import { V2V3CurrencyOption } from 'models/v2v3/currencyOption' | ||
import moment from 'moment' | ||
import React, { Fragment, useMemo } from 'react' | ||
import { twMerge } from 'tailwind-merge' | ||
import { isBigNumberish } from 'utils/bigNumbers' | ||
import { formatCurrencyAmount } from 'utils/format/formatCurrencyAmount' | ||
import { fromWad } from 'utils/format/formatNumber' | ||
import { V2V3_CURRENCY_ETH } from 'utils/v2v3/currency' | ||
import { | ||
sgFCToV2V3FundingCycle, | ||
sgFCToV2V3FundingCycleMetadata, | ||
} from 'utils/v2v3/fundingCycle' | ||
import { useProjectContext } from '../../../hooks/useProjectContext' | ||
import { HistoricalConfigurationPanel } from './HistoricalConfigurationPanel' | ||
|
||
type QueriedFundingCycle = FundingCyclesQuery['fundingCycles'][number] | ||
|
||
const HistoricalCycle: React.FC<QueriedFundingCycle> = cycle => { | ||
const { projectId } = useProjectMetadataContext() | ||
const { primaryETHTerminal } = useProjectContext() | ||
|
||
const { data: distributionLimit } = useProjectDistributionLimit({ | ||
projectId, | ||
configuration: cycle.configuration.toString(), | ||
terminal: primaryETHTerminal, | ||
}) | ||
const currency = | ||
useMemo(() => { | ||
if (typeof distributionLimit === 'undefined') return | ||
|
||
if ( | ||
!(Array.isArray(distributionLimit) && distributionLimit.length === 2) | ||
) { | ||
console.error( | ||
'Unexpected result from distributionLimitOf', | ||
distributionLimit, | ||
) | ||
throw new Error('Unexpected result from distributionLimitOf') | ||
} | ||
|
||
const [, currency] = distributionLimit | ||
|
||
if (!isBigNumberish(currency)) { | ||
console.error( | ||
'Unexpected result from distributionLimitOf', | ||
distributionLimit, | ||
) | ||
throw new Error('Unexpected result from distributionLimitOf') | ||
} | ||
const _currencyOption = BigNumber.from(currency).toNumber() | ||
if (_currencyOption !== 0) return _currencyOption as V2V3CurrencyOption | ||
}, [distributionLimit]) ?? V2V3_CURRENCY_ETH | ||
|
||
const withdrawnAmountAndCurrency = { | ||
amount: parseFloat(fromWad(cycle.withdrawnAmount)), | ||
currency: currency, | ||
} | ||
|
||
return ( | ||
<Disclosure key={cycle.number} as={Fragment}> | ||
{({ open }) => ( | ||
<div className="p-4 pr-2"> | ||
<Disclosure.Button | ||
data-testid={`disclosure-button-${cycle.number}`} | ||
as="div" | ||
className="grid cursor-pointer grid-cols-config-table gap-3 whitespace-nowrap text-sm font-medium" | ||
> | ||
<div>#{cycle.number}</div> | ||
<div> | ||
<span> | ||
{formatCurrencyAmount(withdrawnAmountAndCurrency) ?? '0'} | ||
</span> | ||
</div> | ||
<div className="text-grey-500 dark:text-slate-200"> | ||
{`${moment( | ||
(cycle.startTimestamp + cycle.duration) * 1000, | ||
).fromNow(true)} ago`} | ||
</div> | ||
<div className="text-gray-500 flex items-center justify-end whitespace-nowrap text-sm"> | ||
<ChevronDownIcon | ||
className={twMerge(open && 'rotate-180', 'h-5 w-5')} | ||
/> | ||
</div> | ||
</Disclosure.Button> | ||
<Transition | ||
show={open} | ||
as={Fragment} | ||
enter="transition-all ease-in-out duration-300" | ||
enterFrom="max-h-0 overflow-hidden opacity-0" | ||
enterTo="max-h-[1000px] overflow-hidden opacity-100" | ||
leave="transition-all ease-in-out duration-300" | ||
leaveFrom="max-h-[1000px] overflow-hidden opacity-100" | ||
leaveTo="max-h-0 overflow-hidden opacity-0" | ||
> | ||
<Disclosure.Panel className="p-4"> | ||
<HistoricalConfigurationPanel | ||
fundingCycle={sgFCToV2V3FundingCycle(cycle)} | ||
metadata={sgFCToV2V3FundingCycleMetadata(cycle)} | ||
withdrawnAmountAndCurrency={withdrawnAmountAndCurrency} | ||
/> | ||
</Disclosure.Panel> | ||
</Transition> | ||
</div> | ||
)} | ||
</Disclosure> | ||
) | ||
} | ||
|
||
export default HistoricalCycle |
60 changes: 60 additions & 0 deletions
60
...oject/ProjectDashboard/components/CyclesPayoutsPanel/components/HistoricalPayoutsData.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import EthereumAddress from 'components/EthereumAddress' | ||
import { ETH_PAYOUT_SPLIT_GROUP } from 'constants/splits' | ||
import { ProjectMetadataContext } from 'contexts/shared/ProjectMetadataContext' | ||
import useProjectSplits from 'hooks/v2v3/contractReader/useProjectSplits' | ||
import round from 'lodash/round' | ||
import React, { useContext } from 'react' | ||
import { formatCurrencyAmount } from 'utils/format/formatCurrencyAmount' | ||
import { V2V3_CURRENCY_ETH } from 'utils/v2v3/currency' | ||
import { derivePayoutAmount } from 'utils/v2v3/distributions' | ||
import { ConfigurationPanelTableData } from './ConfigurationPanel' | ||
import { ConfigurationTable } from './ConfigurationTable' | ||
import { HistoricalConfigurationPanelProps } from './HistoricalConfigurationPanel' | ||
|
||
export const HistoricalPayoutsData: React.FC< | ||
HistoricalConfigurationPanelProps | ||
> = p => { | ||
const { projectId } = useContext(ProjectMetadataContext) | ||
|
||
const config = p.fundingCycle?.configuration?.toString() | ||
const { data: payoutSplits } = useProjectSplits({ | ||
projectId, | ||
splitGroup: ETH_PAYOUT_SPLIT_GROUP, | ||
domain: config, | ||
}) | ||
|
||
const currency = p.withdrawnAmountAndCurrency.currency | ||
const withdrawnAmount = p.withdrawnAmountAndCurrency.amount | ||
|
||
const payoutSplitsData = | ||
payoutSplits?.reduce<ConfigurationPanelTableData>((acc, split) => { | ||
const key = split.beneficiary ?? '' | ||
const payoutAmount = round( | ||
derivePayoutAmount({ | ||
payoutSplit: split, | ||
distributionLimit: withdrawnAmount, | ||
}), | ||
currency === V2V3_CURRENCY_ETH ? 4 : 2, | ||
) | ||
|
||
const formattedPayout = | ||
formatCurrencyAmount({ | ||
amount: payoutAmount, | ||
currency, | ||
}) ?? '0' | ||
|
||
acc[key] = { | ||
name: <EthereumAddress address={split.beneficiary} />, | ||
new: <span>{formattedPayout}</span>, | ||
} | ||
return acc | ||
}, {}) ?? {} | ||
|
||
return ( | ||
<> | ||
{payoutSplits && payoutSplits.length ? ( | ||
<ConfigurationTable title="Payouts" data={payoutSplitsData} /> | ||
) : null} | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.