@vtex/faststore-plugin-buyer-portal 1.3.42 → 1.3.43

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 CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.3.43] - 2025-12-16
11
+
12
+ ### Fixed
13
+ - Update maskPhoneNumber to include country DDI
14
+ - Send only phone digits to API in Users and Recipients pages
15
+ - Show masked phone in layout and forms in Users and Recipients pages
16
+
10
17
  ## [1.3.42] - 2025-12-11
11
18
 
12
19
  ### Fixed
@@ -377,7 +384,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
377
384
  - Add CHANGELOG file
378
385
  - Add README file
379
386
 
380
- [unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/1.3.42...HEAD
387
+ [unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.43...HEAD
381
388
  [1.2.3]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.2.2...1.2.3
382
389
  [1.2.3]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.2.3
383
390
  [1.2.4]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.2.4
@@ -427,4 +434,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
427
434
  [1.3.36]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.35...v1.3.36
428
435
  [1.3.35]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.35
429
436
 
437
+ [1.3.43]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.42...v1.3.43
430
438
  [1.3.42]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.42
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.3.42",
3
+ "version": "1.3.43",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -19,6 +19,7 @@ import {
19
19
  usePageItems,
20
20
  } from "../../../shared/hooks/usePageItems";
21
21
  import { maskPhoneNumber } from "../../../shared/utils/phoneNumber";
22
+ import { type CountryCodes } from "../../data/countries";
22
23
  import { useSearchAddressRecipients } from "../../hooks/useSearchAddressRecipients";
23
24
  import { RecipientData } from "../../types";
24
25
  import { DeleteRecipientAddressDrawer } from "../DeleteRecipientAddressDrawer/DeleteRecipientAddressDrawer";
@@ -33,7 +34,7 @@ export type AddressRecipientsListProps = {
33
34
  total: number;
34
35
  search: string;
35
36
  page: number;
36
- countryCode?: string;
37
+ countryCode?: CountryCodes;
37
38
  };
38
39
 
39
40
  export const AddressRecipientsList = forwardRef<
@@ -46,7 +47,7 @@ export const AddressRecipientsList = forwardRef<
46
47
  search,
47
48
  total,
48
49
  page = 1,
49
- countryCode = "",
50
+ countryCode,
50
51
  }: AddressRecipientsListProps,
51
52
  ref
52
53
  ) => {
@@ -1,5 +1,8 @@
1
1
  import { Icon, InputText } from "../../../../shared/components";
2
- import { maskPhoneNumber } from "../../../../shared/utils/phoneNumber";
2
+ import {
3
+ maskPhoneNumber,
4
+ normalizePhoneNumber,
5
+ } from "../../../../shared/utils/phoneNumber";
3
6
 
4
7
  import type { RecipientInput } from "../../../types";
5
8
 
@@ -48,7 +51,7 @@ export const RecipientItem = ({
48
51
  <InputText
49
52
  label="Phone Number"
50
53
  className="recipients-phone"
51
- value={recipient.recipientPhone}
54
+ value={maskPhoneNumber(recipient.recipientPhone, "USA")}
52
55
  wrapperProps={{
53
56
  style: {
54
57
  borderTopLeftRadius: 0,
@@ -59,7 +62,7 @@ export const RecipientItem = ({
59
62
  onChange(
60
63
  index,
61
64
  "recipientPhone",
62
- maskPhoneNumber(event.target.value, "USA")
65
+ normalizePhoneNumber(event.target.value)
63
66
  )
64
67
  }
65
68
  />
@@ -1,5 +1,5 @@
1
1
  export type CountryOption = {
2
- id: string;
2
+ id: CountryCodes;
3
3
  name: string;
4
4
  };
5
5
 
@@ -9,3 +9,5 @@ export const CountryOptions: CountryOption[] = [
9
9
  { id: "CAN", name: "Canada" },
10
10
  { id: "MEX", name: "Mexico" },
11
11
  ];
12
+
13
+ export type CountryCodes = "USA" | "MEX" | "BRA" | "CAN";
@@ -1,3 +1,4 @@
1
+ import { normalizePhoneNumber } from "../../../shared/utils/phoneNumber";
1
2
  import { recipientsClient } from "../../clients/RecipientsClient";
2
3
 
3
4
  import type { RecipientsResponse } from "../../types/AddressData";
@@ -34,7 +35,13 @@ export const getAddressRecipientsService = async ({
34
35
  page
35
36
  );
36
37
 
37
- return recipients;
38
+ return {
39
+ ...recipients,
40
+ data: recipients.data.map((recipient) => ({
41
+ ...recipient,
42
+ phone: normalizePhoneNumber(recipient.phone),
43
+ })),
44
+ };
38
45
  } catch (err) {
39
46
  console.error("Failed to get address recipients", err);
40
47
  return { data: [], total: 0 };
@@ -22,4 +22,4 @@ export const SCOPE_KEYS = {
22
22
  CREDIT_CARDS: "creditCards",
23
23
  } as const;
24
24
 
25
- export const CURRENT_VERSION = "1.3.42";
25
+ export const CURRENT_VERSION = "1.3.43";
@@ -1,18 +1,34 @@
1
+ import { type CountryCodes } from "../../addresses/data/countries";
2
+
1
3
  import mask from "./mask";
2
4
 
3
- export function maskPhoneNumber(phoneNumber: string, country?: string) {
4
- if (!phoneNumber) return phoneNumber;
5
+ type MaskType = {
6
+ mask: string;
7
+ length: number;
8
+ ddi: string;
9
+ };
10
+
11
+ const MASK_MAP: Record<CountryCodes, MaskType> = {
12
+ USA: { mask: "(999) 999-9999", length: 14, ddi: "1" },
13
+ MEX: { mask: "(999) 999-9999", length: 14, ddi: "52" },
14
+ BRA: { mask: "(99) 99999-9999", length: 15, ddi: "55" },
15
+ CAN: { mask: "(999) 999-9999", length: 14, ddi: "1" },
16
+ };
17
+
18
+ export function maskPhoneNumber(phoneNumber: string, country?: CountryCodes) {
19
+ if (!phoneNumber || !country || !MASK_MAP[country]) return phoneNumber;
20
+
21
+ const { mask: phoneMask, length, ddi } = MASK_MAP[country];
5
22
 
6
- switch (country) {
7
- case "USA":
8
- return mask(phoneNumber, "(999) 999-9999").substring(0, 14);
9
- case "MEX":
10
- return mask(phoneNumber, "(999) 999-9999").substring(0, 14);
11
- case "BRA":
12
- return mask(phoneNumber, "(99) 99999-9999").substring(0, 15);
13
- case "CAN":
14
- return mask(phoneNumber, "(999) 999-9999").substring(0, 14);
15
- default:
16
- return phoneNumber;
17
- }
23
+ const normalizedPhone = normalizePhoneNumber(phoneNumber);
24
+ const phoneWithoutDdi = normalizedPhone.startsWith(ddi)
25
+ ? normalizedPhone.slice(ddi.length)
26
+ : normalizedPhone;
27
+
28
+ return `+${ddi} ${mask(phoneWithoutDdi, phoneMask).substring(0, length)}`;
29
+ }
30
+
31
+ export function normalizePhoneNumber(phoneNumber: string) {
32
+ if (!phoneNumber) return phoneNumber;
33
+ return phoneNumber.replace(/\D/g, "");
18
34
  }
@@ -15,7 +15,10 @@ import {
15
15
  import { useAnalytics } from "../../../shared/hooks";
16
16
  import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
17
17
  import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
18
- import { maskPhoneNumber } from "../../../shared/utils/phoneNumber";
18
+ import {
19
+ maskPhoneNumber,
20
+ normalizePhoneNumber,
21
+ } from "../../../shared/utils/phoneNumber";
19
22
  import { useAddUserToOrgUnit } from "../../hooks";
20
23
 
21
24
  export type CreateUserDrawerProps = Omit<BasicDrawerProps, "children"> & {
@@ -256,12 +259,12 @@ export const CreateUserDrawer = ({
256
259
 
257
260
  <InputText
258
261
  label="Phone number (optional)"
259
- value={phone}
262
+ value={maskPhoneNumber(phone, "USA")}
260
263
  onChange={(event) =>
261
264
  // TODO: Update this when implementing i18n
262
265
  updateField(
263
266
  "phone",
264
- maskPhoneNumber(event.target.value, "USA")
267
+ normalizePhoneNumber(event.target.value)
265
268
  )
266
269
  }
267
270
  />
@@ -12,7 +12,10 @@ import {
12
12
  } from "../../../shared/components";
13
13
  import { useAnalytics } from "../../../shared/hooks";
14
14
  import { ANALYTICS_EVENTS } from "../../../shared/services/logger/analytics/constants";
15
- import { maskPhoneNumber } from "../../../shared/utils/phoneNumber";
15
+ import {
16
+ maskPhoneNumber,
17
+ normalizePhoneNumber,
18
+ } from "../../../shared/utils/phoneNumber";
16
19
  import { useGetUserById, useUpdateUser } from "../../hooks";
17
20
 
18
21
  export type UpdateUserDrawerProps = Omit<BasicDrawerProps, "children"> & {
@@ -174,7 +177,7 @@ export const UpdateUserDrawer = ({
174
177
  updateUser({
175
178
  userId,
176
179
  name,
177
- phone,
180
+ phone: phone ?? "",
178
181
  roles,
179
182
  orgUnitId,
180
183
  });
@@ -245,10 +248,10 @@ export const UpdateUserDrawer = ({
245
248
  ) : (
246
249
  <InputText
247
250
  label="Phone number (optional)"
248
- value={phone}
251
+ value={maskPhoneNumber(phone, "USA")}
249
252
  onChange={(event) =>
250
253
  // TODO: Update this when implementing i18n
251
- updateField("phone", maskPhoneNumber(event.target.value, "USA"))
254
+ updateField("phone", normalizePhoneNumber(event.target.value))
252
255
  }
253
256
  />
254
257
  )}
@@ -9,6 +9,7 @@ import { useBuyerPortal, useDrawerProps } from "../../../shared/hooks";
9
9
  import { GlobalLayout } from "../../../shared/layouts";
10
10
  import { OrgUnitTabsLayout } from "../../../shared/layouts/OrgUnitTabsLayout/OrgUnitTabLayout";
11
11
  import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
12
+ import { maskPhoneNumber } from "../../../shared/utils/phoneNumber";
12
13
  import { ReassignOrgUnitDrawer, UpdateUserDrawer } from "../../components";
13
14
  import { UserDropdownMenu } from "../../components/UserDropdownMenu/UserDropdownMenu";
14
15
 
@@ -82,7 +83,9 @@ export const UserDetailsLayout = ({
82
83
 
83
84
  <div data-fs-user-details-row>
84
85
  <span data-fs-user-details-row-label>Phone number</span>
85
- <span data-fs-user-details-row-value>{user?.phone}</span>
86
+ <span data-fs-user-details-row-value>
87
+ {maskPhoneNumber(user?.phone ?? "", "USA")}
88
+ </span>
86
89
  </div>
87
90
 
88
91
  <hr data-fs-user-details-divider />
@@ -1,3 +1,4 @@
1
+ import { normalizePhoneNumber } from "../../shared/utils/phoneNumber";
1
2
  import { usersClient } from "../clients/UsersClient";
2
3
 
3
4
  import type { UserData } from "../types";
@@ -23,7 +24,7 @@ export const getUserByIdService = async ({
23
24
  roles: role ? role : [],
24
25
  id: userId,
25
26
  email: email ?? "",
26
- phone: phone ?? "",
27
+ phone: normalizePhoneNumber(phone ?? ""),
27
28
  orgUnit: {
28
29
  name: orgUnit,
29
30
  },