@vtex/faststore-plugin-buyer-portal 1.1.115 → 1.1.116-poc-1
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 +42 -42
- package/src/features/addresses/layouts/AddressDetailsLayout/AddressDetailsLayout.tsx +1 -0
- package/src/features/addresses/layouts/AddressesLayout/AddressesLayout.tsx +1 -0
- package/src/features/budgets/layouts/BudgetsDetailsLayout/BudgetsDetailsLayout.tsx +1 -0
- package/src/features/collections/layouts/CollectionsLayout/CollectionsLayout.tsx +1 -0
- package/src/features/contracts/hooks/index.ts +2 -0
- package/src/features/contracts/hooks/useContractDetails.ts +22 -0
- package/src/features/contracts/hooks/useContractsByOrgUnitId.ts +20 -0
- package/src/features/credit-cards/layouts/CreditCardsLayout/CreditCardLayout.tsx +1 -0
- package/src/features/custom-fields/layouts/CustomFieldsLayout/CustomFieldsLayout.tsx +1 -0
- package/src/features/org-units/hooks/index.ts +1 -0
- package/src/features/org-units/hooks/useOrgUnitBasicData.ts +20 -0
- package/src/features/org-units/layouts/OrgUnitDetailsLayout/OrgUnitDetailsLayout.tsx +31 -28
- package/src/features/payment-methods/layouts/PaymentMethodsLayout/PaymentMethodsLayout.tsx +1 -0
- package/src/features/profile/layouts/ProfileLayout/ProfileLayout.tsx +33 -16
- package/src/features/shared/components/Error/Error.tsx +12 -13
- package/src/features/shared/components/PageLoader/PageLoader.tsx +36 -11
- package/src/features/shared/components/withErrorBoundary/withErrorBoundary.tsx +6 -7
- package/src/features/shared/hooks/index.ts +1 -0
- package/src/features/shared/hooks/useAuth.ts +54 -0
- package/src/features/shared/hooks/useCookieMonitor.ts +2 -6
- package/src/features/shared/layouts/ContractTabsLayout/ContractTabsLayout.tsx +6 -4
- package/src/features/shared/layouts/ErrorTabsLayout/ErrorTabsLayout.tsx +1 -0
- package/src/features/shared/layouts/LoadingTabsLayout/LoadingTabsLayout.tsx +2 -27
- package/src/features/shared/types/AuthRouteProps.ts +2 -8
- package/src/features/shared/utils/withAuth.tsx +10 -62
- package/src/features/shared/utils/withAuthLoader.ts +0 -28
- package/src/features/shared/utils/withAuthProvider.tsx +11 -81
- package/src/features/shared/utils/withLoaderErrorBoundary.ts +71 -79
- package/src/features/shared/utils/withProviders.tsx +1 -2
- package/src/pages/org-unit-details.tsx +32 -58
- package/src/pages/profile.tsx +46 -64
package/package.json
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
2
|
+
"name": "@vtex/faststore-plugin-buyer-portal",
|
|
3
|
+
"version": "1.1.116-poc-1",
|
|
4
|
+
"description": "A plugin for faststore with buyer portal",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
|
8
|
+
"lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
|
|
9
|
+
"prepare": "husky"
|
|
10
|
+
},
|
|
11
|
+
"lint-staged": {
|
|
12
|
+
"*.{js,jsx,ts,tsx}": [
|
|
13
|
+
"eslint --fix"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@types/react-dom": "^19.0.3",
|
|
18
|
+
"react-dom": "^19.0.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@eslint/js": "^9.29.0",
|
|
22
|
+
"@faststore/core": "^3.41.5",
|
|
23
|
+
"@faststore/ui": "^3.41.5",
|
|
24
|
+
"@types/react": "^18.2.42",
|
|
25
|
+
"cypress": "13",
|
|
26
|
+
"eslint": "^9.29.0",
|
|
27
|
+
"eslint-config-prettier": "^10.1.5",
|
|
28
|
+
"eslint-plugin-import": "^2.32.0",
|
|
29
|
+
"eslint-plugin-prettier": "^5.5.1",
|
|
30
|
+
"eslint-plugin-react": "^7.37.5",
|
|
31
|
+
"globals": "^16.2.0",
|
|
32
|
+
"husky": "^9.1.7",
|
|
33
|
+
"lint-staged": "^16.1.2",
|
|
34
|
+
"next": "13.5.7",
|
|
35
|
+
"typescript": "4.7.3",
|
|
36
|
+
"typescript-eslint": "^8.35.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": "^18.2.0",
|
|
40
|
+
"react-dom": "^18.2.0"
|
|
41
|
+
},
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
44
44
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type QueryOptions, useQuery } from "../../shared/hooks";
|
|
2
|
+
import { getContractDetailsService } from "../services";
|
|
3
|
+
|
|
4
|
+
export const useContractDetails = (
|
|
5
|
+
contractId: string,
|
|
6
|
+
unitId: string,
|
|
7
|
+
options?: QueryOptions<AwaitedType<typeof getContractDetailsService>>
|
|
8
|
+
) => {
|
|
9
|
+
const { data, error, isLoading, refetch } = useQuery(
|
|
10
|
+
`api/contract-details/${unitId}`,
|
|
11
|
+
({ cookie }) =>
|
|
12
|
+
getContractDetailsService({ contractId, cookie, unitId: unitId }),
|
|
13
|
+
options
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
contract: data,
|
|
18
|
+
hasContractError: error,
|
|
19
|
+
isContractLoading: isLoading,
|
|
20
|
+
refetchContract: refetch,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type QueryOptions, useQuery } from "../../shared/hooks";
|
|
2
|
+
import { getContractsByOrgUnitIdService } from "../services";
|
|
3
|
+
|
|
4
|
+
export const useContractsByOrgUnitId = (
|
|
5
|
+
orgUnitId: string,
|
|
6
|
+
options?: QueryOptions<AwaitedType<typeof getContractsByOrgUnitIdService>>
|
|
7
|
+
) => {
|
|
8
|
+
const { data, error, isLoading, refetch } = useQuery(
|
|
9
|
+
`api/contracts-by-org-unit-id/${orgUnitId}`,
|
|
10
|
+
({ cookie }) => getContractsByOrgUnitIdService({ orgUnitId, cookie }),
|
|
11
|
+
options
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
contracts: data ?? [],
|
|
16
|
+
hasContractsError: error,
|
|
17
|
+
isContractsLoading: isLoading,
|
|
18
|
+
refetchContracts: refetch,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -5,3 +5,4 @@ export { useUpdateOrgUnit } from "./useUpdateOrgUnit";
|
|
|
5
5
|
export { useChildrenOrgUnits } from "./useChildrenOrgUnits";
|
|
6
6
|
export { useOrgUnitByUser } from "./useOrgUnitByUser";
|
|
7
7
|
export { useSearchOrgUnits } from "./useSearchOrgUnits";
|
|
8
|
+
export { useOrgUnitBasicData } from "./useOrgUnitBasicData";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type QueryOptions, useQuery } from "../../shared/hooks";
|
|
2
|
+
import { getOrgUnitBasicDataService } from "../services";
|
|
3
|
+
|
|
4
|
+
export const useOrgUnitBasicData = (
|
|
5
|
+
id: string,
|
|
6
|
+
options?: QueryOptions<AwaitedType<typeof getOrgUnitBasicDataService>>
|
|
7
|
+
) => {
|
|
8
|
+
const { data, error, isLoading, refetch } = useQuery(
|
|
9
|
+
`api/org-unit-basic-data/${id}`,
|
|
10
|
+
({ cookie }) => getOrgUnitBasicDataService({ id, cookie }),
|
|
11
|
+
options
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
orgUnit: data,
|
|
16
|
+
hasOrgUnitError: error,
|
|
17
|
+
isOrgUnitLoading: isLoading,
|
|
18
|
+
refetchOrgUnit: refetch,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
Skeleton,
|
|
6
6
|
} from "@faststore/ui";
|
|
7
7
|
|
|
8
|
+
import { useContractsByOrgUnitId } from "../../../contracts/hooks";
|
|
8
9
|
import {
|
|
9
10
|
BasicCard,
|
|
10
11
|
BasicDropdownMenu,
|
|
@@ -21,13 +22,14 @@ import {
|
|
|
21
22
|
getOrganizationSettingsLinks,
|
|
22
23
|
} from "../../../shared/utils";
|
|
23
24
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
25
|
+
import { useGetUserById } from "../../../users/hooks";
|
|
24
26
|
import {
|
|
25
27
|
AddAllToOrgUnitDropdown,
|
|
26
28
|
OrgUnitBreadcrumb,
|
|
27
29
|
OrgUnitDetailsNavbar,
|
|
28
30
|
OrgUnitsDropdownMenu,
|
|
29
31
|
} from "../../components";
|
|
30
|
-
import { useOrgUnitByUser } from "../../hooks";
|
|
32
|
+
import { useOrgUnitBasicData, useOrgUnitByUser } from "../../hooks";
|
|
31
33
|
|
|
32
34
|
import {
|
|
33
35
|
MAX_DESKTOP_BREADCRUMB_ITEMS,
|
|
@@ -35,28 +37,29 @@ import {
|
|
|
35
37
|
QUERY_TABLET,
|
|
36
38
|
} from "./utils";
|
|
37
39
|
|
|
38
|
-
import type { ContractData } from "../../../contracts/types";
|
|
39
|
-
import type { UserData } from "../../../users/types";
|
|
40
|
-
import type { OrgUnitBasicData } from "../../types";
|
|
41
|
-
|
|
42
40
|
export type OrgUnitsDetailsLayoutProps = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
contracts: ContractData[];
|
|
46
|
-
user: UserData | null;
|
|
47
|
-
};
|
|
41
|
+
orgUnitId: string;
|
|
42
|
+
userId: string;
|
|
48
43
|
loading?: boolean;
|
|
49
44
|
};
|
|
50
45
|
|
|
51
46
|
export const OrgUnitsDetailsLayout = ({
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
orgUnitId,
|
|
48
|
+
userId,
|
|
49
|
+
loading = true,
|
|
54
50
|
}: OrgUnitsDetailsLayoutProps) => {
|
|
51
|
+
const { orgUnit, isOrgUnitLoading } = useOrgUnitBasicData(orgUnitId);
|
|
52
|
+
|
|
53
|
+
const { contracts, isContractsLoading } = useContractsByOrgUnitId(orgUnitId);
|
|
54
|
+
|
|
55
|
+
const { user, isUserLoading } = useGetUserById({ orgUnitId, userId });
|
|
56
|
+
|
|
57
|
+
loading = isOrgUnitLoading || isContractsLoading || isUserLoading;
|
|
55
58
|
const isMobile = useMediaQuery(QUERY_TABLET);
|
|
56
59
|
|
|
57
60
|
const isSingleContract = contracts.length <= 1;
|
|
58
61
|
|
|
59
|
-
const { orgUnit: userUnit } = useOrgUnitByUser(
|
|
62
|
+
const { orgUnit: userUnit } = useOrgUnitByUser(userId);
|
|
60
63
|
|
|
61
64
|
const orgUnitList = orgUnit?.path.ids.split("/").slice(1) ?? [];
|
|
62
65
|
|
|
@@ -67,7 +70,7 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
67
70
|
const breadcrumbList = orgUnitList.map((orgUnitId, index) => ({
|
|
68
71
|
unitId: orgUnitId,
|
|
69
72
|
item: buyerPortalRoutes.orgUnitDetails({ orgUnitId }),
|
|
70
|
-
name: orgUnit
|
|
73
|
+
name: orgUnit?.path.names.split("/")[index] ?? "",
|
|
71
74
|
position: index + 1,
|
|
72
75
|
enabled: index >= userUnitIndex,
|
|
73
76
|
}));
|
|
@@ -76,7 +79,7 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
76
79
|
<GlobalLayout>
|
|
77
80
|
{/* TODO: Add person here */}
|
|
78
81
|
<OrgUnitDetailsNavbar
|
|
79
|
-
orgName={orgUnit
|
|
82
|
+
orgName={orgUnit?.name ?? ""}
|
|
80
83
|
person={{
|
|
81
84
|
name: user?.name ?? "",
|
|
82
85
|
role: user?.roles?.[0] ?? "",
|
|
@@ -107,8 +110,8 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
107
110
|
<BasicDropdownMenu.Trigger />
|
|
108
111
|
<OrgUnitsDropdownMenu
|
|
109
112
|
isComplete={false}
|
|
110
|
-
id={
|
|
111
|
-
name={orgUnit
|
|
113
|
+
id={orgUnitId}
|
|
114
|
+
name={orgUnit?.name ?? ""}
|
|
112
115
|
/>
|
|
113
116
|
</Dropdown>
|
|
114
117
|
<Dropdown>
|
|
@@ -118,8 +121,8 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
118
121
|
<AddAllToOrgUnitDropdown
|
|
119
122
|
isSingleContract={isSingleContract}
|
|
120
123
|
contractId={contracts[0]?.id}
|
|
121
|
-
unitId={
|
|
122
|
-
unitName={orgUnit?.name}
|
|
124
|
+
unitId={orgUnitId}
|
|
125
|
+
unitName={orgUnit?.name ?? ""}
|
|
123
126
|
/>
|
|
124
127
|
</Dropdown>
|
|
125
128
|
</HeaderInside>
|
|
@@ -129,13 +132,13 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
129
132
|
data-fs-bp-contracts-settings-card
|
|
130
133
|
footerMessage="Manage contract settings"
|
|
131
134
|
footerLink={buyerPortalRoutes.profileDetails({
|
|
132
|
-
orgUnitId:
|
|
135
|
+
orgUnitId: orgUnitId,
|
|
133
136
|
contractId: contracts[0]?.id ?? "",
|
|
134
137
|
})}
|
|
135
138
|
enableFooter
|
|
136
139
|
>
|
|
137
|
-
<LetterHighlight letter={orgUnit
|
|
138
|
-
<VerticalNav.Menu title={orgUnit
|
|
140
|
+
<LetterHighlight letter={orgUnit?.name?.[0] ?? ""} />
|
|
141
|
+
<VerticalNav.Menu title={orgUnit?.name ?? ""} loading={loading}>
|
|
139
142
|
{loading
|
|
140
143
|
? Array(8)
|
|
141
144
|
.fill(null)
|
|
@@ -150,7 +153,7 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
150
153
|
</li>
|
|
151
154
|
))
|
|
152
155
|
: getContractSettingsLinks({
|
|
153
|
-
orgUnitId:
|
|
156
|
+
orgUnitId: orgUnitId,
|
|
154
157
|
contractId: contracts[0]?.id ?? "",
|
|
155
158
|
}).map(({ name, link }) => (
|
|
156
159
|
<VerticalNav.Link key={name} link={link}>
|
|
@@ -177,7 +180,7 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
177
180
|
/>
|
|
178
181
|
}
|
|
179
182
|
href={buyerPortalRoutes.profileDetails({
|
|
180
|
-
orgUnitId:
|
|
183
|
+
orgUnitId: orgUnitId,
|
|
181
184
|
contractId: contract.id,
|
|
182
185
|
})}
|
|
183
186
|
menu={
|
|
@@ -196,12 +199,12 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
196
199
|
data-fs-bp-organizations-settings-card
|
|
197
200
|
footerMessage="Manage organization settings"
|
|
198
201
|
footerLink={buyerPortalRoutes.users({
|
|
199
|
-
orgUnitId:
|
|
202
|
+
orgUnitId: orgUnitId,
|
|
200
203
|
})}
|
|
201
204
|
enableFooter
|
|
202
205
|
>
|
|
203
206
|
<VerticalNav.Menu title="Organization">
|
|
204
|
-
{getOrganizationSettingsLinks(
|
|
207
|
+
{getOrganizationSettingsLinks(orgUnitId).map((option) => (
|
|
205
208
|
<VerticalNav.Link key={option.name} link={option.link}>
|
|
206
209
|
{option.name}
|
|
207
210
|
</VerticalNav.Link>
|
|
@@ -212,14 +215,14 @@ export const OrgUnitsDetailsLayout = ({
|
|
|
212
215
|
data-fs-bp-compliance-settings-card
|
|
213
216
|
footerMessage="Manage finance and compliance settings"
|
|
214
217
|
footerLink={buyerPortalRoutes.buyingPolicies({
|
|
215
|
-
orgUnitId:
|
|
218
|
+
orgUnitId: orgUnitId,
|
|
216
219
|
contractId: contracts[0]?.id,
|
|
217
220
|
})}
|
|
218
221
|
enableFooter
|
|
219
222
|
>
|
|
220
223
|
<VerticalNav.Menu title="Finance and Compliance">
|
|
221
224
|
{getFinanceSettingsLinks({
|
|
222
|
-
orgUnitId:
|
|
225
|
+
orgUnitId: orgUnitId,
|
|
223
226
|
contractId: contracts[0]?.id ?? "",
|
|
224
227
|
}).map((option) => (
|
|
225
228
|
<VerticalNav.Link key={option.name} link={option.link}>
|
|
@@ -1,18 +1,33 @@
|
|
|
1
|
+
import { useContractDetails } from "../../../contracts/hooks";
|
|
2
|
+
import { useOrgUnitBasicData } from "../../../org-units/hooks";
|
|
1
3
|
import { HeaderInside } from "../../../shared/components";
|
|
2
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
3
4
|
import { GlobalLayout, ContractTabsLayout } from "../../../shared/layouts";
|
|
4
|
-
|
|
5
|
-
import type { ContractData } from "../../../contracts/types";
|
|
5
|
+
import { useGetUserById } from "../../../users/hooks";
|
|
6
6
|
|
|
7
7
|
export type ProfileLayoutProps = {
|
|
8
|
-
|
|
8
|
+
orgUnitId: string;
|
|
9
|
+
contractId: string;
|
|
10
|
+
userId: string;
|
|
9
11
|
};
|
|
10
12
|
|
|
11
|
-
export const ProfileLayout = ({
|
|
12
|
-
|
|
13
|
+
export const ProfileLayout = ({
|
|
14
|
+
orgUnitId,
|
|
15
|
+
contractId,
|
|
16
|
+
userId,
|
|
17
|
+
}: ProfileLayoutProps) => {
|
|
18
|
+
const { orgUnit, isOrgUnitLoading } = useOrgUnitBasicData(orgUnitId);
|
|
19
|
+
|
|
20
|
+
const { contract, isContractLoading } = useContractDetails(
|
|
21
|
+
contractId,
|
|
22
|
+
orgUnitId
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const { user, isUserLoading } = useGetUserById({ orgUnitId, userId });
|
|
26
|
+
|
|
27
|
+
const loading = isContractLoading || isOrgUnitLoading || isUserLoading;
|
|
13
28
|
|
|
14
|
-
const creationDate =
|
|
15
|
-
? new Date(
|
|
29
|
+
const creationDate = contract
|
|
30
|
+
? new Date(contract.creationDate).toLocaleDateString("en-US", {
|
|
16
31
|
year: "numeric",
|
|
17
32
|
month: "long",
|
|
18
33
|
day: "numeric",
|
|
@@ -23,30 +38,32 @@ export const ProfileLayout = ({ data }: ProfileLayoutProps) => {
|
|
|
23
38
|
<GlobalLayout>
|
|
24
39
|
<ContractTabsLayout
|
|
25
40
|
orgUnitName={orgUnit?.name ?? ""}
|
|
26
|
-
orgUnitId={
|
|
27
|
-
contractName={
|
|
28
|
-
contractId={
|
|
41
|
+
orgUnitId={orgUnitId}
|
|
42
|
+
contractName={contract?.name ?? ""}
|
|
43
|
+
contractId={contract?.id ?? ""}
|
|
29
44
|
pageName="Contract"
|
|
30
45
|
person={{
|
|
31
46
|
image: undefined,
|
|
32
47
|
name: user?.name ?? "",
|
|
33
|
-
role: user?.
|
|
48
|
+
role: user?.roles?.[0] ?? "",
|
|
49
|
+
id: userId,
|
|
34
50
|
}}
|
|
51
|
+
loading={loading}
|
|
35
52
|
>
|
|
36
53
|
<section data-fs-bp-profile>
|
|
37
54
|
<HeaderInside title="Profile" />
|
|
38
55
|
|
|
39
|
-
{
|
|
56
|
+
{contract && (
|
|
40
57
|
<div data-fs-bp-profile-details>
|
|
41
58
|
<span data-fs-bp-profile-details-title>Details</span>
|
|
42
59
|
|
|
43
|
-
{!!
|
|
60
|
+
{!!contract.name && (
|
|
44
61
|
<>
|
|
45
62
|
<hr data-fs-bp-profile-divider />
|
|
46
63
|
<div data-fs-bp-profile-details-row>
|
|
47
64
|
<span data-fs-bp-profile-details-row-label>Name</span>
|
|
48
65
|
<span data-fs-bp-profile-details-row-value>
|
|
49
|
-
{
|
|
66
|
+
{contract.name}
|
|
50
67
|
</span>
|
|
51
68
|
</div>
|
|
52
69
|
</>
|
|
@@ -57,7 +74,7 @@ export const ProfileLayout = ({ data }: ProfileLayoutProps) => {
|
|
|
57
74
|
<div data-fs-bp-profile-details-row>
|
|
58
75
|
<span data-fs-bp-profile-details-row-label>Email</span>
|
|
59
76
|
<span data-fs-bp-profile-details-row-value>
|
|
60
|
-
<a href={`mailto:${
|
|
77
|
+
<a href={`mailto:${contract.email}`}>{contract.email}</a>
|
|
61
78
|
</span>
|
|
62
79
|
</div>
|
|
63
80
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { isDevelopment } from "../../utils/environment";
|
|
2
2
|
import { Icon } from "../Icon";
|
|
3
3
|
|
|
4
4
|
export type ErrorProps = {
|
|
@@ -20,18 +20,17 @@ export default function Error({ error }: ErrorProps) {
|
|
|
20
20
|
<button data-fs-bp-error-button onClick={() => window.location.reload()}>
|
|
21
21
|
Try again
|
|
22
22
|
</button>
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
</div>
|
|
23
|
+
{isDevelopment() ? (
|
|
24
|
+
<div data-fs-bp-error-details>
|
|
25
|
+
<span data-fs-bp-error-details-type>{error?.tags?.errorType}</span>
|
|
26
|
+
<h2 data-fs-bp-error-details-title>Error Details</h2>
|
|
27
|
+
<p data-fs-bp-error-details-message>{error?.error.message}</p>
|
|
28
|
+
<p data-fs-bp-error-details-stack>Stack: {error?.error.stack}</p>
|
|
29
|
+
<p data-fs-bp-error-details-component>
|
|
30
|
+
Component: {error?.tags?.component}
|
|
31
|
+
</p>
|
|
32
|
+
</div>
|
|
33
|
+
) : null}
|
|
35
34
|
</div>
|
|
36
35
|
);
|
|
37
36
|
}
|
|
@@ -1,22 +1,47 @@
|
|
|
1
1
|
import { Skeleton } from "@faststore/ui";
|
|
2
2
|
|
|
3
|
+
import { useBuyerPortal } from "../../hooks";
|
|
4
|
+
import { BaseTabsLayout } from "../../layouts";
|
|
5
|
+
|
|
3
6
|
/**
|
|
4
7
|
* PageLoader component displays skeleton loaders while page data is being fetched.
|
|
5
8
|
* Used when cookies are not yet available during pre-fetch scenarios.
|
|
6
9
|
*/
|
|
7
10
|
export const PageLoader = () => {
|
|
11
|
+
const { currentOrgUnit, currentUser } = useBuyerPortal();
|
|
8
12
|
return (
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
<BaseTabsLayout data-fs-bp-page-loader>
|
|
14
|
+
<BaseTabsLayout.Navbar
|
|
15
|
+
orgUnit={currentOrgUnit}
|
|
16
|
+
pageName="Loading"
|
|
17
|
+
person={{
|
|
18
|
+
name: currentUser?.name ?? "",
|
|
19
|
+
role: currentUser?.role ?? "",
|
|
20
|
+
id: currentUser?.id ?? "",
|
|
21
|
+
}}
|
|
22
|
+
loading={true}
|
|
23
|
+
/>
|
|
24
|
+
<BaseTabsLayout.Container>
|
|
25
|
+
<BaseTabsLayout.SidebarMenu
|
|
26
|
+
verticalLinks={[]}
|
|
27
|
+
showLetterHighlight={false}
|
|
28
|
+
loading={true}
|
|
29
|
+
/>
|
|
30
|
+
<BaseTabsLayout.Content>
|
|
31
|
+
<div data-fs-bp-page-loader>
|
|
32
|
+
<div data-fs-bp-page-loader-header>
|
|
33
|
+
<Skeleton size={{ width: "12rem", height: "2rem" }} />
|
|
34
|
+
<Skeleton size={{ width: "8rem", height: "1.5rem" }} />
|
|
35
|
+
</div>
|
|
14
36
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
37
|
+
<div data-fs-bp-page-loader-content>
|
|
38
|
+
<Skeleton size={{ width: "100%", height: "4rem" }} />
|
|
39
|
+
<Skeleton size={{ width: "100%", height: "8rem" }} />
|
|
40
|
+
<Skeleton size={{ width: "100%", height: "8rem" }} />
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</BaseTabsLayout.Content>
|
|
44
|
+
</BaseTabsLayout.Container>
|
|
45
|
+
</BaseTabsLayout>
|
|
21
46
|
);
|
|
22
47
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import React from "react";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import { ErrorBoundary } from "../ErrorBoundary/ErrorBoundary";
|
|
6
6
|
|
|
7
7
|
type WithErrorBoundaryOptions = {
|
|
8
8
|
fallback?: React.ReactNode;
|
|
@@ -15,16 +15,15 @@ type WithErrorBoundaryOptions = {
|
|
|
15
15
|
|
|
16
16
|
export function withErrorBoundary<P extends Record<string, unknown>>(
|
|
17
17
|
WrappedComponent: React.ComponentType<P>,
|
|
18
|
-
|
|
19
|
-
_options: WithErrorBoundaryOptions = {}
|
|
18
|
+
options: WithErrorBoundaryOptions = {}
|
|
20
19
|
) {
|
|
21
|
-
|
|
20
|
+
const { onError, tags } = options;
|
|
22
21
|
|
|
23
22
|
const ComponentWithErrorBoundary = (props: P) => {
|
|
24
23
|
return (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
<ErrorBoundary onError={onError} tags={tags}>
|
|
25
|
+
<WrappedComponent {...props} />
|
|
26
|
+
</ErrorBoundary>
|
|
28
27
|
);
|
|
29
28
|
};
|
|
30
29
|
|
|
@@ -13,3 +13,4 @@ export { useAddToScope } from "./useAddToScope";
|
|
|
13
13
|
export { useRemoveFromScope } from "./useRemoveFromScope";
|
|
14
14
|
export { usePageItems, type UsePageItemsProps } from "./usePageItems";
|
|
15
15
|
export { useRouterLoading } from "./useRouterLoading";
|
|
16
|
+
export { useAuth, type UseAuthResult } from "./useAuth";
|