@vtex/faststore-plugin-buyer-portal 1.3.26 → 1.3.28
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/CHANGELOG.md +15 -1
- package/package.json +1 -1
- package/src/features/addresses/components/AddRecipientsDrawer/AddRecipientsDrawer.tsx +20 -2
- package/src/features/addresses/components/CreateAddressDrawer/CreateAddressDrawer.tsx +50 -4
- package/src/features/addresses/components/DeleteAddressDrawer/DeleteAddressDrawer.tsx +26 -2
- package/src/features/addresses/components/DeleteAddressLocationDrawer/DeleteAddressLocationDrawer.tsx +29 -3
- package/src/features/addresses/components/DeleteRecipientAddressDrawer/DeleteRecipientAddressDrawer.tsx +24 -2
- package/src/features/addresses/components/EditAddressDrawer/EditAddressDrawer.tsx +28 -2
- package/src/features/addresses/components/EditAddressLocationDrawer/EditAddressLocationDrawer.tsx +30 -4
- package/src/features/addresses/components/EditRecipientAddressDrawer/EditRecipientAddressDrawer.tsx +30 -2
- package/src/features/addresses/components/LocationsDrawer/LocationsDrawer.tsx +29 -2
- package/src/features/budgets/components/BudgetDeleteDrawer/BudgetDeleteDrawer.tsx +32 -4
- package/src/features/budgets/components/CreateBudgetDrawer/CreateBudgetDrawer.tsx +59 -4
- package/src/features/budgets/components/EditBudgetDrawer/EditBudgetDrawer.tsx +28 -1
- package/src/features/buying-policies/components/AddBuyingPolicyDrawer/AddBuyingPolicyDrawer.tsx +48 -5
- package/src/features/buying-policies/components/BasicBuyingPolicyDrawer/basic-buying-policy-drawer.scss +25 -18
- package/src/features/buying-policies/components/DeleteBuyingPolicyDrawer/DeleteBuyingPolicyDrawer.tsx +28 -2
- package/src/features/buying-policies/components/UpdateBuyingPolicyDrawer/UpdateBuyingPolicyDrawer.tsx +49 -5
- package/src/features/custom-fields/components/CreateCustomFieldValueDrawer/CreateCustomFieldValueDrawer.tsx +60 -5
- package/src/features/custom-fields/components/DeleteCustomFieldValueDrawer/DeleteCustomFieldValueDrawer.tsx +61 -5
- package/src/features/custom-fields/components/UpdateCustomFieldValueDrawer/UpdateCustomFieldValueDrawer.tsx +32 -3
- package/src/features/org-units/components/CreateOrgUnitDrawer/CreateOrgUnitDrawer.tsx +18 -0
- package/src/features/org-units/components/DeleteOrgUnitDrawer/DeleteOrgUnitDrawer.tsx +28 -0
- package/src/features/org-units/components/UpdateOrgUnitDrawer/UpdateOrgUnitDrawer.tsx +28 -0
- package/src/features/shared/hooks/analytics/types.ts +14 -0
- package/src/features/shared/hooks/analytics/useAnalytics.ts +249 -0
- package/src/features/shared/hooks/index.ts +1 -0
- package/src/features/shared/services/logger/analytics/analytics.ts +101 -0
- package/src/features/shared/services/logger/analytics/constants.ts +83 -0
- package/src/features/shared/services/logger/analytics/types.ts +108 -0
- package/src/features/shared/services/logger/index.ts +1 -0
- package/src/features/shared/utils/constants.ts +1 -1
- package/src/features/users/components/CreateUserDrawer/CreateUserDrawer.tsx +24 -0
- package/src/features/users/components/DeleteUserDrawer/DeleteUserDrawer.tsx +23 -2
- package/src/features/users/components/UpdateUserDrawer/UpdateUserDrawer.tsx +45 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.3.28] - 2025-11-25
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Setup business metrics and analytics events
|
|
15
|
+
|
|
16
|
+
## [1.3.27] - 2025-11-25
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Style improvements and consistency updates to the `basic-buying-policy-drawer.scss` file.
|
|
21
|
+
|
|
10
22
|
## [1.3.26] - 2025-11-25
|
|
11
23
|
|
|
12
24
|
### Added
|
|
@@ -262,7 +274,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
262
274
|
- Add CHANGELOG file
|
|
263
275
|
- Add README file
|
|
264
276
|
|
|
265
|
-
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.
|
|
277
|
+
[unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.28...HEAD
|
|
266
278
|
[1.2.3]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.2.2...1.2.3
|
|
267
279
|
[1.2.3]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.2.3
|
|
268
280
|
[1.2.4]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.2.4
|
|
@@ -277,6 +289,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
277
289
|
|
|
278
290
|
# <<<<<<< HEAD
|
|
279
291
|
|
|
292
|
+
[1.3.28]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.27...v1.3.28
|
|
293
|
+
[1.3.27]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.26...v1.3.27
|
|
280
294
|
[1.3.26]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.25...v1.3.26
|
|
281
295
|
[1.3.25]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.24...v1.3.25
|
|
282
296
|
[1.3.24]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.23...v1.3.24
|
package/package.json
CHANGED
|
@@ -6,7 +6,8 @@ import { useUI } from "@faststore/ui";
|
|
|
6
6
|
|
|
7
7
|
import { RecipientsForm } from "..";
|
|
8
8
|
import { type BasicDrawerProps, BasicDrawer } from "../../../shared/components";
|
|
9
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
9
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
10
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
10
11
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
11
12
|
import { useAddRecipientsToAddress } from "../../hooks/useAddRecipientsToAddress";
|
|
12
13
|
|
|
@@ -30,12 +31,24 @@ export const AddRecipientsDrawer = ({
|
|
|
30
31
|
const router = useRouter();
|
|
31
32
|
const { pushToast } = useUI();
|
|
32
33
|
const { currentOrgUnit } = useBuyerPortal();
|
|
34
|
+
const { trackEvent, trackEntityCreateError } = useAnalytics({
|
|
35
|
+
entityType: "recipient",
|
|
36
|
+
defaultTimerName: "recipient_creation",
|
|
37
|
+
shouldTrackDefaultTimer: true,
|
|
38
|
+
});
|
|
33
39
|
|
|
34
40
|
const { addRecipientsToAddress, isAddRecipientToAddressLoading } =
|
|
35
41
|
useAddRecipientsToAddress({
|
|
36
42
|
onSuccess: () => {
|
|
37
43
|
const hasTabParam = router.query?.tab === "recipient-tab";
|
|
38
44
|
|
|
45
|
+
trackEvent(ANALYTICS_EVENTS.RECIPIENT_CREATED, {
|
|
46
|
+
recipients_count: recipients.length,
|
|
47
|
+
recipient_names: recipients.map((r) => r.recipientName),
|
|
48
|
+
address_id: addressId ?? router.query.addressId,
|
|
49
|
+
org_unit_id: currentOrgUnit?.id,
|
|
50
|
+
});
|
|
51
|
+
|
|
39
52
|
pushToast({
|
|
40
53
|
message: "Recipients added successfully ",
|
|
41
54
|
status: "INFO",
|
|
@@ -63,7 +76,12 @@ export const AddRecipientsDrawer = ({
|
|
|
63
76
|
refetchRecipients?.();
|
|
64
77
|
}
|
|
65
78
|
},
|
|
66
|
-
onError: () => {
|
|
79
|
+
onError: (error) => {
|
|
80
|
+
trackEntityCreateError(ANALYTICS_EVENTS.RECIPIENT_CREATE_ERROR, error, {
|
|
81
|
+
address_id: addressId ?? router.query.addressId,
|
|
82
|
+
org_unit_id: currentOrgUnit?.id,
|
|
83
|
+
});
|
|
84
|
+
|
|
67
85
|
pushToast({
|
|
68
86
|
message: "An error occurred while adding recipients",
|
|
69
87
|
status: "ERROR",
|
|
@@ -12,7 +12,12 @@ import {
|
|
|
12
12
|
import { TabBar } from "../../../shared/components/Tab/TabBar";
|
|
13
13
|
import { TabContent } from "../../../shared/components/Tab/TabContent";
|
|
14
14
|
import { TabOption } from "../../../shared/components/Tab/TabOption";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
useAddToScope,
|
|
17
|
+
useAnalytics,
|
|
18
|
+
useBuyerPortal,
|
|
19
|
+
} from "../../../shared/hooks";
|
|
20
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
16
21
|
import { useCreateNewAddress } from "../../hooks";
|
|
17
22
|
import { LocationInput } from "../../types/AddressData";
|
|
18
23
|
|
|
@@ -32,6 +37,13 @@ export const CreateAddressDrawer = ({
|
|
|
32
37
|
const [isTouched, setIsTouched] = useState(false);
|
|
33
38
|
const [useExistingAddress, setUseExistingAddress] = useState(false);
|
|
34
39
|
const { currentOrgUnit } = useBuyerPortal();
|
|
40
|
+
const { trackEvent, trackEntityCreated, trackEntityCreateError } =
|
|
41
|
+
useAnalytics({
|
|
42
|
+
entityType: "address",
|
|
43
|
+
defaultTimerName: "address_creation",
|
|
44
|
+
shouldTrackDefaultTimer: true,
|
|
45
|
+
});
|
|
46
|
+
|
|
35
47
|
const [completedAddress, setCompletedAddress] = useState<AddressData>(
|
|
36
48
|
{} as AddressData
|
|
37
49
|
);
|
|
@@ -52,8 +64,33 @@ export const CreateAddressDrawer = ({
|
|
|
52
64
|
const [locations, setLocations] = useState<LocationInput[]>([{ name: "" }]);
|
|
53
65
|
const [recipients, setRecipients] = useState<RecipientInput[]>([]);
|
|
54
66
|
const [invalidAddress, setInvalidAddress] = useState(false);
|
|
67
|
+
const [currentTab, setCurrentTab] = useState<string>("address-tab");
|
|
68
|
+
|
|
69
|
+
const handleTabChange = (tabId: string) => {
|
|
70
|
+
if (currentTab !== tabId) {
|
|
71
|
+
trackEvent(ANALYTICS_EVENTS.ADDRESS_STEP_TIMING, {
|
|
72
|
+
flow_name: "address_creation",
|
|
73
|
+
from_step: currentTab,
|
|
74
|
+
to_step: tabId,
|
|
75
|
+
step_name: tabId,
|
|
76
|
+
org_unit_id: currentOrgUnit?.id,
|
|
77
|
+
});
|
|
78
|
+
setCurrentTab(tabId);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
55
81
|
|
|
56
82
|
const handleCreateNewAddressSuccess = () => {
|
|
83
|
+
trackEntityCreated(ANALYTICS_EVENTS.ADDRESS_CREATED, "address", {
|
|
84
|
+
address_name: address.name,
|
|
85
|
+
address_country: address.country,
|
|
86
|
+
address_city: address.city,
|
|
87
|
+
address_types: address.types,
|
|
88
|
+
locations_count: locations.filter((l) => l.name).length,
|
|
89
|
+
recipients_count: recipients.length,
|
|
90
|
+
use_existing_address: useExistingAddress,
|
|
91
|
+
org_unit_id: currentOrgUnit?.id,
|
|
92
|
+
});
|
|
93
|
+
|
|
57
94
|
pushToast({
|
|
58
95
|
message: "Address added successfully",
|
|
59
96
|
status: "INFO",
|
|
@@ -64,7 +101,11 @@ export const CreateAddressDrawer = ({
|
|
|
64
101
|
|
|
65
102
|
const { createNewAddress, isCreateNewAddressLoading } = useCreateNewAddress({
|
|
66
103
|
onSuccess: handleCreateNewAddressSuccess,
|
|
67
|
-
onError: () => {
|
|
104
|
+
onError: (error) => {
|
|
105
|
+
trackEntityCreateError(ANALYTICS_EVENTS.ADDRESS_CREATE_ERROR, error, {
|
|
106
|
+
org_unit_id: currentOrgUnit?.id,
|
|
107
|
+
});
|
|
108
|
+
|
|
68
109
|
pushToast({
|
|
69
110
|
message: "An error occurred while creating the address",
|
|
70
111
|
status: "ERROR",
|
|
@@ -74,7 +115,12 @@ export const CreateAddressDrawer = ({
|
|
|
74
115
|
|
|
75
116
|
const { addToScope } = useAddToScope({
|
|
76
117
|
onSuccess: handleCreateNewAddressSuccess,
|
|
77
|
-
onError: () => {
|
|
118
|
+
onError: (error) => {
|
|
119
|
+
trackEntityCreateError(ANALYTICS_EVENTS.ADDRESS_CREATE_ERROR, error, {
|
|
120
|
+
org_unit_id: currentOrgUnit?.id,
|
|
121
|
+
use_existing_address: true,
|
|
122
|
+
});
|
|
123
|
+
|
|
78
124
|
pushToast({
|
|
79
125
|
message: "An error occurred while creating the address",
|
|
80
126
|
status: "ERROR",
|
|
@@ -124,7 +170,7 @@ export const CreateAddressDrawer = ({
|
|
|
124
170
|
return (
|
|
125
171
|
<BasicDrawer data-fs-bp-create-address-drawer close={close} {...props}>
|
|
126
172
|
<BasicDrawer.Heading title="Add address" onClose={close} />
|
|
127
|
-
<Tab defaultTabId="address-tab">
|
|
173
|
+
<Tab defaultTabId="address-tab" onChange={handleTabChange}>
|
|
128
174
|
<TabBar>
|
|
129
175
|
<TabOption id="address-tab">Details</TabOption>
|
|
130
176
|
<TabOption id="location-tab">Locations</TabOption>
|
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
BasicDrawer,
|
|
8
8
|
InputText,
|
|
9
9
|
} from "../../../shared/components";
|
|
10
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
10
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
11
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
11
12
|
import { useDeleteAddress } from "../../hooks";
|
|
12
13
|
|
|
13
14
|
export type DeleteAddressDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
@@ -26,9 +27,22 @@ export const DeleteAddressDrawer = ({
|
|
|
26
27
|
}: DeleteAddressDrawerProps) => {
|
|
27
28
|
const { pushToast } = useUI();
|
|
28
29
|
const { currentOrgUnit } = useBuyerPortal();
|
|
30
|
+
const { trackEvent } = useAnalytics({
|
|
31
|
+
entityType: "address",
|
|
32
|
+
entityId: addressId,
|
|
33
|
+
defaultTimerName: "address_delete",
|
|
34
|
+
shouldTrackDefaultTimer: true,
|
|
35
|
+
});
|
|
29
36
|
const [addressNameConfirmation, setAddressNameConfirmation] = useState("");
|
|
30
37
|
|
|
31
38
|
const handleDeleteSuccess = () => {
|
|
39
|
+
trackEvent(ANALYTICS_EVENTS.ADDRESS_DELETED, {
|
|
40
|
+
address_id: addressId,
|
|
41
|
+
address_name: addressName,
|
|
42
|
+
org_unit_id: currentOrgUnit?.id,
|
|
43
|
+
entity_type: "address",
|
|
44
|
+
});
|
|
45
|
+
|
|
32
46
|
pushToast({
|
|
33
47
|
message: "Address deleted successfully",
|
|
34
48
|
status: "INFO",
|
|
@@ -39,7 +53,17 @@ export const DeleteAddressDrawer = ({
|
|
|
39
53
|
|
|
40
54
|
const { deleteAddress, isDeleteAddressLoading } = useDeleteAddress({
|
|
41
55
|
onSuccess: handleDeleteSuccess,
|
|
42
|
-
onError: () => {
|
|
56
|
+
onError: (error) => {
|
|
57
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
58
|
+
|
|
59
|
+
trackEvent(ANALYTICS_EVENTS.ADDRESS_DELETE_ERROR, {
|
|
60
|
+
entity_type: "address",
|
|
61
|
+
entity_id: addressId,
|
|
62
|
+
address_name: addressName,
|
|
63
|
+
org_unit_id: currentOrgUnit?.id,
|
|
64
|
+
error_message: errorMessage,
|
|
65
|
+
});
|
|
66
|
+
|
|
43
67
|
pushToast({
|
|
44
68
|
message: "An error occurred while removing the address from the unit",
|
|
45
69
|
status: "ERROR",
|
|
@@ -3,7 +3,8 @@ import { useState } from "react";
|
|
|
3
3
|
import { useUI } from "@faststore/ui";
|
|
4
4
|
|
|
5
5
|
import { BasicDrawer, BasicDrawerProps } from "../../../shared/components";
|
|
6
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
6
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
7
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
7
8
|
import { useAddressLocationDelete } from "../../hooks";
|
|
8
9
|
import { LocationField } from "../LocationForm/LocationField/LocationField";
|
|
9
10
|
|
|
@@ -28,10 +29,24 @@ export const DeleteAddressLocationDrawer = ({
|
|
|
28
29
|
const [confirmationValue, setConfirmationValue] = useState({ name: "" });
|
|
29
30
|
const deleteIsDisable = confirmationValue.name !== location.value;
|
|
30
31
|
const { currentOrgUnit } = useBuyerPortal();
|
|
32
|
+
const { trackEvent } = useAnalytics({
|
|
33
|
+
entityType: "location",
|
|
34
|
+
entityId: location.id,
|
|
35
|
+
defaultTimerName: "location_delete",
|
|
36
|
+
shouldTrackDefaultTimer: true,
|
|
37
|
+
});
|
|
31
38
|
|
|
32
39
|
const { deleteLocationMutate, deleteLocationLoading } =
|
|
33
40
|
useAddressLocationDelete({
|
|
34
41
|
onSuccess: () => {
|
|
42
|
+
trackEvent(ANALYTICS_EVENTS.LOCATION_DELETED, {
|
|
43
|
+
location_id: location.id,
|
|
44
|
+
location_name: location.value,
|
|
45
|
+
address_id: location.auxId,
|
|
46
|
+
org_unit_id: currentOrgUnit?.id,
|
|
47
|
+
entity_type: "location",
|
|
48
|
+
});
|
|
49
|
+
|
|
35
50
|
pushToast({
|
|
36
51
|
message: "Location removed successfully",
|
|
37
52
|
status: "INFO",
|
|
@@ -40,11 +55,22 @@ export const DeleteAddressLocationDrawer = ({
|
|
|
40
55
|
onDeleteSuccess?.();
|
|
41
56
|
close();
|
|
42
57
|
},
|
|
43
|
-
onError: () =>
|
|
58
|
+
onError: (error) => {
|
|
59
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
60
|
+
|
|
61
|
+
trackEvent(ANALYTICS_EVENTS.LOCATION_DELETE_ERROR, {
|
|
62
|
+
entity_type: "location",
|
|
63
|
+
entity_id: location.id,
|
|
64
|
+
location_name: location.value,
|
|
65
|
+
org_unit_id: currentOrgUnit?.id,
|
|
66
|
+
error_message: errorMessage,
|
|
67
|
+
});
|
|
68
|
+
|
|
44
69
|
pushToast({
|
|
45
70
|
message: "An error occurred while removing location",
|
|
46
71
|
status: "ERROR",
|
|
47
|
-
})
|
|
72
|
+
});
|
|
73
|
+
},
|
|
48
74
|
});
|
|
49
75
|
|
|
50
76
|
const handleDeleteClick = () => {
|
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
BasicDrawer,
|
|
10
10
|
InputText,
|
|
11
11
|
} from "../../../shared/components";
|
|
12
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
12
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
13
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
13
14
|
import { useDeleteRecipientAddress } from "../../hooks/useDeleteRecipientAddress";
|
|
14
15
|
|
|
15
16
|
export type DeleteRecipientAddressDrawerProps = Omit<
|
|
@@ -32,10 +33,24 @@ export const DeleteRecipientAddressDrawer = ({
|
|
|
32
33
|
const { pushToast } = useUI();
|
|
33
34
|
const router = useRouter();
|
|
34
35
|
const { currentOrgUnit } = useBuyerPortal();
|
|
36
|
+
const { trackEvent } = useAnalytics({
|
|
37
|
+
entityType: "recipient",
|
|
38
|
+
entityId: recipientAddressId,
|
|
39
|
+
defaultTimerName: "recipient_delete",
|
|
40
|
+
shouldTrackDefaultTimer: true,
|
|
41
|
+
});
|
|
35
42
|
const [recipientNameConfirmation, setRecipientNameConfirmation] =
|
|
36
43
|
useState("");
|
|
37
44
|
|
|
38
45
|
const handleDeleteSuccess = () => {
|
|
46
|
+
trackEvent(ANALYTICS_EVENTS.RECIPIENT_DELETED, {
|
|
47
|
+
recipient_id: recipientAddressId,
|
|
48
|
+
recipient_name: recipientAddressName,
|
|
49
|
+
address_id: router.query.addressId as string,
|
|
50
|
+
org_unit_id: currentOrgUnit?.id,
|
|
51
|
+
entity_type: "recipient",
|
|
52
|
+
});
|
|
53
|
+
|
|
39
54
|
pushToast({
|
|
40
55
|
message: "Recipient deleted successfully",
|
|
41
56
|
status: "INFO",
|
|
@@ -47,7 +62,14 @@ export const DeleteRecipientAddressDrawer = ({
|
|
|
47
62
|
const { deleteRecipientAddress, isDeleteRecipientAddressLoading } =
|
|
48
63
|
useDeleteRecipientAddress({
|
|
49
64
|
onSuccess: handleDeleteSuccess,
|
|
50
|
-
onError: () => {
|
|
65
|
+
onError: (error) => {
|
|
66
|
+
trackEvent(ANALYTICS_EVENTS.RECIPIENT_DELETE_ERROR, {
|
|
67
|
+
entity_id: recipientAddressId,
|
|
68
|
+
recipient_name: recipientAddressName,
|
|
69
|
+
error_message: error instanceof Error ? error.message : String(error),
|
|
70
|
+
org_unit_id: currentOrgUnit?.id,
|
|
71
|
+
});
|
|
72
|
+
|
|
51
73
|
pushToast({
|
|
52
74
|
message:
|
|
53
75
|
"An error occurred while removing the recipient from address",
|
|
@@ -4,7 +4,8 @@ import { useUI } from "@faststore/ui";
|
|
|
4
4
|
|
|
5
5
|
import { AddressForm } from "..";
|
|
6
6
|
import { type BasicDrawerProps, BasicDrawer } from "../../../shared/components";
|
|
7
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
7
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
8
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
8
9
|
import { useEditAddress } from "../../hooks";
|
|
9
10
|
|
|
10
11
|
import type { AddressInput, AddressData } from "../../types";
|
|
@@ -24,6 +25,12 @@ export const EditAddressDrawer = ({
|
|
|
24
25
|
const { pushToast } = useUI();
|
|
25
26
|
const [isTouched, setIsTouched] = useState(false);
|
|
26
27
|
const { currentOrgUnit } = useBuyerPortal();
|
|
28
|
+
const { trackEntityEdited, trackEntityEditError } = useAnalytics({
|
|
29
|
+
entityType: "address",
|
|
30
|
+
entityId: currentAddress.id,
|
|
31
|
+
defaultTimerName: "address_edit",
|
|
32
|
+
shouldTrackDefaultTimer: true,
|
|
33
|
+
});
|
|
27
34
|
|
|
28
35
|
const [address, setAddress] = useState<AddressInput>({
|
|
29
36
|
...currentAddress,
|
|
@@ -33,6 +40,15 @@ export const EditAddressDrawer = ({
|
|
|
33
40
|
const [, setInvalidAddress] = useState(false);
|
|
34
41
|
|
|
35
42
|
const handleUpdatedAddressSuccess = () => {
|
|
43
|
+
trackEntityEdited(ANALYTICS_EVENTS.ADDRESS_EDITED, {
|
|
44
|
+
address_id: currentAddress.id,
|
|
45
|
+
address_name: address.name,
|
|
46
|
+
address_country: address.country,
|
|
47
|
+
address_city: address.city,
|
|
48
|
+
address_types: address.types,
|
|
49
|
+
org_unit_id: currentOrgUnit?.id,
|
|
50
|
+
});
|
|
51
|
+
|
|
36
52
|
pushToast({
|
|
37
53
|
message: "Address updated successfully",
|
|
38
54
|
status: "INFO",
|
|
@@ -43,7 +59,17 @@ export const EditAddressDrawer = ({
|
|
|
43
59
|
|
|
44
60
|
const { editAddress, isEditAddressLoading } = useEditAddress({
|
|
45
61
|
onSuccess: handleUpdatedAddressSuccess,
|
|
46
|
-
onError: () => {
|
|
62
|
+
onError: (error) => {
|
|
63
|
+
trackEntityEditError(
|
|
64
|
+
ANALYTICS_EVENTS.ADDRESS_EDIT_ERROR,
|
|
65
|
+
"address",
|
|
66
|
+
currentAddress.id ?? "",
|
|
67
|
+
error,
|
|
68
|
+
{
|
|
69
|
+
org_unit_id: currentOrgUnit?.id,
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
47
73
|
pushToast({
|
|
48
74
|
message: "An error occurred while updating the address",
|
|
49
75
|
status: "ERROR",
|
package/src/features/addresses/components/EditAddressLocationDrawer/EditAddressLocationDrawer.tsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
2
|
|
|
3
3
|
import { CheckboxField, useUI } from "@faststore/ui";
|
|
4
4
|
|
|
5
5
|
import { BasicDrawer, BasicDrawerProps } from "../../../shared/components";
|
|
6
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
6
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
7
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
7
8
|
import { LOCAL_STORAGE_LOCATION_EDIT_KEY } from "../../../shared/utils/constants";
|
|
8
9
|
import { useAddressLocationEdit } from "../../hooks";
|
|
9
10
|
import { LocationField } from "../LocationForm/LocationField/LocationField";
|
|
@@ -38,9 +39,23 @@ export const EditAddressLocationDrawer = ({
|
|
|
38
39
|
const saveIsDisable = location.value === field.name;
|
|
39
40
|
const drawerTitle = confirmView ? "Confirm location update" : "Edit location";
|
|
40
41
|
const { currentOrgUnit } = useBuyerPortal();
|
|
42
|
+
const { trackEntityEdited, trackEntityEditError } = useAnalytics({
|
|
43
|
+
entityType: "location",
|
|
44
|
+
entityId: location.id,
|
|
45
|
+
defaultTimerName: "location_edit",
|
|
46
|
+
shouldTrackDefaultTimer: true,
|
|
47
|
+
});
|
|
41
48
|
|
|
42
49
|
const { editLocationMutate, editLocationLoading } = useAddressLocationEdit({
|
|
43
50
|
onSuccess: () => {
|
|
51
|
+
trackEntityEdited(ANALYTICS_EVENTS.LOCATION_EDITED, {
|
|
52
|
+
location_id: location.id,
|
|
53
|
+
location_old_name: location.value,
|
|
54
|
+
location_new_name: field.name,
|
|
55
|
+
address_id: location.auxId,
|
|
56
|
+
org_unit_id: currentOrgUnit?.id,
|
|
57
|
+
});
|
|
58
|
+
|
|
44
59
|
pushToast({
|
|
45
60
|
message: "Location edited successfully",
|
|
46
61
|
status: "INFO",
|
|
@@ -49,11 +64,22 @@ export const EditAddressLocationDrawer = ({
|
|
|
49
64
|
onEditSuccess();
|
|
50
65
|
close();
|
|
51
66
|
},
|
|
52
|
-
onError: () =>
|
|
67
|
+
onError: (error) => {
|
|
68
|
+
trackEntityEditError(
|
|
69
|
+
ANALYTICS_EVENTS.LOCATION_EDIT_ERROR,
|
|
70
|
+
"location",
|
|
71
|
+
location.id,
|
|
72
|
+
error,
|
|
73
|
+
{
|
|
74
|
+
org_unit_id: currentOrgUnit?.id,
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
53
78
|
pushToast({
|
|
54
79
|
message: "An error occurred while editing the location",
|
|
55
80
|
status: "ERROR",
|
|
56
|
-
})
|
|
81
|
+
});
|
|
82
|
+
},
|
|
57
83
|
});
|
|
58
84
|
|
|
59
85
|
const handleSaveClick = () => {
|
package/src/features/addresses/components/EditRecipientAddressDrawer/EditRecipientAddressDrawer.tsx
CHANGED
|
@@ -5,7 +5,8 @@ import { useRouter } from "next/router";
|
|
|
5
5
|
import { CheckboxField, useUI } from "@faststore/ui";
|
|
6
6
|
|
|
7
7
|
import { type BasicDrawerProps, BasicDrawer } from "../../../shared/components";
|
|
8
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
8
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
9
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
9
10
|
import { LOCAL_STORAGE_RECIPIENT_EDIT_KEY } from "../../../shared/utils/constants";
|
|
10
11
|
import { useEditRecipientsToAddress } from "../../hooks/useEditRecipientsToAddress";
|
|
11
12
|
import { type RecipientData, RecipientInput } from "../../types";
|
|
@@ -29,6 +30,13 @@ export const EditRecipientAddressDrawer = ({
|
|
|
29
30
|
const { pushToast } = useUI();
|
|
30
31
|
const router = useRouter();
|
|
31
32
|
const { currentOrgUnit } = useBuyerPortal();
|
|
33
|
+
const { trackEntityEdited, trackEntityEditError } = useAnalytics({
|
|
34
|
+
entityType: "recipient",
|
|
35
|
+
entityId: recipient.id,
|
|
36
|
+
defaultTimerName: "recipient_edit",
|
|
37
|
+
shouldTrackDefaultTimer: true,
|
|
38
|
+
});
|
|
39
|
+
|
|
32
40
|
const initialRecipientName = recipient.firstName + " " + recipient.lastName;
|
|
33
41
|
const [newRecipient, setNewRecipient] = useState({
|
|
34
42
|
name: initialRecipientName,
|
|
@@ -45,6 +53,16 @@ export const EditRecipientAddressDrawer = ({
|
|
|
45
53
|
}, []);
|
|
46
54
|
|
|
47
55
|
const handleEditSuccess = () => {
|
|
56
|
+
trackEntityEdited(ANALYTICS_EVENTS.RECIPIENT_EDITED, {
|
|
57
|
+
recipient_id: recipient.id,
|
|
58
|
+
recipient_old_name: initialRecipientName,
|
|
59
|
+
recipient_new_name: newRecipient.name,
|
|
60
|
+
recipient_old_phone: recipient.phone,
|
|
61
|
+
recipient_new_phone: newRecipient.phone,
|
|
62
|
+
address_id: router.query.addressId as string,
|
|
63
|
+
org_unit_id: currentOrgUnit?.id,
|
|
64
|
+
});
|
|
65
|
+
|
|
48
66
|
pushToast({
|
|
49
67
|
message: "Recipient edited successfully",
|
|
50
68
|
status: "INFO",
|
|
@@ -56,7 +74,17 @@ export const EditRecipientAddressDrawer = ({
|
|
|
56
74
|
const { editRecipientsToAddress, isEditRecipientToAddressLoading } =
|
|
57
75
|
useEditRecipientsToAddress({
|
|
58
76
|
onSuccess: handleEditSuccess,
|
|
59
|
-
onError: () => {
|
|
77
|
+
onError: (error) => {
|
|
78
|
+
trackEntityEditError(
|
|
79
|
+
ANALYTICS_EVENTS.RECIPIENT_EDIT_ERROR,
|
|
80
|
+
"recipient",
|
|
81
|
+
recipient.id,
|
|
82
|
+
error,
|
|
83
|
+
{
|
|
84
|
+
org_unit_id: currentOrgUnit?.id,
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
|
|
60
88
|
pushToast({
|
|
61
89
|
message: "An error occurred while editing the recipient",
|
|
62
90
|
status: "ERROR",
|
|
@@ -6,7 +6,8 @@ import { useUI } from "@faststore/ui";
|
|
|
6
6
|
|
|
7
7
|
import { LocationForm } from "../";
|
|
8
8
|
import { type BasicDrawerProps, BasicDrawer } from "../../../shared/components";
|
|
9
|
-
import { useBuyerPortal } from "../../../shared/hooks";
|
|
9
|
+
import { useAnalytics, useBuyerPortal } from "../../../shared/hooks";
|
|
10
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
10
11
|
import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
|
|
11
12
|
import { useAddLocationsToAddress } from "../../hooks";
|
|
12
13
|
|
|
@@ -28,13 +29,34 @@ export const LocationDrawer = ({
|
|
|
28
29
|
const [locations, setLocations] = useState<LocationInput[]>([{ name: "" }]);
|
|
29
30
|
const { pushToast } = useUI();
|
|
30
31
|
const router = useRouter();
|
|
32
|
+
const { trackEvent, trackEntityCreated, trackEntityCreateError } =
|
|
33
|
+
useAnalytics({
|
|
34
|
+
entityType: "location",
|
|
35
|
+
defaultTimerName: "location_creation",
|
|
36
|
+
shouldTrackDefaultTimer: true,
|
|
37
|
+
});
|
|
31
38
|
|
|
32
39
|
const saveIsDisabled = locations.filter(({ name }) => !!name).length === 0;
|
|
33
40
|
|
|
34
41
|
const { addLocationsMutate, addLocationsLoading } = useAddLocationsToAddress({
|
|
35
42
|
onSuccess: () => {
|
|
43
|
+
const validLocations = locations.filter(({ name }) => !!name);
|
|
36
44
|
const hasTabParam = router.query?.tab === "location-tab";
|
|
37
45
|
|
|
46
|
+
trackEvent(ANALYTICS_EVENTS.LOCATION_CREATED, {
|
|
47
|
+
locations_count: validLocations.length,
|
|
48
|
+
location_names: validLocations.map((l) => l.name),
|
|
49
|
+
address_id: addressId ?? router.query.addressId,
|
|
50
|
+
org_unit_id: currentOrgUnit?.id,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
trackEntityCreated(ANALYTICS_EVENTS.LOCATION_CREATED, "location", {
|
|
54
|
+
locations_count: validLocations.length,
|
|
55
|
+
location_names: validLocations.map((l) => l.name),
|
|
56
|
+
address_id: addressId ?? router.query.addressId,
|
|
57
|
+
org_unit_id: currentOrgUnit?.id,
|
|
58
|
+
});
|
|
59
|
+
|
|
38
60
|
pushToast({
|
|
39
61
|
message: "Locations added successfully ",
|
|
40
62
|
status: "INFO",
|
|
@@ -62,7 +84,12 @@ export const LocationDrawer = ({
|
|
|
62
84
|
onAddLocationSuccess?.();
|
|
63
85
|
}
|
|
64
86
|
},
|
|
65
|
-
onError: () => {
|
|
87
|
+
onError: (error) => {
|
|
88
|
+
trackEntityCreateError(ANALYTICS_EVENTS.LOCATION_CREATE_ERROR, error, {
|
|
89
|
+
address_id: addressId ?? router.query.addressId,
|
|
90
|
+
org_unit_id: currentOrgUnit?.id,
|
|
91
|
+
});
|
|
92
|
+
|
|
66
93
|
pushToast({
|
|
67
94
|
message: "An error occurred while adding locations",
|
|
68
95
|
status: "ERROR",
|
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
ErrorMessage,
|
|
11
11
|
InputText,
|
|
12
12
|
} from "../../../shared/components";
|
|
13
|
-
import { useDebounce } from "../../../shared/hooks";
|
|
13
|
+
import { useAnalytics, useDebounce } from "../../../shared/hooks";
|
|
14
|
+
import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
|
|
14
15
|
import { useDeleteBudget } from "../../hooks/useDeleteBudget";
|
|
15
16
|
|
|
16
17
|
export interface BudgetDeleteDrawerProps
|
|
@@ -33,6 +34,12 @@ export function BudgetDeleteDrawer({
|
|
|
33
34
|
}: BudgetDeleteDrawerProps) {
|
|
34
35
|
const { pushToast } = useUI();
|
|
35
36
|
const router = useRouter();
|
|
37
|
+
const { trackEvent } = useAnalytics({
|
|
38
|
+
entityType: "budget",
|
|
39
|
+
entityId: budgetId,
|
|
40
|
+
defaultTimerName: "budget_delete",
|
|
41
|
+
shouldTrackDefaultTimer: true,
|
|
42
|
+
});
|
|
36
43
|
|
|
37
44
|
const [inputValue, setInputValue] = useState<string>("");
|
|
38
45
|
const [isTouched, setIsTouched] = useState<boolean>(false);
|
|
@@ -47,21 +54,42 @@ export function BudgetDeleteDrawer({
|
|
|
47
54
|
return debouncedValue && debouncedValue !== budgetName
|
|
48
55
|
? "Budget name is invalid"
|
|
49
56
|
: null;
|
|
50
|
-
}, [debouncedValue, isTouched]);
|
|
57
|
+
}, [debouncedValue, isTouched, inputValue, budgetName]);
|
|
51
58
|
|
|
52
59
|
const { mutate: deleteBudget, isLoading: isLoadingDeleteBudget } =
|
|
53
60
|
useDeleteBudget({
|
|
54
61
|
options: {
|
|
55
62
|
onSuccess: handleDeleteSuccess,
|
|
56
|
-
onError: () =>
|
|
63
|
+
onError: (error: Error) => {
|
|
64
|
+
const errorMessage =
|
|
65
|
+
typeof error === "string" ? error : error.message;
|
|
66
|
+
|
|
67
|
+
trackEvent(ANALYTICS_EVENTS.BUDGET_DELETE_ERROR, {
|
|
68
|
+
entity_type: "budget",
|
|
69
|
+
entity_id: budgetId,
|
|
70
|
+
budget_name: budgetName,
|
|
71
|
+
org_unit_id: orgUnitId,
|
|
72
|
+
contract_id: contractId,
|
|
73
|
+
error_message: errorMessage,
|
|
74
|
+
});
|
|
75
|
+
|
|
57
76
|
pushToast({
|
|
58
77
|
status: "ERROR",
|
|
59
78
|
message: "An error occurred while removing the budget",
|
|
60
|
-
})
|
|
79
|
+
});
|
|
80
|
+
},
|
|
61
81
|
},
|
|
62
82
|
});
|
|
63
83
|
|
|
64
84
|
function handleDeleteSuccess() {
|
|
85
|
+
trackEvent(ANALYTICS_EVENTS.BUDGET_DELETED, {
|
|
86
|
+
budget_id: budgetId,
|
|
87
|
+
budget_name: budgetName,
|
|
88
|
+
org_unit_id: orgUnitId,
|
|
89
|
+
contract_id: contractId,
|
|
90
|
+
entity_type: "budget",
|
|
91
|
+
});
|
|
92
|
+
|
|
65
93
|
pushToast({
|
|
66
94
|
status: "INFO",
|
|
67
95
|
message: "Budget deleted successfully",
|