diff --git a/src/components/NftRewards/AddNftCollectionForm/AddNftCollectionForm.tsx b/src/components/NftRewards/AddNftCollectionForm/AddNftCollectionForm.tsx index 4fe7c335db..17252d33f6 100644 --- a/src/components/NftRewards/AddNftCollectionForm/AddNftCollectionForm.tsx +++ b/src/components/NftRewards/AddNftCollectionForm/AddNftCollectionForm.tsx @@ -4,10 +4,11 @@ import { Form, FormInstance } from 'antd' import ExternalLink from 'components/ExternalLink' import TooltipLabel from 'components/TooltipLabel' import { JuiceInput } from 'components/inputs/JuiceTextInput' -import { NftRewardTier } from 'models/nftRewards' +import { NftPostPayModalConfig, NftRewardTier } from 'models/nftRewards' import { CreateCollapse } from 'packages/v2v3/components/Create/components/CreateCollapse/CreateCollapse' import { OptionalHeader } from 'packages/v2v3/components/Create/components/OptionalHeader' import { useLockPageRulesWrapper } from 'packages/v2v3/components/Create/hooks/useLockPageRulesWrapper' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' import { inputMustExistRule } from 'utils/antdRules' import { RewardsList } from '../RewardsList/RewardsList' import { NftAdvancedFormItems } from './NftAdvancedFormItems' @@ -28,11 +29,15 @@ export type NftRewardsFormProps = Partial<{ export const AddNftCollectionForm = ({ form, initialValues, + postPayModalData, + nftRewardsData, okButton, onFinish, }: { form: FormInstance initialValues?: NftRewardsFormProps + postPayModalData: NftPostPayModalConfig | undefined + nftRewardsData: NftRewardsData okButton: React.ReactNode onFinish?: VoidFunction }) => { @@ -53,7 +58,7 @@ export const AddNftCollectionForm = ({ >
- + {hasNfts && ( @@ -122,7 +127,9 @@ export const AddNftCollectionForm = ({ header={} hideDivider > - + state.editingV2Project.nftRewards.postPayModal, - ) return ( <>
diff --git a/src/components/NftRewards/RewardsList/AddEditRewardModal.tsx b/src/components/NftRewards/RewardsList/AddEditRewardModal.tsx index 48ac10911f..eb45425d6c 100644 --- a/src/components/NftRewards/RewardsList/AddEditRewardModal.tsx +++ b/src/components/NftRewards/RewardsList/AddEditRewardModal.tsx @@ -20,7 +20,7 @@ import { DEFAULT_NFT_MAX_SUPPLY } from 'packages/v2v3/constants/nftRewards' import { V2V3_CURRENCY_USD } from 'packages/v2v3/utils/currency' import { UploadRequestOption } from 'rc-upload/lib/interface' import { useCallback, useEffect, useLayoutEffect, useState } from 'react' -import { useAppSelector } from 'redux/hooks/useAppSelector' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' import { inputIsIntegerRule, inputIsValidUrlRule, @@ -57,6 +57,7 @@ export const NEW_NFT_ID_LOWER_LIMIT = 1000000 export const AddEditRewardModal = ({ className, editingData, + nftRewards, open, onOk, onCancel, @@ -64,6 +65,7 @@ export const AddEditRewardModal = ({ }: { className?: string editingData?: NftRewardTier | undefined + nftRewards: NftRewardsData open?: boolean onOk: (reward: NftRewardTier) => void onCancel: VoidFunction @@ -74,7 +76,6 @@ export const AddEditRewardModal = ({ const [isReservingNfts, setIsReservingNfts] = useState(false) const [advancedOptionsOpen, setAdvancedOptionsOpen] = useState(false) - const { nftRewards } = useAppSelector(state => state.editingV2Project) const nftCurrency = nftRewards?.pricing.currency useLayoutEffect(() => { diff --git a/src/components/NftRewards/RewardsList/RewardItem.tsx b/src/components/NftRewards/RewardsList/RewardItem.tsx index 02e75f0b1b..0e5a64be6c 100644 --- a/src/components/NftRewards/RewardsList/RewardItem.tsx +++ b/src/components/NftRewards/RewardsList/RewardItem.tsx @@ -8,7 +8,7 @@ import round from 'lodash/round' import { NftRewardTier } from 'models/nftRewards' import { V2V3_CURRENCY_USD } from 'packages/v2v3/utils/currency' import { ReactNode } from 'react' -import { useAppSelector } from 'redux/hooks/useAppSelector' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' import { isZeroAddress } from 'utils/address' import { hasLimitedSupply } from 'utils/nftRewards' import { prettyUrl } from 'utils/url' @@ -28,10 +28,12 @@ function numberUpToPrecisionFormat( export const RewardItem = ({ reward, + nftRewards, onEditClicked, onDeleteClicked, }: { reward: NftRewardTier + nftRewards: NftRewardsData onEditClicked?: () => void onDeleteClicked?: () => void }) => { @@ -47,7 +49,6 @@ export const RewardItem = ({ fileUrl, } = reward - const { nftRewards } = useAppSelector(state => state.editingV2Project) const nftCurrency = nftRewards?.pricing.currency const hasBeneficiary = Boolean(beneficiary) && !isZeroAddress(beneficiary) diff --git a/src/components/NftRewards/RewardsList/RewardsList.tsx b/src/components/NftRewards/RewardsList/RewardsList.tsx index 3054187d74..305bb0f493 100644 --- a/src/components/NftRewards/RewardsList/RewardsList.tsx +++ b/src/components/NftRewards/RewardsList/RewardsList.tsx @@ -7,6 +7,7 @@ import { FormItemInput } from 'models/formItemInput' import { NftRewardTier } from 'models/nftRewards' import { MAX_NFT_REWARD_TIERS } from 'packages/v2v3/constants/nftRewards' import { createContext, useCallback, useContext, useState } from 'react' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' import { sortNftsByContributionFloor } from 'utils/nftRewards' import { AddEditRewardModal } from './AddEditRewardModal' import { RewardItem } from './RewardItem' @@ -32,6 +33,7 @@ const useRewardsInstance = () => { type RewardsListProps = FormItemInput & { allowCreate?: boolean withEditWarning?: boolean + nftRewardsData: NftRewardsData } interface RewardsListChildrenExports { @@ -45,6 +47,7 @@ export const RewardsList: React.FC> & value, onChange, withEditWarning, + nftRewardsData, }: RewardsListProps) => { const rewardsHook = useRewards({ value, onChange }) const [selectedReward, setSelectedReward] = useState() @@ -78,6 +81,7 @@ export const RewardsList: React.FC> & {sortNftsByContributionFloor(rewards).map((reward, i) => (
{ setSelectedReward(reward) @@ -110,6 +114,7 @@ export const RewardsList: React.FC> & { @@ -41,14 +41,14 @@ export const usePage = ({ name }: { name: string }) => { const lockPageProgress = useCallback(() => { dispatch( - editingV2ProjectActions.addCreateSoftLockedPage(name as CreatePage), + creatingV2ProjectActions.addCreateSoftLockedPage(name as CreatePage), ) }, [dispatch, name]) const unlockPageProgress = useCallback(() => { // We need to make sure pages can't unsoftlock other pages :\ dispatch( - editingV2ProjectActions.removeCreateSoftLockedPage(name as CreatePage), + creatingV2ProjectActions.removeCreateSoftLockedPage(name as CreatePage), ) }, [dispatch, name]) diff --git a/src/packages/v2v3/components/Create/components/Wizard/hooks/useSteps.ts b/src/packages/v2v3/components/Create/components/Wizard/hooks/useSteps.ts index 1947d1ff9c..cf35d259a1 100644 --- a/src/packages/v2v3/components/Create/components/Wizard/hooks/useSteps.ts +++ b/src/packages/v2v3/components/Create/components/Wizard/hooks/useSteps.ts @@ -21,7 +21,7 @@ export const useSteps = () => { const { pages, currentPage, goToPage } = useContext(WizardContext) const { furthestPageReached } = useEditingCreateFurthestPageReached() const softLockedPageQueue = useAppSelector( - state => state.editingV2Project.createSoftLockPageQueue, + state => state.creatingV2Project.createSoftLockPageQueue, ) const firstIndexOfLockedPage = useMemo(() => { diff --git a/src/packages/v2v3/components/Create/components/Wizard/hooks/useWizard.ts b/src/packages/v2v3/components/Create/components/Wizard/hooks/useWizard.ts index b14c816043..fb995801e9 100644 --- a/src/packages/v2v3/components/Create/components/Wizard/hooks/useWizard.ts +++ b/src/packages/v2v3/components/Create/components/Wizard/hooks/useWizard.ts @@ -13,7 +13,7 @@ export const useWizard = ({ children }: { children?: any[] }) => { const [currentPage, setCurrentPage] = useState('') const { furthestPageReached } = useEditingCreateFurthestPageReached() const softLockedPageQueue = useAppSelector( - state => state.editingV2Project.createSoftLockPageQueue, + state => state.creatingV2Project.createSoftLockPageQueue, ) const pages: PageProps[] = useMemo(() => { diff --git a/src/packages/v2v3/components/Create/components/pages/FundingCycles/hooks/useFundingCyclesForm.ts b/src/packages/v2v3/components/Create/components/pages/FundingCycles/hooks/useFundingCyclesForm.ts index 31f668ec79..0f3760b486 100644 --- a/src/packages/v2v3/components/Create/components/pages/FundingCycles/hooks/useFundingCyclesForm.ts +++ b/src/packages/v2v3/components/Create/components/pages/FundingCycles/hooks/useFundingCyclesForm.ts @@ -6,8 +6,8 @@ import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' import { DEFAULT_MUST_START_AT_OR_AFTER, - editingV2ProjectActions, -} from 'redux/slices/editingV2Project' + creatingV2ProjectActions, +} from 'redux/slices/creatingV2Project' import { deriveDurationUnit, otherUnitToSeconds, @@ -23,7 +23,7 @@ export type FundingCyclesFormProps = Partial<{ export const useFundingCyclesForm = () => { const [form] = useForm() const { fundingCycleData, fundingCyclesPageSelection, mustStartAtOrAfter } = - useAppSelector(state => state.editingV2Project) + useAppSelector(state => state.creatingV2Project) useDebugValue(form.getFieldsValue()) const initialValues: FundingCyclesFormProps | undefined = useMemo(() => { @@ -63,17 +63,17 @@ export const useFundingCyclesForm = () => { const launchDate = useWatch('launchDate', form) useEffect(() => { - dispatch(editingV2ProjectActions.setFundingCyclesPageSelection(selection)) + dispatch(creatingV2ProjectActions.setFundingCyclesPageSelection(selection)) // We need to handle manual case first as duration might be undefined, but // manual set. if (selection === 'manual') { - dispatch(editingV2ProjectActions.setDuration('0')) + dispatch(creatingV2ProjectActions.setDuration('0')) return } if (!selection || duration?.duration === undefined) { - dispatch(editingV2ProjectActions.setDuration('')) + dispatch(creatingV2ProjectActions.setDuration('')) return } if (selection === 'automated') { @@ -81,7 +81,7 @@ export const useFundingCyclesForm = () => { duration: duration.duration, unit: duration.unit, }) - dispatch(editingV2ProjectActions.setDuration(newDuration.toString())) + dispatch(creatingV2ProjectActions.setDuration(newDuration.toString())) return } }, [selection, duration, dispatch]) @@ -90,14 +90,14 @@ export const useFundingCyclesForm = () => { if (launchDate === undefined) return if (launchDate === null || !launchDate.unix().toString()) { dispatch( - editingV2ProjectActions.setMustStartAtOrAfter( + creatingV2ProjectActions.setMustStartAtOrAfter( DEFAULT_MUST_START_AT_OR_AFTER, ), ) return } dispatch( - editingV2ProjectActions.setMustStartAtOrAfter( + creatingV2ProjectActions.setMustStartAtOrAfter( launchDate?.unix().toString(), ), ) diff --git a/src/packages/v2v3/components/Create/components/pages/NftRewards/NftRewardsPage.tsx b/src/packages/v2v3/components/Create/components/pages/NftRewards/NftRewardsPage.tsx index 79b9e9612c..40aaf02b0b 100644 --- a/src/packages/v2v3/components/Create/components/pages/NftRewards/NftRewardsPage.tsx +++ b/src/packages/v2v3/components/Create/components/pages/NftRewards/NftRewardsPage.tsx @@ -2,6 +2,7 @@ import { AddNftCollectionForm } from 'components/NftRewards/AddNftCollectionForm import { CREATE_FLOW } from 'constants/fathomEvents' import { trackFathomGoal } from 'lib/fathom' import { useContext } from 'react' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { useSetCreateFurthestPageReached } from 'redux/hooks/useEditingCreateFurthestPageReached' import { Wizard } from '../../Wizard/Wizard' import { PageContext } from '../../Wizard/contexts/PageContext' @@ -11,12 +12,22 @@ export function NftRewardsPage() { const { goToNextPage } = useContext(PageContext) const { form, initialValues } = useCreateFlowNftRewardsForm() + + const postPayModalData = useAppSelector( + state => state.creatingV2Project.nftRewards.postPayModal, + ) + const nftRewardsData = useAppSelector( + state => state.creatingV2Project.nftRewards, + ) + useSetCreateFurthestPageReached('nftRewards') return ( } onFinish={() => { goToNextPage?.() diff --git a/src/packages/v2v3/components/Create/components/pages/NftRewards/hooks/useCreateFlowNftRewardsForm.ts b/src/packages/v2v3/components/Create/components/pages/NftRewards/hooks/useCreateFlowNftRewardsForm.ts index e308334d8a..4bd4f9a295 100644 --- a/src/packages/v2v3/components/Create/components/pages/NftRewards/hooks/useCreateFlowNftRewardsForm.ts +++ b/src/packages/v2v3/components/Create/components/pages/NftRewards/hooks/useCreateFlowNftRewardsForm.ts @@ -4,7 +4,7 @@ import { NftRewardTier } from 'models/nftRewards' import { useEffect, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { withHttps, withoutHttp } from 'utils/externalLink' import { defaultNftCollectionDescription, @@ -20,9 +20,9 @@ export const useCreateFlowNftRewardsForm = () => { postPayModal, governanceType, flags, - } = useAppSelector(state => state.editingV2Project.nftRewards) + } = useAppSelector(state => state.creatingV2Project.nftRewards) const { projectMetadata, fundingCycleMetadata } = useAppSelector( - state => state.editingV2Project, + state => state.creatingV2Project, ) const initialValues: NftRewardsFormProps = useMemo(() => { const collectionName = @@ -79,7 +79,7 @@ export const useCreateFlowNftRewardsForm = () => { fieldName: 'rewards', ignoreUndefined: true, // Needed to stop an infinite loop currentValue: rewardTiers, - dispatchFunction: editingV2ProjectActions.setNftRewardTiers, + dispatchFunction: creatingV2ProjectActions.setNftRewardTiers, formatter: v => { if (!v) return [] if (typeof v !== 'object') { @@ -106,7 +106,7 @@ export const useCreateFlowNftRewardsForm = () => { form, fieldName: 'collectionName', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setNftRewardsName, + dispatchFunction: creatingV2ProjectActions.setNftRewardsName, formatter: v => { if (!v || typeof v !== 'string') return '' return v @@ -117,7 +117,7 @@ export const useCreateFlowNftRewardsForm = () => { form, fieldName: 'collectionSymbol', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setNftRewardsSymbol, + dispatchFunction: creatingV2ProjectActions.setNftRewardsSymbol, formatter: v => { if (!v || typeof v !== 'string') return '' return v @@ -129,7 +129,7 @@ export const useCreateFlowNftRewardsForm = () => { fieldName: 'collectionDescription', ignoreUndefined: true, dispatchFunction: - editingV2ProjectActions.setNftRewardsCollectionDescription, + creatingV2ProjectActions.setNftRewardsCollectionDescription, formatter: v => { if (!v || typeof v !== 'string') return '' return v @@ -140,7 +140,7 @@ export const useCreateFlowNftRewardsForm = () => { form, fieldName: 'useDataSourceForRedeem', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setUseDataSourceForRedeem, + dispatchFunction: creatingV2ProjectActions.setUseDataSourceForRedeem, formatter: v => !!v, }) @@ -148,7 +148,7 @@ export const useCreateFlowNftRewardsForm = () => { form, fieldName: 'preventOverspending', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setNftPreventOverspending, + dispatchFunction: creatingV2ProjectActions.setNftPreventOverspending, formatter: v => !!v, }) @@ -178,11 +178,11 @@ export const useCreateFlowNftRewardsForm = () => { postPayButtonText === undefined && postPayButtonLink === undefined ) { - dispatch(editingV2ProjectActions.setNftPostPayModalConfig(undefined)) + dispatch(creatingV2ProjectActions.setNftPostPayModalConfig(undefined)) return } dispatch( - editingV2ProjectActions.setNftPostPayModalConfig({ + creatingV2ProjectActions.setNftPostPayModalConfig({ content: postPayMessage, ctaText: postPayButtonText, ctaLink: withHttps(postPayButtonLink), diff --git a/src/packages/v2v3/components/Create/components/pages/PayoutsPage/components/CreateFlowPayoutsTable.tsx b/src/packages/v2v3/components/Create/components/pages/PayoutsPage/components/CreateFlowPayoutsTable.tsx index 1cafe219a4..9139ad9b9b 100644 --- a/src/packages/v2v3/components/Create/components/pages/PayoutsPage/components/CreateFlowPayoutsTable.tsx +++ b/src/packages/v2v3/components/Create/components/pages/PayoutsPage/components/CreateFlowPayoutsTable.tsx @@ -7,9 +7,12 @@ import { getV2V3CurrencyOption, } from 'packages/v2v3/utils/currency' import { MAX_DISTRIBUTION_LIMIT } from 'packages/v2v3/utils/math' -import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v2v3/utils/splitToAllocation' import { ReactNode } from 'react' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { useCreatingDistributionLimit } from 'redux/hooks/v2v3/create' import { fromWad, parseWad } from 'utils/format/formatNumber' import { usePayoutsForm } from '../hooks/usePayoutsForm' @@ -31,7 +34,7 @@ export function CreateFlowPayoutsTable({ , setDistributionLimitAmount, setDistributionLimitCurrency, - ] = useEditingDistributionLimit() + ] = useCreatingDistributionLimit() const { form, initialValues } = usePayoutsForm() const distributionLimit = !editingDistributionLimit diff --git a/src/packages/v2v3/components/Create/components/pages/PayoutsPage/components/TreasuryOptionsRadio.tsx b/src/packages/v2v3/components/Create/components/pages/PayoutsPage/components/TreasuryOptionsRadio.tsx index 0389eae6df..0499a8dd47 100644 --- a/src/packages/v2v3/components/Create/components/pages/PayoutsPage/components/TreasuryOptionsRadio.tsx +++ b/src/packages/v2v3/components/Create/components/pages/PayoutsPage/components/TreasuryOptionsRadio.tsx @@ -8,9 +8,13 @@ import { useModal } from 'hooks/useModal' import { TreasurySelection } from 'models/treasurySelection' import { ConvertAmountsModal } from 'packages/v2v3/components/shared/PayoutsTable/ConvertAmountsModal' import { usePayoutsTable } from 'packages/v2v3/components/shared/PayoutsTable/hooks/usePayoutsTable' +import { + V2V3_CURRENCY_ETH, + V2V3_CURRENCY_USD, +} from 'packages/v2v3/utils/currency' import { useCallback, useEffect, useMemo, useState } from 'react' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { ReduxDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { ReduxDistributionLimit } from 'redux/hooks/v2v3/shared' import { fromWad } from 'utils/format/formatNumber' import { Icons } from '../../../Icons' import { RadioCard } from './RadioCard' @@ -23,15 +27,15 @@ const treasuryOptions = () => [ export function TreasuryOptionsRadio() { const initialTreasurySelection = useAppSelector( - state => state.editingV2Project.treasurySelection, + state => state.creatingV2Project.treasurySelection, ) - const [treasuryOption, setTreasuryOption] = useState( initialTreasurySelection ?? 'zero', ) const { distributionLimit, + currency, setDistributionLimit, payoutSplits, setCurrency, @@ -168,6 +172,7 @@ export function TreasuryOptionsRadio() { onOk={switchToAmountsPayoutSelection} onCancel={switchingToAmountsModal.close} splits={payoutSplits} + currency={currency === 'ETH' ? V2V3_CURRENCY_ETH : V2V3_CURRENCY_USD} /> ) diff --git a/src/packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections.ts b/src/packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections.ts index 993611ee99..1e2cc22d03 100644 --- a/src/packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections.ts +++ b/src/packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections.ts @@ -1,8 +1,8 @@ import { PayoutsSelection } from 'models/payoutsSelection' import { determineAvailablePayoutsSelections } from 'packages/v2v3/components/Create/utils/determineAvailablePayoutsSelections' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { useCreatingDistributionLimit } from 'redux/hooks/v2v3/create' export const useAvailablePayoutsSelections = (): Set => { - const [distributionLimit] = useEditingDistributionLimit() + const [distributionLimit] = useCreatingDistributionLimit() return determineAvailablePayoutsSelections(distributionLimit?.amount) } diff --git a/src/packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/usePayoutsForm.ts b/src/packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/usePayoutsForm.ts index 8a7b6c80fe..24edcf412a 100644 --- a/src/packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/usePayoutsForm.ts +++ b/src/packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/usePayoutsForm.ts @@ -1,11 +1,14 @@ import { Form } from 'antd' import { TreasurySelection } from 'models/treasurySelection' import { AllocationSplit } from 'packages/v2v3/components/shared/Allocation/Allocation' -import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v2v3/utils/splitToAllocation' import { useDebugValue, useEffect, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingPayoutSplits } from 'redux/hooks/useEditingPayoutSplits' +import { useCreatingPayoutSplits } from 'redux/hooks/v2v3/create' type PayoutsFormProps = Partial<{ selection: TreasurySelection @@ -14,8 +17,8 @@ type PayoutsFormProps = Partial<{ export const usePayoutsForm = () => { const [form] = Form.useForm() - const { treasurySelection } = useAppSelector(state => state.editingV2Project) - const [splits, setSplits] = useEditingPayoutSplits() + const { treasurySelection } = useAppSelector(state => state.creatingV2Project) + const [splits, setSplits] = useCreatingPayoutSplits() useDebugValue(form.getFieldsValue()) const initialValues: PayoutsFormProps | undefined = useMemo(() => { diff --git a/src/packages/v2v3/components/Create/components/pages/ProjectDetails/hooks/useProjectDetailsForm.ts b/src/packages/v2v3/components/Create/components/pages/ProjectDetails/hooks/useProjectDetailsForm.ts index 6bdefa459e..115903809a 100644 --- a/src/packages/v2v3/components/Create/components/pages/ProjectDetails/hooks/useProjectDetailsForm.ts +++ b/src/packages/v2v3/components/Create/components/pages/ProjectDetails/hooks/useProjectDetailsForm.ts @@ -8,8 +8,8 @@ import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' import { DEFAULT_MUST_START_AT_OR_AFTER, - editingV2ProjectActions, -} from 'redux/slices/editingV2Project' + creatingV2ProjectActions, +} from 'redux/slices/creatingV2Project' import { useFormDispatchWatch } from '../../hooks/useFormDispatchWatch' import { AmountInputValue } from '../ProjectDetailsPage' @@ -40,7 +40,7 @@ type ProjectDetailsFormProps = Partial<{ export const useProjectDetailsForm = () => { const [form] = useForm() const { projectMetadata, inputProjectOwner, mustStartAtOrAfter } = - useAppSelector(state => state.editingV2Project) + useAppSelector(state => state.creatingV2Project) const initialValues: ProjectDetailsFormProps = useMemo( () => ({ @@ -103,90 +103,90 @@ export const useProjectDetailsForm = () => { form, fieldName: 'projectName', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setName, + dispatchFunction: creatingV2ProjectActions.setName, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectTagline', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setProjectTagline, + dispatchFunction: creatingV2ProjectActions.setProjectTagline, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectDescription', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setDescription, + dispatchFunction: creatingV2ProjectActions.setDescription, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'tags', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setTags, + dispatchFunction: creatingV2ProjectActions.setTags, formatter: v => v ?? [], }) useFormDispatchWatch({ form, fieldName: 'logo', - dispatchFunction: editingV2ProjectActions.setLogoUri, + dispatchFunction: creatingV2ProjectActions.setLogoUri, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'coverImage', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setCoverImageUri, + dispatchFunction: creatingV2ProjectActions.setCoverImageUri, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectWebsite', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setInfoUri, + dispatchFunction: creatingV2ProjectActions.setInfoUri, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectTwitter', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setTwitter, + dispatchFunction: creatingV2ProjectActions.setTwitter, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectDiscord', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setDiscord, + dispatchFunction: creatingV2ProjectActions.setDiscord, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectTelegram', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setTelegram, + dispatchFunction: creatingV2ProjectActions.setTelegram, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'inputProjectOwner', ignoreUndefined: false, - dispatchFunction: editingV2ProjectActions.setInputProjectOwner, + dispatchFunction: creatingV2ProjectActions.setInputProjectOwner, formatter: v => v, }) useFormDispatchWatch({ form, fieldName: 'payButtonText', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setPayButton, + dispatchFunction: creatingV2ProjectActions.setPayButton, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'payDisclosure', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setPayDisclosure, + dispatchFunction: creatingV2ProjectActions.setPayDisclosure, formatter: v => v ?? '', }) @@ -194,21 +194,21 @@ export const useProjectDetailsForm = () => { form, fieldName: 'introVideoUrl', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setIntroVideoUrl, + dispatchFunction: creatingV2ProjectActions.setIntroVideoUrl, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'introImageUri', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setIntroImageUri, + dispatchFunction: creatingV2ProjectActions.setIntroImageUri, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'softTarget', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setSoftTarget, + dispatchFunction: creatingV2ProjectActions.setSoftTarget, formatter: v => v ?? { amount: '', currency: V2V3_CURRENCY_USD }, }) @@ -222,13 +222,13 @@ export const useProjectDetailsForm = () => { // check if launch date is in ms or seconds if (launchDate > 1000000000000) { dispatch( - editingV2ProjectActions.setMustStartAtOrAfter( + creatingV2ProjectActions.setMustStartAtOrAfter( (launchDate / 1000).toString(), ), ) } else { dispatch( - editingV2ProjectActions.setMustStartAtOrAfter(launchDate.toString()), + creatingV2ProjectActions.setMustStartAtOrAfter(launchDate.toString()), ) } }, [dispatch, startTimestamp]) diff --git a/src/packages/v2v3/components/Create/components/pages/ProjectToken/components/CustomTokenSettings/CustomTokenSettings.tsx b/src/packages/v2v3/components/Create/components/pages/ProjectToken/components/CustomTokenSettings/CustomTokenSettings.tsx index 1a245d56ef..4dca9f6920 100644 --- a/src/packages/v2v3/components/Create/components/pages/ProjectToken/components/CustomTokenSettings/CustomTokenSettings.tsx +++ b/src/packages/v2v3/components/Create/components/pages/ProjectToken/components/CustomTokenSettings/CustomTokenSettings.tsx @@ -17,7 +17,7 @@ import { formatFundingCycleDuration } from 'packages/v2v3/components/Create/util import { ReservedTokensList } from 'packages/v2v3/components/shared/ReservedTokensList' import { MAX_DISTRIBUTION_LIMIT, MAX_MINT_RATE } from 'packages/v2v3/utils/math' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { useCreatingDistributionLimit } from 'redux/hooks/v2v3/create' import { inputMustExistRule } from 'utils/antdRules' import { formatAmount } from 'utils/format/formatAmount' import * as ProjectTokenForm from '../../hooks/useProjectTokenForm' @@ -37,9 +37,9 @@ const calculateMintRateAfterDiscount = ({ export const CustomTokenSettings = () => { const isMobile = useMobile() const duration = useAppSelector( - state => state.editingV2Project.fundingCycleData.duration, + state => state.creatingV2Project.fundingCycleData.duration, ) - const [distributionLimit] = useEditingDistributionLimit() + const [distributionLimit] = useCreatingDistributionLimit() const form = Form.useFormInstance() const discountRate = Form.useWatch('discountRate', form) ?? diff --git a/src/packages/v2v3/components/Create/components/pages/ProjectToken/hooks/useProjectTokenForm.ts b/src/packages/v2v3/components/Create/components/pages/ProjectToken/hooks/useProjectTokenForm.ts index 9e743f07aa..0537cdb63c 100644 --- a/src/packages/v2v3/components/Create/components/pages/ProjectToken/hooks/useProjectTokenForm.ts +++ b/src/packages/v2v3/components/Create/components/pages/ProjectToken/hooks/useProjectTokenForm.ts @@ -14,13 +14,18 @@ import { redemptionRateFrom, reservedRateFrom, } from 'packages/v2v3/utils/math' -import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v2v3/utils/splitToAllocation' import { useDebugValue, useEffect, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' -import { useEditingReservedTokensSplits } from 'redux/hooks/useEditingReservedTokensSplits' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { + useCreatingDistributionLimit, + useCreatingReservedTokensSplits, +} from 'redux/hooks/v2v3/create' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { useFormDispatchWatch } from '../../hooks/useFormDispatchWatch' export type ProjectTokensFormProps = Partial<{ @@ -52,10 +57,10 @@ export const DefaultSettings: Required< export const useProjectTokensForm = () => { const [form] = Form.useForm() const { fundingCycleMetadata, fundingCycleData, projectTokensSelection } = - useAppSelector(state => state.editingV2Project) - const [tokenSplits] = useEditingReservedTokensSplits() + useAppSelector(state => state.creatingV2Project) + const [tokenSplits] = useCreatingReservedTokensSplits() useDebugValue(form.getFieldsValue()) - const [distributionLimit] = useEditingDistributionLimit() + const [distributionLimit] = useCreatingDistributionLimit() const redemptionRateDisabled = !distributionLimit || distributionLimit.amount.eq(MAX_DISTRIBUTION_LIMIT) @@ -117,15 +122,15 @@ export const useProjectTokensForm = () => { useEffect(() => { // We only want to update changes when selection is set if (selection === undefined) return - dispatch(editingV2ProjectActions.setProjectTokensSelection(selection)) + dispatch(creatingV2ProjectActions.setProjectTokensSelection(selection)) if (selection === 'default') { form.setFieldsValue({ ...DefaultSettings }) - dispatch(editingV2ProjectActions.setTokenSettings(DefaultSettings)) + dispatch(creatingV2ProjectActions.setTokenSettings(DefaultSettings)) return } dispatch( - editingV2ProjectActions.setTokenSettings({ + creatingV2ProjectActions.setTokenSettings({ ...DefaultSettings, ...form.getFieldsValue(), }), @@ -135,7 +140,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'initialMintRate', - dispatchFunction: editingV2ProjectActions.setWeight, + dispatchFunction: creatingV2ProjectActions.setWeight, formatter: v => { if (v === undefined || typeof v !== 'string') return issuanceRateFrom(DefaultSettings.initialMintRate) @@ -146,7 +151,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'reservedTokensPercentage', - dispatchFunction: editingV2ProjectActions.setReservedRate, + dispatchFunction: creatingV2ProjectActions.setReservedRate, formatter: v => { if (v === undefined || typeof v !== 'number') return reservedRateFrom( @@ -161,7 +166,7 @@ export const useProjectTokensForm = () => { fieldName: 'reservedTokenAllocation', ignoreUndefined: true, // Needed to stop an infinite loop currentValue: tokenSplits, // Needed to stop an infinite loop - dispatchFunction: editingV2ProjectActions.setReservedTokensSplits, + dispatchFunction: creatingV2ProjectActions.setReservedTokensSplits, formatter: v => { if (v === undefined || typeof v !== 'object') return [] return v.map(allocationToSplit) @@ -171,7 +176,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'discountRate', - dispatchFunction: editingV2ProjectActions.setDiscountRate, + dispatchFunction: creatingV2ProjectActions.setDiscountRate, formatter: v => { if (v === undefined || typeof v !== 'number') return discountRateFrom(DefaultSettings.discountRate).toHexString() @@ -182,7 +187,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'redemptionRate', - dispatchFunction: editingV2ProjectActions.setRedemptionRate, + dispatchFunction: creatingV2ProjectActions.setRedemptionRate, formatter: v => { if (v === undefined || typeof v !== 'number') return redemptionRateFrom(DefaultSettings.redemptionRate).toHexString() @@ -192,7 +197,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'redemptionRate', - dispatchFunction: editingV2ProjectActions.setBallotRedemptionRate, + dispatchFunction: creatingV2ProjectActions.setBallotRedemptionRate, formatter: v => { if (v === undefined || typeof v !== 'number') return redemptionRateFrom(DefaultSettings.redemptionRate).toHexString() @@ -203,7 +208,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'tokenMinting', - dispatchFunction: editingV2ProjectActions.setAllowMinting, + dispatchFunction: creatingV2ProjectActions.setAllowMinting, formatter: v => { if (typeof v !== 'boolean') return false return v @@ -213,7 +218,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'pauseTransfers', - dispatchFunction: editingV2ProjectActions.setPauseTransfers, + dispatchFunction: creatingV2ProjectActions.setPauseTransfers, ignoreUndefined: true, formatter: v => { if (typeof v !== 'boolean') return false diff --git a/src/packages/v2v3/components/Create/components/pages/ReconfigurationRules/hooks/useReconfigurationRulesForm.ts b/src/packages/v2v3/components/Create/components/pages/ReconfigurationRules/hooks/useReconfigurationRulesForm.ts index 23434ae661..92bd9755d7 100644 --- a/src/packages/v2v3/components/Create/components/pages/ReconfigurationRules/hooks/useReconfigurationRulesForm.ts +++ b/src/packages/v2v3/components/Create/components/pages/ReconfigurationRules/hooks/useReconfigurationRulesForm.ts @@ -6,7 +6,7 @@ import { useAvailableReconfigurationStrategies } from 'packages/v2v3/components/ import { useEffect, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { isEqualAddress, isZeroAddress } from 'utils/address' import { useFormDispatchWatch } from '../../hooks/useFormDispatchWatch' @@ -47,7 +47,7 @@ export const useReconfigurationRulesForm = () => { fundingCycleData: { ballot }, reconfigurationRuleSelection, fundingCycleMetadata, - } = useAppSelector(state => state.editingV2Project) + } = useAppSelector(state => state.creatingV2Project) const initialValues: ReconfigurationRulesFormProps | undefined = useMemo(() => { const pausePayments = fundingCycleMetadata.pausePay @@ -128,15 +128,17 @@ export const useReconfigurationRulesForm = () => { address = customAddress break } - dispatch(editingV2ProjectActions.setBallot(address ?? '')) - dispatch(editingV2ProjectActions.setReconfigurationRuleSelection(selection)) + dispatch(creatingV2ProjectActions.setBallot(address ?? '')) + dispatch( + creatingV2ProjectActions.setReconfigurationRuleSelection(selection), + ) }, [customAddress, dispatch, selection, strategies]) useFormDispatchWatch({ form, fieldName: 'pausePayments', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setPausePay, + dispatchFunction: creatingV2ProjectActions.setPausePay, formatter: v => !!v, }) @@ -144,7 +146,7 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'holdFees', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setHoldFees, + dispatchFunction: creatingV2ProjectActions.setHoldFees, formatter: v => !!v, }) @@ -152,7 +154,7 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'allowTerminalConfiguration', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setAllowSetTerminals, + dispatchFunction: creatingV2ProjectActions.setAllowSetTerminals, formatter: v => !!v, }) @@ -160,7 +162,7 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'allowControllerConfiguration', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setAllowSetController, + dispatchFunction: creatingV2ProjectActions.setAllowSetController, formatter: v => !!v, }) @@ -168,7 +170,7 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'allowTerminalMigration', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setAllowTerminalMigration, + dispatchFunction: creatingV2ProjectActions.setAllowTerminalMigration, formatter: v => !!v, }) @@ -176,14 +178,14 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'allowControllerMigration', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setAllowControllerMigration, + dispatchFunction: creatingV2ProjectActions.setAllowControllerMigration, formatter: v => !!v, }) useFormDispatchWatch({ form, fieldName: 'projectRequiredOFACCheck', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setRequiredOFACCheck, + dispatchFunction: creatingV2ProjectActions.setRequiredOFACCheck, formatter: v => v, }) diff --git a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/ReviewDeployPage.tsx b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/ReviewDeployPage.tsx index 12b411967e..cd06e55bb2 100644 --- a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/ReviewDeployPage.tsx +++ b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/ReviewDeployPage.tsx @@ -15,7 +15,7 @@ import { useCallback, useContext, useEffect, useMemo, useState } from 'react' import { useDispatch } from 'react-redux' import { useAppSelector } from 'redux/hooks/useAppSelector' import { useSetCreateFurthestPageReached } from 'redux/hooks/useEditingCreateFurthestPageReached' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { helpPagePath } from 'utils/helpPagePath' import { CreateBadge } from '../../CreateBadge' import { CreateCollapse } from '../../CreateCollapse/CreateCollapse' @@ -65,7 +65,7 @@ export const ReviewDeployPage = () => { const { deployProject, isDeploying, deployTransactionPending } = useDeployProject() const nftRewards = useAppSelector( - state => state.editingV2Project.nftRewards.rewardTiers, + state => state.creatingV2Project.nftRewards.rewardTiers, ) const nftRewardsAreSet = useMemo( @@ -78,7 +78,7 @@ export const ReviewDeployPage = () => { const handleStartOverClicked = useCallback(() => { router.push('/create') goToPage?.('projectDetails') - dispatch(editingV2ProjectActions.resetState()) + dispatch(creatingV2ProjectActions.resetState()) }, [dispatch, goToPage, router]) const onFinish = useCallback(async () => { diff --git a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/FundingConfigurationReview/hooks/useFundingConfigurationReview.ts b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/FundingConfigurationReview/hooks/useFundingConfigurationReview.ts index 83b7f6a8e3..2ef2f54203 100644 --- a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/FundingConfigurationReview/hooks/useFundingConfigurationReview.ts +++ b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/FundingConfigurationReview/hooks/useFundingConfigurationReview.ts @@ -3,19 +3,24 @@ import moment from 'moment' import { useAvailablePayoutsSelections } from 'packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections' import { formatFundingCycleDuration } from 'packages/v2v3/components/Create/utils/formatFundingCycleDuration' import { AllocationSplit } from 'packages/v2v3/components/shared/Allocation/Allocation' -import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v2v3/utils/splitToAllocation' import { useCallback, useMemo } from 'react' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' -import { useEditingPayoutSplits } from 'redux/hooks/useEditingPayoutSplits' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' +import { + useCreatingDistributionLimit, + useCreatingPayoutSplits, +} from 'redux/hooks/v2v3/create' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/creatingV2Project' import { formatFundingTarget } from 'utils/format/formatFundingTarget' export const useFundingConfigurationReview = () => { const { fundingCycleData, payoutsSelection, mustStartAtOrAfter } = - useAppSelector(state => state.editingV2Project) - const [distributionLimit] = useEditingDistributionLimit() - const [payoutSplits, setPayoutSplits] = useEditingPayoutSplits() + useAppSelector(state => state.creatingV2Project) + const [distributionLimit] = useCreatingDistributionLimit() + const [payoutSplits, setPayoutSplits] = useCreatingPayoutSplits() const fundingCycles = useMemo( () => (fundingCycleData.duration == '0' ? t`Manual` : t`Automated`), diff --git a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/ProjectDetailsReview/ProjectDetailsReview.tsx b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/ProjectDetailsReview/ProjectDetailsReview.tsx index b7b74c3504..d5ea262bc2 100644 --- a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/ProjectDetailsReview/ProjectDetailsReview.tsx +++ b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/ProjectDetailsReview/ProjectDetailsReview.tsx @@ -31,7 +31,7 @@ export const ProjectDetailsReview = () => { softTargetCurrency, }, inputProjectOwner, - } = useAppSelector(state => state.editingV2Project) + } = useAppSelector(state => state.creatingV2Project) const youtubeUrl = useMemo(() => { if (!introVideoUrl) return undefined diff --git a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/ProjectTokenReview/hooks/useProjectTokenReview.ts b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/ProjectTokenReview/hooks/useProjectTokenReview.ts index c5f4b5da21..5c6a1cf39d 100644 --- a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/ProjectTokenReview/hooks/useProjectTokenReview.ts +++ b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/ProjectTokenReview/hooks/useProjectTokenReview.ts @@ -1,8 +1,11 @@ import { AllocationSplit } from 'packages/v2v3/components/shared/Allocation/Allocation' -import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v2v3/utils/splitToAllocation' import { useCallback, useMemo } from 'react' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingReservedTokensSplits } from 'redux/hooks/useEditingReservedTokensSplits' +import { useCreatingReservedTokensSplits } from 'redux/hooks/v2v3/create' import { formatEnabled, formatPaused } from 'utils/format/formatBoolean' export const useProjectTokenReview = () => { @@ -14,8 +17,8 @@ export const useProjectTokenReview = () => { redemptionRate, global, }, - } = useAppSelector(state => state.editingV2Project) - const [tokenSplits, setTokenSplits] = useEditingReservedTokensSplits() + } = useAppSelector(state => state.creatingV2Project) + const [tokenSplits, setTokenSplits] = useCreatingReservedTokensSplits() const allocationSplits = useMemo( () => tokenSplits.map(splitToAllocation), diff --git a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx index 23c08e274d..fbfa22b23a 100644 --- a/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx +++ b/src/packages/v2v3/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx @@ -4,22 +4,21 @@ import { NftRewardTier } from 'models/nftRewards' import { useCallback, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { formatEnabled } from 'utils/format/formatBoolean' import { v4 } from 'uuid' import { ReviewDescription } from '../ReviewDescription' export const RewardsReview = () => { - const { - nftRewards: { rewardTiers, flags }, - fundingCycleMetadata, - } = useAppSelector(state => state.editingV2Project) + const { nftRewards: nftRewardsData, fundingCycleMetadata } = useAppSelector( + state => state.creatingV2Project, + ) const dispatch = useAppDispatch() const rewards: NftRewardTier[] = useMemo(() => { return ( - rewardTiers?.map(t => ({ + nftRewardsData.rewardTiers?.map(t => ({ id: parseInt(v4()), name: t.name, contributionFloor: t.contributionFloor, @@ -33,12 +32,12 @@ export const RewardsReview = () => { votingWeight: t.votingWeight, })) ?? [] ) - }, [rewardTiers]) + }, [nftRewardsData.rewardTiers]) const setRewards = useCallback( (rewards: NftRewardTier[]) => { dispatch( - editingV2ProjectActions.setNftRewardTiers( + creatingV2ProjectActions.setNftRewardTiers( rewards.map(reward => ({ contributionFloor: reward.contributionFloor, maxSupply: reward.maxSupply, @@ -63,12 +62,16 @@ export const RewardsReview = () => { }, [fundingCycleMetadata.useDataSourceForRedeem]) const preventOverspending = useMemo(() => { - return formatEnabled(flags.preventOverspending) - }, [flags.preventOverspending]) + return formatEnabled(nftRewardsData.flags.preventOverspending) + }, [nftRewardsData.flags.preventOverspending]) return (
- +
{ reconfigurationRuleSelection, fundingCycleMetadata, projectMetadata, - } = useAppSelector(state => state.editingV2Project) + } = useAppSelector(state => state.creatingV2Project) const pausePayments = useMemo(() => { return formatPaused(fundingCycleMetadata.pausePay) diff --git a/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useDeployNftProject.ts b/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useDeployNftProject.ts index 75ab2342d8..2b0fd1a462 100644 --- a/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useDeployNftProject.ts +++ b/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useDeployNftProject.ts @@ -2,13 +2,13 @@ import { TransactionCallbacks } from 'models/transaction' import { useLaunchProjectWithNftsTx } from 'packages/v2v3/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx' import { DEFAULT_JB_721_DELEGATE_VERSION } from 'packages/v2v3/hooks/defaultContracts/useDefaultJB721Delegate' import { useCallback, useMemo } from 'react' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { - useAppSelector, - useEditingV2V3FundAccessConstraintsSelector, - useEditingV2V3FundingCycleDataSelector, - useEditingV2V3FundingCycleMetadataSelector, -} from 'redux/hooks/useAppSelector' -import { DEFAULT_NFT_FLAGS } from 'redux/slices/editingV2Project' + useCreatingV2V3FundAccessConstraintsSelector, + useCreatingV2V3FundingCycleDataSelector, + useCreatingV2V3FundingCycleMetadataSelector, +} from 'redux/hooks/v2v3/create' +import { DEFAULT_NFT_FLAGS } from 'redux/slices/creatingV2Project' import { NFT_FUNDING_CYCLE_METADATA_OVERRIDES } from 'utils/nftFundingCycleMetadataOverrides' import { buildJB721TierParams } from 'utils/nftRewards' @@ -28,10 +28,10 @@ export const useDeployNftProject = () => { reservedTokensGroupedSplits, inputProjectOwner, mustStartAtOrAfter, - } = useAppSelector(state => state.editingV2Project) - const fundingCycleMetadata = useEditingV2V3FundingCycleMetadataSelector() - const fundingCycleData = useEditingV2V3FundingCycleDataSelector() - const fundAccessConstraints = useEditingV2V3FundAccessConstraintsSelector() + } = useAppSelector(state => state.creatingV2Project) + const fundingCycleMetadata = useCreatingV2V3FundingCycleMetadataSelector() + const fundingCycleData = useCreatingV2V3FundingCycleDataSelector() + const fundAccessConstraints = useCreatingV2V3FundAccessConstraintsSelector() const collectionName = useMemo( () => diff --git a/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useIsNftProject.ts b/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useIsNftProject.ts index 5d38d3d9d3..5dc9700221 100644 --- a/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useIsNftProject.ts +++ b/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useIsNftProject.ts @@ -6,7 +6,7 @@ import { useAppSelector } from 'redux/hooks/useAppSelector' * @returns Whether the project to be deployed is an NFT project. */ export const useIsNftProject = (): boolean => { - const { nftRewards } = useAppSelector(state => state.editingV2Project) + const { nftRewards } = useAppSelector(state => state.creatingV2Project) return useMemo( () => diff --git a/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useUploadNftRewards.ts b/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useUploadNftRewards.ts index 5b4193e286..2f795a20d1 100644 --- a/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useUploadNftRewards.ts +++ b/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/NFT/useUploadNftRewards.ts @@ -14,7 +14,7 @@ export const useUploadNftRewards = () => { const { nftRewards, projectMetadata: { name: projectName, logoUri, infoUri }, - } = useAppSelector(state => state.editingV2Project) + } = useAppSelector(state => state.creatingV2Project) return useCallback(async () => { if (!nftRewards?.rewardTiers || !nftRewards?.collectionMetadata) return diff --git a/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/useDeployStandardProject.ts b/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/useDeployStandardProject.ts index a3dc8d3be4..dc7cdfb971 100644 --- a/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/useDeployStandardProject.ts +++ b/src/packages/v2v3/components/Create/hooks/DeployProject/hooks/useDeployStandardProject.ts @@ -1,12 +1,12 @@ import { TransactionCallbacks } from 'models/transaction' import { useLaunchProjectTx } from 'packages/v2v3/hooks/transactor/useLaunchProjectTx' import { useCallback } from 'react' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { - useAppSelector, - useEditingV2V3FundAccessConstraintsSelector, - useEditingV2V3FundingCycleDataSelector, - useEditingV2V3FundingCycleMetadataSelector, -} from 'redux/hooks/useAppSelector' + useCreatingV2V3FundAccessConstraintsSelector, + useCreatingV2V3FundingCycleDataSelector, + useCreatingV2V3FundingCycleMetadataSelector, +} from 'redux/hooks/v2v3/create' /** * Hook that returns a function that deploys a project. @@ -22,10 +22,10 @@ export const useDeployStandardProject = () => { reservedTokensGroupedSplits, inputProjectOwner, mustStartAtOrAfter, - } = useAppSelector(state => state.editingV2Project) - const fundingCycleMetadata = useEditingV2V3FundingCycleMetadataSelector() - const fundingCycleData = useEditingV2V3FundingCycleDataSelector() - const fundAccessConstraints = useEditingV2V3FundAccessConstraintsSelector() + } = useAppSelector(state => state.creatingV2Project) + const fundingCycleMetadata = useCreatingV2V3FundingCycleMetadataSelector() + const fundingCycleData = useCreatingV2V3FundingCycleDataSelector() + const fundAccessConstraints = useCreatingV2V3FundAccessConstraintsSelector() const deployStandardProjectCallback = useCallback( async ({ diff --git a/src/packages/v2v3/components/Create/hooks/DeployProject/useDeployProject.ts b/src/packages/v2v3/components/Create/hooks/DeployProject/useDeployProject.ts index fa363ac619..7dfb5ccee4 100644 --- a/src/packages/v2v3/components/Create/hooks/DeployProject/useDeployProject.ts +++ b/src/packages/v2v3/components/Create/hooks/DeployProject/useDeployProject.ts @@ -4,13 +4,13 @@ import { uploadProjectMetadata } from 'lib/api/ipfs' import { TransactionCallbacks } from 'models/transaction' import { useCallback, useState } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { - useAppSelector, - useEditingV2V3FundAccessConstraintsSelector, - useEditingV2V3FundingCycleDataSelector, - useEditingV2V3FundingCycleMetadataSelector, -} from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' + useCreatingV2V3FundAccessConstraintsSelector, + useCreatingV2V3FundingCycleDataSelector, + useCreatingV2V3FundingCycleMetadataSelector, +} from 'redux/hooks/v2v3/create' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { emitErrorNotification } from 'utils/notifications' import { useDeployNftProject } from './hooks/NFT/useDeployNftProject' import { useIsNftProject } from './hooks/NFT/useIsNftProject' @@ -94,10 +94,10 @@ export const useDeployProject = () => { const { projectMetadata, nftRewards: { postPayModal }, - } = useAppSelector(state => state.editingV2Project) - const fundingCycleMetadata = useEditingV2V3FundingCycleMetadataSelector() - const fundingCycleData = useEditingV2V3FundingCycleDataSelector() - const fundAccessConstraints = useEditingV2V3FundAccessConstraintsSelector() + } = useAppSelector(state => state.creatingV2Project) + const fundingCycleMetadata = useCreatingV2V3FundingCycleMetadataSelector() + const fundingCycleData = useCreatingV2V3FundingCycleDataSelector() + const fundAccessConstraints = useCreatingV2V3FundAccessConstraintsSelector() const dispatch = useAppDispatch() @@ -138,7 +138,7 @@ export const useDeployProject = () => { } // Reset the project state - dispatch(editingV2ProjectActions.resetState()) + dispatch(creatingV2ProjectActions.resetState()) onProjectDeployed?.(projectId) }, onError: error => { diff --git a/src/packages/v2v3/components/Create/hooks/useLoadInitialStateFromQuery.ts b/src/packages/v2v3/components/Create/hooks/useLoadInitialStateFromQuery.ts index a2d3097086..ecd122f276 100644 --- a/src/packages/v2v3/components/Create/hooks/useLoadInitialStateFromQuery.ts +++ b/src/packages/v2v3/components/Create/hooks/useLoadInitialStateFromQuery.ts @@ -11,10 +11,10 @@ import { useEffect, useState } from 'react' import { useDispatch } from 'react-redux' import { DEFAULT_REDUX_STATE, - INITIAL_REDUX_STATE, - editingV2ProjectActions, -} from 'redux/slices/editingV2Project' -import { CreateState, ProjectState } from 'redux/slices/editingV2Project/types' + creatingV2ProjectActions, +} from 'redux/slices/creatingV2Project' +import { INITIAL_REDUX_STATE } from 'redux/slices/shared/v2ProjectInitialReduxState' +import { CreateState, ProjectState } from 'redux/slices/shared/v2ProjectTypes' import { isEqualAddress } from 'utils/address' import { parseWad } from 'utils/format/formatNumber' import { DefaultSettings as DefaultTokenSettings } from '../components/pages/ProjectToken/hooks/useProjectTokenForm' @@ -140,7 +140,7 @@ export function useLoadingInitialStateFromQuery() { parseCreateFlowStateFromInitialState(parsedInitialState) dispatch( - editingV2ProjectActions.setState({ + creatingV2ProjectActions.setState({ ...INITIAL_REDUX_STATE, ...createFlowState, ...parsedInitialState, diff --git a/src/packages/v2v3/components/Create/utils/projectTokenSettingsToReduxFormat.ts b/src/packages/v2v3/components/Create/utils/projectTokenSettingsToReduxFormat.ts index de6f55ff2d..fa7d98954e 100644 --- a/src/packages/v2v3/components/Create/utils/projectTokenSettingsToReduxFormat.ts +++ b/src/packages/v2v3/components/Create/utils/projectTokenSettingsToReduxFormat.ts @@ -5,7 +5,7 @@ import { reservedRateFrom, } from 'packages/v2v3/utils/math' import { allocationToSplit } from 'packages/v2v3/utils/splitToAllocation' -import { EMPTY_RESERVED_TOKENS_GROUPED_SPLITS } from 'redux/slices/editingV2Project' +import { EMPTY_RESERVED_TOKENS_GROUPED_SPLITS } from 'redux/slices/creatingV2Project' import { ProjectTokensFormProps } from '../components/pages/ProjectToken/hooks/useProjectTokenForm' export const projectTokenSettingsToReduxFormat = ( diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/hooks/useEditingFundingCycleConfig.ts b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/hooks/useEditingFundingCycleConfig.ts index 35b19119a5..5e367d14c4 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/hooks/useEditingFundingCycleConfig.ts +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/hooks/useEditingFundingCycleConfig.ts @@ -7,13 +7,13 @@ import { ETHPayoutGroupedSplits, ReservedTokensGroupedSplits, } from 'packages/v2v3/models/splits' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { - useAppSelector, useEditingV2V3FundAccessConstraintsSelector, useEditingV2V3FundingCycleDataSelector, useEditingV2V3FundingCycleMetadataSelector, -} from 'redux/hooks/useAppSelector' -import { NftRewardsData } from 'redux/slices/editingV2Project/types' +} from 'redux/hooks/v2v3/edit' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' export interface EditingFundingCycleConfig { editingPayoutGroupedSplits: ETHPayoutGroupedSplits diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/hooks/useInitialEditingData.ts b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/hooks/useInitialEditingData.ts index d2a9075db0..af2e688ea8 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/hooks/useInitialEditingData.ts +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/hooks/useInitialEditingData.ts @@ -25,7 +25,7 @@ import { DEFAULT_MUST_START_AT_OR_AFTER, editingV2ProjectActions, } from 'redux/slices/editingV2Project' -import { NftRewardsData } from 'redux/slices/editingV2Project/types' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' import useDeepCompareEffect from 'use-deep-compare-effect' import { fromWad } from 'utils/format/formatNumber' diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditCyclePage/EditCycleFormFields.ts b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditCyclePage/EditCycleFormFields.ts index 3d7940503d..92327b64fb 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditCyclePage/EditCycleFormFields.ts +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditCyclePage/EditCycleFormFields.ts @@ -1,7 +1,7 @@ import { DurationOption } from 'components/inputs/DurationInput' import { CurrencyName } from 'constants/currency' import { Split } from 'packages/v2v3/models/splits' -import { NftRewardsData } from 'redux/slices/editingV2Project/types' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' type DetailsSectionFields = { duration: number diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditCyclePage/hooks/usePrepareSaveEditCycleData.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditCyclePage/hooks/usePrepareSaveEditCycleData.tsx index 4153ce30b5..e2fc94eb6e 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditCyclePage/hooks/usePrepareSaveEditCycleData.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditCyclePage/hooks/usePrepareSaveEditCycleData.tsx @@ -20,7 +20,7 @@ import { import { BaseV3FundingCycleMetadataGlobal } from 'packages/v3/models/fundingCycle' import { useContext } from 'react' import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' -import { NftRewardsData } from 'redux/slices/editingV2Project/types' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' import { isZeroAddress } from 'utils/address' import { parseWad } from 'utils/format/formatNumber' import { otherUnitToSeconds } from 'utils/format/formatTime' diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/LaunchNftCollection/LaunchNftsCollection.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/LaunchNftCollection/LaunchNftsCollection.tsx index 29d144f9cd..3c7915e439 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/LaunchNftCollection/LaunchNftsCollection.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/LaunchNftCollection/LaunchNftsCollection.tsx @@ -2,6 +2,7 @@ import { Trans } from '@lingui/macro' import { Button } from 'antd' import { AddNftCollectionForm } from 'components/NftRewards/AddNftCollectionForm/AddNftCollectionForm' import TransactionModal from 'components/modals/TransactionModal' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { TransactionSuccessModal } from '../../../TransactionSuccessModal' import { useLaunchNftsForm } from './hooks/useLaunchNftsForm' @@ -14,10 +15,20 @@ export function LaunchNftsPage() { successModalOpen, setSuccessModalOpen, } = useLaunchNftsForm() + + const postPayModalData = useAppSelector( + state => state.creatingV2Project.nftRewards.postPayModal, + ) + const nftRewardsData = useAppSelector( + state => state.creatingV2Project.nftRewards, + ) + return ( <> state.editingV2Project.nftRewards.postPayModal, + ) + const editProjectDetailsTx = useEditProjectDetailsTx() const onProjectFormSaved = useCallback(async () => { @@ -82,7 +87,10 @@ export function EditNftsPostPaySection() { return (
- + diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/UpdateNftsPage/EditNftsSection.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/UpdateNftsPage/EditNftsSection.tsx index 5871a499f9..00aa83ea6e 100644 --- a/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/UpdateNftsPage/EditNftsSection.tsx +++ b/src/packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/UpdateNftsPage/EditNftsSection.tsx @@ -7,12 +7,16 @@ import { RewardsList } from 'components/NftRewards/RewardsList/RewardsList' import { useUpdateCurrentCollection } from 'packages/v2v3/components/V2V3Project/V2V3ProjectSettings/pages/EditNftsPage/hooks/useUpdateCurrentCollection' import { useHasNftRewards } from 'packages/v2v3/hooks/JB721Delegate/useHasNftRewards' import { useCallback, useState } from 'react' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { useEditingFundingCycleConfig } from '../../../hooks/useEditingFundingCycleConfig' import { useReconfigureFundingCycle } from '../../../hooks/useReconfigureFundingCycle' import { TransactionSuccessModal } from '../../../TransactionSuccessModal' import { useEditingNfts } from '../hooks/useEditingNfts' export function EditNftsSection() { + const nftRewardsData = useAppSelector( + state => state.editingV2Project.nftRewards, + ) const [submitLoading, setSubmitLoading] = useState(false) const [successModalOpen, setSuccessModalOpen] = useState(false) @@ -64,6 +68,7 @@ export function EditNftsSection() {
void onCancel: VoidFunction splits: Split[] + currency: V2V3CurrencyOption | undefined }) => { - const [distributionLimit] = useEditingDistributionLimit() const [newDistributionLimit, setNewDistributionLimit] = useState('') const [currency, setCurrency] = useState( - distributionLimit?.currency ?? V2V3_CURRENCY_ETH, + c ?? V2V3_CURRENCY_ETH, ) const totalPayoutsPercent = useMemo( diff --git a/src/packages/v2v3/components/shared/PayoutsTable/PayoutTableSettings.tsx b/src/packages/v2v3/components/shared/PayoutsTable/PayoutTableSettings.tsx index 91f21f5d1d..5571cb575d 100644 --- a/src/packages/v2v3/components/shared/PayoutsTable/PayoutTableSettings.tsx +++ b/src/packages/v2v3/components/shared/PayoutsTable/PayoutTableSettings.tsx @@ -4,8 +4,12 @@ import { SwitchToUnlimitedModal } from 'components/PayoutsTable/SwitchToUnlimite import { PopupMenu, PopupMenuItem } from 'components/ui/PopupMenu' import { handleConfirmationDeletion } from 'hooks/emitConfirmationDeletionModal' import { ConvertAmountsModal } from 'packages/v2v3/components/shared/PayoutsTable/ConvertAmountsModal' +import { + V2V3_CURRENCY_ETH, + V2V3_CURRENCY_USD, +} from 'packages/v2v3/utils/currency' import { useState } from 'react' -import { ReduxDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { ReduxDistributionLimit } from 'redux/hooks/v2v3/shared' import { fromWad } from 'utils/format/formatNumber' import { usePayoutsTable } from './hooks/usePayoutsTable' @@ -20,6 +24,7 @@ export function PayoutTableSettings() { const { payoutSplits, + currency, distributionLimitIsInfinite, handleDeleteAllPayoutSplits, setDistributionLimit, @@ -103,6 +108,7 @@ export function PayoutTableSettings() { onOk={handleSwitchToLimitedPayouts} onCancel={() => setSwitchToLimitedModalOpen(false)} splits={payoutSplits} + currency={currency === 'ETH' ? V2V3_CURRENCY_ETH : V2V3_CURRENCY_USD} /> ) diff --git a/src/packages/v2v3/components/shared/PayoutsTable/context/PayoutsTableContext.tsx b/src/packages/v2v3/components/shared/PayoutsTable/context/PayoutsTableContext.tsx index 3ee6000eba..7f5a04622c 100644 --- a/src/packages/v2v3/components/shared/PayoutsTable/context/PayoutsTableContext.tsx +++ b/src/packages/v2v3/components/shared/PayoutsTable/context/PayoutsTableContext.tsx @@ -9,6 +9,7 @@ export interface PayoutsTableContextProps { setCurrency?: (currency: CurrencyName) => void distributionLimit: number | undefined setDistributionLimit?: (distributionLimit: number | undefined) => void + hideExplaination?: boolean hideHeader?: boolean showAvatars?: boolean diff --git a/src/packages/v2v3/contexts/NftRewards/NftRewardsContext.ts b/src/packages/v2v3/contexts/NftRewards/NftRewardsContext.ts index 8bfd7394fc..a7d72df221 100644 --- a/src/packages/v2v3/contexts/NftRewards/NftRewardsContext.ts +++ b/src/packages/v2v3/contexts/NftRewards/NftRewardsContext.ts @@ -4,8 +4,8 @@ import { DEFAULT_NFT_FLAGS, DEFAULT_NFT_PRICING, EMPTY_NFT_COLLECTION_METADATA, -} from 'redux/slices/editingV2Project' -import { NftRewardsData } from 'redux/slices/editingV2Project/types' +} from 'redux/slices/shared/v2ProjectDefaultState' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' type NftRewardsContextType = { nftRewards: NftRewardsData diff --git a/src/packages/v2v3/contexts/NftRewards/NftRewardsProvider.tsx b/src/packages/v2v3/contexts/NftRewards/NftRewardsProvider.tsx index b4a4443a76..9a45761c0d 100644 --- a/src/packages/v2v3/contexts/NftRewards/NftRewardsProvider.tsx +++ b/src/packages/v2v3/contexts/NftRewards/NftRewardsProvider.tsx @@ -12,7 +12,7 @@ import { DEFAULT_NFT_FLAGS, DEFAULT_NFT_PRICING, EMPTY_NFT_COLLECTION_METADATA, -} from 'redux/slices/editingV2Project' +} from 'redux/slices/shared/v2ProjectDefaultState' import { CIDsOfNftRewardTiersResponse } from 'utils/nftRewards' import { JB721DelegateContractsContext } from './JB721DelegateContracts/JB721DelegateContractsContext' diff --git a/src/packages/v2v3/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx.ts b/src/packages/v2v3/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx.ts index facc3450c3..26d352af87 100644 --- a/src/packages/v2v3/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx.ts +++ b/src/packages/v2v3/hooks/JB721Delegate/transactor/useLaunchProjectWithNftsTx.ts @@ -29,11 +29,9 @@ import { V2V3FundingCycleData, } from 'packages/v2v3/models/fundingCycle' import { GroupedSplits, SplitGroup } from 'packages/v2v3/models/splits' -import { - isValidMustStartAtOrAfter -} from 'packages/v2v3/utils/fundingCycle' +import { isValidMustStartAtOrAfter } from 'packages/v2v3/utils/fundingCycle' import { useContext } from 'react' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' import { buildDeployTiered721DelegateData } from 'utils/nftRewards' import { useJB721DelegateContractAddress } from '../contracts/useJB721DelegateContractAddress' import { useJBTiered721DelegateProjectDeployer } from '../contracts/useJBTiered721DelegateProjectDeployer' diff --git a/src/packages/v2v3/hooks/JB721Delegate/transactor/useReconfigureV2V3FundingCycleWithNftsTx.ts b/src/packages/v2v3/hooks/JB721Delegate/transactor/useReconfigureV2V3FundingCycleWithNftsTx.ts index de53a7fbdd..be155aad2c 100644 --- a/src/packages/v2v3/hooks/JB721Delegate/transactor/useReconfigureV2V3FundingCycleWithNftsTx.ts +++ b/src/packages/v2v3/hooks/JB721Delegate/transactor/useReconfigureV2V3FundingCycleWithNftsTx.ts @@ -24,8 +24,8 @@ import { GroupedSplits, SplitGroup } from 'packages/v2v3/models/splits' import { V2V3_CURRENCY_ETH } from 'packages/v2v3/utils/currency' import { isValidMustStartAtOrAfter } from 'packages/v2v3/utils/fundingCycle' import { useContext } from 'react' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' -import { NftRewardsData } from 'redux/slices/editingV2Project/types' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' +import { NftRewardsData } from 'redux/slices/shared/v2ProjectTypes' import { buildDeployTiered721DelegateData, buildJB721TierParams, diff --git a/src/packages/v2v3/hooks/transactor/useLaunchProjectTx.ts b/src/packages/v2v3/hooks/transactor/useLaunchProjectTx.ts index 092e850a70..d41bb30766 100644 --- a/src/packages/v2v3/hooks/transactor/useLaunchProjectTx.ts +++ b/src/packages/v2v3/hooks/transactor/useLaunchProjectTx.ts @@ -13,11 +13,9 @@ import { V2V3FundingCycleMetadata, } from 'packages/v2v3/models/fundingCycle' import { GroupedSplits, SplitGroup } from 'packages/v2v3/models/splits' -import { - isValidMustStartAtOrAfter -} from 'packages/v2v3/utils/fundingCycle' +import { isValidMustStartAtOrAfter } from 'packages/v2v3/utils/fundingCycle' import { useContext } from 'react' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' import { useV2ProjectTitle } from '../useProjectTitle' export interface LaunchV2V3ProjectData { diff --git a/src/packages/v2v3/hooks/transactor/useReconfigureV2V3FundingCycleTx.ts b/src/packages/v2v3/hooks/transactor/useReconfigureV2V3FundingCycleTx.ts index ca4b0c94ac..68b0e7d0fb 100644 --- a/src/packages/v2v3/hooks/transactor/useReconfigureV2V3FundingCycleTx.ts +++ b/src/packages/v2v3/hooks/transactor/useReconfigureV2V3FundingCycleTx.ts @@ -6,7 +6,7 @@ import { TransactorInstance } from 'hooks/useTransactor' import { V2V3ProjectContractsContext } from 'packages/v2v3/contexts/ProjectContracts/V2V3ProjectContractsContext' import { isValidMustStartAtOrAfter } from 'packages/v2v3/utils/fundingCycle' import { useContext } from 'react' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' import { useV2ProjectTitle } from '../useProjectTitle' import { LaunchV2V3ProjectData } from './useLaunchProjectTx' diff --git a/src/packages/v4/components/Create/components/Wizard/hooks/usePage.ts b/src/packages/v4/components/Create/components/Wizard/hooks/usePage.ts index ca1573a61b..164f6bc00f 100644 --- a/src/packages/v4/components/Create/components/Wizard/hooks/usePage.ts +++ b/src/packages/v4/components/Create/components/Wizard/hooks/usePage.ts @@ -1,7 +1,7 @@ import { CreatePage } from 'models/createPage' import { useCallback, useContext, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { WizardContext } from '../contexts/WizardContext' export const usePage = ({ name }: { name: string }) => { @@ -41,14 +41,14 @@ export const usePage = ({ name }: { name: string }) => { const lockPageProgress = useCallback(() => { dispatch( - editingV2ProjectActions.addCreateSoftLockedPage(name as CreatePage), + creatingV2ProjectActions.addCreateSoftLockedPage(name as CreatePage), ) }, [dispatch, name]) const unlockPageProgress = useCallback(() => { // We need to make sure pages can't unsoftlock other pages :\ dispatch( - editingV2ProjectActions.removeCreateSoftLockedPage(name as CreatePage), + creatingV2ProjectActions.removeCreateSoftLockedPage(name as CreatePage), ) }, [dispatch, name]) diff --git a/src/packages/v4/components/Create/components/Wizard/hooks/useSteps.ts b/src/packages/v4/components/Create/components/Wizard/hooks/useSteps.ts index 89862b1bdc..a777e09d0b 100644 --- a/src/packages/v4/components/Create/components/Wizard/hooks/useSteps.ts +++ b/src/packages/v4/components/Create/components/Wizard/hooks/useSteps.ts @@ -22,7 +22,7 @@ export const useSteps = () => { const { pages, currentPage, goToPage } = useContext(WizardContext) const { furthestPageReached } = useEditingCreateFurthestPageReached() const softLockedPageQueue = useAppSelector( - state => state.editingV2Project.createSoftLockPageQueue, + state => state.creatingV2Project.createSoftLockPageQueue, ) const firstIndexOfLockedPage = useMemo(() => { diff --git a/src/packages/v4/components/Create/components/Wizard/hooks/useWizard.ts b/src/packages/v4/components/Create/components/Wizard/hooks/useWizard.ts index b14c816043..fb995801e9 100644 --- a/src/packages/v4/components/Create/components/Wizard/hooks/useWizard.ts +++ b/src/packages/v4/components/Create/components/Wizard/hooks/useWizard.ts @@ -13,7 +13,7 @@ export const useWizard = ({ children }: { children?: any[] }) => { const [currentPage, setCurrentPage] = useState('') const { furthestPageReached } = useEditingCreateFurthestPageReached() const softLockedPageQueue = useAppSelector( - state => state.editingV2Project.createSoftLockPageQueue, + state => state.creatingV2Project.createSoftLockPageQueue, ) const pages: PageProps[] = useMemo(() => { diff --git a/src/packages/v4/components/Create/components/pages/FundingCycles/hooks/useFundingCyclesForm.ts b/src/packages/v4/components/Create/components/pages/FundingCycles/hooks/useFundingCyclesForm.ts index 50593d7694..bbebd8ff6d 100644 --- a/src/packages/v4/components/Create/components/pages/FundingCycles/hooks/useFundingCyclesForm.ts +++ b/src/packages/v4/components/Create/components/pages/FundingCycles/hooks/useFundingCyclesForm.ts @@ -6,8 +6,8 @@ import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' import { DEFAULT_MUST_START_AT_OR_AFTER, - editingV2ProjectActions, -} from 'redux/slices/editingV2Project' + creatingV2ProjectActions, +} from 'redux/slices/creatingV2Project' import { deriveDurationUnit, otherUnitToSeconds, @@ -23,7 +23,7 @@ export type FundingCyclesFormProps = Partial<{ export const useFundingCyclesForm = () => { const [form] = useForm() const { fundingCycleData, fundingCyclesPageSelection, mustStartAtOrAfter } = - useAppSelector(state => state.editingV2Project) + useAppSelector(state => state.creatingV2Project) useDebugValue(form.getFieldsValue()) const initialValues: FundingCyclesFormProps | undefined = useMemo(() => { @@ -63,17 +63,17 @@ export const useFundingCyclesForm = () => { const launchDate = useWatch('launchDate', form) useEffect(() => { - dispatch(editingV2ProjectActions.setFundingCyclesPageSelection(selection)) + dispatch(creatingV2ProjectActions.setFundingCyclesPageSelection(selection)) // We need to handle manual case first as duration might be undefined, but // manual set. if (selection === 'manual') { - dispatch(editingV2ProjectActions.setDuration('0')) + dispatch(creatingV2ProjectActions.setDuration('0')) return } if (!selection || duration?.duration === undefined) { - dispatch(editingV2ProjectActions.setDuration('')) + dispatch(creatingV2ProjectActions.setDuration('')) return } if (selection === 'automated') { @@ -81,7 +81,7 @@ export const useFundingCyclesForm = () => { duration: duration.duration, unit: duration.unit, }) - dispatch(editingV2ProjectActions.setDuration(newDuration.toString())) + dispatch(creatingV2ProjectActions.setDuration(newDuration.toString())) return } }, [selection, duration, dispatch]) @@ -90,14 +90,14 @@ export const useFundingCyclesForm = () => { if (launchDate === undefined) return if (launchDate === null || !launchDate.unix().toString()) { dispatch( - editingV2ProjectActions.setMustStartAtOrAfter( + creatingV2ProjectActions.setMustStartAtOrAfter( DEFAULT_MUST_START_AT_OR_AFTER, ), ) return } dispatch( - editingV2ProjectActions.setMustStartAtOrAfter( + creatingV2ProjectActions.setMustStartAtOrAfter( launchDate?.unix().toString(), ), ) diff --git a/src/packages/v4/components/Create/components/pages/NftRewards/NftRewardsPage.tsx b/src/packages/v4/components/Create/components/pages/NftRewards/NftRewardsPage.tsx index 79b9e9612c..40aaf02b0b 100644 --- a/src/packages/v4/components/Create/components/pages/NftRewards/NftRewardsPage.tsx +++ b/src/packages/v4/components/Create/components/pages/NftRewards/NftRewardsPage.tsx @@ -2,6 +2,7 @@ import { AddNftCollectionForm } from 'components/NftRewards/AddNftCollectionForm import { CREATE_FLOW } from 'constants/fathomEvents' import { trackFathomGoal } from 'lib/fathom' import { useContext } from 'react' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { useSetCreateFurthestPageReached } from 'redux/hooks/useEditingCreateFurthestPageReached' import { Wizard } from '../../Wizard/Wizard' import { PageContext } from '../../Wizard/contexts/PageContext' @@ -11,12 +12,22 @@ export function NftRewardsPage() { const { goToNextPage } = useContext(PageContext) const { form, initialValues } = useCreateFlowNftRewardsForm() + + const postPayModalData = useAppSelector( + state => state.creatingV2Project.nftRewards.postPayModal, + ) + const nftRewardsData = useAppSelector( + state => state.creatingV2Project.nftRewards, + ) + useSetCreateFurthestPageReached('nftRewards') return ( } onFinish={() => { goToNextPage?.() diff --git a/src/packages/v4/components/Create/components/pages/NftRewards/hooks/useCreateFlowNftRewardsForm.ts b/src/packages/v4/components/Create/components/pages/NftRewards/hooks/useCreateFlowNftRewardsForm.ts index e308334d8a..4bd4f9a295 100644 --- a/src/packages/v4/components/Create/components/pages/NftRewards/hooks/useCreateFlowNftRewardsForm.ts +++ b/src/packages/v4/components/Create/components/pages/NftRewards/hooks/useCreateFlowNftRewardsForm.ts @@ -4,7 +4,7 @@ import { NftRewardTier } from 'models/nftRewards' import { useEffect, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { withHttps, withoutHttp } from 'utils/externalLink' import { defaultNftCollectionDescription, @@ -20,9 +20,9 @@ export const useCreateFlowNftRewardsForm = () => { postPayModal, governanceType, flags, - } = useAppSelector(state => state.editingV2Project.nftRewards) + } = useAppSelector(state => state.creatingV2Project.nftRewards) const { projectMetadata, fundingCycleMetadata } = useAppSelector( - state => state.editingV2Project, + state => state.creatingV2Project, ) const initialValues: NftRewardsFormProps = useMemo(() => { const collectionName = @@ -79,7 +79,7 @@ export const useCreateFlowNftRewardsForm = () => { fieldName: 'rewards', ignoreUndefined: true, // Needed to stop an infinite loop currentValue: rewardTiers, - dispatchFunction: editingV2ProjectActions.setNftRewardTiers, + dispatchFunction: creatingV2ProjectActions.setNftRewardTiers, formatter: v => { if (!v) return [] if (typeof v !== 'object') { @@ -106,7 +106,7 @@ export const useCreateFlowNftRewardsForm = () => { form, fieldName: 'collectionName', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setNftRewardsName, + dispatchFunction: creatingV2ProjectActions.setNftRewardsName, formatter: v => { if (!v || typeof v !== 'string') return '' return v @@ -117,7 +117,7 @@ export const useCreateFlowNftRewardsForm = () => { form, fieldName: 'collectionSymbol', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setNftRewardsSymbol, + dispatchFunction: creatingV2ProjectActions.setNftRewardsSymbol, formatter: v => { if (!v || typeof v !== 'string') return '' return v @@ -129,7 +129,7 @@ export const useCreateFlowNftRewardsForm = () => { fieldName: 'collectionDescription', ignoreUndefined: true, dispatchFunction: - editingV2ProjectActions.setNftRewardsCollectionDescription, + creatingV2ProjectActions.setNftRewardsCollectionDescription, formatter: v => { if (!v || typeof v !== 'string') return '' return v @@ -140,7 +140,7 @@ export const useCreateFlowNftRewardsForm = () => { form, fieldName: 'useDataSourceForRedeem', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setUseDataSourceForRedeem, + dispatchFunction: creatingV2ProjectActions.setUseDataSourceForRedeem, formatter: v => !!v, }) @@ -148,7 +148,7 @@ export const useCreateFlowNftRewardsForm = () => { form, fieldName: 'preventOverspending', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setNftPreventOverspending, + dispatchFunction: creatingV2ProjectActions.setNftPreventOverspending, formatter: v => !!v, }) @@ -178,11 +178,11 @@ export const useCreateFlowNftRewardsForm = () => { postPayButtonText === undefined && postPayButtonLink === undefined ) { - dispatch(editingV2ProjectActions.setNftPostPayModalConfig(undefined)) + dispatch(creatingV2ProjectActions.setNftPostPayModalConfig(undefined)) return } dispatch( - editingV2ProjectActions.setNftPostPayModalConfig({ + creatingV2ProjectActions.setNftPostPayModalConfig({ content: postPayMessage, ctaText: postPayButtonText, ctaLink: withHttps(postPayButtonLink), diff --git a/src/packages/v4/components/Create/components/pages/PayoutsPage/components/CreateFlowPayoutsTable.tsx b/src/packages/v4/components/Create/components/pages/PayoutsPage/components/CreateFlowPayoutsTable.tsx index 8dc36c16ce..e66403b8f7 100644 --- a/src/packages/v4/components/Create/components/pages/PayoutsPage/components/CreateFlowPayoutsTable.tsx +++ b/src/packages/v4/components/Create/components/pages/PayoutsPage/components/CreateFlowPayoutsTable.tsx @@ -13,7 +13,7 @@ import { } from 'packages/v2v3/utils/splitToAllocation' import { MAX_PAYOUT_LIMIT } from 'packages/v4/utils/math' import { ReactNode } from 'react' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { useCreatingDistributionLimit } from 'redux/hooks/v2v3/create' import { fromWad, parseWad } from 'utils/format/formatNumber' import { usePayoutsForm } from '../hooks/usePayoutsForm' @@ -31,18 +31,18 @@ export function CreateFlowPayoutsTable({ addPayoutsDisabled?: boolean }) { const [ - editingDistributionLimit, + creatingDistributionLimit, , setDistributionLimitAmount, setDistributionLimitCurrency, - ] = useEditingDistributionLimit() + ] = useCreatingDistributionLimit() const { form, initialValues } = usePayoutsForm() - const distributionLimit = !editingDistributionLimit + const distributionLimit = !creatingDistributionLimit ? 0 - : editingDistributionLimit.amount.eq(MAX_PAYOUT_LIMIT) + : creatingDistributionLimit.amount.eq(MAX_PAYOUT_LIMIT) ? undefined - : parseFloat(fromWad(editingDistributionLimit?.amount)) + : parseFloat(fromWad(creatingDistributionLimit?.amount)) const splits: Split[] = form.getFieldValue('payoutsList')?.map(allocationToSplit) ?? [] @@ -68,7 +68,7 @@ export function CreateFlowPayoutsTable({ payoutSplits={splits} setPayoutSplits={setSplits} currency={ - V2V3CurrencyName(editingDistributionLimit?.currency) ?? + V2V3CurrencyName(creatingDistributionLimit?.currency) ?? DEFAULT_CURRENCY_NAME } setCurrency={setCurrency} diff --git a/src/packages/v4/components/Create/components/pages/PayoutsPage/components/TreasuryOptionsRadio.tsx b/src/packages/v4/components/Create/components/pages/PayoutsPage/components/TreasuryOptionsRadio.tsx index b595c6d095..4026d92094 100644 --- a/src/packages/v4/components/Create/components/pages/PayoutsPage/components/TreasuryOptionsRadio.tsx +++ b/src/packages/v4/components/Create/components/pages/PayoutsPage/components/TreasuryOptionsRadio.tsx @@ -8,9 +8,13 @@ import { useModal } from 'hooks/useModal' import { TreasurySelection } from 'models/treasurySelection' import { ConvertAmountsModal } from 'packages/v2v3/components/shared/PayoutsTable/ConvertAmountsModal' import { usePayoutsTable } from 'packages/v2v3/components/shared/PayoutsTable/hooks/usePayoutsTable' +import { + V2V3_CURRENCY_ETH, + V2V3_CURRENCY_USD, +} from 'packages/v2v3/utils/currency' import { useCallback, useEffect, useMemo, useState } from 'react' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { ReduxDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { ReduxDistributionLimit } from 'redux/hooks/v2v3/shared' import { fromWad } from 'utils/format/formatNumber' import { Icons } from '../../../Icons' import { RadioCard } from './RadioCard' @@ -23,7 +27,7 @@ const treasuryOptions = () => [ export function TreasuryOptionsRadio() { const initialTreasurySelection = useAppSelector( - state => state.editingV2Project.treasurySelection, + state => state.creatingV2Project.treasurySelection, ) const [treasuryOption, setTreasuryOption] = useState( @@ -32,6 +36,7 @@ export function TreasuryOptionsRadio() { const { distributionLimit, + currency, setDistributionLimit, payoutSplits, setCurrency, @@ -168,6 +173,7 @@ export function TreasuryOptionsRadio() { onOk={switchToAmountsPayoutSelection} onCancel={switchingToAmountsModal.close} splits={payoutSplits} + currency={currency === 'ETH' ? V2V3_CURRENCY_ETH : V2V3_CURRENCY_USD} /> ) diff --git a/src/packages/v4/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections.ts b/src/packages/v4/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections.ts index 993611ee99..1e2cc22d03 100644 --- a/src/packages/v4/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections.ts +++ b/src/packages/v4/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections.ts @@ -1,8 +1,8 @@ import { PayoutsSelection } from 'models/payoutsSelection' import { determineAvailablePayoutsSelections } from 'packages/v2v3/components/Create/utils/determineAvailablePayoutsSelections' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { useCreatingDistributionLimit } from 'redux/hooks/v2v3/create' export const useAvailablePayoutsSelections = (): Set => { - const [distributionLimit] = useEditingDistributionLimit() + const [distributionLimit] = useCreatingDistributionLimit() return determineAvailablePayoutsSelections(distributionLimit?.amount) } diff --git a/src/packages/v4/components/Create/components/pages/PayoutsPage/hooks/usePayoutsForm.ts b/src/packages/v4/components/Create/components/pages/PayoutsPage/hooks/usePayoutsForm.ts index 8a7b6c80fe..24edcf412a 100644 --- a/src/packages/v4/components/Create/components/pages/PayoutsPage/hooks/usePayoutsForm.ts +++ b/src/packages/v4/components/Create/components/pages/PayoutsPage/hooks/usePayoutsForm.ts @@ -1,11 +1,14 @@ import { Form } from 'antd' import { TreasurySelection } from 'models/treasurySelection' import { AllocationSplit } from 'packages/v2v3/components/shared/Allocation/Allocation' -import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v2v3/utils/splitToAllocation' import { useDebugValue, useEffect, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingPayoutSplits } from 'redux/hooks/useEditingPayoutSplits' +import { useCreatingPayoutSplits } from 'redux/hooks/v2v3/create' type PayoutsFormProps = Partial<{ selection: TreasurySelection @@ -14,8 +17,8 @@ type PayoutsFormProps = Partial<{ export const usePayoutsForm = () => { const [form] = Form.useForm() - const { treasurySelection } = useAppSelector(state => state.editingV2Project) - const [splits, setSplits] = useEditingPayoutSplits() + const { treasurySelection } = useAppSelector(state => state.creatingV2Project) + const [splits, setSplits] = useCreatingPayoutSplits() useDebugValue(form.getFieldsValue()) const initialValues: PayoutsFormProps | undefined = useMemo(() => { diff --git a/src/packages/v4/components/Create/components/pages/ProjectDetails/hooks/useProjectDetailsForm.ts b/src/packages/v4/components/Create/components/pages/ProjectDetails/hooks/useProjectDetailsForm.ts index 6bdefa459e..115903809a 100644 --- a/src/packages/v4/components/Create/components/pages/ProjectDetails/hooks/useProjectDetailsForm.ts +++ b/src/packages/v4/components/Create/components/pages/ProjectDetails/hooks/useProjectDetailsForm.ts @@ -8,8 +8,8 @@ import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' import { DEFAULT_MUST_START_AT_OR_AFTER, - editingV2ProjectActions, -} from 'redux/slices/editingV2Project' + creatingV2ProjectActions, +} from 'redux/slices/creatingV2Project' import { useFormDispatchWatch } from '../../hooks/useFormDispatchWatch' import { AmountInputValue } from '../ProjectDetailsPage' @@ -40,7 +40,7 @@ type ProjectDetailsFormProps = Partial<{ export const useProjectDetailsForm = () => { const [form] = useForm() const { projectMetadata, inputProjectOwner, mustStartAtOrAfter } = - useAppSelector(state => state.editingV2Project) + useAppSelector(state => state.creatingV2Project) const initialValues: ProjectDetailsFormProps = useMemo( () => ({ @@ -103,90 +103,90 @@ export const useProjectDetailsForm = () => { form, fieldName: 'projectName', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setName, + dispatchFunction: creatingV2ProjectActions.setName, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectTagline', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setProjectTagline, + dispatchFunction: creatingV2ProjectActions.setProjectTagline, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectDescription', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setDescription, + dispatchFunction: creatingV2ProjectActions.setDescription, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'tags', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setTags, + dispatchFunction: creatingV2ProjectActions.setTags, formatter: v => v ?? [], }) useFormDispatchWatch({ form, fieldName: 'logo', - dispatchFunction: editingV2ProjectActions.setLogoUri, + dispatchFunction: creatingV2ProjectActions.setLogoUri, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'coverImage', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setCoverImageUri, + dispatchFunction: creatingV2ProjectActions.setCoverImageUri, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectWebsite', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setInfoUri, + dispatchFunction: creatingV2ProjectActions.setInfoUri, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectTwitter', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setTwitter, + dispatchFunction: creatingV2ProjectActions.setTwitter, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectDiscord', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setDiscord, + dispatchFunction: creatingV2ProjectActions.setDiscord, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'projectTelegram', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setTelegram, + dispatchFunction: creatingV2ProjectActions.setTelegram, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'inputProjectOwner', ignoreUndefined: false, - dispatchFunction: editingV2ProjectActions.setInputProjectOwner, + dispatchFunction: creatingV2ProjectActions.setInputProjectOwner, formatter: v => v, }) useFormDispatchWatch({ form, fieldName: 'payButtonText', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setPayButton, + dispatchFunction: creatingV2ProjectActions.setPayButton, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'payDisclosure', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setPayDisclosure, + dispatchFunction: creatingV2ProjectActions.setPayDisclosure, formatter: v => v ?? '', }) @@ -194,21 +194,21 @@ export const useProjectDetailsForm = () => { form, fieldName: 'introVideoUrl', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setIntroVideoUrl, + dispatchFunction: creatingV2ProjectActions.setIntroVideoUrl, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'introImageUri', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setIntroImageUri, + dispatchFunction: creatingV2ProjectActions.setIntroImageUri, formatter: v => v ?? '', }) useFormDispatchWatch({ form, fieldName: 'softTarget', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setSoftTarget, + dispatchFunction: creatingV2ProjectActions.setSoftTarget, formatter: v => v ?? { amount: '', currency: V2V3_CURRENCY_USD }, }) @@ -222,13 +222,13 @@ export const useProjectDetailsForm = () => { // check if launch date is in ms or seconds if (launchDate > 1000000000000) { dispatch( - editingV2ProjectActions.setMustStartAtOrAfter( + creatingV2ProjectActions.setMustStartAtOrAfter( (launchDate / 1000).toString(), ), ) } else { dispatch( - editingV2ProjectActions.setMustStartAtOrAfter(launchDate.toString()), + creatingV2ProjectActions.setMustStartAtOrAfter(launchDate.toString()), ) } }, [dispatch, startTimestamp]) diff --git a/src/packages/v4/components/Create/components/pages/ProjectToken/components/CustomTokenSettings/CustomTokenSettings.tsx b/src/packages/v4/components/Create/components/pages/ProjectToken/components/CustomTokenSettings/CustomTokenSettings.tsx index 9671ed27f0..92a9fcf18c 100644 --- a/src/packages/v4/components/Create/components/pages/ProjectToken/components/CustomTokenSettings/CustomTokenSettings.tsx +++ b/src/packages/v4/components/Create/components/pages/ProjectToken/components/CustomTokenSettings/CustomTokenSettings.tsx @@ -18,7 +18,7 @@ import { ReservedTokensList } from 'packages/v2v3/components/shared/ReservedToke import { MAX_MINT_RATE } from 'packages/v2v3/utils/math' import { MAX_PAYOUT_LIMIT } from 'packages/v4/utils/math' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { useCreatingDistributionLimit } from 'redux/hooks/v2v3/create' import { inputMustExistRule } from 'utils/antdRules' import { formatAmount } from 'utils/format/formatAmount' import * as ProjectTokenForm from '../../hooks/useProjectTokenForm' @@ -38,9 +38,9 @@ const calculateMintRateAfterDiscount = ({ export const CustomTokenSettings = () => { const isMobile = useMobile() const duration = useAppSelector( - state => state.editingV2Project.fundingCycleData.duration, + state => state.creatingV2Project.fundingCycleData.duration, ) - const [distributionLimit] = useEditingDistributionLimit() + const [distributionLimit] = useCreatingDistributionLimit() const form = Form.useFormInstance() const discountRate = Form.useWatch('discountRate', form) ?? diff --git a/src/packages/v4/components/Create/components/pages/ProjectToken/hooks/useProjectTokenForm.ts b/src/packages/v4/components/Create/components/pages/ProjectToken/hooks/useProjectTokenForm.ts index 47c1942e8c..e2bdde2235 100644 --- a/src/packages/v4/components/Create/components/pages/ProjectToken/hooks/useProjectTokenForm.ts +++ b/src/packages/v4/components/Create/components/pages/ProjectToken/hooks/useProjectTokenForm.ts @@ -17,14 +17,16 @@ import { allocationToSplit, splitToAllocation, } from 'packages/v2v3/utils/splitToAllocation' +import { MAX_PAYOUT_LIMIT } from 'packages/v4/utils/math' import { useDebugValue, useEffect, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' -import { useEditingReservedTokensSplits } from 'redux/hooks/useEditingReservedTokensSplits' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { + useCreatingDistributionLimit, + useCreatingReservedTokensSplits, +} from 'redux/hooks/v2v3/create' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { useFormDispatchWatch } from '../../hooks/useFormDispatchWatch' -import { MAX_PAYOUT_LIMIT } from 'packages/v4/utils/math' export type ProjectTokensFormProps = Partial<{ selection: ProjectTokensSelection @@ -55,10 +57,10 @@ export const DefaultSettings: Required< export const useProjectTokensForm = () => { const [form] = Form.useForm() const { fundingCycleMetadata, fundingCycleData, projectTokensSelection } = - useAppSelector(state => state.editingV2Project) - const [tokenSplits] = useEditingReservedTokensSplits() + useAppSelector(state => state.creatingV2Project) + const [tokenSplits] = useCreatingReservedTokensSplits() useDebugValue(form.getFieldsValue()) - const [distributionLimit] = useEditingDistributionLimit() + const [distributionLimit] = useCreatingDistributionLimit() const redemptionRateDisabled = !distributionLimit || distributionLimit.amount.eq(MAX_PAYOUT_LIMIT) @@ -120,15 +122,15 @@ export const useProjectTokensForm = () => { useEffect(() => { // We only want to update changes when selection is set if (selection === undefined) return - dispatch(editingV2ProjectActions.setProjectTokensSelection(selection)) + dispatch(creatingV2ProjectActions.setProjectTokensSelection(selection)) if (selection === 'default') { form.setFieldsValue({ ...DefaultSettings }) - dispatch(editingV2ProjectActions.setTokenSettings(DefaultSettings)) + dispatch(creatingV2ProjectActions.setTokenSettings(DefaultSettings)) return } dispatch( - editingV2ProjectActions.setTokenSettings({ + creatingV2ProjectActions.setTokenSettings({ ...DefaultSettings, ...form.getFieldsValue(), }), @@ -138,7 +140,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'initialMintRate', - dispatchFunction: editingV2ProjectActions.setWeight, + dispatchFunction: creatingV2ProjectActions.setWeight, formatter: v => { if (v === undefined || typeof v !== 'string') return issuanceRateFrom(DefaultSettings.initialMintRate) @@ -149,7 +151,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'reservedTokensPercentage', - dispatchFunction: editingV2ProjectActions.setReservedRate, + dispatchFunction: creatingV2ProjectActions.setReservedRate, formatter: v => { if (v === undefined || typeof v !== 'number') return reservedRateFrom( @@ -164,7 +166,7 @@ export const useProjectTokensForm = () => { fieldName: 'reservedTokenAllocation', ignoreUndefined: true, // Needed to stop an infinite loop currentValue: tokenSplits, // Needed to stop an infinite loop - dispatchFunction: editingV2ProjectActions.setReservedTokensSplits, + dispatchFunction: creatingV2ProjectActions.setReservedTokensSplits, formatter: v => { if (v === undefined || typeof v !== 'object') return [] return v.map(allocationToSplit) @@ -174,7 +176,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'discountRate', - dispatchFunction: editingV2ProjectActions.setDiscountRate, + dispatchFunction: creatingV2ProjectActions.setDiscountRate, formatter: v => { if (v === undefined || typeof v !== 'number') return discountRateFrom(DefaultSettings.discountRate).toHexString() @@ -185,7 +187,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'redemptionRate', - dispatchFunction: editingV2ProjectActions.setRedemptionRate, + dispatchFunction: creatingV2ProjectActions.setRedemptionRate, formatter: v => { if (v === undefined || typeof v !== 'number') return redemptionRateFrom(DefaultSettings.redemptionRate).toHexString() @@ -195,7 +197,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'redemptionRate', - dispatchFunction: editingV2ProjectActions.setBallotRedemptionRate, + dispatchFunction: creatingV2ProjectActions.setBallotRedemptionRate, formatter: v => { if (v === undefined || typeof v !== 'number') return redemptionRateFrom(DefaultSettings.redemptionRate).toHexString() @@ -206,7 +208,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'tokenMinting', - dispatchFunction: editingV2ProjectActions.setAllowMinting, + dispatchFunction: creatingV2ProjectActions.setAllowMinting, formatter: v => { if (typeof v !== 'boolean') return false return v @@ -216,7 +218,7 @@ export const useProjectTokensForm = () => { useFormDispatchWatch({ form, fieldName: 'pauseTransfers', - dispatchFunction: editingV2ProjectActions.setPauseTransfers, + dispatchFunction: creatingV2ProjectActions.setPauseTransfers, ignoreUndefined: true, formatter: v => { if (typeof v !== 'boolean') return false diff --git a/src/packages/v4/components/Create/components/pages/ReconfigurationRules/hooks/useReconfigurationRulesForm.ts b/src/packages/v4/components/Create/components/pages/ReconfigurationRules/hooks/useReconfigurationRulesForm.ts index 23434ae661..92bd9755d7 100644 --- a/src/packages/v4/components/Create/components/pages/ReconfigurationRules/hooks/useReconfigurationRulesForm.ts +++ b/src/packages/v4/components/Create/components/pages/ReconfigurationRules/hooks/useReconfigurationRulesForm.ts @@ -6,7 +6,7 @@ import { useAvailableReconfigurationStrategies } from 'packages/v2v3/components/ import { useEffect, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { isEqualAddress, isZeroAddress } from 'utils/address' import { useFormDispatchWatch } from '../../hooks/useFormDispatchWatch' @@ -47,7 +47,7 @@ export const useReconfigurationRulesForm = () => { fundingCycleData: { ballot }, reconfigurationRuleSelection, fundingCycleMetadata, - } = useAppSelector(state => state.editingV2Project) + } = useAppSelector(state => state.creatingV2Project) const initialValues: ReconfigurationRulesFormProps | undefined = useMemo(() => { const pausePayments = fundingCycleMetadata.pausePay @@ -128,15 +128,17 @@ export const useReconfigurationRulesForm = () => { address = customAddress break } - dispatch(editingV2ProjectActions.setBallot(address ?? '')) - dispatch(editingV2ProjectActions.setReconfigurationRuleSelection(selection)) + dispatch(creatingV2ProjectActions.setBallot(address ?? '')) + dispatch( + creatingV2ProjectActions.setReconfigurationRuleSelection(selection), + ) }, [customAddress, dispatch, selection, strategies]) useFormDispatchWatch({ form, fieldName: 'pausePayments', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setPausePay, + dispatchFunction: creatingV2ProjectActions.setPausePay, formatter: v => !!v, }) @@ -144,7 +146,7 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'holdFees', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setHoldFees, + dispatchFunction: creatingV2ProjectActions.setHoldFees, formatter: v => !!v, }) @@ -152,7 +154,7 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'allowTerminalConfiguration', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setAllowSetTerminals, + dispatchFunction: creatingV2ProjectActions.setAllowSetTerminals, formatter: v => !!v, }) @@ -160,7 +162,7 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'allowControllerConfiguration', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setAllowSetController, + dispatchFunction: creatingV2ProjectActions.setAllowSetController, formatter: v => !!v, }) @@ -168,7 +170,7 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'allowTerminalMigration', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setAllowTerminalMigration, + dispatchFunction: creatingV2ProjectActions.setAllowTerminalMigration, formatter: v => !!v, }) @@ -176,14 +178,14 @@ export const useReconfigurationRulesForm = () => { form, fieldName: 'allowControllerMigration', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setAllowControllerMigration, + dispatchFunction: creatingV2ProjectActions.setAllowControllerMigration, formatter: v => !!v, }) useFormDispatchWatch({ form, fieldName: 'projectRequiredOFACCheck', ignoreUndefined: true, - dispatchFunction: editingV2ProjectActions.setRequiredOFACCheck, + dispatchFunction: creatingV2ProjectActions.setRequiredOFACCheck, formatter: v => v, }) diff --git a/src/packages/v4/components/Create/components/pages/ReviewDeploy/ReviewDeployPage.tsx b/src/packages/v4/components/Create/components/pages/ReviewDeploy/ReviewDeployPage.tsx index 7302f3591b..cbe9990e8a 100644 --- a/src/packages/v4/components/Create/components/pages/ReviewDeploy/ReviewDeployPage.tsx +++ b/src/packages/v4/components/Create/components/pages/ReviewDeploy/ReviewDeployPage.tsx @@ -14,7 +14,7 @@ import { useCallback, useContext, useEffect, useMemo, useState } from 'react' import { useDispatch } from 'react-redux' import { useAppSelector } from 'redux/hooks/useAppSelector' import { useSetCreateFurthestPageReached } from 'redux/hooks/useEditingCreateFurthestPageReached' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { helpPagePath } from 'utils/helpPagePath' import { useDeployProject } from '../../../hooks/DeployProject/useDeployProject' import { CreateBadge } from '../../CreateBadge' @@ -65,7 +65,7 @@ export const ReviewDeployPage = () => { const { deployProject, isDeploying, deployTransactionPending } = useDeployProject() const nftRewards = useAppSelector( - state => state.editingV2Project.nftRewards.rewardTiers, + state => state.creatingV2Project.nftRewards.rewardTiers, ) const nftRewardsAreSet = useMemo( @@ -78,7 +78,7 @@ export const ReviewDeployPage = () => { const handleStartOverClicked = useCallback(() => { router.push('/create') goToPage?.('projectDetails') - dispatch(editingV2ProjectActions.resetState()) + dispatch(creatingV2ProjectActions.resetState()) }, [dispatch, goToPage, router]) const onFinish = useCallback(async () => { diff --git a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/FundingConfigurationReview/hooks/useFundingConfigurationReview.ts b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/FundingConfigurationReview/hooks/useFundingConfigurationReview.ts index 83b7f6a8e3..2ef2f54203 100644 --- a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/FundingConfigurationReview/hooks/useFundingConfigurationReview.ts +++ b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/FundingConfigurationReview/hooks/useFundingConfigurationReview.ts @@ -3,19 +3,24 @@ import moment from 'moment' import { useAvailablePayoutsSelections } from 'packages/v2v3/components/Create/components/pages/PayoutsPage/hooks/useAvailablePayoutsSelections' import { formatFundingCycleDuration } from 'packages/v2v3/components/Create/utils/formatFundingCycleDuration' import { AllocationSplit } from 'packages/v2v3/components/shared/Allocation/Allocation' -import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v2v3/utils/splitToAllocation' import { useCallback, useMemo } from 'react' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' -import { useEditingPayoutSplits } from 'redux/hooks/useEditingPayoutSplits' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' +import { + useCreatingDistributionLimit, + useCreatingPayoutSplits, +} from 'redux/hooks/v2v3/create' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/creatingV2Project' import { formatFundingTarget } from 'utils/format/formatFundingTarget' export const useFundingConfigurationReview = () => { const { fundingCycleData, payoutsSelection, mustStartAtOrAfter } = - useAppSelector(state => state.editingV2Project) - const [distributionLimit] = useEditingDistributionLimit() - const [payoutSplits, setPayoutSplits] = useEditingPayoutSplits() + useAppSelector(state => state.creatingV2Project) + const [distributionLimit] = useCreatingDistributionLimit() + const [payoutSplits, setPayoutSplits] = useCreatingPayoutSplits() const fundingCycles = useMemo( () => (fundingCycleData.duration == '0' ? t`Manual` : t`Automated`), diff --git a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/ProjectDetailsReview/ProjectDetailsReview.tsx b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/ProjectDetailsReview/ProjectDetailsReview.tsx index b7b74c3504..d5ea262bc2 100644 --- a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/ProjectDetailsReview/ProjectDetailsReview.tsx +++ b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/ProjectDetailsReview/ProjectDetailsReview.tsx @@ -31,7 +31,7 @@ export const ProjectDetailsReview = () => { softTargetCurrency, }, inputProjectOwner, - } = useAppSelector(state => state.editingV2Project) + } = useAppSelector(state => state.creatingV2Project) const youtubeUrl = useMemo(() => { if (!introVideoUrl) return undefined diff --git a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/ProjectTokenReview/hooks/useProjectTokenReview.ts b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/ProjectTokenReview/hooks/useProjectTokenReview.ts index c5f4b5da21..5c6a1cf39d 100644 --- a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/ProjectTokenReview/hooks/useProjectTokenReview.ts +++ b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/ProjectTokenReview/hooks/useProjectTokenReview.ts @@ -1,8 +1,11 @@ import { AllocationSplit } from 'packages/v2v3/components/shared/Allocation/Allocation' -import { allocationToSplit, splitToAllocation } from 'packages/v2v3/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v2v3/utils/splitToAllocation' import { useCallback, useMemo } from 'react' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { useEditingReservedTokensSplits } from 'redux/hooks/useEditingReservedTokensSplits' +import { useCreatingReservedTokensSplits } from 'redux/hooks/v2v3/create' import { formatEnabled, formatPaused } from 'utils/format/formatBoolean' export const useProjectTokenReview = () => { @@ -14,8 +17,8 @@ export const useProjectTokenReview = () => { redemptionRate, global, }, - } = useAppSelector(state => state.editingV2Project) - const [tokenSplits, setTokenSplits] = useEditingReservedTokensSplits() + } = useAppSelector(state => state.creatingV2Project) + const [tokenSplits, setTokenSplits] = useCreatingReservedTokensSplits() const allocationSplits = useMemo( () => tokenSplits.map(splitToAllocation), diff --git a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx index 23c08e274d..fbfa22b23a 100644 --- a/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx +++ b/src/packages/v4/components/Create/components/pages/ReviewDeploy/components/RewardsReview/RewardsReview.tsx @@ -4,22 +4,21 @@ import { NftRewardTier } from 'models/nftRewards' import { useCallback, useMemo } from 'react' import { useAppDispatch } from 'redux/hooks/useAppDispatch' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { formatEnabled } from 'utils/format/formatBoolean' import { v4 } from 'uuid' import { ReviewDescription } from '../ReviewDescription' export const RewardsReview = () => { - const { - nftRewards: { rewardTiers, flags }, - fundingCycleMetadata, - } = useAppSelector(state => state.editingV2Project) + const { nftRewards: nftRewardsData, fundingCycleMetadata } = useAppSelector( + state => state.creatingV2Project, + ) const dispatch = useAppDispatch() const rewards: NftRewardTier[] = useMemo(() => { return ( - rewardTiers?.map(t => ({ + nftRewardsData.rewardTiers?.map(t => ({ id: parseInt(v4()), name: t.name, contributionFloor: t.contributionFloor, @@ -33,12 +32,12 @@ export const RewardsReview = () => { votingWeight: t.votingWeight, })) ?? [] ) - }, [rewardTiers]) + }, [nftRewardsData.rewardTiers]) const setRewards = useCallback( (rewards: NftRewardTier[]) => { dispatch( - editingV2ProjectActions.setNftRewardTiers( + creatingV2ProjectActions.setNftRewardTiers( rewards.map(reward => ({ contributionFloor: reward.contributionFloor, maxSupply: reward.maxSupply, @@ -63,12 +62,16 @@ export const RewardsReview = () => { }, [fundingCycleMetadata.useDataSourceForRedeem]) const preventOverspending = useMemo(() => { - return formatEnabled(flags.preventOverspending) - }, [flags.preventOverspending]) + return formatEnabled(nftRewardsData.flags.preventOverspending) + }, [nftRewardsData.flags.preventOverspending]) return (
- +
{ reconfigurationRuleSelection, fundingCycleMetadata, projectMetadata, - } = useAppSelector(state => state.editingV2Project) + } = useAppSelector(state => state.creatingV2Project) const pausePayments = useMemo(() => { return formatPaused(fundingCycleMetadata.pausePay) diff --git a/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useDeployNftProject.ts b/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useDeployNftProject.ts index da471c5c53..b4263aa776 100644 --- a/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useDeployNftProject.ts +++ b/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useDeployNftProject.ts @@ -5,13 +5,13 @@ import { LaunchTxOpts } from 'packages/v4/hooks/useLaunchProjectTx' import { useLaunchProjectWithNftsTx } from 'packages/v4/hooks/useLaunchProjectWithNftsTx' import { JB721TierConfig, JB721TiersHookFlags } from 'packages/v4/models/nfts' import { useCallback } from 'react' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { - useAppSelector, - useEditingV2V3FundAccessConstraintsSelector, - useEditingV2V3FundingCycleDataSelector, - useEditingV2V3FundingCycleMetadataSelector, -} from 'redux/hooks/useAppSelector' -import { DEFAULT_NFT_FLAGS } from 'redux/slices/editingV2Project' + useCreatingV2V3FundAccessConstraintsSelector, + useCreatingV2V3FundingCycleDataSelector, + useCreatingV2V3FundingCycleMetadataSelector, +} from 'redux/hooks/v2v3/create' +import { DEFAULT_NFT_FLAGS } from 'redux/slices/creatingV2Project' import { encodeIpfsUri } from 'utils/ipfs' import { NFT_FUNDING_CYCLE_METADATA_OVERRIDES } from 'utils/nftFundingCycleMetadataOverrides' import { sortNftsByContributionFloor } from 'utils/nftRewards' @@ -95,10 +95,10 @@ export const useDeployNftProject = () => { reservedTokensGroupedSplits, inputProjectOwner, mustStartAtOrAfter, - } = useAppSelector(state => state.editingV2Project) - const fundingCycleMetadata = useEditingV2V3FundingCycleMetadataSelector() - const fundingCycleData = useEditingV2V3FundingCycleDataSelector() - const fundAccessConstraints = useEditingV2V3FundAccessConstraintsSelector() + } = useAppSelector(state => state.creatingV2Project) + const fundingCycleMetadata = useCreatingV2V3FundingCycleMetadataSelector() + const fundingCycleData = useCreatingV2V3FundingCycleDataSelector() + const fundAccessConstraints = useCreatingV2V3FundAccessConstraintsSelector() const collectionName = nftRewards.collectionMetadata.name ? nftRewards.collectionMetadata.name diff --git a/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useIsNftProject.ts b/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useIsNftProject.ts index 5d38d3d9d3..5dc9700221 100644 --- a/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useIsNftProject.ts +++ b/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useIsNftProject.ts @@ -6,7 +6,7 @@ import { useAppSelector } from 'redux/hooks/useAppSelector' * @returns Whether the project to be deployed is an NFT project. */ export const useIsNftProject = (): boolean => { - const { nftRewards } = useAppSelector(state => state.editingV2Project) + const { nftRewards } = useAppSelector(state => state.creatingV2Project) return useMemo( () => diff --git a/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useUploadNftRewards.ts b/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useUploadNftRewards.ts index 5b4193e286..2f795a20d1 100644 --- a/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useUploadNftRewards.ts +++ b/src/packages/v4/components/Create/hooks/DeployProject/hooks/NFT/useUploadNftRewards.ts @@ -14,7 +14,7 @@ export const useUploadNftRewards = () => { const { nftRewards, projectMetadata: { name: projectName, logoUri, infoUri }, - } = useAppSelector(state => state.editingV2Project) + } = useAppSelector(state => state.creatingV2Project) return useCallback(async () => { if (!nftRewards?.rewardTiers || !nftRewards?.collectionMetadata) return diff --git a/src/packages/v4/components/Create/hooks/DeployProject/hooks/useDeployStandardProject.ts b/src/packages/v4/components/Create/hooks/DeployProject/hooks/useDeployStandardProject.ts index 2ec6c7a771..84c4e98d7c 100644 --- a/src/packages/v4/components/Create/hooks/DeployProject/hooks/useDeployStandardProject.ts +++ b/src/packages/v4/components/Create/hooks/DeployProject/hooks/useDeployStandardProject.ts @@ -1,11 +1,14 @@ -import { LaunchTxOpts, useLaunchProjectTx } from 'packages/v4/hooks/useLaunchProjectTx' +import { + LaunchTxOpts, + useLaunchProjectTx, +} from 'packages/v4/hooks/useLaunchProjectTx' import { useCallback } from 'react' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { - useAppSelector, - useEditingV2V3FundAccessConstraintsSelector, - useEditingV2V3FundingCycleDataSelector, - useEditingV2V3FundingCycleMetadataSelector, -} from 'redux/hooks/useAppSelector' + useCreatingV2V3FundAccessConstraintsSelector, + useCreatingV2V3FundingCycleDataSelector, + useCreatingV2V3FundingCycleMetadataSelector, +} from 'redux/hooks/v2v3/create' /** * Hook that returns a function that deploys a v4 project. @@ -20,17 +23,17 @@ export const useDeployStandardProject = () => { reservedTokensGroupedSplits, inputProjectOwner, mustStartAtOrAfter, - } = useAppSelector(state => state.editingV2Project) - const fundingCycleMetadata = useEditingV2V3FundingCycleMetadataSelector() - const fundingCycleData = useEditingV2V3FundingCycleDataSelector() - const fundAccessConstraints = useEditingV2V3FundAccessConstraintsSelector() + } = useAppSelector(state => state.creatingV2Project) + const fundingCycleMetadata = useCreatingV2V3FundingCycleMetadataSelector() + const fundingCycleData = useCreatingV2V3FundingCycleDataSelector() + const fundAccessConstraints = useCreatingV2V3FundAccessConstraintsSelector() const deployStandardProjectCallback = useCallback( async ({ metadataCid, onTransactionPending, onTransactionConfirmed, - onTransactionError + onTransactionError, }: { metadataCid: string } & LaunchTxOpts) => { @@ -48,7 +51,7 @@ export const useDeployStandardProject = () => { { onTransactionPending, onTransactionConfirmed, - onTransactionError + onTransactionError, }, ) }, diff --git a/src/packages/v4/components/Create/hooks/DeployProject/useDeployProject.ts b/src/packages/v4/components/Create/hooks/DeployProject/useDeployProject.ts index 843ea6aeb2..0232d7bc7b 100644 --- a/src/packages/v4/components/Create/hooks/DeployProject/useDeployProject.ts +++ b/src/packages/v4/components/Create/hooks/DeployProject/useDeployProject.ts @@ -1,15 +1,15 @@ import { useCallback, useState } from 'react' -import { - useAppSelector, - useEditingV2V3FundAccessConstraintsSelector, - useEditingV2V3FundingCycleDataSelector, - useEditingV2V3FundingCycleMetadataSelector, -} from 'redux/hooks/useAppSelector' +import { useAppSelector } from 'redux/hooks/useAppSelector' import { uploadProjectMetadata } from 'lib/api/ipfs' import { LaunchTxOpts } from 'packages/v4/hooks/useLaunchProjectTx' import { useAppDispatch } from 'redux/hooks/useAppDispatch' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { + useCreatingV2V3FundAccessConstraintsSelector, + useCreatingV2V3FundingCycleDataSelector, + useCreatingV2V3FundingCycleMetadataSelector, +} from 'redux/hooks/v2v3/create' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' import { emitErrorNotification } from 'utils/notifications' import { useDeployNftProject } from './hooks/NFT/useDeployNftProject' import { useIsNftProject } from './hooks/NFT/useIsNftProject' @@ -34,10 +34,10 @@ export const useDeployProject = () => { const { projectMetadata, nftRewards: { postPayModal }, - } = useAppSelector(state => state.editingV2Project) - const fundingCycleMetadata = useEditingV2V3FundingCycleMetadataSelector() - const fundingCycleData = useEditingV2V3FundingCycleDataSelector() - const fundAccessConstraints = useEditingV2V3FundAccessConstraintsSelector() + } = useAppSelector(state => state.creatingV2Project) + const fundingCycleMetadata = useCreatingV2V3FundingCycleMetadataSelector() + const fundingCycleData = useCreatingV2V3FundingCycleDataSelector() + const fundAccessConstraints = useCreatingV2V3FundAccessConstraintsSelector() const dispatch = useAppDispatch() @@ -49,16 +49,14 @@ export const useDeployProject = () => { }, []) const operationCallbacks = useCallback( - ( - onProjectDeployed?: (projectId: number) => void, - ): LaunchTxOpts => ({ + (onProjectDeployed?: (projectId: number) => void): LaunchTxOpts => ({ onTransactionPending: () => { console.info('Project transaction executed. Await confirmation...') setTransactionPending(true) }, onTransactionConfirmed: async (hash, projectId) => { // Reset the project state - dispatch(editingV2ProjectActions.resetState()) + dispatch(creatingV2ProjectActions.resetState()) onProjectDeployed?.(projectId) }, onTransactionError: error => { @@ -140,7 +138,7 @@ export const useDeployProject = () => { if (!tx) { setIsDeploying(false) setTransactionPending(false) - return + return } } catch (error) { handleDeployFailure(error) diff --git a/src/packages/v4/components/Create/hooks/useLoadInitialStateFromQuery.ts b/src/packages/v4/components/Create/hooks/useLoadInitialStateFromQuery.ts index efe17f29bb..cd368837da 100644 --- a/src/packages/v4/components/Create/hooks/useLoadInitialStateFromQuery.ts +++ b/src/packages/v4/components/Create/hooks/useLoadInitialStateFromQuery.ts @@ -10,10 +10,10 @@ import { useEffect, useState } from 'react' import { useDispatch } from 'react-redux' import { DEFAULT_REDUX_STATE, - INITIAL_REDUX_STATE, - editingV2ProjectActions, -} from 'redux/slices/editingV2Project' -import { CreateState, ProjectState } from 'redux/slices/editingV2Project/types' + creatingV2ProjectActions, +} from 'redux/slices/creatingV2Project' +import { INITIAL_REDUX_STATE } from 'redux/slices/shared/v2ProjectInitialReduxState' +import { CreateState, ProjectState } from 'redux/slices/shared/v2ProjectTypes' import { isEqualAddress } from 'utils/address' import { parseWad } from 'utils/format/formatNumber' import { zeroAddress } from 'viem' @@ -139,7 +139,7 @@ export function useLoadingInitialStateFromQuery() { parseCreateFlowStateFromInitialState(parsedInitialState) dispatch( - editingV2ProjectActions.setState({ + creatingV2ProjectActions.setState({ ...INITIAL_REDUX_STATE, ...createFlowState, ...parsedInitialState, diff --git a/src/packages/v4/components/Create/utils/projectTokenSettingsToReduxFormat.ts b/src/packages/v4/components/Create/utils/projectTokenSettingsToReduxFormat.ts index de6f55ff2d..fa7d98954e 100644 --- a/src/packages/v4/components/Create/utils/projectTokenSettingsToReduxFormat.ts +++ b/src/packages/v4/components/Create/utils/projectTokenSettingsToReduxFormat.ts @@ -5,7 +5,7 @@ import { reservedRateFrom, } from 'packages/v2v3/utils/math' import { allocationToSplit } from 'packages/v2v3/utils/splitToAllocation' -import { EMPTY_RESERVED_TOKENS_GROUPED_SPLITS } from 'redux/slices/editingV2Project' +import { EMPTY_RESERVED_TOKENS_GROUPED_SPLITS } from 'redux/slices/creatingV2Project' import { ProjectTokensFormProps } from '../components/pages/ProjectToken/hooks/useProjectTokenForm' export const projectTokenSettingsToReduxFormat = ( diff --git a/src/packages/v4/components/PayoutsTable/ConvertAmountsModal.tsx b/src/packages/v4/components/PayoutsTable/ConvertAmountsModal.tsx index 53a9afecb8..0bb137eda1 100644 --- a/src/packages/v4/components/PayoutsTable/ConvertAmountsModal.tsx +++ b/src/packages/v4/components/PayoutsTable/ConvertAmountsModal.tsx @@ -14,13 +14,14 @@ import { derivePayoutAmount, } from 'packages/v4/utils/distributions' import { formatCurrencyAmount } from 'packages/v4/utils/formatCurrencyAmount' -import { allocationToSplit, splitToAllocation } from 'packages/v4/utils/splitToAllocation' +import { + allocationToSplit, + splitToAllocation, +} from 'packages/v4/utils/splitToAllocation' import { isJuiceboxProjectSplit } from 'packages/v4/utils/v4Splits' import { ReactNode, useCallback, useMemo, useState } from 'react' -import { - ReduxDistributionLimit, - useEditingDistributionLimit, -} from 'redux/hooks/useEditingDistributionLimit' +import { useCreatingDistributionLimit } from 'redux/hooks/v2v3/create' +import { ReduxDistributionLimit } from 'redux/hooks/v2v3/shared' import { parseWad } from 'utils/format/formatNumber' import { formatPercent } from 'utils/format/formatPercent' import { helpPagePath } from 'utils/helpPagePath' @@ -37,7 +38,7 @@ export const ConvertAmountsModal = ({ onCancel: VoidFunction splits: Split[] }) => { - const [distributionLimit] = useEditingDistributionLimit() + const [distributionLimit] = useCreatingDistributionLimit() const [newDistributionLimit, setNewDistributionLimit] = useState('') const [currency, setCurrency] = useState( distributionLimit?.currency ?? V4_CURRENCY_ETH, @@ -155,7 +156,9 @@ export const ConvertAmountsModal = ({ }), currency, })}{' '} - {allocation.percent.formatPercentage()}% + + {allocation.percent.formatPercentage()}% + } /> diff --git a/src/packages/v4/components/PayoutsTable/PayoutTableSettings.tsx b/src/packages/v4/components/PayoutsTable/PayoutTableSettings.tsx index 6789390223..567ead4de6 100644 --- a/src/packages/v4/components/PayoutsTable/PayoutTableSettings.tsx +++ b/src/packages/v4/components/PayoutsTable/PayoutTableSettings.tsx @@ -4,7 +4,7 @@ import { SwitchToUnlimitedModal } from 'components/PayoutsTable/SwitchToUnlimite import { PopupMenu, PopupMenuItem } from 'components/ui/PopupMenu' import { handleConfirmationDeletion } from 'hooks/emitConfirmationDeletionModal' import { useState } from 'react' -import { ReduxDistributionLimit } from 'redux/hooks/useEditingDistributionLimit' +import { ReduxDistributionLimit } from 'redux/hooks/v2v3/shared' import { fromWad } from 'utils/format/formatNumber' import { ConvertAmountsModal } from './ConvertAmountsModal' import { usePayoutsTable } from './hooks/usePayoutsTable' diff --git a/src/packages/v4/hooks/useLaunchProjectTx.ts b/src/packages/v4/hooks/useLaunchProjectTx.ts index e2817e6740..6fd5a9381f 100644 --- a/src/packages/v4/hooks/useLaunchProjectTx.ts +++ b/src/packages/v4/hooks/useLaunchProjectTx.ts @@ -13,7 +13,7 @@ import { useWallet } from 'hooks/Wallet' import { NATIVE_TOKEN } from 'juice-sdk-core' import { useWriteJbControllerLaunchProjectFor } from 'juice-sdk-react' import { LaunchV2V3ProjectData } from 'packages/v2v3/hooks/transactor/useLaunchProjectTx' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' import { useChainId } from 'wagmi' import { wagmiConfig } from '../wagmiConfig' @@ -68,15 +68,16 @@ export function useLaunchProjectTx() { const { writeContractAsync: writeLaunchProject } = useWriteJbControllerLaunchProjectFor() - const chainId = useChainId() - const chainIdStr = chainId?.toString() as keyof typeof SUPPORTED_JB_MULTITERMINAL_ADDRESS - const terminalAddress = chainId - ? SUPPORTED_JB_MULTITERMINAL_ADDRESS[chainIdStr] - : undefined - - const controllerAddress = chainId - ? SUPPORTED_JB_CONTROLLER_ADDRESS[chainIdStr] - : undefined + const chainId = useChainId() + const chainIdStr = + chainId?.toString() as keyof typeof SUPPORTED_JB_MULTITERMINAL_ADDRESS + const terminalAddress = chainId + ? SUPPORTED_JB_MULTITERMINAL_ADDRESS[chainIdStr] + : undefined + + const controllerAddress = chainId + ? SUPPORTED_JB_CONTROLLER_ADDRESS[chainIdStr] + : undefined const { addTransaction } = useContext(TxHistoryContext) diff --git a/src/packages/v4/hooks/useLaunchProjectWithNftsTx.ts b/src/packages/v4/hooks/useLaunchProjectWithNftsTx.ts index bf24a7ccc1..fbbb65353e 100644 --- a/src/packages/v4/hooks/useLaunchProjectWithNftsTx.ts +++ b/src/packages/v4/hooks/useLaunchProjectWithNftsTx.ts @@ -1,4 +1,8 @@ -import { DEFAULT_MEMO, NATIVE_TOKEN, NATIVE_TOKEN_DECIMALS } from 'juice-sdk-core' +import { + DEFAULT_MEMO, + NATIVE_TOKEN, + NATIVE_TOKEN_DECIMALS, +} from 'juice-sdk-core' import { jbPricesAddress, useJBContractContext, @@ -23,7 +27,7 @@ import { import { LaunchTxOpts, SUPPORTED_JB_CONTROLLER_ADDRESS, - SUPPORTED_JB_MULTITERMINAL_ADDRESS + SUPPORTED_JB_MULTITERMINAL_ADDRESS, } from './useLaunchProjectTx' import { waitForTransactionReceipt } from '@wagmi/core' @@ -32,7 +36,7 @@ import { TxHistoryContext } from 'contexts/Transaction/TxHistoryContext' import { useWallet } from 'hooks/Wallet' import { isValidMustStartAtOrAfter } from 'packages/v2v3/utils/fundingCycle' import { useContext } from 'react' -import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/editingV2Project' +import { DEFAULT_MUST_START_AT_OR_AFTER } from 'redux/slices/shared/v2ProjectDefaultState' import { ipfsUri } from 'utils/ipfs' import { useChainId } from 'wagmi' import { wagmiConfig } from '../wagmiConfig' @@ -51,8 +55,7 @@ function createSalt() { export const getProjectIdFromNftLaunchReceipt = ( txReceipt: WaitForTransactionReceiptReturnType, ): number => { - const projectIdHex: string | undefined = - txReceipt?.logs[0]?.topics?.[1] + const projectIdHex: string | undefined = txReceipt?.logs[0]?.topics?.[1] if (!projectIdHex) return 0 const projectId = parseInt(projectIdHex, 16) @@ -80,7 +83,8 @@ export function useLaunchProjectWithNftsTx() { const { userAddress } = useWallet() const chainId = useChainId() - const chainIdStr = chainId?.toString() as keyof typeof SUPPORTED_JB_MULTITERMINAL_ADDRESS + const chainIdStr = + chainId?.toString() as keyof typeof SUPPORTED_JB_MULTITERMINAL_ADDRESS const defaultJBController = chainId ? SUPPORTED_JB_CONTROLLER_ADDRESS[chainIdStr] @@ -93,7 +97,7 @@ export function useLaunchProjectWithNftsTx() { : undefined const { writeContractAsync: writeLaunchProject } = - useWriteJb721TiersHookProjectDeployerLaunchProjectFor() + useWriteJb721TiersHookProjectDeployerLaunchProjectFor() return async ( { diff --git a/src/redux/hooks/useAppSelector.ts b/src/redux/hooks/useAppSelector.ts index 6565559f72..8ea48775be 100644 --- a/src/redux/hooks/useAppSelector.ts +++ b/src/redux/hooks/useAppSelector.ts @@ -1,74 +1,4 @@ -import { deserializeV1FundingCycle } from 'packages/v1/utils/serializers' -import { - deserializeFundAccessConstraint, - deserializeV2V3FundingCycleData, - deserializeV2V3FundingCycleMetadata, -} from 'packages/v2v3/utils/serializers' -import { useMemo } from 'react' -import { shallowEqual, TypedUseSelectorHook, useSelector } from 'react-redux' +import { TypedUseSelectorHook, useSelector } from 'react-redux' import { RootState } from 'redux/store' export const useAppSelector: TypedUseSelectorHook = useSelector - -export const useEditingV1FundingCycleSelector = () => { - const serializedFundingCycle = useAppSelector( - state => state.editingProject.fundingCycle, - shallowEqual, - ) - - const fc = useMemo( - () => deserializeV1FundingCycle(serializedFundingCycle), - [serializedFundingCycle], - ) - - return fc -} - -export const useEditingV2V3FundingCycleMetadataSelector = () => { - const serializedFundingCycleMetadata = useAppSelector( - state => state.editingV2Project.fundingCycleMetadata, - shallowEqual, - ) - - const fundingCycleMetadata = useMemo( - () => deserializeV2V3FundingCycleMetadata(serializedFundingCycleMetadata), - [serializedFundingCycleMetadata], - ) - - // force useDataSourceForPay to false, for safety. - // https://github.com/jbx-protocol/juice-interface/issues/1473 - fundingCycleMetadata.useDataSourceForPay = false - - return fundingCycleMetadata -} - -export const useEditingV2V3FundingCycleDataSelector = () => { - const serializedFundingCycleData = useAppSelector( - state => state.editingV2Project.fundingCycleData, - shallowEqual, - ) - - const fundingCycleData = useMemo( - () => deserializeV2V3FundingCycleData(serializedFundingCycleData), - [serializedFundingCycleData], - ) - - return fundingCycleData -} - -export const useEditingV2V3FundAccessConstraintsSelector = () => { - const serializedFundAccessConstraints = useAppSelector( - state => state.editingV2Project.fundAccessConstraints, - shallowEqual, - ) - - const fundAccessConstraints = useMemo( - () => - serializedFundAccessConstraints.map(d => - deserializeFundAccessConstraint(d), - ), - [serializedFundAccessConstraints], - ) - - return fundAccessConstraints -} diff --git a/src/redux/hooks/useEditingCreateFurthestPageReached.ts b/src/redux/hooks/useEditingCreateFurthestPageReached.ts index d731b95792..82f118e487 100644 --- a/src/redux/hooks/useEditingCreateFurthestPageReached.ts +++ b/src/redux/hooks/useEditingCreateFurthestPageReached.ts @@ -2,7 +2,7 @@ import { CreatePage } from 'models/createPage' import { useCallback, useEffect } from 'react' import { useDispatch } from 'react-redux' import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' const pageOrder: CreatePage[] = [ 'projectDetails', @@ -17,7 +17,7 @@ const pageOrder: CreatePage[] = [ export const useEditingCreateFurthestPageReached = () => { const dispatch = useDispatch() const furthestPageReached = useAppSelector( - state => state.editingV2Project.createFurthestPageReached, + state => state.creatingV2Project.createFurthestPageReached, ) const setFurthestPageReached = useCallback( @@ -25,13 +25,15 @@ export const useEditingCreateFurthestPageReached = () => { const currentPageIndex = pageOrder.indexOf(furthestPageReached) const newPageIndex = pageOrder.indexOf(page) if (newPageIndex > currentPageIndex) { - dispatch(editingV2ProjectActions.setCreateFurthestPageReached(page)) + dispatch(creatingV2ProjectActions.setCreateFurthestPageReached(page)) } }, [dispatch, furthestPageReached], ) const resetFurthestPageReached = useCallback(() => { - dispatch(editingV2ProjectActions.setCreateFurthestPageReached(pageOrder[0])) + dispatch( + creatingV2ProjectActions.setCreateFurthestPageReached(pageOrder[0]), + ) }, [dispatch]) return { diff --git a/src/redux/hooks/useEditingDistributionLimit.ts b/src/redux/hooks/useEditingDistributionLimit.ts deleted file mode 100644 index 8d707517c9..0000000000 --- a/src/redux/hooks/useEditingDistributionLimit.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { AddressZero } from '@ethersproject/constants' -import { ETH_TOKEN_ADDRESS } from 'constants/juiceboxTokens' -import { BigNumber } from 'ethers' -import { useDefaultJBETHPaymentTerminal } from 'packages/v2v3/hooks/defaultContracts/useDefaultJBETHPaymentTerminal' -import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' -import { V2V3_CURRENCY_ETH } from 'packages/v2v3/utils/currency' -import { MAX_DISTRIBUTION_LIMIT } from 'packages/v2v3/utils/math' -import { useCallback, useMemo } from 'react' -import { useAppDispatch } from 'redux/hooks/useAppDispatch' -import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' -import { fromWad, parseWad } from 'utils/format/formatNumber' - -export interface ReduxDistributionLimit { - amount: BigNumber - currency: V2V3CurrencyOption -} - -/** - * Hook for accessing and setting the redux editing v2 distribution limit value - * in fundingAccessConstraint. - * @returns - */ -export const useEditingDistributionLimit = (): [ - ReduxDistributionLimit | undefined, - (input: ReduxDistributionLimit | undefined) => void, - (amount: BigNumber) => void, - (currency: V2V3CurrencyOption) => void, -] => { - const defaultJBETHPaymentTerminal = useDefaultJBETHPaymentTerminal() - const dispatch = useAppDispatch() - const fundAccessConstraints = useAppSelector( - state => state.editingV2Project.fundAccessConstraints, - ) - - const distributionLimit: ReduxDistributionLimit | undefined = useMemo(() => { - if ( - !fundAccessConstraints.length || - !fundAccessConstraints?.[0].distributionLimit?.length - ) { - return undefined - } - const distributionLimit = parseWad( - fundAccessConstraints[0].distributionLimit, - ) - const distributionLimitCurrency = (parseInt( - fundAccessConstraints[0].distributionLimitCurrency, - ) ?? V2V3_CURRENCY_ETH) as V2V3CurrencyOption - - return { amount: distributionLimit, currency: distributionLimitCurrency } - }, [fundAccessConstraints]) - - const setDistributionLimit = useCallback( - (input: ReduxDistributionLimit | undefined) => { - if (!input) { - dispatch(editingV2ProjectActions.setFundAccessConstraints([])) - return - } - const distributionLimitCurrency = input.currency.toString() - dispatch( - editingV2ProjectActions.setFundAccessConstraints([ - { - terminal: defaultJBETHPaymentTerminal?.address ?? AddressZero, - token: ETH_TOKEN_ADDRESS, - distributionLimit: fromWad(input.amount), - distributionLimitCurrency, - overflowAllowance: '0', - overflowAllowanceCurrency: '0', - }, - ]), - ) - }, - [defaultJBETHPaymentTerminal, dispatch], - ) - - const setDistributionLimitAmount = useCallback( - (input: BigNumber) => { - const currentFundAccessConstraint = fundAccessConstraints?.[0] ?? { - terminal: defaultJBETHPaymentTerminal?.address ?? AddressZero, - token: ETH_TOKEN_ADDRESS, - distributionLimitCurrency: V2V3_CURRENCY_ETH.toString(), - overflowAllowance: '0', - overflowAllowanceCurrency: '0', - } - dispatch( - editingV2ProjectActions.setFundAccessConstraints([ - { - ...currentFundAccessConstraint, - distributionLimit: fromWad( - input === undefined ? MAX_DISTRIBUTION_LIMIT : input, - ), - }, - ]), - ) - }, - [defaultJBETHPaymentTerminal, dispatch, fundAccessConstraints], - ) - - const setDistributionLimitCurrency = useCallback( - (input: V2V3CurrencyOption) => { - dispatch( - editingV2ProjectActions.setDistributionLimitCurrency(input.toString()), - ) - }, - [dispatch], - ) - - return [ - distributionLimit, - setDistributionLimit, - setDistributionLimitAmount, - setDistributionLimitCurrency, - ] -} diff --git a/src/redux/hooks/useEditingPayoutSplits.ts b/src/redux/hooks/useEditingPayoutSplits.ts deleted file mode 100644 index 67efa9dfdd..0000000000 --- a/src/redux/hooks/useEditingPayoutSplits.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Split } from 'packages/v2v3/models/splits' -import { useCallback } from 'react' -import { useAppDispatch } from 'redux/hooks/useAppDispatch' -import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' - -/** - * Hook for accessing and setting the redux editing v2 payout splits value. - */ -export const useEditingPayoutSplits = (): [ - Split[], - (input: Split[]) => void, -] => { - const dispatch = useAppDispatch() - const { splits } = useAppSelector( - state => state.editingV2Project.payoutGroupedSplits, - ) - - const setSplits = useCallback( - (input: Split[]) => { - if (!input || !input.length) { - dispatch(editingV2ProjectActions.setPayoutSplits([])) - return - } - dispatch(editingV2ProjectActions.setPayoutSplits(input)) - }, - [dispatch], - ) - - return [splits, setSplits] -} diff --git a/src/redux/hooks/useEditingReservedTokensSplits.ts b/src/redux/hooks/useEditingReservedTokensSplits.ts deleted file mode 100644 index 7899e7d899..0000000000 --- a/src/redux/hooks/useEditingReservedTokensSplits.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Split } from 'packages/v2v3/models/splits' -import { useCallback } from 'react' -import { useAppDispatch } from 'redux/hooks/useAppDispatch' -import { useAppSelector } from 'redux/hooks/useAppSelector' -import { editingV2ProjectActions } from 'redux/slices/editingV2Project' - -/** - * Hook for accessing and setting the redux editing v2 reserved token splits value. - */ -export const useEditingReservedTokensSplits = (): [ - Split[], - (input: Split[]) => void, -] => { - const dispatch = useAppDispatch() - const { splits } = useAppSelector( - state => state.editingV2Project.reservedTokensGroupedSplits, - ) - - const setSplits = useCallback( - (input: Split[]) => { - if (!input || !input.length) { - dispatch(editingV2ProjectActions.setReservedTokensSplits([])) - return - } - dispatch(editingV2ProjectActions.setReservedTokensSplits(input)) - }, - [dispatch], - ) - - return [splits, setSplits] -} diff --git a/src/redux/hooks/v1/index.ts b/src/redux/hooks/v1/index.ts new file mode 100644 index 0000000000..576a734ede --- /dev/null +++ b/src/redux/hooks/v1/index.ts @@ -0,0 +1,18 @@ +import { deserializeV1FundingCycle } from 'packages/v1/utils/serializers' +import { useMemo } from 'react' +import { shallowEqual } from 'react-redux' +import { useAppSelector } from '../useAppSelector' + +export const useEditingV1FundingCycleSelector = () => { + const serializedFundingCycle = useAppSelector( + state => state.editingProject.fundingCycle, + shallowEqual, + ) + + const fc = useMemo( + () => deserializeV1FundingCycle(serializedFundingCycle), + [serializedFundingCycle], + ) + + return fc +} diff --git a/src/redux/hooks/v2v3/create.ts b/src/redux/hooks/v2v3/create.ts new file mode 100644 index 0000000000..f4dcd7f5de --- /dev/null +++ b/src/redux/hooks/v2v3/create.ts @@ -0,0 +1,218 @@ +import { AddressZero } from '@ethersproject/constants' +import { ETH_TOKEN_ADDRESS } from 'constants/juiceboxTokens' +import { BigNumber } from 'ethers' +import { useDefaultJBETHPaymentTerminal } from 'packages/v2v3/hooks/defaultContracts/useDefaultJBETHPaymentTerminal' +import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' +import { Split } from 'packages/v2v3/models/splits' +import { V2V3_CURRENCY_ETH } from 'packages/v2v3/utils/currency' +import { MAX_DISTRIBUTION_LIMIT } from 'packages/v2v3/utils/math' +import { + deserializeFundAccessConstraint, + deserializeV2V3FundingCycleData, + deserializeV2V3FundingCycleMetadata, +} from 'packages/v2v3/utils/serializers' +import { useCallback, useMemo } from 'react' +import { shallowEqual } from 'react-redux' +import { useAppDispatch } from 'redux/hooks/useAppDispatch' +import { creatingV2ProjectActions } from 'redux/slices/creatingV2Project' +import { fromWad, parseWad } from 'utils/format/formatNumber' +import { useAppSelector } from '../useAppSelector' +import { ReduxDistributionLimit } from './shared' + +export const useCreatingV2V3FundingCycleMetadataSelector = () => { + const serializedFundingCycleMetadata = useAppSelector( + state => state.creatingV2Project.fundingCycleMetadata, + shallowEqual, + ) + + const fundingCycleMetadata = useMemo( + () => deserializeV2V3FundingCycleMetadata(serializedFundingCycleMetadata), + [serializedFundingCycleMetadata], + ) + + // force useDataSourceForPay to false, for safety. + // https://github.com/jbx-protocol/juice-interface/issues/1473 + fundingCycleMetadata.useDataSourceForPay = false + + return fundingCycleMetadata +} + +export const useCreatingV2V3FundingCycleDataSelector = () => { + const serializedFundingCycleData = useAppSelector( + state => state.creatingV2Project.fundingCycleData, + shallowEqual, + ) + + const fundingCycleData = useMemo( + () => deserializeV2V3FundingCycleData(serializedFundingCycleData), + [serializedFundingCycleData], + ) + + return fundingCycleData +} + +export const useCreatingV2V3FundAccessConstraintsSelector = () => { + const serializedFundAccessConstraints = useAppSelector( + state => state.creatingV2Project.fundAccessConstraints, + shallowEqual, + ) + + const fundAccessConstraints = useMemo( + () => + serializedFundAccessConstraints.map(d => + deserializeFundAccessConstraint(d), + ), + [serializedFundAccessConstraints], + ) + + return fundAccessConstraints +} + +/** + * Hook for accessing and setting the redux creating v2 distribution limit value + * in fundingAccessConstraint. + * @returns + */ +export const useCreatingDistributionLimit = (): [ + ReduxDistributionLimit | undefined, + (input: ReduxDistributionLimit | undefined) => void, + (amount: BigNumber) => void, + (currency: V2V3CurrencyOption) => void, +] => { + const defaultJBETHPaymentTerminal = useDefaultJBETHPaymentTerminal() + const dispatch = useAppDispatch() + const fundAccessConstraints = useAppSelector( + state => state.creatingV2Project.fundAccessConstraints, + ) + + const distributionLimit: ReduxDistributionLimit | undefined = useMemo(() => { + if ( + !fundAccessConstraints.length || + !fundAccessConstraints?.[0].distributionLimit?.length + ) { + return undefined + } + const distributionLimit = parseWad( + fundAccessConstraints[0].distributionLimit, + ) + const distributionLimitCurrency = (parseInt( + fundAccessConstraints[0].distributionLimitCurrency, + ) ?? V2V3_CURRENCY_ETH) as V2V3CurrencyOption + + return { amount: distributionLimit, currency: distributionLimitCurrency } + }, [fundAccessConstraints]) + + const setDistributionLimit = useCallback( + (input: ReduxDistributionLimit | undefined) => { + if (!input) { + dispatch(creatingV2ProjectActions.setFundAccessConstraints([])) + return + } + const distributionLimitCurrency = input.currency.toString() + dispatch( + creatingV2ProjectActions.setFundAccessConstraints([ + { + terminal: defaultJBETHPaymentTerminal?.address ?? AddressZero, + token: ETH_TOKEN_ADDRESS, + distributionLimit: fromWad(input.amount), + distributionLimitCurrency, + overflowAllowance: '0', + overflowAllowanceCurrency: '0', + }, + ]), + ) + }, + [defaultJBETHPaymentTerminal, dispatch], + ) + + const setDistributionLimitAmount = useCallback( + (input: BigNumber) => { + const currentFundAccessConstraint = fundAccessConstraints?.[0] ?? { + terminal: defaultJBETHPaymentTerminal?.address ?? AddressZero, + token: ETH_TOKEN_ADDRESS, + distributionLimitCurrency: V2V3_CURRENCY_ETH.toString(), + overflowAllowance: '0', + overflowAllowanceCurrency: '0', + } + dispatch( + creatingV2ProjectActions.setFundAccessConstraints([ + { + ...currentFundAccessConstraint, + distributionLimit: fromWad( + input === undefined ? MAX_DISTRIBUTION_LIMIT : input, + ), + }, + ]), + ) + }, + [defaultJBETHPaymentTerminal, dispatch, fundAccessConstraints], + ) + + const setDistributionLimitCurrency = useCallback( + (input: V2V3CurrencyOption) => { + dispatch( + creatingV2ProjectActions.setDistributionLimitCurrency(input.toString()), + ) + }, + [dispatch], + ) + + return [ + distributionLimit, + setDistributionLimit, + setDistributionLimitAmount, + setDistributionLimitCurrency, + ] +} + +/** + * Hook for accessing and setting the redux creating v2 payout splits value. + */ +export const useCreatingPayoutSplits = (): [ + Split[], + (input: Split[]) => void, +] => { + const dispatch = useAppDispatch() + const { splits } = useAppSelector( + state => state.creatingV2Project.payoutGroupedSplits, + ) + + const setSplits = useCallback( + (input: Split[]) => { + if (!input || !input.length) { + dispatch(creatingV2ProjectActions.setPayoutSplits([])) + return + } + dispatch(creatingV2ProjectActions.setPayoutSplits(input)) + }, + [dispatch], + ) + + return [splits, setSplits] +} + +/** + * Hook for accessing and setting the redux creating v2 reserved token splits value. + */ +export const useCreatingReservedTokensSplits = (): [ + Split[], + (input: Split[]) => void, +] => { + const dispatch = useAppDispatch() + const { splits } = useAppSelector( + state => state.creatingV2Project.reservedTokensGroupedSplits, + ) + + const setSplits = useCallback( + (input: Split[]) => { + if (!input || !input.length) { + dispatch(creatingV2ProjectActions.setReservedTokensSplits([])) + return + } + dispatch(creatingV2ProjectActions.setReservedTokensSplits(input)) + }, + [dispatch], + ) + + return [splits, setSplits] +} diff --git a/src/redux/hooks/v2v3/edit.ts b/src/redux/hooks/v2v3/edit.ts new file mode 100644 index 0000000000..3e5af7f694 --- /dev/null +++ b/src/redux/hooks/v2v3/edit.ts @@ -0,0 +1,57 @@ +import { + deserializeFundAccessConstraint, + deserializeV2V3FundingCycleData, + deserializeV2V3FundingCycleMetadata, +} from 'packages/v2v3/utils/serializers' +import { useMemo } from 'react' +import { shallowEqual } from 'react-redux' +import { useAppSelector } from 'redux/hooks/useAppSelector' + +export const useEditingV2V3FundingCycleMetadataSelector = () => { + const serializedFundingCycleMetadata = useAppSelector( + state => state.editingV2Project.fundingCycleMetadata, + shallowEqual, + ) + + const fundingCycleMetadata = useMemo( + () => deserializeV2V3FundingCycleMetadata(serializedFundingCycleMetadata), + [serializedFundingCycleMetadata], + ) + + // force useDataSourceForPay to false, for safety. + // https://github.com/jbx-protocol/juice-interface/issues/1473 + fundingCycleMetadata.useDataSourceForPay = false + + return fundingCycleMetadata +} + +export const useEditingV2V3FundingCycleDataSelector = () => { + const serializedFundingCycleData = useAppSelector( + state => state.editingV2Project.fundingCycleData, + shallowEqual, + ) + + const fundingCycleData = useMemo( + () => deserializeV2V3FundingCycleData(serializedFundingCycleData), + [serializedFundingCycleData], + ) + + return fundingCycleData +} + +export const useEditingV2V3FundAccessConstraintsSelector = () => { + const serializedFundAccessConstraints = useAppSelector( + state => state.editingV2Project.fundAccessConstraints, + shallowEqual, + ) + + const fundAccessConstraints = useMemo( + () => + serializedFundAccessConstraints.map(d => + deserializeFundAccessConstraint(d), + ), + [serializedFundAccessConstraints], + ) + + return fundAccessConstraints +} diff --git a/src/redux/hooks/v2v3/shared/index.ts b/src/redux/hooks/v2v3/shared/index.ts new file mode 100644 index 0000000000..c9f6f047dc --- /dev/null +++ b/src/redux/hooks/v2v3/shared/index.ts @@ -0,0 +1 @@ +export * from './types' diff --git a/src/redux/hooks/v2v3/shared/types.ts b/src/redux/hooks/v2v3/shared/types.ts new file mode 100644 index 0000000000..92b236c323 --- /dev/null +++ b/src/redux/hooks/v2v3/shared/types.ts @@ -0,0 +1,7 @@ +import { BigNumber } from 'ethers/lib/ethers' +import { V2V3CurrencyOption } from 'packages/v2v3/models/currencyOption' + +export interface ReduxDistributionLimit { + amount: BigNumber + currency: V2V3CurrencyOption +} diff --git a/src/redux/localStoragePreload.ts b/src/redux/localStoragePreload.ts index 287651b1f3..d3e02e815e 100644 --- a/src/redux/localStoragePreload.ts +++ b/src/redux/localStoragePreload.ts @@ -2,8 +2,8 @@ import { defaultProjectState as defaultV1ProjectState, REDUX_STORE_V1_PROJECT_VERSION, } from './slices/editingProject' -import { INITIAL_REDUX_STATE as defaultV2ProjectState } from './slices/editingV2Project' -import { REDUX_STORE_V2_PROJECT_VERSION } from './slices/editingV2Project/version' +import { INITIAL_REDUX_STATE as defaultV2ProjectState } from './slices/shared/v2ProjectInitialReduxState' +import { REDUX_STORE_V2_PROJECT_VERSION } from './slices/shared/v2ProjectVersion' import { RootState } from './store' interface PreloadedState { @@ -35,6 +35,23 @@ export function getLocalStoragePreloadedState( } } + // If theres a version mismatch, reset the creatingV2Project state + if ( + parsedState?.reduxState?.creatingV2Project?.version !== + REDUX_STORE_V2_PROJECT_VERSION + ) { + console.info( + 'redux::creatingV2Project::default redux state changed, resetting creatingV2Project state.', + ) + parsedState = { + ...parsedState, + reduxState: { + ...parsedState.reduxState, + creatingV2Project: defaultV2ProjectState, + }, + } + } + // if theres a version mismatch, reset the editingV2Project state if ( parsedState?.reduxState?.editingV2Project?.version !== diff --git a/src/redux/slices/creatingV2Project/creatingV2Project.ts b/src/redux/slices/creatingV2Project/creatingV2Project.ts new file mode 100644 index 0000000000..7920e05f91 --- /dev/null +++ b/src/redux/slices/creatingV2Project/creatingV2Project.ts @@ -0,0 +1,325 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit' +import { CreatePage } from 'models/createPage' +import { + JB721GovernanceType, + NftCollectionMetadata, + NftPostPayModalConfig, + NftRewardTier, +} from 'models/nftRewards' +import { PayoutsSelection } from 'models/payoutsSelection' +import { ProjectTagName } from 'models/project-tags' +import { ProjectTokensSelection } from 'models/projectTokenSelection' +import { ReconfigurationStrategy } from 'models/reconfigurationStrategy' +import { TreasurySelection } from 'models/treasurySelection' +import { AmountInputValue } from 'packages/v2v3/components/Create/components/pages/ProjectDetails/ProjectDetailsPage' +import { projectTokenSettingsToReduxFormat } from 'packages/v2v3/components/Create/utils/projectTokenSettingsToReduxFormat' +import { AllocationSplit } from 'packages/v2v3/components/shared/Allocation/Allocation' +import { Split } from 'packages/v2v3/models/splits' +import { + SerializedV2V3FundAccessConstraint, + SerializedV2V3FundingCycleData, + SerializedV2V3FundingCycleMetadata, +} from 'packages/v2v3/utils/serializers' +import { + EMPTY_PAYOUT_GROUPED_SPLITS, + EMPTY_RESERVED_TOKENS_GROUPED_SPLITS, +} from '../shared/v2ProjectDefaultState' +import { INITIAL_REDUX_STATE } from '../shared/v2ProjectInitialReduxState' +import { NftRewardsData, ReduxState } from '../shared/v2ProjectTypes' + +const creatingV2ProjectSlice = createSlice({ + name: 'creatingV2Project', + initialState: INITIAL_REDUX_STATE, + reducers: { + setState: (_, action: PayloadAction) => { + return action.payload + }, + resetState: () => INITIAL_REDUX_STATE, + setName: (state, action: PayloadAction) => { + state.projectMetadata.name = action.payload + }, + setProjectTagline: (state, action: PayloadAction) => { + state.projectMetadata.projectTagline = action.payload + }, + setRequiredOFACCheck: ( + state, + action: PayloadAction, + ) => { + state.projectMetadata.projectRequiredOFACCheck = action.payload + }, + setInfoUri: (state, action: PayloadAction) => { + state.projectMetadata.infoUri = action.payload + }, + setLogoUri: (state, action: PayloadAction) => { + state.projectMetadata.logoUri = action.payload + }, + setCoverImageUri: (state, action: PayloadAction) => { + state.projectMetadata.coverImageUri = action.payload + }, + setTwitter: (state, action: PayloadAction) => { + state.projectMetadata.twitter = action.payload + }, + setDiscord: (state, action: PayloadAction) => { + state.projectMetadata.discord = action.payload + }, + setTelegram: (state, action: PayloadAction) => { + state.projectMetadata.telegram = action.payload + }, + setPayButton: (state, action: PayloadAction) => { + state.projectMetadata.payButton = action.payload + }, + setPayDisclosure: (state, action: PayloadAction) => { + state.projectMetadata.payDisclosure = action.payload + }, + setDescription: (state, action: PayloadAction) => { + state.projectMetadata.description = action.payload + }, + setTags: (state, action: PayloadAction) => { + state.projectMetadata.tags = action.payload + }, + setFundingCycleData: ( + state, + action: PayloadAction, + ) => { + state.fundingCycleData = action.payload + }, + setFundingCycleMetadata: ( + state, + action: PayloadAction, + ) => { + state.fundingCycleMetadata = action.payload + }, + setDuration: (state, action: PayloadAction) => { + state.fundingCycleData.duration = action.payload + }, + setDiscountRate: (state, action: PayloadAction) => { + state.fundingCycleData.discountRate = action.payload + }, + setReservedRate: (state, action: PayloadAction) => { + state.fundingCycleMetadata.reservedRate = action.payload + }, + setRedemptionRate: (state, action: PayloadAction) => { + state.fundingCycleMetadata.redemptionRate = action.payload + }, + setBallotRedemptionRate: (state, action: PayloadAction) => { + state.fundingCycleMetadata.ballotRedemptionRate = action.payload + }, + setWeight: (state, action: PayloadAction) => { + state.fundingCycleData.weight = action.payload + }, + setFundAccessConstraints: ( + state, + action: PayloadAction, + ) => { + state.fundAccessConstraints = action.payload + }, + setDistributionLimit: (state, action: PayloadAction) => { + if (state.fundAccessConstraints.length) { + state.fundAccessConstraints[0].distributionLimit = action.payload + } + }, + setDistributionLimitCurrency: (state, action: PayloadAction) => { + if (state.fundAccessConstraints.length) { + state.fundAccessConstraints[0].distributionLimitCurrency = + action.payload + } + }, + setTreasurySelection: ( + state, + action: PayloadAction, + ) => { + state.treasurySelection = action.payload + }, + setFundingTargetSelection: ( + state, + action: PayloadAction<'specific' | 'infinite' | undefined>, + ) => { + state.fundingTargetSelection = action.payload + }, + setPayoutSplits: (state, action: PayloadAction) => { + state.payoutGroupedSplits = { + ...EMPTY_PAYOUT_GROUPED_SPLITS, + splits: action.payload, + } + }, + setPayoutsSelection: ( + state, + action: PayloadAction, + ) => { + state.payoutsSelection = action.payload + }, + setReservedTokensSplits: (state, action: PayloadAction) => { + state.reservedTokensGroupedSplits = { + ...EMPTY_RESERVED_TOKENS_GROUPED_SPLITS, + splits: action.payload, + } + }, + setProjectTokensSelection: ( + state, + action: PayloadAction, + ) => { + state.projectTokensSelection = action.payload + }, + setPausePay: (state, action: PayloadAction) => { + state.fundingCycleMetadata.pausePay = action.payload + }, + setHoldFees: (state, action: PayloadAction) => { + state.fundingCycleMetadata.holdFees = action.payload + }, + setAllowMinting: (state, action: PayloadAction) => { + state.fundingCycleMetadata.allowMinting = action.payload + }, + setBallot: (state, action: PayloadAction) => { + state.fundingCycleData.ballot = action.payload + }, + setNftRewards: (state, action: PayloadAction) => { + state.nftRewards = action.payload + }, + setNftRewardTiers: (state, action: PayloadAction) => { + state.nftRewards.rewardTiers = action.payload + }, + setNftRewardsCIDs: (state, action: PayloadAction) => { + state.nftRewards.CIDs = action.payload + }, + setNftRewardsCollectionMetadata: ( + state, + action: PayloadAction, + ) => { + state.nftRewards.collectionMetadata = action.payload + }, + setNftRewardsCollectionMetadataUri: ( + state, + action: PayloadAction, + ) => { + state.nftRewards.collectionMetadata.uri = action.payload + }, + setNftRewardsSymbol: (state, action: PayloadAction) => { + state.nftRewards.collectionMetadata.symbol = action.payload + }, + setNftRewardsCollectionDescription: ( + state, + action: PayloadAction, + ) => { + state.nftRewards.collectionMetadata.description = action.payload + }, + setNftRewardsGovernance: ( + state, + action: PayloadAction, + ) => { + state.nftRewards.governanceType = action.payload + }, + setNftPostPayModalConfig: ( + state, + action: PayloadAction, + ) => { + state.nftRewards.postPayModal = action.payload + }, + setNftRewardsName: (state, action: PayloadAction) => { + state.nftRewards.collectionMetadata.name = action.payload + }, + setNftPreventOverspending: (state, action: PayloadAction) => { + state.nftRewards.flags.preventOverspending = action.payload + }, + setAllowSetTerminals: (state, action: PayloadAction) => { + state.fundingCycleMetadata.global.allowSetTerminals = action.payload + }, + setAllowSetController: (state, action: PayloadAction) => { + state.fundingCycleMetadata.global.allowSetController = action.payload + }, + setAllowControllerMigration: (state, action: PayloadAction) => { + state.fundingCycleMetadata.allowControllerMigration = action.payload + }, + setAllowTerminalMigration: (state, action: PayloadAction) => { + state.fundingCycleMetadata.allowTerminalMigration = action.payload + }, + setPauseTransfers: (state, action: PayloadAction) => { + state.fundingCycleMetadata.global.pauseTransfers = action.payload + }, + setFundingCyclesPageSelection: ( + state, + action: PayloadAction<'manual' | 'automated' | undefined>, + ) => { + state.fundingCyclesPageSelection = action.payload + }, + setReconfigurationRuleSelection: ( + state, + action: PayloadAction, + ) => { + state.reconfigurationRuleSelection = action.payload + }, + setCreateFurthestPageReached: ( + state, + action: PayloadAction, + ) => { + state.createFurthestPageReached = action.payload + }, + setInputProjectOwner: ( + state, + action: PayloadAction, + ) => { + state.inputProjectOwner = action.payload + }, + setMustStartAtOrAfter: (state, action: PayloadAction) => { + state.mustStartAtOrAfter = action.payload + }, + addCreateSoftLockedPage: (state, action: PayloadAction) => { + const set = new Set(state.createSoftLockPageQueue) + set.add(action.payload) + state.createSoftLockPageQueue = [...set] + }, + removeCreateSoftLockedPage: (state, action: PayloadAction) => { + if (!state.createSoftLockPageQueue) return + if (state.createSoftLockPageQueue.includes(action.payload)) { + state.createSoftLockPageQueue.splice( + state.createSoftLockPageQueue.indexOf(action.payload), + 1, + ) + } + }, + setUseDataSourceForRedeem: (state, action: PayloadAction) => { + state.fundingCycleMetadata.useDataSourceForRedeem = action.payload + }, + setTokenSettings: ( + state, + action: PayloadAction<{ + initialMintRate: string + reservedTokensPercentage: number + reservedTokenAllocation: AllocationSplit[] + discountRate: number + redemptionRate: number + tokenMinting: boolean + pauseTransfers: boolean + }>, + ) => { + const converted = projectTokenSettingsToReduxFormat(action.payload) + + state.fundingCycleData.weight = converted.weight + state.fundingCycleMetadata.reservedRate = converted.reservedRate + state.reservedTokensGroupedSplits = converted.reservedTokensGroupedSplits + state.fundingCycleData.discountRate = converted.discountRate + state.fundingCycleMetadata.redemptionRate = converted.redemptionRate + state.fundingCycleMetadata.allowMinting = converted.allowMinting + }, + setIntroVideoUrl: (state, action: PayloadAction) => { + state.projectMetadata.introVideoUrl = action.payload + }, + setIntroImageUri: (state, action: PayloadAction) => { + state.projectMetadata.introImageUri = action.payload + }, + setSoftTarget: (state, action: PayloadAction) => { + state.projectMetadata.softTargetAmount = action.payload.amount + state.projectMetadata.softTargetCurrency = + action.payload.currency.toString() + }, + setSoftTargetAmount: (state, action: PayloadAction) => { + state.projectMetadata.softTargetAmount = action.payload + }, + setSoftTargetCurrency: (state, action: PayloadAction) => { + state.projectMetadata.softTargetCurrency = action.payload + }, + }, +}) + +export const creatingV2ProjectActions = creatingV2ProjectSlice.actions + +export default creatingV2ProjectSlice.reducer diff --git a/src/redux/slices/creatingV2Project/index.ts b/src/redux/slices/creatingV2Project/index.ts new file mode 100644 index 0000000000..6cd530683b --- /dev/null +++ b/src/redux/slices/creatingV2Project/index.ts @@ -0,0 +1,3 @@ +export * from '../shared/v2ProjectDefaultState' +export * from './creatingV2Project' +export { default } from './creatingV2Project' diff --git a/src/redux/slices/editingV2Project/editingV2Project.ts b/src/redux/slices/editingV2Project/editingV2Project.ts index cc0279d0ae..df6472c067 100644 --- a/src/redux/slices/editingV2Project/editingV2Project.ts +++ b/src/redux/slices/editingV2Project/editingV2Project.ts @@ -21,17 +21,11 @@ import { SerializedV2V3FundingCycleMetadata, } from 'packages/v2v3/utils/serializers' import { - DEFAULT_REDUX_STATE, EMPTY_PAYOUT_GROUPED_SPLITS, EMPTY_RESERVED_TOKENS_GROUPED_SPLITS, -} from './defaultState' -import { NftRewardsData, ReduxState } from './types' -import { REDUX_STORE_V2_PROJECT_VERSION } from './version' - -export const INITIAL_REDUX_STATE = { - version: REDUX_STORE_V2_PROJECT_VERSION, - ...DEFAULT_REDUX_STATE, -} +} from '../shared/v2ProjectDefaultState' +import { INITIAL_REDUX_STATE } from '../shared/v2ProjectInitialReduxState' +import { NftRewardsData, ReduxState } from '../shared/v2ProjectTypes' const editingV2ProjectSlice = createSlice({ name: 'editingV2Project', diff --git a/src/redux/slices/editingV2Project/index.ts b/src/redux/slices/editingV2Project/index.ts index c69218525f..c91cbd97de 100644 --- a/src/redux/slices/editingV2Project/index.ts +++ b/src/redux/slices/editingV2Project/index.ts @@ -1,3 +1,5 @@ -export * from './defaultState' +// Maintain backward compatibility +export * from '../shared/v2ProjectDefaultState' + export * from './editingV2Project' export { default } from './editingV2Project' diff --git a/src/redux/slices/editingV2Project/defaultState.ts b/src/redux/slices/shared/v2ProjectDefaultState.ts similarity index 98% rename from src/redux/slices/editingV2Project/defaultState.ts rename to src/redux/slices/shared/v2ProjectDefaultState.ts index dacd6c6e16..92637a20f1 100644 --- a/src/redux/slices/editingV2Project/defaultState.ts +++ b/src/redux/slices/shared/v2ProjectDefaultState.ts @@ -24,7 +24,7 @@ import { } from 'packages/v2v3/utils/serializers' import { JB721TiersHookFlags } from 'packages/v4/models/nfts' import { projectDescriptionTemplate } from 'templates/create/projectDescriptionTemplate' -import { CreateState, ProjectState } from './types' +import { CreateState, ProjectState } from './v2ProjectTypes' const DEFAULT_DOMAIN = 'juicebox' @@ -93,7 +93,6 @@ export const DEFAULT_NFT_FLAGS: JBTiered721Flags = { preventOverspending: false, } - export const DEFAULT_NFT_FLAGS_V4: JB721TiersHookFlags = { noNewTiersWithReserves: false, noNewTiersWithVotes: false, diff --git a/src/redux/slices/shared/v2ProjectInitialReduxState.ts b/src/redux/slices/shared/v2ProjectInitialReduxState.ts new file mode 100644 index 0000000000..96cb4e370c --- /dev/null +++ b/src/redux/slices/shared/v2ProjectInitialReduxState.ts @@ -0,0 +1,7 @@ +import { DEFAULT_REDUX_STATE } from './v2ProjectDefaultState' +import { REDUX_STORE_V2_PROJECT_VERSION } from './v2ProjectVersion' + +export const INITIAL_REDUX_STATE = { + version: REDUX_STORE_V2_PROJECT_VERSION, + ...DEFAULT_REDUX_STATE, +} diff --git a/src/redux/slices/editingV2Project/types.ts b/src/redux/slices/shared/v2ProjectTypes.ts similarity index 100% rename from src/redux/slices/editingV2Project/types.ts rename to src/redux/slices/shared/v2ProjectTypes.ts diff --git a/src/redux/slices/editingV2Project/version.ts b/src/redux/slices/shared/v2ProjectVersion.ts similarity index 62% rename from src/redux/slices/editingV2Project/version.ts rename to src/redux/slices/shared/v2ProjectVersion.ts index 33f4a9a78c..e3e695e3e3 100644 --- a/src/redux/slices/editingV2Project/version.ts +++ b/src/redux/slices/shared/v2ProjectVersion.ts @@ -1,4 +1,4 @@ -import { DEFAULT_REDUX_STATE } from './defaultState' import hash from 'object-hash' +import { DEFAULT_REDUX_STATE } from './v2ProjectDefaultState' export const REDUX_STORE_V2_PROJECT_VERSION = hash(DEFAULT_REDUX_STATE) diff --git a/src/redux/store.ts b/src/redux/store.ts index dc92277137..1bb691a222 100644 --- a/src/redux/store.ts +++ b/src/redux/store.ts @@ -4,6 +4,7 @@ import { EnhancedStore, } from '@reduxjs/toolkit' import { getLocalStoragePreloadedState } from './localStoragePreload' +import creatingV2ProjectReducer from './slices/creatingV2Project' import editingProjectReducer from './slices/editingProject' import editingV2ProjectReducer from './slices/editingV2Project' @@ -12,6 +13,7 @@ const REDUX_STATE_LOCALSTORAGE_KEY = 'jb_redux_preloadedState' const rootReducer = combineReducers({ editingProject: editingProjectReducer, editingV2Project: editingV2ProjectReducer, + creatingV2Project: creatingV2ProjectReducer, }) export function createStore(key?: string) {