Skip to content

Commit

Permalink
[PREVIEW] Better organise settings and create flow instances of the N…
Browse files Browse the repository at this point in the history
…FT form and related components
  • Loading branch information
johnnyd-eth committed Sep 13, 2023
1 parent 3621734 commit 2b5e79d
Show file tree
Hide file tree
Showing 27 changed files with 242 additions and 162 deletions.
4 changes: 2 additions & 2 deletions src/components/Create/Create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { NetworkName } from 'models/networkName'
import Link from 'next/link'
import { useRouter } from 'next/router'
import {
AddNftCollectionForm,
FundingCyclesPage,
NftRewardsPage,
ProjectDetailsPage,
ProjectTokenPage,
ReconfigurationRulesPage,
Expand Down Expand Up @@ -124,7 +124,7 @@ export function Create() {
<Trans>Reward your supporters with custom NFTs.</Trans>
}
>
<AddNftCollectionForm />
<NftRewardsPage />
</Wizard.Page>
<Wizard.Page
name="reconfigurationRules"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { AddNftCollectionForm } from 'components/NftRewards/AddNftCollectionForm'
import { CREATE_FLOW } from 'constants/fathomEvents'
import { trackFathomGoal } from 'lib/fathom'
import { useContext } from 'react'
import { useSetCreateFurthestPageReached } from 'redux/hooks/useEditingCreateFurthestPageReached'
import { Wizard } from '../../Wizard'
import { PageContext } from '../../Wizard/contexts/PageContext'
import { useCreateFlowNftRewardsForm } from './hooks'

export function NftRewardsPage() {
const { goToNextPage } = useContext(PageContext)

const { form, initialValues } = useCreateFlowNftRewardsForm()
useSetCreateFurthestPageReached('nftRewards')

return (
<AddNftCollectionForm
form={form}
initialValues={initialValues}
okButton={<Wizard.Page.ButtonControl />}
onFinish={() => {
goToNextPage?.()
trackFathomGoal(CREATE_FLOW.NFT_NEXT_CTA)
}}
/>
)
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './useNftRewardsForm'
export * from './useCreateFlowNftRewardsForm'
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Form } from 'antd'
import { NftRewardsFormProps } from 'components/NftRewards/AddNftCollectionForm'
import { JB721GovernanceType, NftRewardTier } from 'models/nftRewards'
import { useEffect, useMemo } from 'react'
import { useAppDispatch } from 'redux/hooks/useAppDispatch'
Expand All @@ -11,20 +12,7 @@ import {
} from 'utils/nftRewards'
import { useFormDispatchWatch } from '../../hooks'

type NftRewardsFormProps = Partial<{
rewards: NftRewardTier[]
collectionName?: string
collectionSymbol?: string
collectionDescription?: string
postPayMessage?: string
postPayButtonText?: string
postPayButtonLink?: string
onChainGovernance: JB721GovernanceType
useDataSourceForRedeem: boolean
preventOverspending: boolean
}>

export const useNftRewardsForm = () => {
export const useCreateFlowNftRewardsForm = () => {
const [form] = Form.useForm<NftRewardsFormProps>()
const {
collectionMetadata,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Create/components/pages/NftRewards/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './AddNftCollectionForm'
export * from './NftRewardsPage'
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { t } from '@lingui/macro'
import { RewardsList } from 'components/Create/components/RewardsList'
import { RewardsList } from 'components/NftRewards/RewardsList'
import { JB721GovernanceType, NftRewardTier } from 'models/nftRewards'
import { useCallback, useMemo } from 'react'
import { useAppDispatch } from 'redux/hooks/useAppDispatch'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,46 @@
import { RightOutlined } from '@ant-design/icons'
import { Trans, t } from '@lingui/macro'
import { Form, Radio } from 'antd'
import { Form, FormInstance, Radio } from 'antd'
import { useLockPageRulesWrapper } from 'components/Create/hooks/useLockPageRulesWrapper'
import ExternalLink from 'components/ExternalLink'
import TooltipLabel from 'components/TooltipLabel'
import { JuiceInput } from 'components/inputs/JuiceTextInput'
import { RadioItem } from 'components/inputs/RadioItem'
import { CREATE_FLOW } from 'constants/fathomEvents'
import { trackFathomGoal } from 'lib/fathom'
import { JB721GovernanceType } from 'models/nftRewards'
import { useContext } from 'react'
import { useSetCreateFurthestPageReached } from 'redux/hooks/useEditingCreateFurthestPageReached'
import { JB721GovernanceType, NftRewardTier } from 'models/nftRewards'
import { inputMustExistRule } from 'utils/antdRules'
import { helpPagePath } from 'utils/routes'
import { CreateBadge } from '../../CreateBadge'
import { CreateCollapse } from '../../CreateCollapse'
import { OptionalHeader } from '../../OptionalHeader'
import { RewardsList } from '../../RewardsList'
import { Wizard } from '../../Wizard'
import { PageContext } from '../../Wizard/contexts/PageContext'
import { CreateBadge } from '../../Create/components/CreateBadge'
import { CreateCollapse } from '../../Create/components/CreateCollapse'
import { OptionalHeader } from '../../Create/components/OptionalHeader'
import { RewardsList } from '../RewardsList'
import { NftAdvancedFormItems } from './NftAdvancedFormItems'
import { NftPaymentSuccessFormItems } from './NftPaymentSuccessFormItems'
import { useNftRewardsForm } from './hooks'

export type NftRewardsFormProps = Partial<{
rewards: NftRewardTier[]
collectionName?: string
collectionSymbol?: string
collectionDescription?: string
postPayMessage?: string
postPayButtonText?: string
postPayButtonLink?: string
onChainGovernance: JB721GovernanceType
useDataSourceForRedeem: boolean
preventOverspending: boolean
}>

export const AddNftCollectionForm = ({
form,
initialValues,
okButton,
onFinish,
}: {
okButton?: React.ReactNode
form: FormInstance<NftRewardsFormProps>
initialValues?: NftRewardsFormProps
okButton: React.ReactNode
onFinish?: VoidFunction
}) => {
useSetCreateFurthestPageReached('nftRewards')
const { form, initialValues } = useNftRewardsForm()
const lockPageRulesWrapper = useLockPageRulesWrapper()
const { goToNextPage } = useContext(PageContext)

const hasNfts = !!Form.useWatch('rewards', form)?.length

Expand All @@ -43,10 +52,7 @@ export const AddNftCollectionForm = ({
name="fundingCycles"
colon={false}
layout="vertical"
onFinish={() => {
goToNextPage?.()
trackFathomGoal(CREATE_FLOW.NFT_NEXT_CTA)
}}
onFinish={onFinish}
scrollToFirstError
>
<div className="flex flex-col gap-6">
Expand Down Expand Up @@ -171,7 +177,7 @@ export const AddNftCollectionForm = ({
</div>
)}
</div>
{okButton ?? <Wizard.Page.ButtonControl />}
{okButton}
</Form>

<div className="mt-8 text-center">
Expand Down
1 change: 1 addition & 0 deletions src/components/NftRewards/AddNftCollectionForm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './AddNftCollectionForm'
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import {
} from 'utils/antdRules'
import { withHttps } from 'utils/externalLink'
import { ipfsGatewayUrl } from 'utils/ipfs'
import { CreateCollapse } from '../CreateCollapse'
import { OptionalHeader } from '../OptionalHeader'
import { CreateCollapse } from '../../Create/components/CreateCollapse'
import { OptionalHeader } from '../../Create/components/OptionalHeader'

interface AddEditRewardModalFormProps {
fileUrl: string
Expand Down
2 changes: 1 addition & 1 deletion src/components/inputs/UploadNoStyle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { CloseCircleFilled, UploadOutlined } from '@ant-design/icons'
import { Trans, t } from '@lingui/macro'
import { Progress, Upload, UploadProps } from 'antd'
import { RcFile } from 'antd/lib/upload'
import { RewardImage } from 'components/Create/components/RewardImage'
import { JuiceVideoPreview } from 'components/JuiceVideo/JuiceVideoPreview'
import Loading from 'components/Loading'
import { RewardImage } from 'components/NftRewards/RewardImage'
import { CreateButton } from 'components/buttons/CreateButton'
import { useContentType } from 'hooks/useContentType'
import { FormItemInput } from 'models/formItemInput'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { t } from '@lingui/macro'
import { NEW_NFT_ID_LOWER_LIMIT } from 'components/Create/components/RewardsList/AddEditRewardModal'
import { NEW_NFT_ID_LOWER_LIMIT } from 'components/NftRewards/RewardsList/AddEditRewardModal'
import { JB721DelegateContractsContext } from 'contexts/NftRewards/JB721DelegateContracts/JB721DelegateContractsContext'
import { useAdjustTiersTx } from 'hooks/JB721Delegate/transactor/useAdjustTiersTx'
import { NftRewardTier } from 'models/nftRewards'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,49 @@
import { AddNftCollectionForm } from 'components/Create/components'
import { Trans } from '@lingui/macro'
import { AddNftCollectionForm } from 'components/NftRewards/AddNftCollectionForm'
import TransactionModal from 'components/modals/TransactionModal'
import { TransactionSuccessModal } from '../../../TransactionSuccessModal'
import { UploadAndLaunchNftsButton } from './UploadAndLaunchNftsButton'
import { useSettingsLaunchNftsForm } from './hooks/useSettingsLaunchNftsForm'

export function LaunchNftsPage() {
const {
form,
launchCollection,
launchButtonLoading,
launchTxPending,
successModalOpen,
setSuccessModalOpen,
} = useSettingsLaunchNftsForm()
return (
<AddNftCollectionForm
okButton={<UploadAndLaunchNftsButton className="mt-10" />}
/>
<>
<AddNftCollectionForm
form={form}
okButton={
<UploadAndLaunchNftsButton
className="mt-10"
onClick={() => launchCollection}
loading={launchButtonLoading}
/>
}
/>
<TransactionModal transactionPending open={launchTxPending} />
<TransactionSuccessModal
open={successModalOpen}
onClose={() => setSuccessModalOpen(false)}
content={
<>
<div className="w-80 pt-1 text-2xl font-medium">
<Trans>Your new NFTs have been deployed</Trans>
</div>
<div className="text-secondary pb-6">
<Trans>
New NFTs will be available in your next cycle as long as it
starts after your edit deadline.
</Trans>
</div>
</>
}
/>
</>
)
}
Original file line number Diff line number Diff line change
@@ -1,121 +1,23 @@
import { Trans } from '@lingui/macro'
import { Button } from 'antd'
import TransactionModal from 'components/modals/TransactionModal'
import { useState } from 'react'
import { useAppSelector } from 'redux/hooks/useAppSelector'
import { pinNftCollectionMetadata, pinNftRewards } from 'utils/nftRewards'
import { TransactionSuccessModal } from '../../../TransactionSuccessModal'
import {
EditingFundingCycleConfig,
useEditingFundingCycleConfig,
} from '../../ReconfigureFundingCycleSettingsPage/hooks/useEditingFundingCycleConfig'
import { useReconfigureFundingCycle } from '../../ReconfigureFundingCycleSettingsPage/hooks/useReconfigureFundingCycle'

export function UploadAndLaunchNftsButton({
className,
onClick,
loading,
}: {
className?: string
onClick?: VoidFunction
loading: boolean
}) {
const [ipfsUploading, setIpfsUploading] = useState<boolean>(false)
const [successModalOpen, setSuccessModalOpen] = useState<boolean>(false)

const {
projectMetadata: { logoUri },
} = useAppSelector(state => state.editingV2Project)

const editingFundingCycleConfig = useEditingFundingCycleConfig()
const { reconfigureLoading, reconfigureFundingCycle, txPending } =
useReconfigureFundingCycle({
editingFundingCycleConfig,
memo: 'First NFT collection',
launchedNewNfts: true,
onComplete: () => setSuccessModalOpen(true),
})

const buttonLoading = ipfsUploading || reconfigureLoading

const {
editingPayoutGroupedSplits,
editingReservedTokensGroupedSplits,
editingFundingCycleMetadata,
editingFundingCycleData,
editingFundAccessConstraints,
editingNftRewards,
editingMustStartAtOrAfter,
} = editingFundingCycleConfig

const uploadNftsToIpfs = async () => {
setIpfsUploading(true)
const newRewardTiers =
editingFundingCycleConfig.editingNftRewards?.rewardTiers
const collectionName =
editingFundingCycleConfig.editingNftRewards?.collectionMetadata.name ?? ''
const collectionDescription =
editingFundingCycleConfig.editingNftRewards?.collectionMetadata
.description ?? ''
const collectionLogoUri = logoUri ?? ''
const collectionInfoUri =
editingFundingCycleConfig.editingNftRewards?.collectionMetadata.uri ?? ''

const [rewardTiersCIDs, nftCollectionMetadataUri] = await Promise.all([
newRewardTiers ? pinNftRewards(newRewardTiers) : [],
pinNftCollectionMetadata({
collectionName,
collectionDescription,
collectionLogoUri,
collectionInfoUri,
}),
])
const latestEditingData: EditingFundingCycleConfig = {
editingPayoutGroupedSplits,
editingReservedTokensGroupedSplits,
editingFundingCycleMetadata,
editingFundingCycleData,
editingFundAccessConstraints,
editingNftRewards: editingNftRewards
? {
...editingNftRewards,
collectionMetadata: {
...editingNftRewards.collectionMetadata,
uri: nftCollectionMetadataUri,
},
CIDs: rewardTiersCIDs,
}
: undefined,
editingMustStartAtOrAfter,
}
reconfigureFundingCycle(latestEditingData)
setIpfsUploading(false)
}

return (
<>
<Button
type="primary"
onClick={uploadNftsToIpfs}
loading={buttonLoading}
className={className}
>
<Trans>Deploy NFT collection</Trans>
</Button>
<TransactionModal transactionPending open={txPending} />
<TransactionSuccessModal
open={successModalOpen}
onClose={() => setSuccessModalOpen(false)}
content={
<>
<div className="w-80 pt-1 text-2xl font-medium">
<Trans>Your new NFTs have been deployed</Trans>
</div>
<div className="text-secondary pb-6">
<Trans>
New NFTs will be available in your next cycle as long as it
starts after your edit deadline.
</Trans>
</div>
</>
}
/>
</>
<Button
type="primary"
onClick={onClick}
loading={loading}
className={className}
>
<Trans>Deploy NFT collection</Trans>
</Button>
)
}
Loading

0 comments on commit 2b5e79d

Please sign in to comment.