From 9799b31b8c1c1ef09e5bd9dc46e2747024667e57 Mon Sep 17 00:00:00 2001 From: Lautaro Petaccio <1120791+LautaroPetaccio@users.noreply.github.com> Date: Wed, 25 Sep 2024 10:27:58 -0300 Subject: [PATCH] feat: Add Third Party payments (#3189) * feat: Publication fee Payment * feat: Add more changes * fix: Update test * feat: Adds hooks tests and adds loader screen for the Confirm and Pay steps * feat: Add multiple items image * feat: Add publish and push changes tests * fix: Remove unusued action reducers in the curations reducer * fix: Remove unusued action reducers in the curations reducer * fix: Types * fix: Packages problem * fix: Publishing for standard collections * fix: Add missing translations * fix: Use the weiPerEther constant --- package-lock.json | 8 +- package.json | 2 +- .../ConfirmCollectionItemsStep.css | 18 + .../ConfirmCollectionItemsStep.tsx | 32 +- .../PayPublicationFeeStep.css | 146 ------- .../PayPublicationFeeStep.module.css | 170 ++++++++ .../PayPublicationFeeStep.tsx | 232 +++++++---- .../PublishWizardCollectionModal.container.ts | 47 --- ...PublishWizardCollectionModal.container.tsx | 148 +++++++ .../PublishWizardCollectionModal.tsx | 98 ++++- .../PublishWizardCollectionModal.types.ts | 55 +-- .../hooks.spec.tsx | 87 ++++ .../PublishWizardCollectionModal/hooks.ts | 29 ++ .../CollectionPublishButton.container.ts | 7 +- .../CollectionPublishButton.tsx | 32 +- .../CollectionPublishButton.types.ts | 6 +- src/modules/collection/selectors.spec.ts | 4 +- .../curations/itemCuration/reducer.spec.ts | 85 ++-- src/modules/curations/itemCuration/reducer.ts | 8 - src/modules/item/reducer.spec.ts | 3 +- src/modules/item/selectors.ts | 16 + src/modules/thirdParty/actions.ts | 30 +- src/modules/thirdParty/reducer.spec.ts | 140 ++++--- src/modules/thirdParty/reducer.ts | 29 +- src/modules/thirdParty/sagas.spec.ts | 374 +++++++++++++++++- src/modules/thirdParty/sagas.ts | 131 ++++-- src/modules/thirdParty/selectors.spec.ts | 54 ++- src/modules/thirdParty/selectors.ts | 7 +- src/modules/thirdParty/types.ts | 7 + src/modules/thirdParty/utils.spec.ts | 152 ++++++- src/modules/thirdParty/utils.ts | 56 ++- src/modules/translation/languages/en.json | 15 +- src/modules/translation/languages/es.json | 19 +- src/modules/translation/languages/zh.json | 13 +- 34 files changed, 1727 insertions(+), 533 deletions(-) delete mode 100644 src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.css create mode 100644 src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.module.css delete mode 100644 src/components/Modals/PublishWizardCollectionModal/PublishWizardCollectionModal.container.ts create mode 100644 src/components/Modals/PublishWizardCollectionModal/PublishWizardCollectionModal.container.tsx create mode 100644 src/components/Modals/PublishWizardCollectionModal/hooks.spec.tsx create mode 100644 src/components/Modals/PublishWizardCollectionModal/hooks.ts diff --git a/package-lock.json b/package-lock.json index bf332c7a6..14ac30e02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@dcl/crypto": "^3.4.5", "@dcl/hashing": "^3.0.4", "@dcl/mini-rpc": "^1.0.7", - "@dcl/schemas": "^13.9.0", + "@dcl/schemas": "^13.12.0", "@dcl/sdk": "7.5.5", "@dcl/single-sign-on-client": "^0.1.0", "@dcl/ui-env": "^1.5.0", @@ -2737,9 +2737,9 @@ } }, "node_modules/@dcl/schemas": { - "version": "13.10.0", - "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-13.10.0.tgz", - "integrity": "sha512-7YHjzEOLZ5dehY/LIZWIHQwWGqHXSWfIle26LrnbBwHo6gEwVmVrC8KTzkqaXGBWsVjWa/stxh5jn+25OK22gQ==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-13.12.0.tgz", + "integrity": "sha512-YHfiDSYqSRGXwiBaj5qZPzhhW7agT2bvLmrLvNZe3sFmkJTkOoFjWx5ZsG5V7JmRW6sLpJXxfKMFjcryyGU2IQ==", "dependencies": { "ajv": "^8.11.0", "ajv-errors": "^3.0.0", diff --git a/package.json b/package.json index 255c82a14..75344461b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "@dcl/crypto": "^3.4.5", "@dcl/hashing": "^3.0.4", "@dcl/mini-rpc": "^1.0.7", - "@dcl/schemas": "^13.9.0", + "@dcl/schemas": "^13.12.0", "@dcl/sdk": "7.5.5", "@dcl/single-sign-on-client": "^0.1.0", "@dcl/ui-env": "^1.5.0", diff --git a/src/components/Modals/PublishWizardCollectionModal/ConfirmCollectionItemsStep/ConfirmCollectionItemsStep.css b/src/components/Modals/PublishWizardCollectionModal/ConfirmCollectionItemsStep/ConfirmCollectionItemsStep.css index 51295d13b..548a96667 100644 --- a/src/components/Modals/PublishWizardCollectionModal/ConfirmCollectionItemsStep/ConfirmCollectionItemsStep.css +++ b/src/components/Modals/PublishWizardCollectionModal/ConfirmCollectionItemsStep/ConfirmCollectionItemsStep.css @@ -107,3 +107,21 @@ .ui.visible.popup.price-popup { z-index: 4000; } + +.ConfirmCollectionItemsStep .loading-overlay { + position: absolute; + top: 0px; + left: 0px; + z-index: 1000000; + background-color: rgba(var(--dark-raw), 0.78); + font-weight: 500; + border-radius: 8px; + font-size: 20px; + gap: 8px; + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} diff --git a/src/components/Modals/PublishWizardCollectionModal/ConfirmCollectionItemsStep/ConfirmCollectionItemsStep.tsx b/src/components/Modals/PublishWizardCollectionModal/ConfirmCollectionItemsStep/ConfirmCollectionItemsStep.tsx index b65846444..1ac52372b 100644 --- a/src/components/Modals/PublishWizardCollectionModal/ConfirmCollectionItemsStep/ConfirmCollectionItemsStep.tsx +++ b/src/components/Modals/PublishWizardCollectionModal/ConfirmCollectionItemsStep/ConfirmCollectionItemsStep.tsx @@ -2,7 +2,7 @@ import React from 'react' import classNames from 'classnames' import { ethers } from 'ethers' import { Network } from '@dcl/schemas' -import { Button, Column, Mana, Modal, Popup, Row, Table } from 'decentraland-ui' +import { Button, Column, Loader, Mana, Modal, Popup, Row, Table } from 'decentraland-ui' import { RarityBadge } from 'decentraland-dapps/dist/containers/RarityBadge' import { t } from 'decentraland-dapps/dist/modules/translation/utils' import { Item } from 'modules/item/types' @@ -11,8 +11,14 @@ import ItemImage from 'components/ItemImage' import ItemBadge from 'components/ItemBadge' import './ConfirmCollectionItemsStep.css' -export const ConfirmCollectionItemsStep: React.FC<{ items: Item[]; onNextStep: () => void; onPrevStep: () => void }> = props => { - const { items, onNextStep, onPrevStep } = props +export const ConfirmCollectionItemsStep: React.FC<{ + items: Item[] + onNextStep: () => void + onPrevStep: () => void + isSigningCheque: boolean + isThirdParty: boolean +}> = props => { + const { items, onNextStep, onPrevStep, isSigningCheque, isThirdParty } = props const renderPrice = (item: Item) => { const price = ethers.utils.formatEther(item.price!) @@ -86,18 +92,30 @@ export const ConfirmCollectionItemsStep: React.FC<{ items: Item[]; onNextStep: ( + {isSigningCheque && ( +
+ + {t('publish_wizard_collection_modal.accept_in_wallet')} +
+ )}

{t('publish_wizard_collection_modal.confirm_collection_items_step.title')}

-

{t('publish_wizard_collection_modal.confirm_collection_items_step.subtitle', { br:
})}

-

{t('publish_wizard_collection_modal.confirm_collection_items_step.description')}

+

+ {t(`publish_wizard_collection_modal.confirm_collection_items_step.${isThirdParty ? 'third_party' : 'standard'}.subtitle`, { + br:
+ })} +

+

+ {t(`publish_wizard_collection_modal.confirm_collection_items_step.${isThirdParty ? 'third_party' : 'standard'}.description`)} +

{renderItemsTable()}
- - diff --git a/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.css b/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.css deleted file mode 100644 index 5b4f238ef..000000000 --- a/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.css +++ /dev/null @@ -1,146 +0,0 @@ -.PayPublicationFeeStep .details { - background-color: rgba(var(--dark-raw), 0.48); - border-radius: 8px; - width: 100%; - padding: 20px 24px 48px; - font-size: 15px; - font-weight: 400; - line-height: 24px; - text-align: justify; -} - -.PayPublicationFeeStep .details .title { - font-size: 18px; - font-weight: 700; - line-height: 24px; -} - -.PayPublicationFeeStep .details .subtitle { - font-size: 15px; - font-weight: 400; - line-height: 24px; - color: var(--clear-divider); -} - -.PayPublicationFeeStep .details .learn-more { - font-size: 15px; - font-weight: 400; - line-height: 24px; -} - -.PayPublicationFeeStep .details .learn-more > a { - color: var(--clear-divider); - text-decoration: underline; -} - -.PayPublicationFeeStep .price-breakdown-container { - margin: 20px 0; - position: relative; - display: flex; - justify-content: space-between; - border-radius: 10px; - width: 100%; -} - -.PayPublicationFeeStep .price-breakdown-container::after { - content: ''; - position: absolute; - top: 40%; - left: 0; - width: 100%; - height: 1px; - background-color: var(--light-gray); - opacity: 40%; -} - -.PayPublicationFeeStep .price-breakdown-container .element .element-header { - display: flex; - font-size: 13px; - justify-content: center; - align-items: center; - text-align: center; - padding: 0.5rem 0 0.5rem 0; - color: var(--light-gray); -} - -.PayPublicationFeeStep .price-breakdown-container .element .element-content { - display: flex; - justify-content: center; - align-items: center; - padding: 1rem 0 1rem 0; - text-align: center; - font-weight: 400; -} - -.PayPublicationFeeStep .price-breakdown-container .element .element-content.total-amount { - font-weight: 500; -} - -.PayPublicationFeeStep .price-breakdown-container .element .element-content.total-amount .dcl.mana { - margin-top: 0; - font-size: 15px; - line-height: 24px; -} - -.PayPublicationFeeStep .actions { - margin-top: 24px; - width: 100%; - justify-content: space-between !important; -} - -.PayPublicationFeeStep .actions .actions-right { - display: flex; - gap: 1rem; - align-items: center; -} - -.PayPublicationFeeStep .actions .actions-right button { - padding-left: 16px; - padding-right: 16px; -} - -.PayPublicationFeeStep .actions .actions-right button span { - margin-left: 6px; -} - -.PayPublicationFeeStep .actions .actions-right .pay-with-card { - background-color: white !important; - color: black; -} - -.pay-with-card-info-tooltip { - z-index: 3000 !important; -} - -.PayPublicationFeeStep .actions .button { - max-width: 220px; -} - -.PayPublicationFeeStep .actions .button > .ui.dcl.mana { - font-size: 13px; - font-weight: 600; - line-height: 18px; -} - -.PayPublicationFeeStep .actions .button.loading > .ui.dcl.mana { - visibility: hidden; -} - -.PayPublicationFeeStep .error-container { - border-radius: 8px; - background: #ff2d5533; - width: 100%; - display: flex; - justify-content: center; - padding: 16px; - margin-top: 16px; - text-align: center; -} - -.PayPublicationFeeStep .error { - flex: 1 1 0; -} - -.PayPublicationFeeStep .not-enough-mana-notice .dcl.mana .symbol { - padding-right: 0; -} diff --git a/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.module.css b/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.module.css new file mode 100644 index 000000000..23002bcab --- /dev/null +++ b/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.module.css @@ -0,0 +1,170 @@ +.details { + background-color: rgba(var(--dark-raw), 0.48); + border-radius: 8px; + width: 100%; + padding: 20px 24px 48px; + font-size: 15px; + font-weight: 400; + line-height: 24px; + text-align: justify; +} + +.details .title { + font-size: 18px; + font-weight: 700; + line-height: 24px; +} + +.details .subtitle { + font-size: 15px; + font-weight: 400; + line-height: 24px; + color: var(--clear-divider); +} + +.details .learnMore { + font-size: 15px; + font-weight: 400; + line-height: 24px; +} + +.details .learnMore > a { + color: var(--clear-divider); + text-decoration: underline; +} + +.totalAmount { + font-weight: 500; +} + +.totalAmount :global(.dcl.mana.header) { + margin-top: 0; + font-size: 15px; + line-height: 24px; +} + +.actions { + margin-top: 24px; + width: 100%; + justify-content: space-between !important; +} + +.actions .actionsRight { + display: flex; + gap: 1rem; + align-items: center; +} + +.actions .actionsRight button { + padding-left: 16px; + padding-right: 16px; +} + +.actions .actionsRight button span { + margin-left: 6px; +} + +.actions .actionsRight .payWithCard { + background-color: white !important; + color: black; +} + +.payWithCardInfoTooltip { + z-index: 3000 !important; +} + +.actions :global(.button) { + max-width: 220px; +} + +.actions :global(.button) > :global(.ui.dcl.mana) { + font-size: 13px; + font-weight: 600; + line-height: 18px; +} + +.actions :global(.button.loading) > :global(.ui.dcl.mana) { + visibility: hidden; +} + +.errorContainer { + border-radius: 8px; + background: #ff2d5533; + width: 100%; + display: flex; + justify-content: center; + padding: 16px; + margin-top: 16px; + text-align: center; +} + +.error { + flex: 1 1 0; +} + +.notEnoughManaNotice :global(.dcl.mana .symbol) { + padding-right: 0; +} + +.notPayable { + color: #ffbc5b; +} + +.multipleItemImages { + position: relative; + height: 58px; + width: 58px; +} + +.itemImage { + height: 48px; + width: 48px; + z-index: 4; +} + +.layerOne { + height: 48px; + width: 48px; + position: absolute; + top: 5px; + left: 5px; + opacity: 0.7; + z-index: 3; + border-radius: 5px; +} + +.layerTwo { + height: 48px; + width: 48px; + position: absolute; + top: 10px; + left: 10px; + opacity: 0.4; + z-index: 2; + border-radius: 5px; +} + +.itemCell { + display: flex; + flex-direction: row; + gap: 16px; + align-items: center; +} + +.loadingOverlay { + position: absolute; + top: 0px; + left: 0px; + z-index: 1000000; + background-color: rgba(var(--dark-raw), 0.78); + font-weight: 500; + border-radius: 8px; + font-size: 20px; + gap: 8px; + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} diff --git a/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.tsx b/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.tsx index 4ce4c22d2..00a4ea20e 100644 --- a/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.tsx +++ b/src/components/Modals/PublishWizardCollectionModal/PayPublicationFeeStep/PayPublicationFeeStep.tsx @@ -1,58 +1,87 @@ -import React, { useCallback } from 'react' +import classNames from 'classnames' +import React, { useCallback, useMemo } from 'react' import { ethers } from 'ethers' import { Network } from '@dcl/schemas' import { config } from 'config' -import { Button, Column, Icon, InfoTooltip, Mana, Modal, Row } from 'decentraland-ui' +import { Button, Column, Icon, InfoTooltip, Loader, Mana, Modal, Row, Table } from 'decentraland-ui' +import ItemImage from 'components/ItemImage' import { t } from 'decentraland-dapps/dist/modules/translation/utils' import { toFixedMANAValue } from 'decentraland-dapps/dist/lib/mana' -import { Currency, BlockchainRarity } from 'modules/item/types' +import { Currency, Item } from 'modules/item/types' +import { isTPCollection } from 'modules/collection/utils' import { PaymentMethod } from 'modules/collection/types' -import { MapStateProps } from '../PublishWizardCollectionModal.types' -import './PayPublicationFeeStep.css' +import { Props } from '../PublishWizardCollectionModal.types' +import styles from './PayPublicationFeeStep.module.css' +import { getBackgroundStyle } from 'modules/item/utils' + +const MultipleItemImages: React.FC<{ referenceItem: Item }> = ({ referenceItem }) => ( +
+ +
+
+
+) export const PayPublicationFeeStep: React.FC< - MapStateProps & { onNextStep: (paymentMethod: PaymentMethod) => void; onPrevStep: () => void } + Props & { onNextStep: (paymentMethod: PaymentMethod) => void; onPrevStep: () => void } > = props => { const { collection, - items, - rarities, + itemsToPublish, + itemsWithChanges, + price, wallet, collectionError, unsyncedCollectionError, isLoading, + thirdParty, isPublishCollectionsWertEnabled, onNextStep, onPrevStep } = props - // The UI is designed in a way that considers that all rarities have the same price, so only using the first one - // as reference for the prices is enough. - const refRarity: BlockchainRarity | undefined = rarities[0] - - let priceUSD = '0' - let totalPrice = '0' - let totalPriceUSD = '0' - let hasInsufficientMANA = true - - if (refRarity) { - priceUSD = refRarity.prices!.USD - - totalPrice = ethers.BigNumber.from(refRarity.prices!.MANA).mul(items.length).toString() - - totalPriceUSD = ethers.BigNumber.from(priceUSD).mul(items.length).toString() + const isThirdParty = useMemo(() => isTPCollection(collection), [collection]) + const availableSlots = useMemo(() => thirdParty?.availableSlots ?? 0, [thirdParty?.availableSlots]) + const amountOfItemsToPublish = useMemo( + () => (itemsToPublish.length - availableSlots > 0 ? itemsToPublish.length - availableSlots : 0), + [itemsToPublish, availableSlots] + ) + const amountOfItemsAlreadyPayed = useMemo( + () => amountOfItemsToPublish - itemsToPublish.length, + [amountOfItemsToPublish, itemsToPublish.length] + ) + const amountOfItemsAlreadyPublishedWithChanges = useMemo(() => itemsWithChanges.length, [itemsWithChanges]) - hasInsufficientMANA = !!wallet && wallet.networks.MATIC.mana < Number(ethers.utils.formatEther(totalPrice)) - } + const priceUSD = useMemo( + () => (thirdParty?.isProgrammatic ? price?.programmatic?.usd : price?.item.usd) ?? '0', + [thirdParty?.isProgrammatic, price?.item.usd, price?.programmatic?.usd] + ) + const totalPriceMANA = useMemo( + () => + thirdParty?.isProgrammatic + ? price?.programmatic?.mana ?? '0' + : ethers.BigNumber.from(price?.item.mana ?? '0') + .mul(itemsToPublish.length) + .toString(), + [price?.item.mana, itemsToPublish, thirdParty?.isProgrammatic] + ) + const totalPriceUSD = useMemo( + () => (thirdParty?.isProgrammatic ? priceUSD : ethers.BigNumber.from(priceUSD).mul(itemsToPublish.length).toString()), + [priceUSD, itemsToPublish] + ) + const hasInsufficientMANA = useMemo( + () => !!wallet && wallet.networks.MATIC.mana < Number(ethers.utils.formatEther(totalPriceMANA)), + [wallet, totalPriceMANA] + ) const renderErrorMessage = () => { let content: React.ReactNode | undefined = undefined - if (!refRarity) { - content = {t('publish_collection_modal_with_oracle.rarities_error')} + if (!price) { + content = {t('publish_collection_modal_with_oracle.rarities_error')} } else if (hasInsufficientMANA) { content = ( - + {t('publish_collection_modal_with_oracle.not_enough_mana', { symbol: ( @@ -71,12 +100,12 @@ export const PayPublicationFeeStep: React.FC< ) } else if (unsyncedCollectionError && !isLoading) { - content = {t('publish_collection_modal_with_oracle.unsynced_collection')} + content = {t('publish_collection_modal_with_oracle.unsynced_collection')} } else if (collectionError && !isLoading) { - content = {collectionError} + content = {collectionError} } - return content ?
{content}
: null + return content ?
{content}
: null } const handleBuyWithMana = useCallback(() => { @@ -88,73 +117,120 @@ export const PayPublicationFeeStep: React.FC< }, [onNextStep]) return ( - + - + + {isLoading && ( +
+ + {t('publish_wizard_collection_modal.accept_in_wallet')} +
+ )} - {t('publish_wizard_collection_modal.pay_publication_fee_step.title')} - + {t('publish_wizard_collection_modal.pay_publication_fee_step.title')} + {t('publish_wizard_collection_modal.pay_publication_fee_step.subtitle', { collection_name: {collection.name}, - count: items.length, + count: amountOfItemsToPublish, currency: 'USD', publication_fee: toFixedMANAValue(ethers.utils.formatEther(priceUSD)) })} - + {t('publish_wizard_collection_modal.pay_publication_fee_step.learn_more')} -
-
-
{t('publish_wizard_collection_modal.pay_publication_fee_step.quantity')}
-
- {t('publish_wizard_collection_modal.pay_publication_fee_step.items', { count: items.length })} -
-
-
-
{t('publish_wizard_collection_modal.pay_publication_fee_step.fee_per_item')}
-
- {Currency.USD} {toFixedMANAValue(ethers.utils.formatEther(priceUSD))} -
-
-
-
- {t('publish_wizard_collection_modal.pay_publication_fee_step.total_in_usd', { currency: Currency.USD })} -
-
- {Currency.USD} {toFixedMANAValue(ethers.utils.formatEther(totalPriceUSD))} -
-
-
-
{t('publish_wizard_collection_modal.pay_publication_fee_step.total_in_mana')}
-
- - {toFixedMANAValue(ethers.utils.formatEther(totalPrice))} - -
-
-
+ + + + {t('publish_wizard_collection_modal.pay_publication_fee_step.quantity')} + {t('publish_wizard_collection_modal.pay_publication_fee_step.fee_per_item')} + + {t('publish_wizard_collection_modal.pay_publication_fee_step.total_in_usd', { currency: Currency.USD })} + + {t('publish_wizard_collection_modal.pay_publication_fee_step.total_in_mana')} + + + + {amountOfItemsToPublish ? ( + + + {amountOfItemsToPublish > 1 ? ( + + ) : ( + + )} + {t('publish_wizard_collection_modal.pay_publication_fee_step.items', { count: amountOfItemsToPublish })} + + + {Currency.USD} {toFixedMANAValue(ethers.utils.formatEther(priceUSD))} + + + {Currency.USD} {toFixedMANAValue(ethers.utils.formatEther(totalPriceUSD))} + + + + {toFixedMANAValue(ethers.utils.formatEther(totalPriceMANA))} + + + + ) : null} + {amountOfItemsAlreadyPayed ? ( + + + {amountOfItemsAlreadyPayed > 1 ? ( + + ) : ( + + )} + {t('publish_wizard_collection_modal.pay_publication_fee_step.items', { count: amountOfItemsToPublish })} + + + {t('publish_wizard_collection_modal.pay_publication_fee_step.already_payed')} + + + ) : null} + {amountOfItemsAlreadyPublishedWithChanges ? ( + + + {amountOfItemsAlreadyPublishedWithChanges > 1 ? ( + + ) : ( + + )} + {t('publish_wizard_collection_modal.pay_publication_fee_step.items', { count: amountOfItemsToPublish })} + + + {t('publish_wizard_collection_modal.pay_publication_fee_step.already_published')} + + + ) : null} + +
{renderErrorMessage()} - + -
+
{isPublishCollectionsWertEnabled ? ( <> - - + {!isThirdParty && ( + <> + + + + )} ) : null}