@vtex/faststore-plugin-buyer-portal 1.1.65 → 1.1.67

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.1.65",
3
+ "version": "1.1.67",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -189,6 +189,21 @@ export const AddressForm = ({
189
189
  }
190
190
  />
191
191
 
192
+ <InputText
193
+ label="Neighborhood"
194
+ value={address.neighborhood}
195
+ className="address-postal-code"
196
+ hasError={isTouched && !address.neighborhood?.trim()}
197
+ onChange={(event) =>
198
+ setAddress({ ...address, neighborhood: event.target.value })
199
+ }
200
+ />
201
+
202
+ <ErrorMessage
203
+ show={isTouched && !address.neighborhood?.trim()}
204
+ message="Neighborhood is required"
205
+ />
206
+
192
207
  <InputText
193
208
  label="City"
194
209
  className="address-city"
@@ -104,6 +104,7 @@ export const CreateAddressDrawer = ({
104
104
  address.country &&
105
105
  address.zip &&
106
106
  address.state &&
107
+ address.neighborhood &&
107
108
  address.city &&
108
109
  address.types.length > 0) ||
109
110
  useExistingAddress
@@ -97,7 +97,7 @@ export type AddressInput = {
97
97
  locations?: string[];
98
98
  city: string;
99
99
  types: string[];
100
- neighborhood?: string;
100
+ neighborhood: string;
101
101
  };
102
102
 
103
103
  export type GetAddressesByUnitIdParams = {
@@ -12,6 +12,7 @@ import {
12
12
  InputText,
13
13
  Icon,
14
14
  } from "../../../shared/components";
15
+ import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
15
16
  import { useCreateNewOrgUnit } from "../../hooks";
16
17
 
17
18
  import type { createNewOrgUnitService } from "../../services";
@@ -51,7 +52,13 @@ export const CreateOrgUnitDrawer = ({
51
52
  <button
52
53
  data-fs-bp-toast-view-button
53
54
  type="button"
54
- onClick={() => router.push(`/org-unit/${data.id}`)}
55
+ onClick={() =>
56
+ router.push(
57
+ buyerPortalRoutes.orgUnitDetails({
58
+ orgUnitId: data.id,
59
+ })
60
+ )
61
+ }
55
62
  >
56
63
  View
57
64
  </button>
@@ -1,11 +1,19 @@
1
1
  import { Icon } from "../../../shared/components";
2
+ import { useBuyerPortal } from "../../../shared/hooks";
2
3
  import { OrgUnitBreadcrumbProps } from "../../types";
3
4
 
4
5
  import { OrgUnitBreadcrumbDropdown } from "./OrgUnitBreadcrumbDropdown";
5
6
  import { OrgUnitBreadcrumbPath } from "./OrgUnitBreadcrumbPath";
6
7
 
7
- export const OrgUnitBreadcrumb = ({ items }: OrgUnitBreadcrumbProps) => {
8
+ export const OrgUnitBreadcrumb = ({
9
+ items,
10
+ maxItems,
11
+ }: OrgUnitBreadcrumbProps) => {
12
+ const { currentContract } = useBuyerPortal();
8
13
  const sortedByPosition = [...items].sort((a, b) => a.position - b.position);
14
+
15
+ const offset = -Math.min(items.length, maxItems);
16
+
9
17
  const divider = (
10
18
  <Icon
11
19
  data-fs-bp-breadcrumb-divider
@@ -15,12 +23,16 @@ export const OrgUnitBreadcrumb = ({ items }: OrgUnitBreadcrumbProps) => {
15
23
  />
16
24
  );
17
25
 
26
+ const inBreadcrumb = sortedByPosition.slice(0, offset);
27
+
18
28
  return (
19
29
  <nav data-fs-bp-breadcrumb-nav>
20
- <OrgUnitBreadcrumbDropdown items={sortedByPosition.slice(0, -2)} />
21
- {items.length > 2 && divider}
30
+ <OrgUnitBreadcrumbDropdown items={inBreadcrumb} />
31
+ {Boolean(inBreadcrumb.length) && divider}
32
+
22
33
  <OrgUnitBreadcrumbPath
23
- items={sortedByPosition.slice(-2)}
34
+ contractId={currentContract?.id ?? ""}
35
+ items={sortedByPosition.slice(offset)}
24
36
  divider={divider}
25
37
  />
26
38
  </nav>
@@ -7,7 +7,7 @@ import { OrgUnitBreadcrumbProps } from "../../types";
7
7
 
8
8
  export const OrgUnitBreadcrumbDropdown = ({
9
9
  items,
10
- }: OrgUnitBreadcrumbProps) => {
10
+ }: Pick<OrgUnitBreadcrumbProps, "items">) => {
11
11
  const { push } = useRouter();
12
12
 
13
13
  const dropdownItems = items.map((item) => (
@@ -1,27 +1,53 @@
1
1
  import { Fragment } from "react";
2
2
 
3
+ import { Dropdown } from "@faststore/ui";
4
+
5
+ import { BasicDropdownMenu } from "../../../shared/components";
3
6
  import { OrgUnitBreadcrumbPathProps } from "../../types";
7
+ import { AddAllToOrgUnitDropdown } from "../AddAllToOrgUnitDropdown/AddAllToOrgUnitDropdown";
8
+ import { OrgUnitsDropdownMenu } from "../OrgUnitsDropdownMenu/OrgUnitsDropdownMenu";
4
9
 
5
10
  import { OrgUnitBreadcrumbLink } from "./OrgUnitBreadcrumbLink";
6
11
 
7
12
  export const OrgUnitBreadcrumbPath = ({
8
13
  items,
14
+ contractId,
9
15
  divider,
10
16
  }: OrgUnitBreadcrumbPathProps) =>
11
- items.flatMap((item, index) => {
17
+ items.map((item, index) => {
12
18
  const isLast = index === items.length - 1;
13
- const link = [
14
- <OrgUnitBreadcrumbLink
15
- key={item.item}
16
- item={item.item}
17
- name={item.name}
18
- isLast={isLast}
19
- />,
20
- ];
21
19
 
22
- if (!isLast && divider) {
23
- link.push(<Fragment key={index}>{divider}</Fragment>);
20
+ if (isLast) {
21
+ return (
22
+ <Fragment key={item.item}>
23
+ <OrgUnitBreadcrumbLink
24
+ item={item.item}
25
+ name={item.name}
26
+ isLast={isLast}
27
+ />
28
+ <Dropdown>
29
+ <BasicDropdownMenu.Trigger iconName="ArrowDropDown" />
30
+
31
+ <OrgUnitsDropdownMenu id={item.item} name={item.name} />
32
+ <AddAllToOrgUnitDropdown
33
+ isSingleContract
34
+ contractId={contractId}
35
+ unitId={item.unitId}
36
+ unitName={item.name}
37
+ />
38
+ </Dropdown>
39
+ </Fragment>
40
+ );
24
41
  }
25
42
 
26
- return link;
43
+ return (
44
+ <Fragment key={item.item}>
45
+ <OrgUnitBreadcrumbLink
46
+ item={item.item}
47
+ name={item.name}
48
+ isLast={isLast}
49
+ />
50
+ {divider}
51
+ </Fragment>
52
+ );
27
53
  });
@@ -1,16 +1,25 @@
1
- @import '@faststore/ui/src/components/molecules/Dropdown/styles.scss';
2
- @import '@faststore/ui/src/components/molecules/Tooltip/styles.scss';
1
+ @import "@faststore/ui/src/components/molecules/Dropdown/styles.scss";
2
+ @import "@faststore/ui/src/components/molecules/Tooltip/styles.scss";
3
3
 
4
4
  [data-fs-bp-breadcrumb-nav] {
5
5
  flex: 1;
6
6
  display: flex;
7
7
  align-items: center;
8
- flex-wrap: wrap;
9
8
  gap: var(--fs-spacing-1);
10
9
 
11
10
  [data-fs-tooltip] {
12
- --fs-tooltip-background: #1F1F1F;
13
- --fs-tooltip-border-radius: .25rem;
11
+ --fs-tooltip-background: #1f1f1f;
12
+ --fs-tooltip-border-radius: 0.25rem;
13
+ }
14
+ @include media(">=tablet") {
15
+ flex-wrap: wrap;
16
+ }
17
+
18
+ [data-fs-bp-basic-dropdown-menu-trigger] {
19
+ color: var(--fs-color-neutral-6);
20
+ padding: 0;
21
+ width: calc(var(--fs-spacing-0) + var(--fs-spacing-3));
22
+ height: calc(var(--fs-spacing-0) + var(--fs-spacing-3));
14
23
  }
15
24
  }
16
25
 
@@ -18,11 +27,12 @@
18
27
  flex: 0 0 max-content;
19
28
  max-width: 28.125rem; // 450px
20
29
 
21
- p, a {
30
+ p,
31
+ a {
22
32
  font-size: var(--fs-text-size-4);
23
33
  line-height: var(--fs-text-size-6);
24
34
  font-weight: var(--fs-text-weight-semibold);
25
- color: #5C5C5C;
35
+ color: #5c5c5c;
26
36
  text-decoration: none;
27
37
  cursor: pointer;
28
38
  transition: all 0.2s;
@@ -47,4 +57,4 @@
47
57
  [data-fs-bp-breadcrumb-divider] {
48
58
  color: #858585;
49
59
  flex: 0 0 auto;
50
- }
60
+ }
@@ -6,6 +6,10 @@
6
6
  background-color: #ffffff;
7
7
  border-bottom: var(--fs-border-width) solid #ebebeb;
8
8
 
9
+ @include media("<=tablet") {
10
+ padding: var(--fs-spacing-0) calc(var(--fs-spacing-3) + var(--fs-spacing-0));
11
+ }
12
+
9
13
  [data-fs-bp-org-unit-details-navbar-link] {
10
14
  font-weight: var(--fs-text-weight-bold);
11
15
  font-size: var(--fs-text-size-4);
@@ -26,6 +30,10 @@
26
30
  padding: calc(var(--fs-spacing-1) + var(--fs-spacing-2))
27
31
  calc(var(--fs-spacing-3) + var(--fs-spacing-0));
28
32
 
33
+ @include media("<=tablet") {
34
+ display: none;
35
+ }
36
+
29
37
  color: #3d3d3d;
30
38
  font-weight: var(--fs-text-weight-semibold);
31
39
  line-height: calc(var(--fs-spacing-3) + var(--fs-spacing-0));
@@ -10,6 +10,7 @@ import {
10
10
  ErrorMessage,
11
11
  InputText,
12
12
  } from "../../../shared/components";
13
+ import { buyerPortalRoutes } from "../../../shared/utils/buyerPortalRoutes";
13
14
  import { useUpdateOrgUnit } from "../../hooks";
14
15
 
15
16
  export type UpdateOrgUnitDrawerProps = Omit<BasicDrawerProps, "children"> & {
@@ -41,7 +42,13 @@ export const UpdateOrgUnitDrawer = ({
41
42
  <button
42
43
  data-fs-bp-toast-view-button
43
44
  type="button"
44
- onClick={() => router.push(`/org-unit/${id}`)}
45
+ onClick={() =>
46
+ router.push(
47
+ buyerPortalRoutes.orgUnitDetails({
48
+ orgUnitId: id,
49
+ })
50
+ )
51
+ }
45
52
  >
46
53
  View
47
54
  </button>
@@ -13,6 +13,7 @@ import {
13
13
  LetterHighlight,
14
14
  VerticalNav,
15
15
  } from "../../../shared/components";
16
+ import { useMediaQuery } from "../../../shared/hooks/useMediaQuery";
16
17
  import { GlobalLayout } from "../../../shared/layouts";
17
18
  import {
18
19
  getContractSettingsLinks,
@@ -27,6 +28,12 @@ import {
27
28
  OrgUnitsDropdownMenu,
28
29
  } from "../../components";
29
30
 
31
+ import {
32
+ MAX_DESKTOP_BREADCRUMB_ITEMS,
33
+ MAX_MOBILE_BREADCRUMB_ITEMS,
34
+ QUERY_TABLET,
35
+ } from "./utils";
36
+
30
37
  import type { ContractData } from "../../../contracts/types";
31
38
  import type { UserData } from "../../../users/types";
32
39
  import type { OrgUnitBasicData } from "../../types";
@@ -44,11 +51,14 @@ export const OrgUnitsDetailsLayout = ({
44
51
  data: { orgUnit, contracts, user },
45
52
  loading = false,
46
53
  }: OrgUnitsDetailsLayoutProps) => {
54
+ const isMobile = useMediaQuery(QUERY_TABLET);
55
+
47
56
  const isSingleContract = contracts.length <= 1;
48
57
  const breadcrumbList = orgUnit.path.ids
49
58
  .split("/")
50
59
  .slice(1)
51
60
  .map((orgUnitId, index) => ({
61
+ unitId: orgUnitId,
52
62
  item: buyerPortalRoutes.orgUnitDetails({ orgUnitId }),
53
63
  name: orgUnit.path.names.split("/")[index],
54
64
  position: index + 1,
@@ -75,7 +85,14 @@ export const OrgUnitsDetailsLayout = ({
75
85
  }}
76
86
  />
77
87
  ) : (
78
- <OrgUnitBreadcrumb items={breadcrumbList} />
88
+ <OrgUnitBreadcrumb
89
+ items={breadcrumbList}
90
+ maxItems={
91
+ isMobile
92
+ ? MAX_MOBILE_BREADCRUMB_ITEMS
93
+ : MAX_DESKTOP_BREADCRUMB_ITEMS
94
+ }
95
+ />
79
96
  )}
80
97
 
81
98
  <Dropdown>
@@ -1,5 +1,5 @@
1
1
  @import "@faststore/ui/src/components/molecules/Dropdown/styles.scss";
2
- @import '@faststore/ui/src/components/molecules/Breadcrumb/styles.scss';
2
+ @import "@faststore/ui/src/components/molecules/Breadcrumb/styles.scss";
3
3
  @import "../../../shared/components/BasicDropdownMenu/basic-dropdown-menu.scss";
4
4
  @import "../../components/OrgUnitDetailsNavbar/org-unit-details-navbar.scss";
5
5
  @import "../../../credit-cards/components/CreateCreditCardDrawer/create-credit-card-drawer.scss";
@@ -10,97 +10,99 @@
10
10
  @import "../../../shared/components/VerticalNav/vertical-nav.scss";
11
11
  @import "../../../shared/components/LetterHighlight/letter-highlight.scss";
12
12
  @import "../../../shared/components/HeaderInside/header-inside.scss";
13
+
14
+
15
+ $fs-spacing-3-0: calc(var(--fs-spacing-3) + var(--fs-spacing-0)); // 1.25rem, 20px
16
+ $fs-spacing-3-2: calc(var(--fs-spacing-3) + var(--fs-spacing-2)); // 1.75rem, 28px
17
+ $fs-spacing-7-2: calc(var(--fs-spacing-7) + var(--fs-spacing-2)); // 3.75rem, 52px
18
+ $fs-spacing-9-0: calc(var(--fs-spacing-9) + var(--fs-spacing-0)); // 4.25rem, 68px
19
+ $fs-spacing-13-4: calc(var(--fs-spacing-13) + var(--fs-spacing-4)); // 7.5rem, 120px
13
20
 
14
- padding: 0 calc(var(--fs-spacing-8) + var(--fs-spacing-0))
15
- calc(var(--fs-spacing-13) - var(--fs-spacing-0))
16
- calc(var(--fs-spacing-8) + var(--fs-spacing-0));
17
- min-height: calc(100vh - calc(var(--fs-spacing-9) + var(--fs-spacing-0)));
21
+ padding: 0 $fs-spacing-7-2 $fs-spacing-13-4 $fs-spacing-7-2;
22
+
23
+ @include media("<notebook") {
24
+ padding: 0 var(--fs-spacing-7) $fs-spacing-13-4;
25
+ }
26
+
27
+ @include media("<tablet") {
28
+ padding: 0 $fs-spacing-3-0 $fs-spacing-7-2;
29
+ }
30
+
31
+ min-height: calc(100vh - $fs-spacing-9-0);
18
32
  display: flex;
19
33
  flex-direction: column;
20
34
 
35
+ [data-fs-bp-header-inside] {
36
+ margin: 0;
37
+ height: 4.5rem;
38
+
39
+ @include media("<tablet") {
40
+ margin: var(--fs-spacing-3) 0;
41
+ }
42
+
43
+ [data-fs-header-inside-button] {
44
+ @include media("<tablet") {
45
+ display: none;
46
+ }
47
+ }
48
+ }
49
+
21
50
  [data-fs-org-units-details-grid] {
22
51
  display: grid;
23
52
  flex: 1;
24
53
  gap: var(--fs-spacing-3);
25
54
  grid-template-columns: repeat(2, 1fr);
26
55
  grid-auto-rows: 1fr;
27
- }
28
56
 
29
- [data-fs-card-row-dropdown-button] {
30
- width: var(--fs-spacing-6);
31
- height: var(--fs-spacing-6);
32
- min-height: var(--fs-spacing-6);
33
- margin-left: calc(var(--fs-spacing-2) - var(--fs-spacing-0));
34
- [data-fs-button-wrapper] {
35
- svg {
36
- color: #858585;
37
- }
38
- }
39
- }
40
-
41
- [data-fs-org-units-details-grid] {
42
- [data-fs-org-units-details-grid-column] {
43
- flex: 1;
44
- display: flex;
45
- flex-direction: column;
46
- gap: var(--fs-spacing-3);
47
- min-width: 25rem;
48
-
49
- [data-fs-card] {
50
- @include media(">=tablet") {
51
- flex: 1;
52
- }
53
- }
57
+ @include media("<notebook") {
58
+ grid-template-columns: 1fr;
59
+ grid-auto-rows: auto;
54
60
  }
55
61
  }
56
62
 
57
- [data-fs-org-unit-details-menu] {
58
- display: flex;
59
- flex-direction: column;
60
-
61
- [data-fs-org-unit-details-menu-org-name] {
62
- font-weight: 600;
63
- font-size: var(--fs-text-size-3);
64
- line-height: var(--fs-text-size-5);
65
- color: #000000;
63
+ [data-fs-bp-basic-card] {
64
+ [data-fs-bp-letter-highlight] {
66
65
  margin-left: calc(var(--fs-spacing-3) + var(--fs-spacing-0));
67
- margin-top: var(--fs-spacing-1);
68
- }
69
-
70
- [data-fs-org-unit-details-menu-list] {
71
- margin-top: calc(var(--fs-spacing-3) + var(--fs-spacing-0));
72
- display: flex;
73
- flex-direction: column;
74
66
 
75
- [data-fs-org-unit-details-menu-item] {
76
- width: 100%;
67
+ @include media("<tablet") {
68
+ width: var(--fs-spacing-6);
69
+ height: var(--fs-spacing-6);
70
+ margin-left: 0;
71
+ }
72
+ }
73
+ [data-fs-vertical-nav-menu] {
74
+ [data-fs-vertical-nav-menu-org-wrapper] {
75
+ [data-fs-vertical-nav-menu-org-name] {
76
+ @include media("<tablet") {
77
+ margin-left: 0;
78
+ margin-top: var(--fs-spacing-1);
79
+ }
80
+ }
77
81
  }
78
82
 
79
- [data-fs-org-unit-details-menu-link] {
80
- display: flex;
81
- text-decoration: none;
82
- color: #000000;
83
- padding: var(--fs-spacing-2)
84
- calc(var(--fs-spacing-3) + var(--fs-spacing-0));
85
- width: 21.25rem;
86
- height: var(--fs-spacing-6);
87
- border-radius: var(--fs-border-radius-pill);
83
+ [data-fs-vertical-nav-menu-list] {
84
+ @include media("<tablet") {
85
+ margin-top: var(--fs-spacing-1);
86
+ }
87
+
88
+ @include media("<tablet") {
89
+ [data-fs-vertical-nav-menu-link] {
90
+ position: relative;
91
+ padding: 0;
92
+ height: auto;
93
+ line-height: var(--fs-spacing-6);
88
94
 
89
- &:hover {
90
- background-color: #f5f5f5;
95
+ &:hover {
96
+ border-radius: 0;
97
+ }
98
+ }
91
99
  }
92
100
  }
93
101
  }
94
102
  }
95
103
 
96
- [data-fs-bp-contracts-settings-card] {
97
- [data-fs-bp-letter-highlight] {
98
- margin-left: calc(var(--fs-spacing-3) + var(--fs-spacing-0));
99
- }
100
- }
101
-
102
- [data-fs-bp-contracts-settings-card],[data-fs-bp-contracts-list-card] {
103
- flex: 1;
104
+ [data-fs-bp-contracts-settings-card],
105
+ [data-fs-bp-contracts-list-card] {
104
106
  grid-row: 1 / span 2;
105
107
  }
106
108
 
@@ -0,0 +1,3 @@
1
+ export const MAX_MOBILE_BREADCRUMB_ITEMS = 1;
2
+ export const MAX_DESKTOP_BREADCRUMB_ITEMS = 2;
3
+ export const QUERY_TABLET = "(max-width: 768px)";
@@ -1,6 +1,7 @@
1
1
  import { ReactNode } from "react";
2
2
 
3
3
  export type OrgUnitBreadcrumbItem = {
4
+ unitId: string;
4
5
  item: string;
5
6
  name: string;
6
7
  position: number;
@@ -8,13 +9,16 @@ export type OrgUnitBreadcrumbItem = {
8
9
 
9
10
  export type OrgUnitBreadcrumbProps = {
10
11
  items: OrgUnitBreadcrumbItem[];
12
+ maxItems: number;
11
13
  };
12
14
 
13
15
  export interface OrgUnitBreadcrumbItemProps
14
- extends Omit<OrgUnitBreadcrumbItem, "position"> {
16
+ extends Omit<OrgUnitBreadcrumbItem, "position" | "unitId"> {
15
17
  isLast?: boolean;
16
18
  }
17
19
 
18
- export interface OrgUnitBreadcrumbPathProps extends OrgUnitBreadcrumbProps {
20
+ export interface OrgUnitBreadcrumbPathProps {
19
21
  divider: ReactNode;
22
+ items: OrgUnitBreadcrumbItem[];
23
+ contractId: string;
20
24
  }
@@ -0,0 +1,28 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ export const useMediaQuery = (query: string) => {
4
+ const [matches, setMatches] = useState(() => {
5
+ if (typeof window !== "undefined") {
6
+ return window.matchMedia(query).matches;
7
+ }
8
+ return false;
9
+ });
10
+
11
+ useEffect(() => {
12
+ if (typeof window === "undefined") {
13
+ return;
14
+ }
15
+
16
+ const mql = window.matchMedia(query);
17
+
18
+ const onChange = (e: MediaQueryListEvent) => setMatches(e.matches);
19
+
20
+ setMatches(mql.matches);
21
+
22
+ mql.addEventListener("change", onChange);
23
+
24
+ return () => mql.removeEventListener("change", onChange);
25
+ }, [query]);
26
+
27
+ return matches;
28
+ };