Skip to content

Commit

Permalink
Add useValidateCampaignWithCountryCodes hook.
Browse files Browse the repository at this point in the history
  • Loading branch information
asvinb committed Sep 18, 2024
1 parent 7adc092 commit 90e8d95
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import GridiconNoticeOutline from 'gridicons/dist/notice-outline';
* Internal dependencies
*/
import useCountryKeyNameMap from '.~/hooks/useCountryKeyNameMap';
import useFetchBudgetRecommendationEffect from './useFetchBudgetRecommendationEffect';
import useFetchBudgetRecommendationEffect from '.~/hooks/useFetchBudgetRecommendationEffect';
import './index.scss';

/*
Expand Down
15 changes: 13 additions & 2 deletions js/src/components/paid-ads/campaign-assets-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { useState, useMemo } from '@wordpress/element';
*/
import { ASSET_GROUP_KEY, ASSET_FORM_KEY } from '.~/constants';
import AdaptiveForm from '.~/components/adaptive-form';
import validateCampaign from '.~/components/paid-ads/validateCampaign';
import validateAssetGroup from '.~/components/paid-ads/validateAssetGroup';
import useValidateCampaignWithCountryCodes from '.~/hooks/useValidateCampaignWithCountryCodes';

/**
* @typedef {import('.~/components/types.js').CampaignFormValues} CampaignFormValues
Expand Down Expand Up @@ -64,11 +64,13 @@ function convertAssetEntityGroupToFormValues( assetEntityGroup = {} ) {
* @augments AdaptiveForm
* @param {Object} props React props.
* @param {CampaignFormValues} props.initialCampaign Initial campaign values.
* @param {Function} [props.onChange] Callback when the form values change.
* @param {AssetEntityGroup} [props.assetEntityGroup] The asset entity group to be used in initializing the form values for editing.
*/
export default function CampaignAssetsForm( {
initialCampaign,
assetEntityGroup,
onChange,
...adaptiveFormProps
} ) {
const initialAssetGroup = useMemo( () => {
Expand All @@ -77,6 +79,14 @@ export default function CampaignAssetsForm( {

const [ baseAssetGroup, setBaseAssetGroup ] = useState( initialAssetGroup );
const [ hasImportedAssets, setHasImportedAssets ] = useState( false );
const [ countryCodes, setCountryCodes ] = useState( [] );
const { validateCampaignWithCountryCodes } =
useValidateCampaignWithCountryCodes( countryCodes );

const handleOnChange = ( _, values, arg ) => {
setCountryCodes( values.countryCodes );
onChange( _, values, arg );
};

const extendAdapter = ( formContext ) => {
const assetGroupErrors = validateAssetGroup( formContext.values );
Expand Down Expand Up @@ -120,8 +130,9 @@ export default function CampaignAssetsForm( {
...initialCampaign,
...initialAssetGroup,
} }
validate={ validateCampaign }
validate={ validateCampaignWithCountryCodes }
extendAdapter={ extendAdapter }
onChange={ handleOnChange }
{ ...adaptiveFormProps }
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { addQueryArgs } from '@wordpress/url';
* Internal dependencies
*/
import { API_NAMESPACE } from '.~/data/constants';
import useApiFetchEffect from '.~/hooks/useApiFetchEffect';
import useApiFetchEffect from './useApiFetchEffect';

/**
* @typedef { import(".~/data/actions").CountryCode } CountryCode
Expand Down
31 changes: 31 additions & 0 deletions js/src/hooks/useHighestBudgetRecommendation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Internal dependencies
*/
import useFetchBudgetRecommendationEffect from './useFetchBudgetRecommendationEffect';
import getHighestBudget from '.~/utils/getHighestBudget';
import useStoreCurrency from './useStoreCurrency';

/**
* @typedef { import(".~/data/actions").CountryCode } CountryCode
*/

/**
* Fetch the highest budget recommendation for countries in a side effect.
*
* @param {Array<CountryCode>} countryCodes Country code array.
* @return {Object} Budget recommendation.
*/
const useHighestBudgetRecommendation = ( countryCodes ) => {
const { code: currency, formatNumber } = useStoreCurrency();
const { data: budgetData } =
useFetchBudgetRecommendationEffect( countryCodes );
const budget = getHighestBudget( budgetData?.recommendations );

return {
dailyBudget: budget?.daily_budget,
currency,
formatNumber,
};
};

export default useHighestBudgetRecommendation;
42 changes: 42 additions & 0 deletions js/src/hooks/useValidateCampaignWithCountryCodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Internal dependencies
*/
import useHighestBudgetRecommendation from './useHighestBudgetRecommendation';
import validateCampaign from '.~/components/paid-ads/validateCampaign';

/**
* @typedef {import('.~/components/types.js').CampaignFormValues} CampaignFormValues
*/

/**
* @typedef { import(".~/data/actions").CountryCode } CountryCode
*/

/**
* Validate campaign form. Accepts the form values object and returns errors object.
*
* @param {Array<CountryCode>} countryCodes Country code array.
* @return {Object} errors.
*/
const useValidateCampaignWithCountryCodes = ( countryCodes ) => {
const { currency, dailyBudget, formatNumber } =
useHighestBudgetRecommendation( countryCodes );

/**
* Validate campaign form. Accepts the form values object and returns errors object.
*
* @param {CampaignFormValues} values Campaign form values.
* @return {Object} errors.
*/
const validateCampaignWithCountryCodes = ( values ) => {
return validateCampaign( values, {
currency,
dailyBudget,
formatNumber,
} );
};

return { validateCampaignWithCountryCodes };
};

export default useValidateCampaignWithCountryCodes;
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@ import { Form } from '@woocommerce/components';
* Internal dependencies
*/
import useGoogleAdsAccountBillingStatus from '.~/hooks/useGoogleAdsAccountBillingStatus';
import useFetchBudgetRecommendationEffect from '.~/components/paid-ads/budget-section/budget-recommendation/useFetchBudgetRecommendationEffect';
import BudgetSection from '.~/components/paid-ads/budget-section';
import BillingCard from '.~/components/paid-ads/billing-card';
import SpinnerCard from '.~/components/spinner-card';
import Section from '.~/wcdl/section';
import validateCampaign from '.~/components/paid-ads/validateCampaign';
import clientSession from './clientSession';
import { GOOGLE_ADS_BILLING_STATUS } from '.~/constants';
import getHighestBudget from '.~/utils/getHighestBudget';
import useStoreCurrency from '.~/hooks/useStoreCurrency';
import useValidateCampaignWithCountryCodes from '.~/hooks/useValidateCampaignWithCountryCodes';

/**
* @typedef {import('.~/data/actions').CountryCode} CountryCode
Expand Down Expand Up @@ -62,8 +60,9 @@ export default function PaidAdsSetupSections( {
onStatesReceived,
countryCodes,
} ) {
const { validateCampaignWithCountryCodes } =
useValidateCampaignWithCountryCodes( countryCodes );
const { billingStatus } = useGoogleAdsAccountBillingStatus();
const { code: currency, formatNumber } = useStoreCurrency();

const onStatesReceivedRef = useRef();
onStatesReceivedRef.current = onStatesReceived;
Expand All @@ -77,10 +76,6 @@ export default function PaidAdsSetupSections( {
return resolveInitialPaidAds( startingPaidAds );
} );

const { data: budgetData } =
useFetchBudgetRecommendationEffect( countryCodes );
const budget = getHighestBudget( budgetData?.recommendations );

const isBillingCompleted =
billingStatus?.status === GOOGLE_ADS_BILLING_STATUS.APPROVED;

Expand Down Expand Up @@ -119,21 +114,13 @@ export default function PaidAdsSetupSections( {
amount: paidAds.amount,
};

const formOpts = {
dailyBudget: budget?.daily_budget,
currency,
formatNumber,
};

return (
<Form
initialValues={ initialValues }
onChange={ ( _, values, isValid ) => {
setPaidAds( { ...paidAds, ...values, isValid } );
} }
validate={ ( formValues ) =>
validateCampaign( formValues, formOpts )
}
validate={ validateCampaignWithCountryCodes }
>
{ ( formProps ) => {
return (
Expand Down

0 comments on commit 90e8d95

Please sign in to comment.