-
Notifications
You must be signed in to change notification settings - Fork 264
feat: added tax id picker field #3469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
WalkthroughA new dynamic form field component, Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DynamicForm
participant TaxIdPickerField
participant Helpers
User->>DynamicForm: Interacts with form (country selection)
DynamicForm->>TaxIdPickerField: Renders TaxIdPickerField with countryCodePath
TaxIdPickerField->>Helpers: getTaxTypeOptionsByCountryCode(countryCode)
Helpers-->>TaxIdPickerField: Returns tax type options array
TaxIdPickerField->>DynamicForm: Renders SelectField with options
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/TaxIdPickerField.tsx(1 hunks)packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/helpers.ts(1 hunks)packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/index.ts(1 hunks)packages/ui/src/components/organisms/Form/DynamicForm/repositories/fields-repository.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (4)
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/index.ts (5)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Export both components and hooks as named exports to improve discoverability and enable easier refactoring.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Export types and interfaces from separate files to promote reuse and maintain a clean codebase.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: Export all types from separate files (e.g., in a types directory) to centralize and reuse type definitions.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-service.mdc:0-0
Timestamp: 2025-06-24T09:37:14.531Z
Learning: Imports in TypeScript files should be grouped in the following order with blank lines between groups: Node.js built-in modules, external npm packages, internal modules using @/ alias, and relative imports.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-service.mdc:0-0
Timestamp: 2025-06-24T09:37:14.531Z
Learning: Only import what is needed using named imports to reduce bundle size and improve clarity.
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/TaxIdPickerField.tsx (3)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Export both components and hooks as named exports to improve discoverability and enable easier refactoring.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/backoffice-v2.mdc:0-0
Timestamp: 2025-06-24T09:35:48.303Z
Learning: In the apps/backoffice-v2 React TypeScript codebase, always use functional components and TypeScript for all UI components to ensure consistency and type safety.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-dashboard.mdc:0-0
Timestamp: 2025-06-24T09:37:03.204Z
Learning: Using React Hook Form for forms enables robust validation, controlled inputs, and user feedback, which are essential for reliable form handling.
packages/ui/src/components/organisms/Form/DynamicForm/repositories/fields-repository.ts (1)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Export both components and hooks as named exports to improve discoverability and enable easier refactoring.
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/helpers.ts (2)
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/kyb-app.mdc:0-0
Timestamp: 2025-06-24T09:36:16.111Z
Learning: Export types and interfaces from separate files to promote reuse and maintain a clean codebase.
Learnt from: CR
PR: ballerine-io/ballerine#0
File: .cursor/rules/workflows-service.mdc:0-0
Timestamp: 2025-06-24T09:37:14.531Z
Learning: Use TypeScript 'as const' for fixed sets of values to ensure literal type inference.
🧬 Code Graph Analysis (2)
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/TaxIdPickerField.tsx (3)
packages/ui/src/components/organisms/Form/DynamicForm/types/index.ts (1)
TDynamicFormField(50-53)packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/helpers.ts (1)
getTaxTypeOptionsByCountryCode(252-267)packages/ui/src/components/organisms/Form/DynamicForm/fields/SelectField/SelectField.tsx (1)
ISelectFieldParams(19-23)
packages/ui/src/components/organisms/Form/DynamicForm/repositories/fields-repository.ts (1)
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/TaxIdPickerField.tsx (1)
TaxIdPickerField(15-41)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/index.ts (1)
1-1: LGTM!Clean re-export following standard patterns for module organization.
packages/ui/src/components/organisms/Form/DynamicForm/repositories/fields-repository.ts (2)
15-15: LGTM!Import follows the established pattern and is placed correctly with other field imports.
35-35: LGTM!Field registration follows the established pattern and maintains consistency with the existing codebase.
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/TaxIdPickerField.tsx (2)
10-13: LGTM!Interface definition is clean and follows TypeScript best practices with optional placeholder and required countryCodePath.
15-41: LGTM!Component implementation follows established patterns with proper memoization, type safety, and clean separation of concerns. The component correctly integrates with the dynamic form system and delegates to SelectField for rendering.
| export const getTaxTypeOptionsByCountryCode = (countryCode: string) => { | ||
| const taxTypes = | ||
| TAX_TYPES_TO_COUNTRY_CODES[countryCode as keyof typeof TAX_TYPES_TO_COUNTRY_CODES]; | ||
|
|
||
| if (!taxTypes) { | ||
| console.error('No tax types found for country code', countryCode); | ||
| toast.error('Something went wrong, please try again or contact support'); | ||
|
|
||
| return []; | ||
| } | ||
|
|
||
| return taxTypes.map(taxType => ({ | ||
| value: taxType, | ||
| label: taxType, | ||
| })); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve type safety and error handling in the helper function.
The function has a few areas for improvement:
- Type assertion safety: The type assertion on line 254 could fail if
countryCodeis not a valid key - Dependency on removed mapping: This function depends on the large mapping that could be optimized
- Error message specificity: The generic error message might not be helpful to users
If keeping the current mapping structure, improve type safety:
export const getTaxTypeOptionsByCountryCode = (countryCode: string) => {
- const taxTypes =
- TAX_TYPES_TO_COUNTRY_CODES[countryCode as keyof typeof TAX_TYPES_TO_COUNTRY_CODES];
+ const taxTypes = TAX_TYPES_TO_COUNTRY_CODES[countryCode as keyof typeof TAX_TYPES_TO_COUNTRY_CODES] || null;
if (!taxTypes) {
- console.error('No tax types found for country code', countryCode);
- toast.error('Something went wrong, please try again or contact support');
+ console.error(`No tax types found for country code: ${countryCode}`);
+ toast.error('Tax ID types not available for selected country');
return [];
}
return taxTypes.map(taxType => ({
value: taxType,
label: taxType,
}));
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const getTaxTypeOptionsByCountryCode = (countryCode: string) => { | |
| const taxTypes = | |
| TAX_TYPES_TO_COUNTRY_CODES[countryCode as keyof typeof TAX_TYPES_TO_COUNTRY_CODES]; | |
| if (!taxTypes) { | |
| console.error('No tax types found for country code', countryCode); | |
| toast.error('Something went wrong, please try again or contact support'); | |
| return []; | |
| } | |
| return taxTypes.map(taxType => ({ | |
| value: taxType, | |
| label: taxType, | |
| })); | |
| }; | |
| export const getTaxTypeOptionsByCountryCode = (countryCode: string) => { | |
| const taxTypes = TAX_TYPES_TO_COUNTRY_CODES[countryCode as keyof typeof TAX_TYPES_TO_COUNTRY_CODES] || null; | |
| if (!taxTypes) { | |
| console.error(`No tax types found for country code: ${countryCode}`); | |
| toast.error('Tax ID types not available for selected country'); | |
| return []; | |
| } | |
| return taxTypes.map(taxType => ({ | |
| value: taxType, | |
| label: taxType, | |
| })); | |
| }; |
🤖 Prompt for AI Agents
In
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/helpers.ts
around lines 252 to 267, improve type safety by avoiding unsafe type assertions
on the countryCode key when accessing TAX_TYPES_TO_COUNTRY_CODES. Instead,
explicitly check if the countryCode exists as a key in the mapping before
accessing it. Enhance error handling by providing a more specific error message
that includes the invalid countryCode value to aid debugging and user clarity.
If the mapping structure remains, ensure the function gracefully handles unknown
country codes without throwing errors and returns an empty array with a clear
log and user notification.
| export const TAX_TYPES_TO_COUNTRY_CODES = { | ||
| AF: ['n/a'], | ||
| AX: ['n/a'], | ||
| AL: ['n/a'], | ||
| DZ: ['n/a'], | ||
| AS: ['n/a'], | ||
| AD: ['n/a'], | ||
| AO: ['n/a'], | ||
| AI: ['n/a'], | ||
| AQ: ['n/a'], | ||
| AG: ['n/a'], | ||
| AR: ['CUIT', 'n/a'], | ||
| AM: ['n/a'], | ||
| AW: ['n/a'], | ||
| AU: ['ABN', 'n/a'], | ||
| AT: ['VAT', 'n/a'], | ||
| AZ: ['n/a'], | ||
| BS: ['n/a'], | ||
| BH: ['n/a'], | ||
| BD: ['n/a'], | ||
| BB: ['n/a'], | ||
| BY: ['n/a'], | ||
| BE: ['VAT', 'n/a'], | ||
| BZ: ['n/a'], | ||
| BJ: ['n/a'], | ||
| BM: ['n/a'], | ||
| BT: ['n/a'], | ||
| BO: ['n/a'], | ||
| BA: ['n/a'], | ||
| BW: ['n/a'], | ||
| BV: ['n/a'], | ||
| BR: ['CNPJ', 'n/a'], | ||
| IO: ['n/a'], | ||
| BN: ['n/a'], | ||
| BG: ['VAT', 'n/a'], | ||
| BF: ['n/a'], | ||
| BI: ['n/a'], | ||
| KH: ['n/a'], | ||
| CM: ['n/a'], | ||
| CA: ['BN', 'SIN', 'n/a'], | ||
| CV: ['n/a'], | ||
| KY: ['n/a'], | ||
| CF: ['n/a'], | ||
| TD: ['n/a'], | ||
| CL: ['RUT', 'n/a'], | ||
| CN: ['n/a'], | ||
| CX: ['n/a'], | ||
| CC: ['n/a'], | ||
| CO: ['RUT', 'n/a'], | ||
| KM: ['n/a'], | ||
| CG: ['n/a'], | ||
| CD: ['n/a'], | ||
| CK: ['n/a'], | ||
| CR: ['n/a'], | ||
| CI: ['n/a'], | ||
| HR: ['VAT', 'n/a'], | ||
| CU: ['n/a'], | ||
| CW: ['n/a'], | ||
| CY: ['VAT', 'n/a'], | ||
| CZ: ['VAT', 'n/a'], | ||
| DK: ['VAT', 'n/a'], | ||
| DJ: ['n/a'], | ||
| DM: ['n/a'], | ||
| DO: ['NATIONAL_ID', 'RNC', 'n/a'], | ||
| EC: ['n/a'], | ||
| EG: ['n/a'], | ||
| SV: ['n/a'], | ||
| GQ: ['n/a'], | ||
| ER: ['n/a'], | ||
| EE: ['VAT', 'n/a'], | ||
| ET: ['n/a'], | ||
| FO: ['n/a'], | ||
| FK: ['n/a'], | ||
| FJ: ['n/a'], | ||
| FI: ['VAT', 'n/a'], | ||
| FR: ['VAT', 'n/a'], | ||
| GF: ['n/a'], | ||
| PF: ['n/a'], | ||
| TF: ['VAT', 'n/a'], | ||
| GA: ['n/a'], | ||
| GM: ['n/a'], | ||
| GE: ['n/a'], | ||
| DE: ['VAT', 'n/a'], | ||
| GH: ['n/a'], | ||
| GI: ['n/a'], | ||
| GR: ['VAT', 'n/a'], | ||
| GL: ['n/a'], | ||
| GD: ['n/a'], | ||
| GP: ['n/a'], | ||
| GU: ['n/a'], | ||
| GT: ['n/a'], | ||
| GG: ['n/a'], | ||
| GN: ['n/a'], | ||
| GW: ['n/a'], | ||
| GY: ['n/a'], | ||
| HT: ['n/a'], | ||
| HM: ['n/a'], | ||
| HN: ['n/a'], | ||
| HK: ['HKBR', 'n/a'], | ||
| HU: ['VAT', 'n/a'], | ||
| IS: ['n/a'], | ||
| IN: ['PAN', 'n/a'], | ||
| ID: ['n/a'], | ||
| IR: ['n/a'], | ||
| IQ: ['n/a'], | ||
| IE: ['VAT', 'n/a'], | ||
| IM: ['n/a'], | ||
| IL: ['n/a'], | ||
| IT: ['VAT', 'n/a'], | ||
| JM: ['n/a'], | ||
| JP: ['n/a'], | ||
| JE: ['n/a'], | ||
| JO: ['n/a'], | ||
| KZ: ['n/a'], | ||
| KE: ['n/a'], | ||
| KI: ['n/a'], | ||
| KP: ['n/a'], | ||
| KR: ['n/a'], | ||
| KW: ['CLN', 'n/a'], | ||
| KG: ['n/a'], | ||
| LA: ['n/a'], | ||
| LV: ['VAT', 'n/a'], | ||
| LB: ['n/a'], | ||
| LS: ['n/a'], | ||
| LR: ['n/a'], | ||
| LY: ['n/a'], | ||
| LI: ['n/a'], | ||
| LT: ['VAT', 'n/a'], | ||
| LU: ['VAT', 'n/a'], | ||
| MO: ['n/a'], | ||
| MK: ['n/a'], | ||
| MG: ['n/a'], | ||
| MW: ['n/a'], | ||
| MY: ['BRNO', 'n/a'], | ||
| MV: ['n/a'], | ||
| ML: ['n/a'], | ||
| MT: ['VAT', 'n/a'], | ||
| MH: ['n/a'], | ||
| MQ: ['n/a'], | ||
| MR: ['n/a'], | ||
| MU: ['n/a'], | ||
| YT: ['n/a'], | ||
| MX: ['RFC', 'n/a'], | ||
| FM: ['n/a'], | ||
| MD: ['n/a'], | ||
| MC: ['n/a'], | ||
| MN: ['n/a'], | ||
| ME: ['n/a'], | ||
| MS: ['n/a'], | ||
| MA: ['n/a'], | ||
| MZ: ['n/a'], | ||
| MM: ['n/a'], | ||
| NA: ['n/a'], | ||
| NR: ['n/a'], | ||
| NP: ['n/a'], | ||
| NL: ['VAT', 'n/a'], | ||
| NC: ['n/a'], | ||
| NZ: ['NZBN', 'n/a'], | ||
| NI: ['n/a'], | ||
| NE: ['n/a'], | ||
| NG: ['n/a'], | ||
| NU: ['n/a'], | ||
| NF: ['n/a'], | ||
| MP: ['n/a'], | ||
| NO: ['VAT', 'n/a'], | ||
| OM: ['n/a'], | ||
| PK: ['n/a'], | ||
| PW: ['n/a'], | ||
| PS: ['n/a'], | ||
| PA: ['RUC', 'n/a'], | ||
| PG: ['n/a'], | ||
| PY: ['n/a'], | ||
| PE: ['RUC', 'n/a'], | ||
| PH: ['n/a'], | ||
| PN: ['n/a'], | ||
| PL: ['VAT', 'n/a'], | ||
| PT: ['VAT', 'n/a'], | ||
| PR: ['n/a'], | ||
| QA: ['CL', 'n/a'], | ||
| RE: ['n/a'], | ||
| RO: ['VAT', 'n/a'], | ||
| RU: ['n/a'], | ||
| RW: ['n/a'], | ||
| BL: ['n/a'], | ||
| SH: ['n/a'], | ||
| KN: ['n/a'], | ||
| LC: ['n/a'], | ||
| MF: ['n/a'], | ||
| PM: ['n/a'], | ||
| VC: ['n/a'], | ||
| WS: ['n/a'], | ||
| SM: ['n/a'], | ||
| ST: ['n/a'], | ||
| SA: ['CR', 'VAT', 'n/a'], | ||
| SN: ['n/a'], | ||
| RS: ['n/a'], | ||
| SC: ['n/a'], | ||
| SL: ['n/a'], | ||
| SG: ['UEN', 'n/a'], | ||
| SK: ['VAT', 'n/a'], | ||
| SI: ['VAT', 'n/a'], | ||
| SB: ['n/a'], | ||
| SO: ['n/a'], | ||
| ZA: ['VAT', 'n/a'], | ||
| GS: ['n/a'], | ||
| ES: ['VAT', 'n/a'], | ||
| LK: ['n/a'], | ||
| SD: ['n/a'], | ||
| SR: ['n/a'], | ||
| SJ: ['n/a'], | ||
| SZ: ['n/a'], | ||
| SE: ['VAT', 'n/a'], | ||
| CH: ['VAT', 'n/a'], | ||
| SY: ['n/a'], | ||
| TW: ['n/a'], | ||
| TJ: ['n/a'], | ||
| TZ: ['n/a'], | ||
| TH: ['n/a'], | ||
| TL: ['n/a'], | ||
| TG: ['n/a'], | ||
| TK: ['n/a'], | ||
| TO: ['n/a'], | ||
| TT: ['n/a'], | ||
| TN: ['n/a'], | ||
| TR: ['VAT', 'n/a'], | ||
| TM: ['n/a'], | ||
| TC: ['n/a'], | ||
| TV: ['n/a'], | ||
| UG: ['n/a'], | ||
| UA: ['EDRPOU', 'VAT', 'n/a'], | ||
| AE: ['VAT', 'n/a'], | ||
| GB: ['VAT', 'n/a'], | ||
| US: ['EIN', 'SSN', 'n/a'], | ||
| UM: ['EIN', 'SSN', 'n/a'], | ||
| UY: ['n/a'], | ||
| UZ: ['n/a'], | ||
| VU: ['n/a'], | ||
| VA: ['n/a'], | ||
| VE: ['n/a'], | ||
| VN: ['n/a'], | ||
| VG: ['n/a'], | ||
| VI: ['n/a'], | ||
| WF: ['n/a'], | ||
| EH: ['n/a'], | ||
| YE: ['n/a'], | ||
| ZM: ['n/a'], | ||
| ZW: ['n/a'], | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Optimize the mapping structure to reduce repetition and improve maintainability.
The current mapping contains significant repetition with most countries having only ['n/a']. This makes the code verbose and harder to maintain.
Consider refactoring to use a more efficient structure:
-export const TAX_TYPES_TO_COUNTRY_CODES = {
- AF: ['n/a'],
- AX: ['n/a'],
- // ... 200+ similar entries
-};
+const SPECIFIC_TAX_TYPES = {
+ AR: ['CUIT', 'n/a'],
+ AU: ['ABN', 'n/a'],
+ AT: ['VAT', 'n/a'],
+ // ... only countries with specific tax types
+} as const;
+
+const DEFAULT_TAX_TYPES = ['n/a'] as const;
+
+export const getTaxTypesByCountryCode = (countryCode: string) => {
+ return SPECIFIC_TAX_TYPES[countryCode as keyof typeof SPECIFIC_TAX_TYPES] || DEFAULT_TAX_TYPES;
+};This approach reduces the mapping from 250+ entries to ~30 entries, improving maintainability and reducing bundle size.
🤖 Prompt for AI Agents
In
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/helpers.ts
around lines 3 to 250, the TAX_TYPES_TO_COUNTRY_CODES object has many entries
with the same value ['n/a'], causing unnecessary repetition and verbosity.
Refactor by creating a default set of countries that map to ['n/a'] and then
explicitly define only the countries with specific tax types. Use this approach
to reduce the total number of entries, improve maintainability, and minimize
bundle size.
| const options = useMemo( | ||
| () => (countryCode ? getTaxTypeOptionsByCountryCode(countryCode) : []), | ||
| [countryCode, countryCodePath], | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix useMemo dependency array to avoid unnecessary re-computations.
The dependency array includes countryCodePath but this value doesn't directly affect the options computation - only countryCode does.
const options = useMemo(
() => (countryCode ? getTaxTypeOptionsByCountryCode(countryCode) : []),
- [countryCode, countryCodePath],
+ [countryCode],
);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const options = useMemo( | |
| () => (countryCode ? getTaxTypeOptionsByCountryCode(countryCode) : []), | |
| [countryCode, countryCodePath], | |
| ); | |
| const options = useMemo( | |
| () => (countryCode ? getTaxTypeOptionsByCountryCode(countryCode) : []), | |
| [countryCode], | |
| ); |
🤖 Prompt for AI Agents
In
packages/ui/src/components/organisms/Form/DynamicForm/fields/TaxIdPickerField/TaxIdPickerField.tsx
around lines 24 to 27, the useMemo hook's dependency array incorrectly includes
countryCodePath, which does not influence the computed options. Remove
countryCodePath from the dependency array so that useMemo only depends on
countryCode, preventing unnecessary recomputations.
Summary by CodeRabbit
New Features
Bug Fixes