Skip to content

Commit 7b571fb

Browse files
authored
Merge pull request #40 from woocommerce/REDTWOO-69
REDTWOO-69: Implement the Campaign Budget form Component
2 parents 87f0f0a + a8cf6d5 commit 7b571fb

File tree

97 files changed

+5156
-652
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+5156
-652
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ module.exports = {
8181
definedTypes: [
8282
...jsdocConfig.rules[ 'jsdoc/no-undefined-types' ][ 1 ]
8383
.definedTypes,
84+
'rfw_documentation_link_click',
8485
],
8586
},
8687
],

.externalized.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
["@woocommerce/components","@woocommerce/navigation","@woocommerce/settings","@wordpress/api-fetch","@wordpress/components","@wordpress/compose","@wordpress/data","@wordpress/element","@wordpress/hooks","@wordpress/i18n","@wordpress/url","lodash","react","react/jsx-runtime"]
1+
["@woocommerce/components","@woocommerce/currency","@woocommerce/navigation","@woocommerce/number","@woocommerce/settings","@wordpress/api-fetch","@wordpress/components","@wordpress/compose","@wordpress/data","@wordpress/element","@wordpress/hooks","@wordpress/i18n","@wordpress/primitives","@wordpress/url","lodash","react","react/jsx-runtime"]

includes/API/AdPartner/AdAccountsApi.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public function get() {
8585
}
8686

8787
return $this->wcs->proxy_get(
88-
'/v3/ad_accounts/' . $ad_account_id
88+
'/ads/ad_accounts/' . $ad_account_id
8989
);
9090
}
9191
}

includes/API/Site/Controllers/RedditConnectionController.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ public function delete_connection() {
321321
Options::delete( OptionDefaults::CATALOG_ID );
322322
Options::delete( OptionDefaults::FEED_STATUS );
323323
Options::delete( OptionDefaults::WCS_PRODUCTS_TOKEN );
324+
Options::delete( OptionDefaults::ADS_ACCOUNT_CURRENCY );
324325
Transients::delete( TransientDefaults::REDDIT_ACCOUNT_EMAIL );
325326
Transients::delete( TransientDefaults::PIXEL_SCRIPT );
326327

@@ -401,6 +402,14 @@ public function do_config( WP_REST_Request $request ) {
401402
}
402403
}
403404

405+
// Set the ad account currency.
406+
$ad_account = $this->ad_partner_api->ad_accounts->get();
407+
if ( ! is_wp_error( $ad_account ) ) {
408+
$ad_account_data = $ad_account->get_data();
409+
$ad_account_currency = $ad_account_data['data']['currency'] ?? '';
410+
Options::set( OptionDefaults::ADS_ACCOUNT_CURRENCY, $ad_account_currency );
411+
}
412+
404413
/**
405414
* Triggers when the Reddit onboarding process is completed.
406415
*
@@ -420,13 +429,18 @@ public function do_config( WP_REST_Request $request ) {
420429
* @return WP_REST_Response
421430
*/
422431
public function get_connection_details() {
432+
$currency = Options::get( OptionDefaults::ADS_ACCOUNT_CURRENCY );
433+
$symbol = html_entity_decode( get_woocommerce_currency_symbol( $currency ), ENT_QUOTES );
434+
423435
return rest_ensure_response(
424436
array(
425437
'business_id' => Options::get( OptionDefaults::BUSINESS_ID ),
426438
'business_name' => Options::get( OptionDefaults::BUSINESS_NAME ),
427439
'ad_account_id' => Options::get( OptionDefaults::AD_ACCOUNT_ID ),
428440
'ad_account_name' => Options::get( OptionDefaults::AD_ACCOUNT_NAME ),
429441
'pixel_id' => Options::get( OptionDefaults::PIXEL_ID ),
442+
'currency' => $currency,
443+
'symbol' => $symbol,
430444
)
431445
);
432446
}

includes/Utils/Storage/OptionDefaults.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ final class OptionDefaults {
168168
*/
169169
public const WCS_PRODUCTS_TOKEN = 'wcs_products_token';
170170

171+
/**
172+
* Option key to store the Ad Partner's currency.
173+
*
174+
* @since 0.1.0
175+
*/
176+
public const ADS_ACCOUNT_CURRENCY = 'ad_account_currency';
177+
171178
/**
172179
* Returns default values for all known Ad Partner options.
173180
*
@@ -198,6 +205,7 @@ public static function get_all(): array {
198205
self::EXPORT_PRODUCT_IDS => array(),
199206
self::LAST_EXPORT_TIMESTAMP => 0,
200207
self::WCS_PRODUCTS_TOKEN => '',
208+
self::ADS_ACCOUNT_CURRENCY => get_woocommerce_currency(),
201209
);
202210
}
203211
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { createContext, useContext } from '@wordpress/element';
5+
6+
/**
7+
* @typedef {import('react').React} React
8+
*/
9+
10+
/**
11+
* @typedef {Object} InputProps
12+
* @property {*} value Form value.
13+
* @property {boolean} checked Form value converted to boolean.
14+
* @property {*} selected Form value.
15+
* @property {(value: Event<HTMLInputElement> | *) => void} onChange Function to handle onChange event.
16+
* @property {() => void} onBlur Function to handle onBlur event.
17+
* @property {'has-error' | undefined} className 'has-error' if the form value is invalid and marked as touched. `undefined` otherwise.
18+
* @property {string | undefined | null} help The corresponding value in form `errors` if the form value is marked as touched. `null` otherwise.
19+
*/
20+
21+
/**
22+
* @typedef {Object} AdaptiveFormContextAdapter
23+
* @property {boolean} isSubmitting `true` if the form is currently being submitted.
24+
* @property {boolean} isSubmitted Set to `true` after the form is submitted. Initial value and during submission are set to `false`.
25+
* @property { HTMLElement | null} submitter Set to the element triggering the `handleSubmit` callback until the processing of `onSubmit` is completed. `null` otherwise.
26+
* @property {number} validationRequestCount The current validation request count.
27+
* @property {boolean} requestedShowValidation Whether have requested verification. It will be reset to false after calling hideValidation.
28+
* @property {() => void} showValidation Increase the validation request count by 1.
29+
* @property {() => void} hideValidation Reset the validation request count to 0.
30+
*/
31+
32+
/**
33+
* @typedef {Object} AdaptiveFormContext
34+
* @property {Object} values Form values, e.g. `{ nickname: '' age: 0 }`.
35+
* @property {Object} errors Object with key-value pairs representing errors for form values. Empty object if no errors. For example, `{ nickname: 'Nickname is required.' }`.
36+
* @property {Object} touched Object with key-value pairs representing the corresponding input fields of the form values have received focus, e.g. `{ nickname: true }`.
37+
* @property {boolean} isValidForm `true` if form values pass the validation.
38+
* @property {boolean} isDirty `true` after any of the form values is modified.
39+
* @property {(name: string, value: *) => void} setValue Function to set a form value.
40+
* @property {(name: string) => InputProps} getInputProps Function to get the corresponding input props by a name of the form `values`. The returned props is usually used to assign to input field.
41+
* @property {() => Promise<Object>} handleSubmit Function to trigger form submission.
42+
* @property {(initialValues: Object) => void} resetForm Function to reset form with given initial values.
43+
* @property {React.Dispatch<React.SetStateAction<Object>>} setTouched Function to update the `touched` state, e.g. `setTouched( { nickname: false } )`.
44+
* @property {AdaptiveFormContextAdapter} adapter Additional enhancements to AdaptiveForm.
45+
*/
46+
47+
export const AdaptiveFormContext = createContext( null );
48+
49+
/**
50+
* AdaptiveForm's context hook.
51+
*
52+
* @return {AdaptiveFormContext} AdaptiveForm's context.
53+
* @throws Will throw an error if its context provider is not existing in its parents.
54+
*/
55+
export function useAdaptiveFormContext() {
56+
const adaptiveFormContext = useContext( AdaptiveFormContext );
57+
58+
if ( adaptiveFormContext === null ) {
59+
throw new Error(
60+
'useAdaptiveFormContext was used outside of its context provider AdaptiveForm.'
61+
);
62+
}
63+
64+
return adaptiveFormContext;
65+
}
66+
67+
/**
68+
* AdaptiveForm's input props hook.
69+
*
70+
* @param {string} key Key of the form value.
71+
* @param {string} [validationKey=key] Key of the form value to be used for validation.
72+
*
73+
* @return {Object} Props for an adaptive form input.
74+
*/
75+
export function useAdaptiveFormInputProps( key, validationKey = key ) {
76+
const { getInputProps, adapter } = useAdaptiveFormContext();
77+
78+
return {
79+
...getInputProps( key ),
80+
helper: adapter.renderRequestedValidation( validationKey ),
81+
};
82+
}

0 commit comments

Comments
 (0)