Skip to content
This repository was archived by the owner on Dec 1, 2025. It is now read-only.

Commit e009036

Browse files
authored
Merge pull request #84 from thepensionsregulator/feature-trustee-address-returns-destructuring
Feature trustee address returns destructured from a custom string
2 parents 569e4d3 + 6b45382 commit e009036

6 files changed

Lines changed: 57 additions & 16 deletions

File tree

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
version: 2.1
22
orbs:
3-
node: circleci/node@2.1.1
3+
node: circleci/node@3.0.0
44
jobs:
55
build-and-test:
66
working_directory: ~/react-components

packages/layout/src/components/cards/trustee/context.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ export const TrusteeContext = createContext<TrusteeContextProps>({
1515
send: (_, __) => ({}),
1616
onCorrect: () => {},
1717
onRemove: () => new Promise((res) => res()),
18-
addressAPI: { get: () => new Promise((res) => res()) },
18+
addressAPI: {
19+
get: (endpoint) => Promise.resolve(endpoint),
20+
extract: 'results',
21+
limit: 50,
22+
},
1923
});
2024

2125
type RenderProps = (_: TrusteeContextProps) => ReactElement;
@@ -42,6 +46,15 @@ export interface TrusteeInput {
4246
[key: string]: any;
4347
}
4448

49+
export type AddressAPIType = {
50+
/** API instance with auth to get a list of addresses */
51+
get: (endpoint: string) => Promise<any>;
52+
/** interface return path to the results array */
53+
extract: string;
54+
/** limit of items to display per search */
55+
limit: number;
56+
};
57+
4558
export interface TrusteeContextProps {
4659
complete?: boolean;
4760
testId?: string;
@@ -50,7 +63,7 @@ export interface TrusteeContextProps {
5063
onRemove: (...args: any[]) => Promise<any>;
5164
onCorrect: (...args: any[]) => void;
5265
send: (event: any, payload?: EventData) => Partial<State<TC, any, any, any>>;
53-
addressAPI: any;
66+
addressAPI: AddressAPIType;
5467
current: Partial<State<TC, any, any, any>>;
5568
}
5669

@@ -62,7 +75,8 @@ export interface TrusteeCardProps {
6275
onDetailsSave: (values: any, trustee: TrusteeProps) => Promise<any>;
6376
onContactSave: (values: any, trustee: TrusteeProps) => Promise<any>;
6477
onAddressSave: (values: any, trustee: TrusteeProps) => Promise<any>;
65-
addressAPI: any;
78+
addressAPI: AddressAPIType;
79+
/** depending on your network lib, provide a path to the addressAPI results array */
6680
testId?: string;
6781
children?: RenderProps | ReactElement;
6882
cfg?: SpaceProps;

packages/layout/src/components/cards/trustee/trustee.mdx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import { Trustee } from '@tpr/layout';
2929
<Playground>
3030
{() => {
3131
const [complete, setComplete] = useState(false);
32-
const API = experianApiGet;
3332
const callbackFn = (values, _fullTrusteeObject) => {
3433
console.log(values);
3534
return Promise.resolve();
@@ -62,7 +61,11 @@ import { Trustee } from '@tpr/layout';
6261
onAddressSave={callbackFn}
6362
onRemove={callbackFn}
6463
onCorrect={(value) => setComplete(value)}
65-
addressAPI={API}
64+
addressAPI={{
65+
get: (endpont) => experianApiGet(endpont),
66+
extract: 'results',
67+
limit: 100,
68+
}}
6669
complete={complete}
6770
trustee={trustee}
6871
/>

packages/layout/src/components/cards/trustee/views/address/AutoComplete.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Link } from '@tpr/core';
2+
import { Link, P } from '@tpr/core';
33
import { useTrusteeContext } from '../../context';
44
import { Footer, FooterButton } from '../../../components/card';
55
import { Form, FFSelect } from '@tpr/forms';
@@ -19,25 +19,31 @@ const AutoComplete: React.FC<AutoCompleteProps> = ({
1919
const onSubmit = (values) => {
2020
if (Object.values(values).length > 0) {
2121
send('SAVE', { address: values.address.value });
22-
} else {
23-
Promise.reject('Address has not been selected...');
2422
}
2523
};
2624

2725
return (
2826
<Form onSubmit={onSubmit}>
29-
{({ handleSubmit }) => (
27+
{({ handleSubmit, submitError }) => (
3028
<form onSubmit={handleSubmit}>
3129
<FFSelect
3230
name="address"
3331
placeholder="Please select the address from the dropdown"
3432
options={options}
3533
inputWidth={6}
34+
validate={(value) =>
35+
!value
36+
? 'Please select one of the address from the dropdown menu. If you cannot find your address, please click the link below to enter it manually.'
37+
: undefined
38+
}
3639
disabled={loading}
3740
/>
3841
<Link onClick={onClick} cfg={{ mt: 3 }}>
3942
I can't find my address in the list
4043
</Link>
44+
{submitError && (
45+
<P cfg={{ color: 'danger.2', mt: 5 }}>{submitError}</P>
46+
)}
4147
<Footer>
4248
<FooterButton
4349
type="submit"

packages/layout/src/components/cards/trustee/views/address/Postcode.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useEffect, useCallback, ChangeEvent } from 'react';
22
import { Flex, Button, P, Link } from '@tpr/core';
33
import { Input } from '@tpr/forms';
44
import { extractToObject } from './helpers';
5+
import { getObjectValueByString } from '../../../../../utils';
56
import { useTrusteeContext } from '../../context';
67
import styles from './Postcode.module.scss';
78

@@ -26,15 +27,25 @@ const Postcode: React.FC<PostcodeProps> = ({
2627
const { addressAPI } = useTrusteeContext();
2728

2829
const search = useCallback(
29-
(postcode: string, country = 'GBR', take = 25) => {
30+
(postcode: string, country = 'GBR') => {
3031
setLoading(true);
31-
addressAPI(`search?country=${country}&query=${postcode}&take=${take}`)
32-
.then((resp) => {
33-
if (Array.isArray(resp.results) && resp.results.length > 0) {
32+
addressAPI
33+
.get(
34+
`search?country=${country}&query=${postcode}&take=${
35+
addressAPI.limit || 50
36+
}`,
37+
)
38+
.then((response: unknown) => {
39+
const results = getObjectValueByString(
40+
response,
41+
addressAPI.extract || 'results',
42+
);
43+
44+
if (Array.isArray(results) && results.length > 0) {
3445
Promise.all(
35-
resp.results.map(({ format }: { format: string }) => {
46+
results.map(({ format }: { format: string }) => {
3647
const [url] = format.split('v2/').slice(-1);
37-
return addressAPI(url).then(({ address }) => {
48+
return addressAPI.get(url).then(({ address }) => {
3849
const addressObject = extractToObject(address);
3950

4051
const addressToOurFormat = {

packages/layout/src/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,10 @@ export const truncateString = (str: string, num: number) => {
44

55
export const capitalize = (string) =>
66
`${string.charAt(0).toUpperCase()}${string.slice(1, -1)}`;
7+
8+
export const getObjectValueByString = (
9+
obj: { [key: string]: any },
10+
path: string,
11+
): unknown => {
12+
return path.split('.').reduce((acc, part) => acc && acc[part], obj);
13+
};

0 commit comments

Comments
 (0)