@vtex/faststore-plugin-buyer-portal 1.3.79 → 1.3.81

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.
Files changed (24) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/package.json +1 -1
  3. package/plugin.config.js +2 -2
  4. package/src/features/payment-methods/clients/PaymentMethodsClient.ts +5 -4
  5. package/src/features/payment-methods/components/AddPaymentMethodsDrawer/AddPaymentMethodsDrawer.tsx +3 -2
  6. package/src/features/payment-methods/components/RemovePaymentMethodsDrawer/RemovePaymentMethodsDrawer.tsx +2 -1
  7. package/src/features/payment-methods/hooks/useRemovePaymentMethodSubmit.ts +5 -2
  8. package/src/features/payment-methods/services/remove-payment-methods-from-unit.service.ts +3 -1
  9. package/src/features/payment-methods/types/PaymentMethod.ts +3 -1
  10. package/src/features/product-assortment/services/index.ts +0 -5
  11. package/src/features/product-assortment/types/index.ts +0 -7
  12. package/src/features/shared/types/PaymentMethodsClientTypes.ts +2 -1
  13. package/src/features/shared/types/index.ts +1 -0
  14. package/src/features/shared/utils/buyerPortalRoutes.ts +1 -1
  15. package/src/features/shared/utils/constants.ts +1 -1
  16. package/src/features/shared/utils/routeLayoutMapping.ts +1 -1
  17. package/src/features/product-assortment/components/AddProductAssortmentDrawer/AddProductAssortmentDrawer.tsx +0 -198
  18. package/src/features/product-assortment/components/AddProductAssortmentDrawer/add-product-assortment-drawer.scss +0 -66
  19. package/src/features/product-assortment/components/CollectionsSettingsDrawer/CollectionsSettingsDrawer.tsx +0 -81
  20. package/src/features/product-assortment/components/RemoveProductAssortmentDrawer/RemoveProductAssortmentDrawer.tsx +0 -79
  21. package/src/features/product-assortment/components/RemoveProductAssortmentDrawer/remove-product-assortment-drawer.scss +0 -9
  22. package/src/features/product-assortment/components/table/AddProductAssortmentDrawerTable.tsx +0 -124
  23. package/src/features/product-assortment/components/table/add-product-assortment-drawer-table.scss +0 -14
  24. /package/src/pages/{payment-methods.tsx → payment-groups.tsx} +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.3.81] - 2026-04-29
11
+
12
+ ### Changed
13
+
14
+ - Switch payment methods route/api integration to `payment-groups` and support string-based ids in the add/remove flow (`B2BTEAM-3238`)
15
+ - Register the page in `plugin.config.js` as `payment-groups` with path `/pvt/organization-account/payment-groups/[orgUnitId]/[contractId]` so it matches `buyerPortalRoutes` and resolves navigation 404s. Bookmarks or deep links using the previous `/pvt/organization-account/payment-methods/...` path are no longer served by this plugin (`B2BTEAM-3238`)
16
+
17
+ ## [1.3.80] - 2026-04-29
18
+
19
+ ### Fixed
20
+ - Remove the following components/exports to fix broken 1.3.79 build:
21
+ - CollectionsSettingsDrawer
22
+ - AddProductAssortmentDrawer
23
+ - RemoveProductAssortmentDrawer
24
+ - AddProductAssortmentDrawerTable
25
+ - getProductAssortmentFromScopeService
26
+ - RemoveProductAssortmentDrawerProps
27
+
10
28
  ## [1.3.79] - 2026-04-23
11
29
 
12
30
  ### Added
@@ -586,7 +604,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
586
604
  - Add CHANGELOG file
587
605
  - Add README file
588
606
 
589
- [unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.79...HEAD
607
+ [unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.81...HEAD
590
608
  [1.3.55]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.54...v1.3.55
591
609
  [1.3.54]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.53...v1.3.54
592
610
  [1.3.53]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.52...v1.3.53
@@ -654,6 +672,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
654
672
  [1.3.65]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.64...v1.3.65
655
673
  [1.3.64]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.64
656
674
  [1.3.69]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.69
675
+ [1.3.81]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.80...v1.3.81
676
+ [1.3.80]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.79...v1.3.80
657
677
  [1.3.79]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.78...v1.3.79
658
678
  [1.3.78]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.77...v1.3.78
659
679
  [1.3.77]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.76...v1.3.77
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.3.79",
3
+ "version": "1.3.81",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/plugin.config.js CHANGED
@@ -28,8 +28,8 @@ module.exports = {
28
28
  path: "/pvt/organization-account/budgets/[orgUnitId]/[contractId]/[budgetId]",
29
29
  appLayout: false,
30
30
  },
31
- "payment-methods": {
32
- path: "/pvt/organization-account/payment-methods/[orgUnitId]/[contractId]",
31
+ "payment-groups": {
32
+ path: "/pvt/organization-account/payment-groups/[orgUnitId]/[contractId]",
33
33
  appLayout: false,
34
34
  },
35
35
  "credit-cards": {
@@ -2,6 +2,7 @@ import { Client } from "../../shared/clients/Client";
2
2
  import { getApiUrl } from "../../shared/utils";
3
3
 
4
4
  import type {
5
+ PaymentMethodId,
5
6
  PaymentMethodResponse,
6
7
  PaymentMethodsIdArray,
7
8
  PaymentMethodsReqCommonParams,
@@ -39,7 +40,7 @@ export default class PaymentMethodsClient extends Client {
39
40
  }
40
41
 
41
42
  const queryString = queryParams.toString();
42
- const url = `customers/${customerId}/units/${unitId}/payment-methods/paginated${
43
+ const url = `customers/${customerId}/units/${unitId}/payment-groups/paginated${
43
44
  queryString ? `?${queryString}` : ""
44
45
  }`;
45
46
 
@@ -58,7 +59,7 @@ export default class PaymentMethodsClient extends Client {
58
59
  const { customerId, unitId, cookie, paymentMethodsIds } = data;
59
60
 
60
61
  return await this.post<PaymentMethodResponse, PaymentMethodsIdArray>(
61
- `customers/${customerId}/units/${unitId}/payment-methods`,
62
+ `customers/${customerId}/units/${unitId}/payment-groups`,
62
63
  paymentMethodsIds,
63
64
  {
64
65
  headers: {
@@ -71,13 +72,13 @@ export default class PaymentMethodsClient extends Client {
71
72
 
72
73
  async removePaymentMethodFromUnit(
73
74
  data: PaymentMethodsReqCommonParams & {
74
- paymentMethodId: number;
75
+ paymentMethodId: PaymentMethodId;
75
76
  }
76
77
  ) {
77
78
  const { customerId, unitId, cookie, paymentMethodId } = data;
78
79
 
79
80
  return await this.delete(
80
- `customers/${customerId}/units/${unitId}/payment-methods/${paymentMethodId}`,
81
+ `customers/${customerId}/units/${unitId}/payment-groups/${paymentMethodId}`,
81
82
  null,
82
83
  {
83
84
  headers: {
@@ -19,6 +19,7 @@ import { useAddPaymentMethodsToUnit } from "../../hooks";
19
19
  import { useDebouncedSearchPaymentMethods } from "../../hooks/useDebouncedSearchPaymentMethods";
20
20
 
21
21
  import type { TableColumn } from "../../../shared/components/Table/TableHead/TableHead";
22
+ import type { PaymentMethodId } from "../../../shared/types";
22
23
 
23
24
  export type AddPaymentMethodsDrawerProps = Omit<
24
25
  BasicDrawerProps,
@@ -35,7 +36,7 @@ export const AddPaymentMethodsDrawer = ({
35
36
  const [querySearch, setQuerySearch] = useState("");
36
37
  const [drawerPage, setDrawerPage] = useState(1);
37
38
  const [isLastPage, setIsLastPage] = useState(true);
38
- const [selectedMethods, setSelectedMethods] = useState<Set<number>>(
39
+ const [selectedMethods, setSelectedMethods] = useState<Set<PaymentMethodId>>(
39
40
  new Set()
40
41
  );
41
42
 
@@ -116,7 +117,7 @@ export const AddPaymentMethodsDrawer = ({
116
117
  }
117
118
  }, [someSelected]);
118
119
 
119
- const toggleItem = useCallback((id: number) => {
120
+ const toggleItem = useCallback((id: PaymentMethodId) => {
120
121
  setSelectedMethods((prev) => {
121
122
  const next = new Set(prev);
122
123
  if (next.has(id)) next.delete(id);
@@ -2,6 +2,7 @@ import { type BasicDrawerProps, BasicDrawer } from "../../../shared/components";
2
2
  import { useBuyerPortal } from "../../../shared/hooks";
3
3
  import { useRemovePaymentMethod } from "../../hooks/useRemovePaymentMethodSubmit";
4
4
 
5
+ import type { PaymentMethodId } from "../../../shared/types";
5
6
  import type { PaymentMethodData } from "../../types";
6
7
 
7
8
  export type RemovePaymentMethodsDrawerProps = Omit<
@@ -27,7 +28,7 @@ export const RemovePaymentMethodsDrawer = ({
27
28
  const { remove, isRemovingPaymentMethod } =
28
29
  useRemovePaymentMethod(handleSuccess);
29
30
 
30
- const handleSubmit = (paymentMethodId: number) => {
31
+ const handleSubmit = (paymentMethodId: PaymentMethodId) => {
31
32
  remove(paymentMethodId);
32
33
  };
33
34
 
@@ -7,6 +7,7 @@ import { CHANGES_TIMEOUT_MESSAGE } from "../../shared/utils/constants";
7
7
 
8
8
  import { useRemovePaymentMethodFromUnit } from "./useRemovePaymentMethodsFromUnit";
9
9
 
10
+ import type { PaymentMethodId } from "../../shared/types";
10
11
  import type { PaymentMethodData } from "../types";
11
12
 
12
13
  export function useRemovePaymentMethod(onAfterSuccess?: () => void) {
@@ -38,12 +39,14 @@ export function useRemovePaymentMethod(onAfterSuccess?: () => void) {
38
39
  },
39
40
  });
40
41
 
41
- const remove = (paymentMethod: PaymentMethodData | number) => {
42
+ const remove = (paymentMethod: PaymentMethodData | PaymentMethodId) => {
42
43
  removePaymentMethod({
43
44
  customerId,
44
45
  unitId,
45
46
  paymentMethodId:
46
- typeof paymentMethod === "number" ? paymentMethod : paymentMethod?.id,
47
+ typeof paymentMethod === "number" || typeof paymentMethod === "string"
48
+ ? paymentMethod
49
+ : paymentMethod?.id,
47
50
  });
48
51
  };
49
52
 
@@ -1,9 +1,11 @@
1
1
  import { paymentMethodsClient } from "../clients/PaymentMethodsClient";
2
2
 
3
+ import type { PaymentMethodId } from "../../shared/types";
4
+
3
5
  export type RemovePaymentMethodFromUnitServiceProps = {
4
6
  customerId: string;
5
7
  unitId: string;
6
- paymentMethodId: number;
8
+ paymentMethodId: PaymentMethodId;
7
9
  cookie: string;
8
10
  };
9
11
 
@@ -1,7 +1,9 @@
1
1
  import { PageControl } from "../../product-assortment/types";
2
2
 
3
+ import type { PaymentMethodId } from "../../shared/types";
4
+
3
5
  export type PaymentMethodData = {
4
- id: number;
6
+ id: PaymentMethodId;
5
7
  name: string;
6
8
  isEnabled?: boolean;
7
9
  };
@@ -1,8 +1,3 @@
1
- export {
2
- getProductAssortmentFromScopeService,
3
- type GetProductAssortmentFromScopeServiceProps,
4
- } from "./get-product-assortment-from-scope.service";
5
-
6
1
  export {
7
2
  getProductAssortmentAttachedService,
8
3
  type GetProductAssortmentAttachedServiceProps,
@@ -41,13 +41,6 @@ export type AddProductAssortmentDrawerProps = Omit<
41
41
  BasicDrawerProps,
42
42
  "children"
43
43
  >;
44
-
45
- export type RemoveProductAssortmentDrawerProps = Omit<
46
- BasicDrawerProps,
47
- "children"
48
- > & {
49
- productAssortment: ProductAssortmentSelectedProps;
50
- };
51
44
  export interface ProductAssortmentSelectedProps {
52
45
  id: string;
53
46
  name: string;
@@ -1,4 +1,5 @@
1
- export type PaymentMethodsIdArray = Array<{ id: number }>;
1
+ export type PaymentMethodId = string | number;
2
+ export type PaymentMethodsIdArray = Array<{ id: PaymentMethodId }>;
2
3
 
3
4
  export type PaymentMethodResponse = {
4
5
  message: string;
@@ -4,6 +4,7 @@ export type { CurrencyType, LocaleType } from "./CurrencyType";
4
4
  export type { LoaderData } from "./LoaderData";
5
5
  export type { IPagination } from "./Pagination";
6
6
  export type {
7
+ PaymentMethodId,
7
8
  PaymentMethodResponse,
8
9
  PaymentMethodsIdArray,
9
10
  PaymentMethodsReqCommonParams,
@@ -42,7 +42,7 @@ export const buyerPortalRoutes = {
42
42
  ),
43
43
 
44
44
  paymentMethods: (params: { orgUnitId: string; contractId: string }) =>
45
- replaceParams(`${base}/payment-methods/[orgUnitId]/[contractId]`, params),
45
+ replaceParams(`${base}/payment-groups/[orgUnitId]/[contractId]`, params),
46
46
 
47
47
  creditCards: (params: { orgUnitId: string; contractId: string }) =>
48
48
  replaceParams(`${base}/credit-cards/[orgUnitId]/[contractId]`, params),
@@ -22,7 +22,7 @@ export const SCOPE_KEYS = {
22
22
  CREDIT_CARDS: "creditCards",
23
23
  } as const;
24
24
 
25
- export const CURRENT_VERSION = "1.3.79";
25
+ export const CURRENT_VERSION = "1.3.81";
26
26
 
27
27
  export const CHANGES_TIMEOUT_MESSAGE =
28
28
  "Changes may take up to 10 minutes to apply.";
@@ -27,7 +27,7 @@ export const ROUTE_TABS_LAYOUT_MAPPING: Record<string, RouteTabsLayoutConfig> =
27
27
  pageName: "Contract",
28
28
  pageTitle: "Address Details",
29
29
  },
30
- "/pvt/organization-account/payment-methods/[orgUnitId]/[contractId]": {
30
+ "/pvt/organization-account/payment-groups/[orgUnitId]/[contractId]": {
31
31
  layout: "ContractTabsLayout",
32
32
  pageName: "Contract",
33
33
  pageTitle: "Payment Methods",
@@ -1,198 +0,0 @@
1
- import { useEffect, useState } from "react";
2
-
3
- import { useRouter } from "next/router";
4
-
5
- import { Link, Skeleton, useUI } from "@faststore/ui";
6
-
7
- import {
8
- BasicDrawer,
9
- Icon,
10
- InternalSearch,
11
- Paginator,
12
- } from "../../../shared/components";
13
- import { useBuyerPortal, useDebounce } from "../../../shared/hooks";
14
- import { DEBOUNCE_TIMEOUT } from "../../../shared/utils";
15
- import { CHANGES_TIMEOUT_MESSAGE } from "../../../shared/utils/constants";
16
- import { useGetProductAssorments } from "../../hooks";
17
- import { useAddProductAssortmentToScope } from "../../hooks/useAddProductAssortmentToScope";
18
- import { AddProductAssortmentDrawerTable } from "../table/AddProductAssortmentDrawerTable";
19
-
20
- import type {
21
- AddProductAssortmentDrawerProps,
22
- ProductAssortmentWithAdditionalInformation,
23
- } from "../../types";
24
-
25
- export const AddProductAssortmentDrawer = ({
26
- close,
27
- ...props
28
- }: AddProductAssortmentDrawerProps) => {
29
- const { pushToast } = useUI();
30
- const [drawerSearch, setDrawerSearch] = useState("");
31
- const [drawerPage, setDrawerPage] = useState(1);
32
- const { currentOrgUnit, currentContract } = useBuyerPortal();
33
- const { reload } = useRouter();
34
-
35
- const { productAssortments: productAssortment, isLoadingProductAssortments } =
36
- useGetProductAssorments({
37
- contractId: currentContract?.id ?? "",
38
- unitId: currentOrgUnit?.id ?? "",
39
- page: drawerPage,
40
- name: drawerSearch,
41
- });
42
-
43
- const unitId = currentOrgUnit?.id;
44
- const contractId = currentContract?.id;
45
- const isLoading = isLoadingProductAssortments;
46
- const [isLastPage, setIsLastPage] = useState(true);
47
-
48
- useEffect(() => {
49
- setDrawerSearch("");
50
- }, [props.isOpen]);
51
-
52
- useDebounce(drawerSearch, DEBOUNCE_TIMEOUT, {
53
- onDebounce: (value) => {
54
- setDrawerSearch(value);
55
- setDrawerPage(1);
56
- },
57
- });
58
-
59
- useEffect(() => {
60
- if (productAssortment?.paging) {
61
- setIsLastPage(productAssortment.paging.pages === drawerPage);
62
- }
63
- }, [productAssortment.paging]);
64
-
65
- const addProductAssortmentMutation = useAddProductAssortmentToScope();
66
-
67
- const [selectedAssortment, setSelectedAssortment] = useState<
68
- ProductAssortmentWithAdditionalInformation[]
69
- >([]);
70
-
71
- const handleSuccess = async () => {
72
- const itemsToAdd = selectedAssortment.filter((s) => !s.isEnabled);
73
-
74
- if (itemsToAdd.length === 0) {
75
- close();
76
- return;
77
- }
78
-
79
- await addProductAssortmentMutation.mutate({
80
- unitId: unitId ?? "",
81
- contractId: contractId ?? "",
82
- data: itemsToAdd.map((s) => ({ name: s.name })),
83
- });
84
-
85
- pushToast({
86
- message: `Product assortment added successfully\n${CHANGES_TIMEOUT_MESSAGE}`,
87
- status: "INFO",
88
- });
89
-
90
- close();
91
- reload();
92
- };
93
-
94
- return (
95
- <BasicDrawer
96
- data-fs-bp-add-product-assortment-drawer
97
- id="add-product-assortment-drawer"
98
- close={close}
99
- size="large"
100
- {...props}
101
- >
102
- <BasicDrawer.Heading title="Add product assortment" onClose={close} />
103
-
104
- <BasicDrawer.Body>
105
- <span data-fs-bp-add-product-assortment-text-drawer>
106
- Add product assortment to <Link href="#">{currentOrgUnit?.name}</Link>
107
- </span>
108
-
109
- <div data-fs-bp-add-product-assortment-wrapper>
110
- <InternalSearch
111
- textSearch={setDrawerSearch}
112
- defaultValue={drawerSearch}
113
- />
114
-
115
- {productAssortment.paging && productAssortment.items.length > 0 && (
116
- <Paginator.Counter
117
- total={productAssortment.paging.total}
118
- itemsLength={
119
- isLastPage
120
- ? productAssortment.paging.total
121
- : drawerPage * productAssortment.paging.perPage
122
- }
123
- />
124
- )}
125
- </div>
126
- <section>
127
- {isLoading ? (
128
- <div data-fs-bp-drawer-product-assortment-skeleton>
129
- <Skeleton size={{ height: "3.5rem", width: "100%" }} />
130
- </div>
131
- ) : productAssortment.items && productAssortment.items.length ? (
132
- <div>
133
- <AddProductAssortmentDrawerTable
134
- data={productAssortment.items}
135
- onChange={setSelectedAssortment}
136
- />
137
- {productAssortment.items.length > 0 && (
138
- <div data-fs-bp-drawer-product-assortment-paginator>
139
- {productAssortment.items.length > 0 &&
140
- productAssortment.paging.page > 1 ? (
141
- <Paginator.NextPageButton
142
- onClick={() => setDrawerPage(drawerPage - 1)}
143
- disabled={isLoading}
144
- >
145
- {isLoading ? "Loading" : "Previous page"}
146
- </Paginator.NextPageButton>
147
- ) : (
148
- <></>
149
- )}
150
-
151
- {productAssortment.items.length > 0 && !isLastPage ? (
152
- <Paginator.NextPageButton
153
- onClick={() => setDrawerPage(drawerPage + 1)}
154
- disabled={isLoading}
155
- >
156
- {isLoading ? "Loading" : "Next page"}
157
- </Paginator.NextPageButton>
158
- ) : (
159
- <></>
160
- )}
161
-
162
- <Paginator.Counter
163
- total={productAssortment.paging.total}
164
- itemsLength={
165
- isLastPage
166
- ? productAssortment.paging.total
167
- : drawerPage * productAssortment.paging.perPage
168
- }
169
- />
170
- </div>
171
- )}
172
- </div>
173
- ) : (
174
- <div data-fs-bp-add-product-assortment-drawer-empty-state>
175
- <Icon name="Shapes" />
176
- <p>No product assortment found</p>
177
- </div>
178
- )}
179
- </section>
180
- </BasicDrawer.Body>
181
- <BasicDrawer.Footer data-fs-bp-add-product-assortment-drawer-footer>
182
- <BasicDrawer.Button variant="ghost" onClick={close}>
183
- Cancel
184
- </BasicDrawer.Button>
185
- <BasicDrawer.Button
186
- variant="confirm"
187
- disabled={selectedAssortment.filter((s) => !s.isEnabled).length === 0}
188
- onClick={handleSuccess}
189
- isLoading={addProductAssortmentMutation.isLoading}
190
- >
191
- Add
192
- {selectedAssortment.filter((s) => !s.isEnabled).length > 0 &&
193
- `(${selectedAssortment.filter((s) => !s.isEnabled).length})`}
194
- </BasicDrawer.Button>
195
- </BasicDrawer.Footer>
196
- </BasicDrawer>
197
- );
198
- };
@@ -1,66 +0,0 @@
1
- [data-fs-bp-add-product-assortment-drawer] {
2
- @import "@faststore/ui/src/components/atoms/Button/styles.scss";
3
- @import "../../../shared/components/BasicDrawer/basic-drawer.scss";
4
- @import "../../../shared/components/InputText/input-text.scss";
5
- @import "../../../shared/components/InternalSearch/internal-search.scss";
6
- @import "../../../shared/components/ErrorMessage/error-message.scss";
7
- @import "../../../shared/components/Paginator/paginator.scss";
8
- @import "../../components/table/add-product-assortment-drawer-table.scss";
9
-
10
- [data-fs-bp-add-product-assortment-text-drawer] {
11
- display: block;
12
- color: var(--fs-color-neutral-5);
13
- margin-bottom: 1.25rem;
14
- }
15
-
16
- [data-fs-bp-add-product-assortment-wrapper] {
17
- display: flex;
18
- align-items: center;
19
- justify-content: space-between;
20
- height: 2.5rem;
21
-
22
- @include media("<=tablet") {
23
- [data-fs-buyer-portal-internal-search] {
24
- width: 100%;
25
- }
26
-
27
- [data-fs-bp-paginator-counter] {
28
- display: none;
29
- }
30
- }
31
- }
32
-
33
- [data-fs-bp-add-product-assortment-drawer-empty-state] {
34
- display: flex;
35
- flex-direction: column;
36
- justify-content: center;
37
- align-items: center;
38
- gap: var(--fs-spacing-1);
39
- height: 18.75rem;
40
-
41
- color: #858585;
42
- font-weight: var(--fs-text-weight-semibold);
43
-
44
- [data-fs-icon] {
45
- width: var(--fs-spacing-6);
46
- height: var(--fs-spacing-6);
47
- }
48
- }
49
-
50
- [data-fs-bp-drawer-product-assortment-skeleton] {
51
- padding-top: var(--fs-spacing-2);
52
- }
53
-
54
- [data-fs-bp-drawer-product-assortment-paginator] {
55
- display: flex;
56
- align-items: center;
57
- justify-content: space-between;
58
- margin-top: var(--fs-spacing-0);
59
- padding: var(--fs-spacing-2) 0;
60
- }
61
-
62
- [data-fs-bp-add-product-assortment-drawer-footer] {
63
- justify-content: end;
64
- gap: 1.25rem;
65
- }
66
- }
@@ -1,81 +0,0 @@
1
- import { useState } from "react";
2
-
3
- import { useRouter } from "next/router";
4
-
5
- import { useUI } from "@faststore/ui";
6
-
7
- import {
8
- type BasicDrawerProps,
9
- SettingsDrawer,
10
- createListTypeOptions,
11
- } from "../../../shared/components";
12
- import { useSetScopeConfig, SCOPE_KEYS } from "../../../shared/hooks";
13
- import { CHANGES_TIMEOUT_MESSAGE } from "../../../shared/utils/constants";
14
-
15
- export type CollectionsSettingsDrawerProps = Omit<
16
- BasicDrawerProps,
17
- "children"
18
- > & {
19
- readonly?: boolean;
20
- onUpdate?: () => void;
21
- };
22
-
23
- const COLLECTIONS_LIST_TYPE_OPTIONS = createListTypeOptions("collections");
24
-
25
- export const CollectionsSettingsDrawer = ({
26
- close,
27
- onUpdate,
28
- ...otherProps
29
- }: CollectionsSettingsDrawerProps) => {
30
- const { pushToast } = useUI();
31
- const router = useRouter();
32
-
33
- const [listType, setListType] = useState<"sync" | "custom">("custom");
34
-
35
- const { setScopeConfig, isSetScopeConfigLoading } = useSetScopeConfig({
36
- onSuccess: () => {
37
- pushToast({
38
- message: `Scope configuration updated successfully\n${CHANGES_TIMEOUT_MESSAGE}`,
39
- status: "INFO",
40
- });
41
- onUpdate?.();
42
- close();
43
- },
44
- onError: () => {
45
- pushToast({
46
- message: "Failed to update scope configuration",
47
- status: "ERROR",
48
- });
49
- },
50
- });
51
-
52
- const handleConfirmClick = () => {
53
- setScopeConfig({
54
- customerId: router.query.contractId as string,
55
- unitId: router.query.orgUnitId as string,
56
- scopeName: SCOPE_KEYS.COLLECTIONS,
57
- type: listType,
58
- });
59
- };
60
-
61
- return (
62
- <SettingsDrawer
63
- title="Collections settings"
64
- {...otherProps}
65
- close={close}
66
- onPrimaryAction={handleConfirmClick}
67
- isPrimaryButtonLoading={isSetScopeConfigLoading}
68
- scopeName={SCOPE_KEYS.COLLECTIONS}
69
- onDismiss={close}
70
- data-fs-bp-collections-settings-drawer
71
- >
72
- <SettingsDrawer.ListType
73
- title="List type"
74
- name="collections-list-type"
75
- value={listType}
76
- onChange={setListType}
77
- options={COLLECTIONS_LIST_TYPE_OPTIONS}
78
- />
79
- </SettingsDrawer>
80
- );
81
- };
@@ -1,79 +0,0 @@
1
- import { useRouter } from "next/router";
2
-
3
- import { Link, useUI } from "@faststore/ui";
4
-
5
- import { BasicDrawer } from "../../../shared/components";
6
- import { useBuyerPortal } from "../../../shared/hooks";
7
- import { CHANGES_TIMEOUT_MESSAGE } from "../../../shared/utils/constants";
8
- import { useRemoveProductAssortmentFromScope } from "../../hooks/useRemoveProductAssortmentFromScope";
9
-
10
- import type { RemoveProductAssortmentDrawerProps } from "../../types";
11
-
12
- export function RemoveProductAssortmentDrawer({
13
- close,
14
- productAssortment,
15
- ...props
16
- }: RemoveProductAssortmentDrawerProps) {
17
- const { pushToast } = useUI();
18
-
19
- const { reload } = useRouter();
20
- const removeAssortmentMutation = useRemoveProductAssortmentFromScope();
21
- const { currentOrgUnit, currentContract } = useBuyerPortal();
22
-
23
- async function handleSuccess() {
24
- await removeAssortmentMutation.mutate({
25
- productAssortmentId: productAssortment.id,
26
- unitId: currentOrgUnit?.id ?? "",
27
- contractId: currentContract?.id ?? "",
28
- });
29
-
30
- pushToast({
31
- message: `Product assortment access removed successfully\n${CHANGES_TIMEOUT_MESSAGE}`,
32
- status: "INFO",
33
- });
34
- close();
35
-
36
- reload();
37
- }
38
-
39
- return (
40
- <BasicDrawer
41
- data-fs-bp-remove-product-assortment-drawer
42
- close={close}
43
- {...props}
44
- >
45
- <BasicDrawer.Heading
46
- title="Remove product assortment from unit"
47
- onClose={close}
48
- />
49
-
50
- <BasicDrawer.Body>
51
- <span>
52
- Remove <Link href="#">{productAssortment.name}</Link> contract from
53
- <Link href="#"> {currentOrgUnit?.name}</Link> organizational unit?
54
- </span>
55
- <span>
56
- This action will prevent users in this unit from accessing this
57
- product assortment during store navigation and checkout.
58
- </span>
59
- </BasicDrawer.Body>
60
-
61
- <BasicDrawer.Footer data-fs-bp-add-product-assortment-drawer-footer>
62
- <BasicDrawer.Button
63
- variant="ghost"
64
- disabled={removeAssortmentMutation.isLoading}
65
- onClick={close}
66
- >
67
- Cancel
68
- </BasicDrawer.Button>
69
- <BasicDrawer.Button
70
- variant="confirm"
71
- isLoading={removeAssortmentMutation.isLoading}
72
- onClick={handleSuccess}
73
- >
74
- Confirm
75
- </BasicDrawer.Button>
76
- </BasicDrawer.Footer>
77
- </BasicDrawer>
78
- );
79
- }
@@ -1,9 +0,0 @@
1
- [data-fs-bp-remove-product-assortment-drawer] {
2
- @import "@faststore/ui/src/components/atoms/Checkbox/styles.scss";
3
-
4
- span {
5
- display: block;
6
- color: var(--fs-color-neutral-7);
7
- margin-bottom: 1.25rem;
8
- }
9
- }
@@ -1,124 +0,0 @@
1
- import {
2
- Dispatch,
3
- SetStateAction,
4
- useCallback,
5
- useMemo,
6
- useState,
7
- } from "react";
8
-
9
- import { Checkbox } from "@faststore/ui";
10
-
11
- import { Table } from "../../../shared/components";
12
-
13
- import type { TableColumn } from "../../../shared/components/Table/TableHead/TableHead";
14
- import type { ProductAssortmentWithAdditionalInformation } from "../../types";
15
-
16
- interface AddProductAssortmentDrawerTableProps {
17
- loading?: boolean;
18
- data: ProductAssortmentWithAdditionalInformation[];
19
- onChange: Dispatch<
20
- SetStateAction<ProductAssortmentWithAdditionalInformation[]>
21
- >;
22
- }
23
-
24
- export const AddProductAssortmentDrawerTable = ({
25
- data,
26
- loading,
27
- onChange,
28
- }: AddProductAssortmentDrawerTableProps) => {
29
- const enabledIds = useMemo(
30
- () => data.filter((item) => item.isEnabled).map((item) => item.id),
31
- [data]
32
- );
33
-
34
- const [selectedIds, setSelectedIds] = useState<string[]>(enabledIds);
35
-
36
- const selectableIds = useMemo(
37
- () => data.filter((item) => !item.isEnabled).map((item) => item.id),
38
- [data]
39
- );
40
- const allSelected =
41
- selectableIds.every((id) => selectedIds.includes(id)) &&
42
- selectableIds.length > 0;
43
- const partiallySelected =
44
- selectedIds.some((id) => selectableIds.includes(id)) && !allSelected;
45
-
46
- const handleSelect = useCallback(
47
- (id: string, isEnabled: boolean) => {
48
- if (isEnabled) return;
49
-
50
- const newSelectedIds = selectedIds.includes(id)
51
- ? selectedIds.filter((item) => item !== id)
52
- : [...selectedIds, id];
53
-
54
- setSelectedIds(newSelectedIds);
55
- const selectedItems = data.filter((d) => newSelectedIds.includes(d.id));
56
- onChange(selectedItems);
57
- },
58
- [selectedIds, data, onChange]
59
- );
60
-
61
- const handleSelectAll = useCallback(() => {
62
- const newSelectedIds = allSelected
63
- ? enabledIds
64
- : [...selectableIds, ...enabledIds];
65
- setSelectedIds(newSelectedIds);
66
- const selectedItems = data.filter((d) => newSelectedIds.includes(d.id));
67
- onChange(selectedItems);
68
- }, [allSelected, selectableIds, enabledIds, data, onChange]);
69
-
70
- const columns: TableColumn[] = [
71
- {
72
- key: "check",
73
- align: "center",
74
- size: "2.5rem",
75
- label: (
76
- <Checkbox
77
- data-fs-bp-product-assortment-checkbox
78
- checked={allSelected}
79
- partial={partiallySelected}
80
- onChange={handleSelectAll}
81
- />
82
- ),
83
- },
84
- {
85
- key: "name",
86
- label: "Name",
87
- align: "left",
88
- size: "100%",
89
- },
90
- ];
91
-
92
- return (
93
- <div data-fs-bp-add-product-assortment-drawer-table>
94
- <Table layoutFixed>
95
- <Table.Head columns={columns} />
96
- <Table.Body>
97
- {loading ? (
98
- <Table.Loading columns={columns.length} />
99
- ) : (
100
- data.map((option) => (
101
- <Table.Row
102
- key={option.id}
103
- title={option.name}
104
- iconName="Shapes"
105
- iconSize={24}
106
- selected={selectedIds.includes(option.id)}
107
- prependColumns={
108
- <Table.Cell align="center">
109
- <Checkbox
110
- data-fs-bp-product-assortment-checkbox
111
- checked={selectedIds.includes(option.id)}
112
- disabled={option.isEnabled}
113
- onChange={() => handleSelect(option.id, option.isEnabled)}
114
- />
115
- </Table.Cell>
116
- }
117
- />
118
- ))
119
- )}
120
- </Table.Body>
121
- </Table>
122
- </div>
123
- );
124
- };
@@ -1,14 +0,0 @@
1
- [data-fs-bp-add-product-assortment-drawer-table] {
2
- @import "@faststore/ui/src/components/atoms/Checkbox/styles.scss";
3
- @import "../../../shared/components/Table/table.scss";
4
-
5
- margin-top: 1.25rem;
6
-
7
- [data-fs-tooltip] {
8
- --fs-tooltip-background: #1f1f1f;
9
- }
10
-
11
- [data-fs-bp-product-assortment-checkbox] {
12
- margin: 0 auto;
13
- }
14
- }