diff --git a/src/config.js b/src/config.js index 0d0972af..b82f93ed 100644 --- a/src/config.js +++ b/src/config.js @@ -37,6 +37,10 @@ const sdkBaseUrl = process.env.REACT_APP_SHARETRIBE_SDK_BASE_URL; const currency = process.env.REACT_APP_SHARETRIBE_MARKETPLACE_CURRENCY; +// Listing minimum price in currency sub units, e.g. cents. +// 0 means no restriction to the price +const listingMinimumPriceSubUnits = 0; + // Sentry DSN (Data Source Name), a client key for authenticating calls to Sentry const sentryDsn = process.env.REACT_APP_PUBLIC_SENTRY_DSN; @@ -283,6 +287,7 @@ const config = { sdk: { clientId: sdkClientId, baseUrl: sdkBaseUrl }, sortSearchByDistance, currency, + listingMinimumPriceSubUnits, currencyConfig, stripe: { publishableKey: stripePublishableKey, supportedCountries: stripeSupportedCountries }, canonicalRootURL, diff --git a/src/containers/EditListingPricingForm/EditListingPricingForm.js b/src/containers/EditListingPricingForm/EditListingPricingForm.js index 959389cd..a5703480 100644 --- a/src/containers/EditListingPricingForm/EditListingPricingForm.js +++ b/src/containers/EditListingPricingForm/EditListingPricingForm.js @@ -6,11 +6,15 @@ import { intlShape, injectIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import config from '../../config'; import { propTypes } from '../../util/types'; -import { required } from '../../util/validators'; +import * as validators from '../../util/validators'; +import { formatMoney } from '../../util/currency'; +import { types as sdkTypes } from '../../util/sdkLoader'; import { Form, Button, FieldCurrencyInput } from '../../components'; import css from './EditListingPricingForm.css'; +const { Money } = sdkTypes; + export const EditListingPricingFormComponent = props => { const { className, @@ -26,11 +30,31 @@ export const EditListingPricingFormComponent = props => { } = props; const pricePerUnitMessage = intl.formatMessage({ id: 'EditListingPricingForm.pricePerUnit' }); - const priceRequiredMessage = intl.formatMessage({ id: 'EditListingPricingForm.priceRequired' }); const pricePlaceholderMessage = intl.formatMessage({ id: 'EditListingPricingForm.priceInputPlaceholder', }); + const priceRequired = validators.required( + intl.formatMessage({ + id: 'EditListingPricingForm.priceRequired', + }) + ); + const minPrice = new Money(config.listingMinimumPriceSubUnits, config.currency); + const minPriceRequired = validators.moneySubUnitAmountAtLeast( + intl.formatMessage( + { + id: 'EditListingPricingForm.priceTooLow', + }, + { + minPrice: formatMoney(intl, minPrice), + } + ), + config.listingMinimumPriceSubUnits + ); + const priceValidators = config.listingMinimumPriceSubUnits + ? [priceRequired, minPriceRequired] + : [priceRequired]; + const errorMessage = updateError ? (

@@ -53,7 +77,7 @@ export const EditListingPricingFormComponent = props => { label={pricePerUnitMessage} placeholder={pricePlaceholderMessage} currencyConfig={config.currencyConfig} - validate={[required(priceRequiredMessage)]} + validate={priceValidators} />