@vtex/faststore-plugin-buyer-portal 1.1.107 → 1.1.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/features/custom-fields/layouts/CustomFieldsLayout/CustomFieldsLayout.tsx +1 -0
- package/src/features/shared/clients/Auth.ts +25 -0
- package/src/features/shared/clients/Client.ts +11 -1
- package/src/features/shared/services/index.ts +4 -0
- package/src/features/shared/services/validate-access.service.ts +11 -0
- package/src/features/shared/types/AuthRouteProps.ts +5 -0
- package/src/features/shared/types/index.ts +1 -0
- package/src/features/shared/utils/constants.ts +1 -1
- package/src/features/shared/utils/index.ts +5 -0
- package/src/features/shared/utils/withAuth.tsx +31 -0
- package/src/features/shared/utils/withAuthLoader.ts +47 -0
- package/src/features/shared/utils/withAuthProvider.tsx +38 -0
- package/src/features/shared/utils/withBuyerPortal.tsx +24 -0
- package/src/features/shared/utils/withProviders.tsx +35 -0
- package/src/pages/address-details.tsx +95 -91
- package/src/pages/addresses.tsx +63 -63
- package/src/pages/budgets-details.tsx +44 -43
- package/src/pages/budgets.tsx +58 -56
- package/src/pages/buying-policies.tsx +84 -78
- package/src/pages/buying-policy-details.tsx +43 -44
- package/src/pages/collections.tsx +59 -60
- package/src/pages/cost-centers.tsx +48 -51
- package/src/pages/credit-cards.tsx +44 -49
- package/src/pages/home.tsx +28 -23
- package/src/pages/org-unit-details.tsx +39 -36
- package/src/pages/org-units.tsx +86 -90
- package/src/pages/payment-methods.tsx +41 -42
- package/src/pages/po-numbers.tsx +43 -46
- package/src/pages/profile.tsx +54 -52
- package/src/pages/releases.tsx +43 -41
- package/src/pages/role-details.tsx +57 -60
- package/src/pages/roles.tsx +42 -39
- package/src/pages/user-details.tsx +58 -58
- package/src/pages/users.tsx +83 -80
package/package.json
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getApiUrl } from "../../shared/utils";
|
|
2
|
+
|
|
3
|
+
import { Client } from "./Client";
|
|
4
|
+
|
|
5
|
+
type AuthContextProps = {
|
|
6
|
+
cookie: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default class AuthClient extends Client {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(getApiUrl());
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
validateAccess(context: AuthContextProps) {
|
|
15
|
+
return this.get<boolean>("granted", {
|
|
16
|
+
headers: {
|
|
17
|
+
Cookie: context.cookie,
|
|
18
|
+
"Content-Type": "text/plain",
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const authClient = new AuthClient();
|
|
25
|
+
export { authClient };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { toQueryParams } from "../utils";
|
|
2
1
|
import {
|
|
3
2
|
getAuthFromCookie,
|
|
4
3
|
getCookieWithoutSessionObjects,
|
|
5
4
|
} from "../utils/cookie";
|
|
5
|
+
import { toQueryParams } from "../utils/toQueryParams";
|
|
6
6
|
|
|
7
7
|
interface RequestConfig<Input = unknown> {
|
|
8
8
|
url: string;
|
|
@@ -87,6 +87,7 @@ class Client {
|
|
|
87
87
|
? getCookieWithoutSessionObjects(headers.Cookie ?? "")
|
|
88
88
|
: {}),
|
|
89
89
|
...(headers.Cookie ? getAuthFromCookie(headers.Cookie ?? "") : {}),
|
|
90
|
+
...headers,
|
|
90
91
|
},
|
|
91
92
|
...(cache ? { cache, next: { revalidate: 300 } } : {}),
|
|
92
93
|
};
|
|
@@ -106,6 +107,15 @@ class Client {
|
|
|
106
107
|
responseData = await response.json();
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
if (contentType?.includes("text/plain")) {
|
|
111
|
+
const text = await response.text();
|
|
112
|
+
try {
|
|
113
|
+
responseData = JSON.parse(text);
|
|
114
|
+
} catch {
|
|
115
|
+
responseData = text as unknown as Return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
109
119
|
if (!response.ok) {
|
|
110
120
|
console.error(`Request to ${url} failed:`, responseData);
|
|
111
121
|
console.error(response.status, response.statusText);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { authClient } from "../clients/Auth";
|
|
2
|
+
|
|
3
|
+
export type ValidateAccessServiceProps = {
|
|
4
|
+
cookie: string;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const validateAccessService = async ({
|
|
8
|
+
cookie,
|
|
9
|
+
}: ValidateAccessServiceProps) => {
|
|
10
|
+
return authClient.validateAccess({ cookie });
|
|
11
|
+
};
|
|
@@ -4,7 +4,7 @@ export const API_URL = (checkoutUrl: string, operation?: string) =>
|
|
|
4
4
|
`${checkoutUrl}/_v/store-front/${operation}`;
|
|
5
5
|
// DEV URL - CHANGE BEFORE MERGE
|
|
6
6
|
// export const API_URL = (checkoutUrl?: string, operation?: string) =>
|
|
7
|
-
// `https://
|
|
7
|
+
// `https://permission--b2bfaststoredev.myvtex.com/_v/store-front/${operation}`;
|
|
8
8
|
|
|
9
9
|
export const DEBOUNCE_TIMEOUT = 500;
|
|
10
10
|
|
|
@@ -37,3 +37,8 @@ export { isPluginError } from "./isPluginError";
|
|
|
37
37
|
export { serializeLoaderData } from "./serializeLoaderData";
|
|
38
38
|
export { withLoaderErrorBoundary } from "./withLoaderErrorBoundary";
|
|
39
39
|
export { withClientErrorBoundary } from "./withClientErrorBoundary";
|
|
40
|
+
export { withAuthProvider } from "./withAuthProvider";
|
|
41
|
+
export { withAuth } from "./withAuth";
|
|
42
|
+
export { withBuyerPortal } from "./withBuyerPortal";
|
|
43
|
+
export { withProviders } from "./withProviders";
|
|
44
|
+
export { withAuthLoader } from "./withAuthLoader";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect, type ComponentType } from "react";
|
|
2
|
+
|
|
3
|
+
import { useRouter } from "next/router";
|
|
4
|
+
|
|
5
|
+
import type { AuthRouteProps } from "../types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* HOC that checks only for authorization
|
|
9
|
+
*/
|
|
10
|
+
export const withAuth = <T extends Record<string, unknown>>(
|
|
11
|
+
Component: ComponentType<T>
|
|
12
|
+
) => {
|
|
13
|
+
return function AuthenticatedComponent(props: AuthRouteProps<T>) {
|
|
14
|
+
const router = useRouter();
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
// If not authorized, reload the page
|
|
18
|
+
if (!props?.authorized) {
|
|
19
|
+
router.reload();
|
|
20
|
+
}
|
|
21
|
+
}, [props?.authorized, router]);
|
|
22
|
+
|
|
23
|
+
// If not authorized, render nothing
|
|
24
|
+
if (!props?.authorized) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// If authorized, render the component with the data
|
|
29
|
+
return <Component {...(props.data as T)} />;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { validateAccessService } from "../services";
|
|
2
|
+
|
|
3
|
+
import { ClientContext, getClientContext } from "./getClientContext";
|
|
4
|
+
|
|
5
|
+
import type { AuthRouteProps } from "../types";
|
|
6
|
+
import type { LoaderData } from "../types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Utility function to encapsulate access validation in loaders.
|
|
10
|
+
* Similar to withAuthProvider but for server-side usage.
|
|
11
|
+
*/
|
|
12
|
+
export const withAuthLoader = async <T>(
|
|
13
|
+
data: LoaderData,
|
|
14
|
+
dataLoader: (clientContext: ClientContext) => Promise<T>
|
|
15
|
+
): Promise<AuthRouteProps<T>> => {
|
|
16
|
+
try {
|
|
17
|
+
const { cookie, userId, ...clientContext } = await getClientContext(data);
|
|
18
|
+
|
|
19
|
+
const hasAccess = await validateAccessService({ cookie });
|
|
20
|
+
|
|
21
|
+
if (!hasAccess) {
|
|
22
|
+
data.res?.writeHead(302, { Location: "/" });
|
|
23
|
+
data.res?.end();
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
authorized: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const pageData = await dataLoader({ cookie, userId, ...clientContext });
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
authorized: true,
|
|
34
|
+
data: pageData,
|
|
35
|
+
clientContext: { cookie, userId, ...clientContext },
|
|
36
|
+
};
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error("Auth validation failed:", error);
|
|
39
|
+
|
|
40
|
+
data.res?.writeHead(302, { Location: "/" });
|
|
41
|
+
data.res?.end();
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
authorized: false,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useEffect, type ComponentType } from "react";
|
|
2
|
+
|
|
3
|
+
import { useRouter } from "next/router";
|
|
4
|
+
|
|
5
|
+
import { BuyerPortalProvider } from "../components";
|
|
6
|
+
|
|
7
|
+
import type { AuthRouteProps } from "../types";
|
|
8
|
+
import type { ClientContext } from "./getClientContext";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* HOC que encapsula lógica de autenticação e provider
|
|
12
|
+
*/
|
|
13
|
+
export const withAuthProvider = <T,>(
|
|
14
|
+
Component: ComponentType<T & { clientContext: ClientContext }>
|
|
15
|
+
) => {
|
|
16
|
+
return function WrappedPage(props: AuthRouteProps<T>) {
|
|
17
|
+
const router = useRouter();
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
// Se não está autorizado, recarrega a página
|
|
21
|
+
if (!props?.authorized) {
|
|
22
|
+
router.reload();
|
|
23
|
+
}
|
|
24
|
+
}, [props?.authorized, router]);
|
|
25
|
+
|
|
26
|
+
// Se não está autorizado, não renderiza nada
|
|
27
|
+
if (!props?.authorized) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Se autorizado, renderiza o componente envolvido no provider
|
|
32
|
+
return (
|
|
33
|
+
<BuyerPortalProvider clientContext={props?.clientContext}>
|
|
34
|
+
<Component {...props.data} clientContext={props?.clientContext} />
|
|
35
|
+
</BuyerPortalProvider>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ComponentType } from "react";
|
|
2
|
+
|
|
3
|
+
import { BuyerPortalProvider } from "../components";
|
|
4
|
+
|
|
5
|
+
import type { ClientContext } from "./getClientContext";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* HOC que adiciona BuyerPortalProvider e context
|
|
9
|
+
*/
|
|
10
|
+
export const withBuyerPortal = <T extends Record<string, unknown>>(
|
|
11
|
+
Component: ComponentType<T>
|
|
12
|
+
) => {
|
|
13
|
+
return function WrappedWithProvider(
|
|
14
|
+
props: T & { context: { clientContext: ClientContext } }
|
|
15
|
+
) {
|
|
16
|
+
const { context, ...componentProps } = props;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<BuyerPortalProvider {...context}>
|
|
20
|
+
<Component {...(componentProps as unknown as T)} />
|
|
21
|
+
</BuyerPortalProvider>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ComponentType } from "react";
|
|
2
|
+
|
|
3
|
+
import { withAuth } from "./withAuth";
|
|
4
|
+
import { withBuyerPortal } from "./withBuyerPortal";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Type for HOCs that can be applied in sequence
|
|
8
|
+
* Using any for flexibility in HOC composition
|
|
9
|
+
*/
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
type ProviderHOC = (Component: ComponentType<any>) => ComponentType<any>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Default project providers applied to all pages.
|
|
15
|
+
* Order: right to left (like pipe/compose)
|
|
16
|
+
*/
|
|
17
|
+
const projectProviders: ProviderHOC[] = [withAuth, withBuyerPortal];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* HOC that applies all default project providers.
|
|
21
|
+
* To add new providers, just include them in the projectProviders array.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* export default withProviders(MyComponent);
|
|
25
|
+
*/
|
|
26
|
+
export const withProviders = <T extends Record<string, unknown>>(
|
|
27
|
+
Component: ComponentType<T>
|
|
28
|
+
): ComponentType<T> => {
|
|
29
|
+
// Apply providers in sequence (right to left)
|
|
30
|
+
return projectProviders.reduceRight(
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
+
(WrappedComponent, provider) => provider(WrappedComponent) as any,
|
|
33
|
+
Component
|
|
34
|
+
) as ComponentType<T>;
|
|
35
|
+
};
|
|
@@ -4,10 +4,7 @@ import { getAddressLocationService } from "../features/addresses/services/locati
|
|
|
4
4
|
import { getAddressRecipientsService } from "../features/addresses/services/recipients/get-address-recipients.service";
|
|
5
5
|
import { getContractDetailsService } from "../features/contracts/services";
|
|
6
6
|
import { getOrgUnitBasicDataService } from "../features/org-units/services";
|
|
7
|
-
import {
|
|
8
|
-
BuyerPortalProvider,
|
|
9
|
-
withErrorBoundary,
|
|
10
|
-
} from "../features/shared/components";
|
|
7
|
+
import { withErrorBoundary } from "../features/shared/components";
|
|
11
8
|
import { ErrorBoundaryProps } from "../features/shared/components/ErrorBoundary/types";
|
|
12
9
|
import {
|
|
13
10
|
PAGE_PARAMS,
|
|
@@ -16,9 +13,10 @@ import {
|
|
|
16
13
|
import { ErrorTabsLayout } from "../features/shared/layouts/ErrorTabsLayout/ErrorTabsLayout";
|
|
17
14
|
import {
|
|
18
15
|
type ClientContext,
|
|
19
|
-
getClientContext,
|
|
20
16
|
getValidPage,
|
|
21
17
|
withLoaderErrorBoundary,
|
|
18
|
+
withAuthLoader,
|
|
19
|
+
withProviders,
|
|
22
20
|
} from "../features/shared/utils";
|
|
23
21
|
import { getUserByIdService } from "../features/users/services";
|
|
24
22
|
|
|
@@ -29,7 +27,7 @@ import type {
|
|
|
29
27
|
} from "../features/addresses/types/AddressData";
|
|
30
28
|
import type { ContractData } from "../features/contracts/types";
|
|
31
29
|
import type { OrgUnitBasicData } from "../features/org-units/types";
|
|
32
|
-
import type { LoaderData } from "../features/shared/types";
|
|
30
|
+
import type { AuthRouteProps, LoaderData } from "../features/shared/types";
|
|
33
31
|
import type { UserData } from "../features/users/types";
|
|
34
32
|
|
|
35
33
|
const DEFAULT_ADDRESS_PAGINATED_DATA = {
|
|
@@ -69,7 +67,7 @@ export type AddressDetailsPageData = {
|
|
|
69
67
|
|
|
70
68
|
const loaderFunction = async (
|
|
71
69
|
data: LoaderData<AddressDetailsPageQuery>
|
|
72
|
-
): Promise<AddressDetailsPageData
|
|
70
|
+
): Promise<AuthRouteProps<AddressDetailsPageData>> => {
|
|
73
71
|
const {
|
|
74
72
|
contractId,
|
|
75
73
|
orgUnitId,
|
|
@@ -82,83 +80,88 @@ const loaderFunction = async (
|
|
|
82
80
|
const pageRecipients = getValidPage(pageRecipientsString);
|
|
83
81
|
const pageLocation = getValidPage(pageLocationString);
|
|
84
82
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const contract = await getContractDetailsService({
|
|
107
|
-
contractId,
|
|
108
|
-
cookie,
|
|
109
|
-
unitId: orgUnitId,
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
const user = await getUserByIdService({ orgUnitId, userId, cookie });
|
|
113
|
-
|
|
114
|
-
const { data: recipients = [], total = 0 } =
|
|
115
|
-
await getAddressRecipientsService({
|
|
116
|
-
unitId: orgUnitId,
|
|
117
|
-
customerId: contractId,
|
|
118
|
-
addressId,
|
|
119
|
-
cookie,
|
|
120
|
-
search: searchRecipients,
|
|
121
|
-
page: pageRecipients,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const { data: locations, total: totalLocations } =
|
|
125
|
-
await getAddressLocationService({
|
|
126
|
-
contractId,
|
|
127
|
-
addressId,
|
|
128
|
-
cookie,
|
|
129
|
-
unitId: orgUnitId,
|
|
130
|
-
search: searchLocations,
|
|
131
|
-
page: pageLocation,
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
data: {
|
|
136
|
-
addressDetails: await getAddressDetailsService(
|
|
137
|
-
addressId,
|
|
83
|
+
return withAuthLoader(
|
|
84
|
+
data,
|
|
85
|
+
async ({ customerId, cookie, userId, ...clientContext }) => {
|
|
86
|
+
if (!contractId || !orgUnitId) {
|
|
87
|
+
return {
|
|
88
|
+
data: {
|
|
89
|
+
addressDetails: null,
|
|
90
|
+
recipientsData: null,
|
|
91
|
+
locationsData: null,
|
|
92
|
+
},
|
|
93
|
+
context: {
|
|
94
|
+
clientContext: { customerId, cookie, userId, ...clientContext },
|
|
95
|
+
currentOrgUnit: null,
|
|
96
|
+
currentContract: null,
|
|
97
|
+
currentUser: null,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const orgUnit = await getOrgUnitBasicDataService({
|
|
138
103
|
cookie,
|
|
104
|
+
id: orgUnitId,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const contract = await getContractDetailsService({
|
|
139
108
|
contractId,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
109
|
+
cookie,
|
|
110
|
+
unitId: orgUnitId,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const user = await getUserByIdService({ orgUnitId, userId, cookie });
|
|
114
|
+
|
|
115
|
+
const { data: recipients = [], total = 0 } =
|
|
116
|
+
await getAddressRecipientsService({
|
|
117
|
+
unitId: orgUnitId,
|
|
118
|
+
customerId: contractId,
|
|
119
|
+
addressId,
|
|
120
|
+
cookie,
|
|
121
|
+
search: searchRecipients,
|
|
122
|
+
page: pageRecipients,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const { data: locations, total: totalLocations } =
|
|
126
|
+
await getAddressLocationService({
|
|
127
|
+
contractId,
|
|
128
|
+
addressId,
|
|
129
|
+
cookie,
|
|
130
|
+
unitId: orgUnitId,
|
|
131
|
+
search: searchLocations,
|
|
132
|
+
page: pageLocation,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
data: {
|
|
137
|
+
addressDetails: await getAddressDetailsService(
|
|
138
|
+
addressId,
|
|
139
|
+
cookie,
|
|
140
|
+
contractId,
|
|
141
|
+
orgUnitId
|
|
142
|
+
),
|
|
143
|
+
recipientsData: {
|
|
144
|
+
data: recipients,
|
|
145
|
+
total,
|
|
146
|
+
search: searchRecipients ?? "",
|
|
147
|
+
page: pageRecipients ?? 1,
|
|
148
|
+
},
|
|
149
|
+
locationsData: {
|
|
150
|
+
data: locations,
|
|
151
|
+
total: totalLocations,
|
|
152
|
+
search: searchLocations ?? "",
|
|
153
|
+
page: pageLocation ?? 1,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
context: {
|
|
157
|
+
clientContext: { customerId, cookie, userId, ...clientContext },
|
|
158
|
+
currentOrgUnit: orgUnit,
|
|
159
|
+
currentContract: contract,
|
|
160
|
+
currentUser: user,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
);
|
|
162
165
|
};
|
|
163
166
|
|
|
164
167
|
export const loader = withLoaderErrorBoundary(loaderFunction, {
|
|
@@ -168,11 +171,10 @@ export const loader = withLoaderErrorBoundary(loaderFunction, {
|
|
|
168
171
|
|
|
169
172
|
const AddressDetailsPage = ({
|
|
170
173
|
data,
|
|
171
|
-
context,
|
|
172
174
|
hasError,
|
|
173
175
|
error,
|
|
174
176
|
}: AddressDetailsPageData) => (
|
|
175
|
-
|
|
177
|
+
<>
|
|
176
178
|
{hasError ? (
|
|
177
179
|
<ErrorTabsLayout error={error} />
|
|
178
180
|
) : (
|
|
@@ -182,12 +184,14 @@ const AddressDetailsPage = ({
|
|
|
182
184
|
locationsData={data.locationsData ?? DEFAULT_ADDRESS_PAGINATED_DATA}
|
|
183
185
|
/>
|
|
184
186
|
)}
|
|
185
|
-
|
|
187
|
+
</>
|
|
186
188
|
);
|
|
187
189
|
|
|
188
|
-
export default
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
190
|
+
export default withProviders(
|
|
191
|
+
withErrorBoundary(AddressDetailsPage, {
|
|
192
|
+
tags: {
|
|
193
|
+
component: "AddressDetailsPage",
|
|
194
|
+
errorType: "address_details_error",
|
|
195
|
+
},
|
|
196
|
+
})
|
|
197
|
+
);
|