Skip to content

Commit

Permalink
refactor: consolidate pay disabled logic (#4170)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomquirk authored Dec 7, 2023
1 parent 500d9a8 commit 80a92b4
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Trans } from '@lingui/macro'
import Banner from 'components/Banner'
import ExternalLink from 'components/ExternalLink'
import { useV2BlockedProject } from 'hooks/useBlockedProject'
import { useV2V3BlockedProject } from 'hooks/v2v3/useBlockedProject'

export function BlockedProjectBanner({ className }: { className?: string }) {
const isBlockedProject = useV2BlockedProject()
const isBlockedProject = useV2V3BlockedProject()
if (!isBlockedProject) return null

const delistingPolicyLink =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
import { Trans } from '@lingui/macro'
import { Button } from 'antd'
import { Button, Tooltip } from 'antd'
import { usePayProjectDisabled } from 'hooks/v2v3/usePayProjectDisabled'
import { useCartSummary } from '../hooks/useCartSummary'

export const SummaryPayButton = ({ className }: { className?: string }) => {
const { payProject, walletConnected } = useCartSummary()
const {
payDisabled,
message,
loading: payDisabledLoading,
} = usePayProjectDisabled()

return (
<Button className={className} type="primary" onClick={payProject}>
<span>
{walletConnected ? (
<Trans>Pay project</Trans>
) : (
<Trans>Connect wallet</Trans>
)}
</span>
</Button>
<Tooltip open={payDisabled ? undefined : false} title={message}>
<Button
disabled={payDisabled}
loading={payDisabledLoading}
className={className}
type="primary"
onClick={payProject}
>
<span>
{walletConnected ? (
<Trans>Pay project</Trans>
) : (
<Trans>Connect wallet to pay</Trans>
)}
</span>
</Button>
</Tooltip>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import { t } from '@lingui/macro'
import { Tooltip } from 'antd'
import { NftPreview } from 'components/NftRewards/NftPreview'
import { useProjectCart } from 'components/v2v3/V2V3Project/ProjectDashboard/hooks/useProjectCart'
import { useProjectContext } from 'components/v2v3/V2V3Project/ProjectDashboard/hooks/useProjectContext'
import { DEFAULT_NFT_MAX_SUPPLY } from 'constants/nftRewards'
import { useNftRewardsEnabledForPay } from 'hooks/JB721Delegate/useNftRewardsEnabledForPay'
import { useIsJuicecrowd } from 'hooks/v2v3/useIsJuiceCrowd'
import { usePayProjectDisabled } from 'hooks/v2v3/usePayProjectDisabled'
import { NftRewardTier } from 'models/nftRewards'
import { useMemo, useState } from 'react'
import { twMerge } from 'tailwind-merge'
import { ipfsUriToGatewayUrl } from 'utils/ipfs'
import { useProjectIsOFACListed } from '../../../hooks/useProjectIsOFACListed'
import { AddNftButton } from './AddNftButton'
import { NftDetails } from './NftDetails'
import { NftThumbnail } from './NftThumbnail'
Expand Down Expand Up @@ -40,27 +38,24 @@ export function NftReward({

const cart = useProjectCart()
const nftsEnabledForPay = useNftRewardsEnabledForPay()
const { fundingCycleMetadata } = useProjectContext()
const { isAddressListedInOFAC, isLoading: isOFACLoading } =
useProjectIsOFACListed()
const {
payDisabled,
message,
loading: payDisabledLoading,
} = usePayProjectDisabled()

const quantitySelected = useMemo(
() => cart.nftRewards.find(nft => nft.id === rewardTier?.id)?.quantity ?? 0,
[cart.nftRewards, rewardTier?.id],
)
const isSelected = quantitySelected > 0

const fileUrl = useMemo(
() =>
rewardTier?.fileUrl ? ipfsUriToGatewayUrl(rewardTier.fileUrl) : undefined,
[rewardTier?.fileUrl],
)

const isSelected = quantitySelected > 0

const openPreview = () => {
setPreviewVisible(true)
}

const remainingSupply = rewardTier?.remainingSupply
const hasRemainingSupply = remainingSupply && remainingSupply > 0
const remainingSupplyText = !hasRemainingSupply
Expand All @@ -69,39 +64,18 @@ export function NftReward({
? t`Unlimited`
: t`${rewardTier?.remainingSupply} remaining`

const isJuicecrowdNft = useIsJuicecrowd()

const disabled = useMemo(() => {
return (
!hasRemainingSupply ||
!nftsEnabledForPay ||
fundingCycleMetadata?.pausePay ||
(!isOFACLoading && isAddressListedInOFAC) ||
isJuicecrowdNft
)
}, [
hasRemainingSupply,
nftsEnabledForPay,
fundingCycleMetadata?.pausePay,
isAddressListedInOFAC,
isOFACLoading,
isJuicecrowdNft,
])
const disabled = Boolean(
!hasRemainingSupply || !nftsEnabledForPay || payDisabled,
)
const disabledReason = useMemo(() => {
if (!hasRemainingSupply) return t`Sold out`
if (!nftsEnabledForPay) return t`NFTs are not enabled for pay`
if (fundingCycleMetadata?.pausePay) return t`Payments are paused`
if (isJuicecrowdNft)
return t`This project's NFTs can only be purchased on juicecrowd.gg.`
if (isAddressListedInOFAC)
return t`NFTs can't be purchased because your wallet address failed the compliance check.`
}, [
isJuicecrowdNft,
nftsEnabledForPay,
hasRemainingSupply,
isAddressListedInOFAC,
fundingCycleMetadata?.pausePay,
])
if (payDisabled) return message
}, [nftsEnabledForPay, hasRemainingSupply, payDisabled, message])

const openPreview = () => {
setPreviewVisible(true)
}

return (
<>
Expand Down Expand Up @@ -131,7 +105,7 @@ export function NftReward({
/>
<NftDetails
rewardTier={rewardTier}
loading={loading}
loading={loading || payDisabledLoading}
hideAttributes={hideAttributes}
remainingSupplyText={remainingSupplyText}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,33 @@ import {
NoSymbolIcon,
QuestionMarkCircleIcon,
} from '@heroicons/react/24/outline'
import { Trans, t } from '@lingui/macro'
import { Trans } from '@lingui/macro'
import { Button, Tooltip } from 'antd'
import { usePayProjectCard } from 'components/v2v3/V2V3Project/ProjectDashboard/hooks/usePayProjectCard'
import { useProjectIsOFACListed } from 'components/v2v3/V2V3Project/ProjectDashboard/hooks/useProjectIsOFACListed'
import { Formik } from 'formik'
import { useV2BlockedProject } from 'hooks/useBlockedProject'
import { useIsJuicecrowd } from 'hooks/v2v3/useIsJuiceCrowd'
import {
PayDisabledReason,
usePayProjectDisabled,
} from 'hooks/v2v3/usePayProjectDisabled'
import { V2V3CurrencyOption } from 'models/v2v3/currencyOption'
import { useMemo } from 'react'
import { twMerge } from 'tailwind-merge'
import { V2V3_CURRENCY_ETH } from 'utils/v2v3/currency'
import { DisplayCard } from '../ui/DisplayCard'
import { PayInput } from './components/PayInput'
import { TokensPerEth } from './components/TokensPerEth'

export const PayProjectCard = ({ className }: { className?: string }) => {
const isBlockedProject = useV2BlockedProject()
const { isAddressListedInOFAC, isLoading: isOFACLoading } =
useProjectIsOFACListed()
const { validationSchema, paymentsPaused, addPay } = usePayProjectCard()
const determiningIfProjectCanReceivePayments = paymentsPaused === undefined

const isJuicecrowdProject = useIsJuicecrowd()

const isPaymentDisabled = useMemo(() => {
return (
paymentsPaused ||
isBlockedProject ||
(!isOFACLoading && isAddressListedInOFAC) ||
isJuicecrowdProject
)
}, [
isAddressListedInOFAC,
isOFACLoading,
paymentsPaused,
isBlockedProject,
isJuicecrowdProject,
])

const paymentTooltip = useMemo(() => {
if (paymentsPaused || isJuicecrowdProject) {
return {
title: t`Payments to this project are paused in this cycle.`,
open: undefined,
}
}

if (isAddressListedInOFAC) {
return {
title: t`You can't pay this project because your wallet address failed the compliance check.`,
open: undefined,
}
}

return {
open: false,
}
}, [paymentsPaused, isAddressListedInOFAC, isJuicecrowdProject])
const { validationSchema, addPay } = usePayProjectCard()
const { payDisabled, reason, message, loading } = usePayProjectDisabled()
const payButtonTooltip =
payDisabled && message
? {
title: message,
open: undefined,
}
: {
open: false,
}

return (
<DisplayCard
Expand All @@ -76,7 +45,10 @@ export const PayProjectCard = ({ className }: { className?: string }) => {
<QuestionMarkCircleIcon className="h-4 w-4 text-grey-500 dark:text-slate-200" />
</Tooltip>
</div>
{paymentsPaused || isJuicecrowdProject ? (
{reason &&
[PayDisabledReason.JUICECROWD, PayDisabledReason.PAUSED].includes(
reason,
) ? (
<div className="text-grey-600 dark:text-slate-200">
<div className="flex cursor-not-allowed items-center gap-2 rounded-lg bg-smoke-100 px-4 py-3 text-base leading-none dark:bg-slate-800">
<NoSymbolIcon className="h-5 w-5" />
Expand Down Expand Up @@ -111,10 +83,10 @@ export const PayProjectCard = ({ className }: { className?: string }) => {
onBlur={props.handleBlur}
name="payAmount"
/>
<Tooltip className="h-12" {...paymentTooltip}>
<Tooltip className="h-12" {...payButtonTooltip}>
<Button
loading={determiningIfProjectCanReceivePayments}
disabled={isPaymentDisabled}
loading={loading}
disabled={payDisabled}
htmlType="submit"
className="h-12 text-base"
style={{ height: '48px' }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,10 @@ export const ProjectTabs = ({ className }: { className?: string }) => {
const { projectOwnerAddress } = useProjectContext()
const isProjectOwner = useIsUserAddress(projectOwnerAddress)
const isJuicecrowd = useIsJuicecrowd()

const { value: hasNftRewards } = useHasNftRewards()

const showNftRewards = useMemo(() => {
// disable juicecrowd nft rewards
if (isJuicecrowd) {
return false
}

return hasNftRewards
}, [hasNftRewards, isJuicecrowd])
// disable juicecrowd nft rewards
const showNftRewards = isJuicecrowd ? false : hasNftRewards

const containerRef = useRef<HTMLDivElement>(null)
const panelRef = useRef<HTMLDivElement>(null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { RewardsList } from 'components/NftRewards/RewardsList/RewardsList'
import { useUpdateCurrentCollection } from 'components/v2v3/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/hooks/useUpdateCurrentCollection'
import { useHasNftRewards } from 'hooks/JB721Delegate/useHasNftRewards'
import { useIsJuicecrowd } from 'hooks/v2v3/useIsJuiceCrowd'
import { useCallback, useMemo, useState } from 'react'
import { useCallback, useState } from 'react'
import { TransactionSuccessModal } from '../../../TransactionSuccessModal'
import { useEditingNfts } from '../hooks/useEditingNfts'

Expand All @@ -17,21 +17,15 @@ export function EditNftsSection() {

const { rewardTiers, setRewardTiers, editedRewardTierIds, loading } =
useEditingNfts()
const { value: hasExistingNfts } = useHasNftRewards()
const { value: hasNftRewards } = useHasNftRewards()
const { updateExistingCollection, txLoading } = useUpdateCurrentCollection({
editedRewardTierIds,
rewardTiers,
onConfirmed: () => setSuccessModalOpen(true),
})
const isJuicecrowd = useIsJuicecrowd()
const showNftRewards = useMemo(() => {
// disable juicecrowd nft rewards
if (isJuicecrowd) {
return false
}

return hasExistingNfts
}, [hasExistingNfts, isJuicecrowd])
// disable juicecrowd nft rewards
const showNftRewards = isJuicecrowd ? false : hasNftRewards

const onNftFormSaved = useCallback(async () => {
if (!rewardTiers) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { PV_V2 } from 'constants/pv'
import { ProjectMetadataContext } from 'contexts/shared/ProjectMetadataContext'
import { useContext } from 'react'

export const useV2BlockedProject = () => {
export const useV2V3BlockedProject = () => {
const { projectId, pv } = useContext(ProjectMetadataContext)
const isBlockedProject = projectId
? V2_BLOCKLISTED_PROJECT_IDS.includes(projectId) && pv === PV_V2
: false

return isBlockedProject
}
Loading

2 comments on commit 80a92b4

@vercel
Copy link

@vercel vercel bot commented on 80a92b4 Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 80a92b4 Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.