@vtex/faststore-plugin-buyer-portal 1.0.38 → 1.0.40
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 +1 -1
- package/plugin.config.js +4 -4
- package/public/buyer-portal-icons.svg +11 -1
- package/src/features/addresses/components/AddressForm/AddressForm.tsx +33 -27
- package/src/features/addresses/components/AddressLine/AddressLine.tsx +1 -1
- package/src/features/contracts/clients/ContractsClient.ts +0 -11
- package/src/features/contracts/services/index.ts +0 -5
- package/src/features/credit-cards/components/CreateCreditCardDrawer/CreateCreditCardDrawer.tsx +135 -0
- package/src/features/credit-cards/components/CreateCreditCardDrawer/create-credit-card-drawer.scss +21 -0
- package/src/features/credit-cards/components/CreditCardDropdownMenu/CreditCardDropdownMenu.tsx +103 -0
- package/src/features/credit-cards/components/CreditCardForm/CreditCardForm.tsx +79 -0
- package/src/features/credit-cards/components/CreditCardForm/credit-card-form.scss +5 -0
- package/src/features/credit-cards/components/DeleteCreditCardDrawer/DeleteCreditCardDrawer.tsx +82 -0
- package/src/features/credit-cards/components/EditCreditCardDrawer/EditCreditCardDrawer.tsx +90 -0
- package/src/features/credit-cards/components/EditCreditCardDrawer/edit-credit-card-drawer.scss +4 -0
- package/src/features/credit-cards/components/RemoveCreditCardDrawer/RemoveCreditCardDrawer.tsx +84 -0
- package/src/features/credit-cards/components/RemoveCreditCardDrawer/remove-credit-card-drawer.scss +9 -0
- package/src/features/credit-cards/components/index.ts +24 -0
- package/src/features/credit-cards/layouts/CreditCardsLayout/CreditCardLayout.tsx +100 -0
- package/src/features/credit-cards/layouts/CreditCardsLayout/credit-card-layout.scss +140 -0
- package/src/features/credit-cards/layouts/index.ts +1 -0
- package/src/features/credit-cards/types/CreditCard.ts +12 -0
- package/src/features/credit-cards/types/index.ts +1 -0
- package/src/features/org-units/clients/OrgUnitClient.ts +0 -11
- package/src/features/org-units/components/AddAllToOrgUnitDropdown/AddAllToOrgUnitDropdown.tsx +65 -48
- package/src/features/org-units/hooks/index.ts +0 -1
- package/src/features/org-units/layouts/OrgUnitDetailsLayout/org-units-details.scss +1 -0
- package/src/features/org-units/services/index.ts +0 -4
- package/src/features/shared/utils/creditCard.ts +16 -0
- package/src/features/shared/utils/index.ts +1 -0
- package/src/pages/credit-cards.tsx +71 -0
- package/src/themes/layouts.scss +3 -0
- package/src/features/contracts/services/get-contracts-by-customer-id.service.ts +0 -37
- package/src/features/org-units/hooks/useRootOrgUnitByCustomer.ts +0 -19
- package/src/features/org-units/services/get-root-org-unit-by-customer-id.service.ts +0 -10
package/package.json
CHANGED
package/plugin.config.js
CHANGED
|
@@ -24,10 +24,10 @@ module.exports = {
|
|
|
24
24
|
// path: "/buyer-portal/payment-methods/[orgUnitId]/[contractId]",
|
|
25
25
|
// appLayout: false,
|
|
26
26
|
// },
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
"credit-cards": {
|
|
28
|
+
path: "/buyer-portal/credit-cards/[orgUnitId]/[contractId]",
|
|
29
|
+
appLayout: false,
|
|
30
|
+
},
|
|
31
31
|
// collections: {
|
|
32
32
|
// path: "/buyer-portal/collections/[orgUnitId]/[contractId]",
|
|
33
33
|
// appLayout: false,
|
|
@@ -337,4 +337,14 @@
|
|
|
337
337
|
fill="currentColor" />
|
|
338
338
|
|
|
339
339
|
</symbol>
|
|
340
|
-
|
|
340
|
+
|
|
341
|
+
<symbol
|
|
342
|
+
id="Rename"
|
|
343
|
+
viewBox="0 0 17 13"
|
|
344
|
+
fill="none"
|
|
345
|
+
xmlns="http://www.w3.org/2000/svg">
|
|
346
|
+
<path d="M10.0712 12.6473V2.64734H6.0712V0.647339H16.0712V2.64734H12.0712V12.6473H10.0712ZM2.5712 12.6473V6.64734H0.0711975V4.64734H7.0712V6.64734H4.5712V12.6473H2.5712Z" fill="currentColor"/>
|
|
347
|
+
</symbol>
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
</svg>
|
|
@@ -25,6 +25,7 @@ export type AddressFormProps = {
|
|
|
25
25
|
completedAddress?: AddressData;
|
|
26
26
|
setCompletedAddress?: (completedAddress: AddressData) => void;
|
|
27
27
|
isEdit?: boolean;
|
|
28
|
+
fixedType?: boolean;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
export const AddressForm = ({
|
|
@@ -37,6 +38,7 @@ export const AddressForm = ({
|
|
|
37
38
|
setUseExistingAddress,
|
|
38
39
|
completedAddress,
|
|
39
40
|
setCompletedAddress,
|
|
41
|
+
fixedType = false,
|
|
40
42
|
}: AddressFormProps) => {
|
|
41
43
|
const addressTypeOptions = ["Shipping", "Billing", "Sold To"];
|
|
42
44
|
|
|
@@ -60,11 +62,13 @@ export const AddressForm = ({
|
|
|
60
62
|
});
|
|
61
63
|
};
|
|
62
64
|
|
|
65
|
+
const hideLabel = isEdit || fixedType;
|
|
66
|
+
|
|
63
67
|
return (
|
|
64
68
|
<>
|
|
65
69
|
{!useExistingAddress ? (
|
|
66
70
|
<div>
|
|
67
|
-
{!
|
|
71
|
+
{!hideLabel && <span>Fill in the address details</span>}
|
|
68
72
|
|
|
69
73
|
<AutocompleteDropdown
|
|
70
74
|
data-fs-bp-create-address-country-selector
|
|
@@ -242,32 +246,34 @@ export const AddressForm = ({
|
|
|
242
246
|
/>
|
|
243
247
|
)}
|
|
244
248
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
249
|
+
{!fixedType && (
|
|
250
|
+
<AutocompleteDropdown
|
|
251
|
+
label="Address Type"
|
|
252
|
+
value={address.types}
|
|
253
|
+
options={addressTypeOptions}
|
|
254
|
+
onConfirmKeyPress={(option) =>
|
|
255
|
+
setAddress({ ...address, types: [option] })
|
|
256
|
+
}
|
|
257
|
+
renderOption={(option, index) => (
|
|
258
|
+
<AutocompleteDropdown.Item
|
|
259
|
+
key={`${option}-${index}`}
|
|
260
|
+
closeOnClick={true}
|
|
261
|
+
index={index}
|
|
262
|
+
isSelected={
|
|
263
|
+
address?.types[0]?.toLocaleLowerCase() ===
|
|
264
|
+
option.toLocaleLowerCase()
|
|
265
|
+
}
|
|
266
|
+
onClick={() => setAddress({ ...address, types: [option] })}
|
|
267
|
+
>
|
|
268
|
+
{option}
|
|
269
|
+
{address?.types[0]?.toLowerCase() ===
|
|
270
|
+
option.toLocaleLowerCase() && (
|
|
271
|
+
<Icon name="Check" width={12} height={12} />
|
|
272
|
+
)}
|
|
273
|
+
</AutocompleteDropdown.Item>
|
|
274
|
+
)}
|
|
275
|
+
/>
|
|
276
|
+
)}
|
|
271
277
|
</div>
|
|
272
278
|
) : (
|
|
273
279
|
<ExistingAddress
|
|
@@ -7,17 +7,6 @@ class ContractsClient extends Client {
|
|
|
7
7
|
super(getApiUrl());
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
getContractsByCustomerId(customerId: string, cookie: string) {
|
|
11
|
-
return this.get<{ data: { contracts: ContractData[]; total: number } }>(
|
|
12
|
-
`contracts/${customerId}/list`,
|
|
13
|
-
{
|
|
14
|
-
headers: {
|
|
15
|
-
Cookie: cookie,
|
|
16
|
-
},
|
|
17
|
-
}
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
10
|
getContractsByOrgUnitId(orgUnitId: string, cookie: string) {
|
|
22
11
|
return this.get<{ contracts: ContractData[]; total: number }>(
|
|
23
12
|
`contracts/${orgUnitId}`,
|
package/src/features/credit-cards/components/CreateCreditCardDrawer/CreateCreditCardDrawer.tsx
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { useUI } from "@faststore/ui";
|
|
4
|
+
import { useRouter } from "next/router";
|
|
5
|
+
import {
|
|
6
|
+
type BasicDrawerProps,
|
|
7
|
+
BasicDrawer,
|
|
8
|
+
InputText,
|
|
9
|
+
} from "../../../shared/components";
|
|
10
|
+
import { AddressForm } from "../../../addresses/components";
|
|
11
|
+
import type { AddressInput, AddressData } from "../../../addresses/types";
|
|
12
|
+
import type { CreditCard } from "../../types";
|
|
13
|
+
import { CreditCardForm } from "../CreditCardForm/CreditCardForm";
|
|
14
|
+
|
|
15
|
+
export type CreateCreditCardDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
16
|
+
readonly?: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const CreateCreditCardDrawer = ({
|
|
20
|
+
close,
|
|
21
|
+
readonly,
|
|
22
|
+
...props
|
|
23
|
+
}: CreateCreditCardDrawerProps) => {
|
|
24
|
+
const { pushToast } = useUI();
|
|
25
|
+
const [isTouched, setIsTouched] = useState(false);
|
|
26
|
+
const [useExistingAddress, setUseExistingAddress] = useState(false);
|
|
27
|
+
const [completedAddress, setCompletedAddress] = useState<AddressData>(
|
|
28
|
+
{} as AddressData
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const router = useRouter();
|
|
32
|
+
|
|
33
|
+
const [address, setAddress] = useState<AddressInput>({
|
|
34
|
+
name: "",
|
|
35
|
+
streetAddress: "",
|
|
36
|
+
streetAddress2: "",
|
|
37
|
+
country: "",
|
|
38
|
+
countryCode: "",
|
|
39
|
+
zip: "",
|
|
40
|
+
state: "",
|
|
41
|
+
geoCordinates: "",
|
|
42
|
+
city: "",
|
|
43
|
+
types: ["Billing"],
|
|
44
|
+
neighborhood: "",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const [newCard, setNewCard] = useState<CreditCard>({} as CreditCard);
|
|
48
|
+
|
|
49
|
+
const [invalidAddress, setInvalidAddress] = useState(false);
|
|
50
|
+
|
|
51
|
+
const handleConfirmClick = () => {
|
|
52
|
+
pushToast({
|
|
53
|
+
message: "Credit card added successfully",
|
|
54
|
+
status: "INFO",
|
|
55
|
+
});
|
|
56
|
+
router.reload();
|
|
57
|
+
close();
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const hasMinimumAddressInformation = () => {
|
|
61
|
+
return (
|
|
62
|
+
(address.name &&
|
|
63
|
+
address.streetAddress &&
|
|
64
|
+
address.country &&
|
|
65
|
+
address.zip &&
|
|
66
|
+
address.state &&
|
|
67
|
+
address.city &&
|
|
68
|
+
address.types.length > 0) ||
|
|
69
|
+
useExistingAddress
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const hasCardInformation = () => {
|
|
74
|
+
return (
|
|
75
|
+
newCard.cardholder &&
|
|
76
|
+
newCard.nickname &&
|
|
77
|
+
newCard.cvv &&
|
|
78
|
+
newCard.expirationDate &&
|
|
79
|
+
newCard.number
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const isConfirmButtonEnabled =
|
|
84
|
+
hasMinimumAddressInformation() && hasCardInformation();
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<BasicDrawer data-fs-bp-create-credit-card-drawer close={close} {...props}>
|
|
88
|
+
<BasicDrawer.Heading title="Add credit card" onClose={close} />
|
|
89
|
+
<BasicDrawer.Body>
|
|
90
|
+
<div data-fs-bp-create-credit-card-drawer-section-label>
|
|
91
|
+
<span>Card nickname</span>
|
|
92
|
+
</div>
|
|
93
|
+
<InputText
|
|
94
|
+
label="Card nickname"
|
|
95
|
+
value={newCard.nickname}
|
|
96
|
+
wrapperProps={{ style: { marginTop: 16 } }}
|
|
97
|
+
onChange={(event) =>
|
|
98
|
+
setNewCard({ ...newCard, nickname: event.target.value })
|
|
99
|
+
}
|
|
100
|
+
/>
|
|
101
|
+
|
|
102
|
+
<CreditCardForm creditCard={newCard} setNewCard={setNewCard} />
|
|
103
|
+
|
|
104
|
+
<div data-fs-bp-create-credit-card-drawer-section-label>
|
|
105
|
+
<span>Billing Address</span>
|
|
106
|
+
</div>
|
|
107
|
+
<AddressForm
|
|
108
|
+
address={address}
|
|
109
|
+
setAddress={setAddress}
|
|
110
|
+
isTouched={isTouched}
|
|
111
|
+
setInvalidAddress={setInvalidAddress}
|
|
112
|
+
useExistingAddress={useExistingAddress}
|
|
113
|
+
setUseExistingAddress={setUseExistingAddress}
|
|
114
|
+
completedAddress={completedAddress}
|
|
115
|
+
setCompletedAddress={setCompletedAddress}
|
|
116
|
+
fixedType={true}
|
|
117
|
+
/>
|
|
118
|
+
</BasicDrawer.Body>
|
|
119
|
+
|
|
120
|
+
<BasicDrawer.Footer>
|
|
121
|
+
<BasicDrawer.Button variant="ghost" onClick={close}>
|
|
122
|
+
Cancel
|
|
123
|
+
</BasicDrawer.Button>
|
|
124
|
+
<BasicDrawer.Button
|
|
125
|
+
variant="confirm"
|
|
126
|
+
disabled={!isConfirmButtonEnabled}
|
|
127
|
+
onClick={handleConfirmClick}
|
|
128
|
+
isLoading={false}
|
|
129
|
+
>
|
|
130
|
+
Save
|
|
131
|
+
</BasicDrawer.Button>
|
|
132
|
+
</BasicDrawer.Footer>
|
|
133
|
+
</BasicDrawer>
|
|
134
|
+
);
|
|
135
|
+
};
|
package/src/features/credit-cards/components/CreateCreditCardDrawer/create-credit-card-drawer.scss
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@import "../../../shared/components/BasicDrawer/basic-drawer.scss";
|
|
2
|
+
@import "../../../shared/components/InputText/input-text.scss";
|
|
3
|
+
@import "../../../shared/components/ErrorMessage/error-message.scss";
|
|
4
|
+
@import "@faststore/ui/src/components/atoms/Select/styles.scss";
|
|
5
|
+
@import "@faststore/ui/src/components/atoms/Button/styles.scss";
|
|
6
|
+
@import "@faststore/ui/src/components/molecules/Alert/styles.scss";
|
|
7
|
+
@import "../CreditCardForm/credit-card-form.scss";
|
|
8
|
+
|
|
9
|
+
[data-fs-bp-create-credit-card-drawer] {
|
|
10
|
+
@import "../../../addresses/components/ExistingAddress/existing-address.scss";
|
|
11
|
+
|
|
12
|
+
[data-fs-bp-create-credit-card-drawer-section-label] {
|
|
13
|
+
font-weight: bold;
|
|
14
|
+
margin-top: var(--fs-spacing-3);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
[data-fs-bp-autocomplete-dropdown] {
|
|
18
|
+
margin-top: var(--fs-spacing-3);
|
|
19
|
+
margin-bottom: var(--fs-spacing-3);
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/features/credit-cards/components/CreditCardDropdownMenu/CreditCardDropdownMenu.tsx
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { DropdownItem, Icon as UIIcon } from "@faststore/ui";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
DeleteCreditCardDrawer,
|
|
5
|
+
EditCreditCardDrawer,
|
|
6
|
+
RemoveCreditCardDrawer,
|
|
7
|
+
} from "..";
|
|
8
|
+
import { useDrawerProps, useBuyerPortal } from "../../../shared/hooks";
|
|
9
|
+
import { BasicDropdownMenu, Icon } from "../../../shared/components";
|
|
10
|
+
import type { CreditCardData } from "../../types";
|
|
11
|
+
|
|
12
|
+
export type CreditCardDropdownMenuProps = {
|
|
13
|
+
currentCreditCard: CreditCardData;
|
|
14
|
+
onUpdate?: () => void;
|
|
15
|
+
onCreate?: () => void;
|
|
16
|
+
isComplete?: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const CreditCardDropdownMenu = ({
|
|
20
|
+
currentCreditCard,
|
|
21
|
+
}: CreditCardDropdownMenuProps) => {
|
|
22
|
+
const { currentOrgUnit } = useBuyerPortal();
|
|
23
|
+
|
|
24
|
+
const idsPath = currentOrgUnit?.path?.ids?.split("/") ?? [];
|
|
25
|
+
|
|
26
|
+
const isRootLevelOrgUnit = idsPath.length === 2 ?? false;
|
|
27
|
+
|
|
28
|
+
const {
|
|
29
|
+
open: openEditDrawerProps,
|
|
30
|
+
isOpen: isEditDrawerOpen,
|
|
31
|
+
...editDrawerProps
|
|
32
|
+
} = useDrawerProps();
|
|
33
|
+
|
|
34
|
+
const {
|
|
35
|
+
open: openRemoveDrawer,
|
|
36
|
+
isOpen: isOpenRemoveDrawer,
|
|
37
|
+
...removeDrawerProps
|
|
38
|
+
} = useDrawerProps();
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
open: openDeleteDrawer,
|
|
42
|
+
isOpen: isOpenDeleteDrawer,
|
|
43
|
+
...deleteDrawerProps
|
|
44
|
+
} = useDrawerProps();
|
|
45
|
+
|
|
46
|
+
const sizeProps = { width: 20, height: 20 };
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<>
|
|
50
|
+
<BasicDropdownMenu data-fs-bp-dropdown-menu>
|
|
51
|
+
<DropdownItem onClick={openEditDrawerProps}>
|
|
52
|
+
<Icon name="Rename" {...sizeProps} />
|
|
53
|
+
Rename
|
|
54
|
+
</DropdownItem>
|
|
55
|
+
<DropdownItem onClick={() => {}}>
|
|
56
|
+
<Icon name="BookmarkAdd" {...sizeProps} />
|
|
57
|
+
Set as Default
|
|
58
|
+
</DropdownItem>
|
|
59
|
+
|
|
60
|
+
<BasicDropdownMenu.Separator />
|
|
61
|
+
<DropdownItem onClick={openRemoveDrawer}>
|
|
62
|
+
<UIIcon name="MinusCircle" {...sizeProps} />
|
|
63
|
+
Remove from Unit
|
|
64
|
+
</DropdownItem>
|
|
65
|
+
{isRootLevelOrgUnit && (
|
|
66
|
+
<DropdownItem
|
|
67
|
+
onClick={openDeleteDrawer}
|
|
68
|
+
data-fs-bp-dropdown-menu-item-mode="danger"
|
|
69
|
+
>
|
|
70
|
+
<Icon name="Delete" {...sizeProps} data-fs-bp-delete-dropdown />
|
|
71
|
+
<span data-fs-bp-delete-dropdown>Delete</span>
|
|
72
|
+
</DropdownItem>
|
|
73
|
+
)}
|
|
74
|
+
</BasicDropdownMenu>
|
|
75
|
+
{isEditDrawerOpen && (
|
|
76
|
+
<EditCreditCardDrawer
|
|
77
|
+
readonly
|
|
78
|
+
{...editDrawerProps}
|
|
79
|
+
isOpen={isEditDrawerOpen}
|
|
80
|
+
creditCard={currentCreditCard}
|
|
81
|
+
/>
|
|
82
|
+
)}
|
|
83
|
+
{isOpenRemoveDrawer && (
|
|
84
|
+
<RemoveCreditCardDrawer
|
|
85
|
+
readonly
|
|
86
|
+
cardName={currentCreditCard.nickname}
|
|
87
|
+
cardId={currentCreditCard.id}
|
|
88
|
+
{...removeDrawerProps}
|
|
89
|
+
isOpen={isOpenRemoveDrawer}
|
|
90
|
+
/>
|
|
91
|
+
)}
|
|
92
|
+
{isOpenDeleteDrawer && (
|
|
93
|
+
<DeleteCreditCardDrawer
|
|
94
|
+
readonly
|
|
95
|
+
cardName={currentCreditCard.nickname}
|
|
96
|
+
cardId={currentCreditCard.id}
|
|
97
|
+
isOpen={isOpenDeleteDrawer}
|
|
98
|
+
{...deleteDrawerProps}
|
|
99
|
+
/>
|
|
100
|
+
)}
|
|
101
|
+
</>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { InputText } from "../../../shared/components";
|
|
2
|
+
import type { CreditCard } from "../../types";
|
|
3
|
+
import {
|
|
4
|
+
maskCardNumber,
|
|
5
|
+
maskExpirationDate,
|
|
6
|
+
maskCVV,
|
|
7
|
+
} from "../../../shared/utils";
|
|
8
|
+
|
|
9
|
+
export type CreditCardFormProps = {
|
|
10
|
+
creditCard: CreditCard;
|
|
11
|
+
setNewCard: (newCard: CreditCard) => void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const CreditCardForm = ({
|
|
15
|
+
creditCard,
|
|
16
|
+
setNewCard,
|
|
17
|
+
}: CreditCardFormProps) => {
|
|
18
|
+
const handleChangeNumber = (cardNumber: string) => {
|
|
19
|
+
setNewCard({
|
|
20
|
+
...creditCard,
|
|
21
|
+
number: maskCardNumber(cardNumber),
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleChangeExpirationDate = (expirationDate: string) => {
|
|
26
|
+
setNewCard({
|
|
27
|
+
...creditCard,
|
|
28
|
+
expirationDate: maskExpirationDate(expirationDate),
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const handleChangeVerificationCode = (verificationCode: string) => {
|
|
33
|
+
setNewCard({
|
|
34
|
+
...creditCard,
|
|
35
|
+
cvv: maskCVV(verificationCode),
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<>
|
|
41
|
+
<div data-fs-bp-create-credit-card-drawer-section-label>
|
|
42
|
+
<span>Card Details</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<InputText
|
|
46
|
+
label="Card number"
|
|
47
|
+
value={creditCard.number}
|
|
48
|
+
wrapperProps={{ style: { marginTop: 16 } }}
|
|
49
|
+
onChange={(event) => handleChangeNumber(event.target.value)}
|
|
50
|
+
/>
|
|
51
|
+
|
|
52
|
+
<div data-fs-bp-create-credit-card-security-line>
|
|
53
|
+
<InputText
|
|
54
|
+
label="Exp MM/YY"
|
|
55
|
+
value={creditCard.expirationDate}
|
|
56
|
+
wrapperProps={{ style: { marginTop: 16 } }}
|
|
57
|
+
onChange={(event) => handleChangeExpirationDate(event.target.value)}
|
|
58
|
+
/>
|
|
59
|
+
|
|
60
|
+
<InputText
|
|
61
|
+
label="CVV"
|
|
62
|
+
value={creditCard.cvv}
|
|
63
|
+
wrapperProps={{ style: { marginTop: 16 } }}
|
|
64
|
+
onChange={(event) => handleChangeVerificationCode(event.target.value)}
|
|
65
|
+
type="number"
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<InputText
|
|
70
|
+
label="Cardholder name"
|
|
71
|
+
value={creditCard.cardholder}
|
|
72
|
+
wrapperProps={{ style: { marginTop: 16 } }}
|
|
73
|
+
onChange={(event) =>
|
|
74
|
+
setNewCard({ ...creditCard, cardholder: event.target.value })
|
|
75
|
+
}
|
|
76
|
+
/>
|
|
77
|
+
</>
|
|
78
|
+
);
|
|
79
|
+
};
|
package/src/features/credit-cards/components/DeleteCreditCardDrawer/DeleteCreditCardDrawer.tsx
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useUI } from "@faststore/ui";
|
|
2
|
+
import { useRouter } from "next/router";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
type BasicDrawerProps,
|
|
6
|
+
BasicDrawer,
|
|
7
|
+
InputText,
|
|
8
|
+
} from "../../../shared/components";
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
|
|
11
|
+
export type DeleteCreditCardDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
12
|
+
readonly?: boolean;
|
|
13
|
+
cardName: string;
|
|
14
|
+
cardId: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const DeleteCreditCardDrawer = ({
|
|
18
|
+
close,
|
|
19
|
+
cardName,
|
|
20
|
+
cardId,
|
|
21
|
+
readonly,
|
|
22
|
+
...props
|
|
23
|
+
}: DeleteCreditCardDrawerProps) => {
|
|
24
|
+
const { pushToast } = useUI();
|
|
25
|
+
const router = useRouter();
|
|
26
|
+
const [creditCardNameConfirmation, setCreditCardNameConfirmation] =
|
|
27
|
+
useState("");
|
|
28
|
+
|
|
29
|
+
const handleConfirmClick = () => {
|
|
30
|
+
pushToast({
|
|
31
|
+
message: "Credit card deleted successfully",
|
|
32
|
+
status: "INFO",
|
|
33
|
+
});
|
|
34
|
+
router.reload();
|
|
35
|
+
close();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const isDeleteButtonEnabled = creditCardNameConfirmation === cardName;
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<BasicDrawer data-fs-bp-remove-credit-card-drawer close={close} {...props}>
|
|
42
|
+
<BasicDrawer.Heading title="Delete credit card" onClose={close} />
|
|
43
|
+
<BasicDrawer.Body>
|
|
44
|
+
<div>
|
|
45
|
+
<p>
|
|
46
|
+
Permanently delete <span data-fs-bp-drawer-label>{cardName} </span>?
|
|
47
|
+
</p>
|
|
48
|
+
<br />
|
|
49
|
+
<p>
|
|
50
|
+
This credit card may be used by multiple units. Deleting it will
|
|
51
|
+
permanently remove it and all iits data from all associated units,
|
|
52
|
+
though usage history will be kept for audit. This action can't be
|
|
53
|
+
undone
|
|
54
|
+
</p>
|
|
55
|
+
<br />
|
|
56
|
+
<p>Confirm by typing the card nickname below:</p>
|
|
57
|
+
<br />
|
|
58
|
+
<InputText
|
|
59
|
+
label="Card nickname"
|
|
60
|
+
value={creditCardNameConfirmation}
|
|
61
|
+
onChange={(event) =>
|
|
62
|
+
setCreditCardNameConfirmation(event.currentTarget.value)
|
|
63
|
+
}
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
</BasicDrawer.Body>
|
|
67
|
+
|
|
68
|
+
<BasicDrawer.Footer>
|
|
69
|
+
<BasicDrawer.Button variant="ghost" onClick={close}>
|
|
70
|
+
Cancel
|
|
71
|
+
</BasicDrawer.Button>
|
|
72
|
+
<BasicDrawer.Button
|
|
73
|
+
variant="confirm"
|
|
74
|
+
onClick={handleConfirmClick}
|
|
75
|
+
disabled={!isDeleteButtonEnabled}
|
|
76
|
+
>
|
|
77
|
+
Delete
|
|
78
|
+
</BasicDrawer.Button>
|
|
79
|
+
</BasicDrawer.Footer>
|
|
80
|
+
</BasicDrawer>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { useUI } from "@faststore/ui";
|
|
4
|
+
import { useRouter } from "next/router";
|
|
5
|
+
import {
|
|
6
|
+
type BasicDrawerProps,
|
|
7
|
+
BasicDrawer,
|
|
8
|
+
InputText,
|
|
9
|
+
} from "../../../shared/components";
|
|
10
|
+
import type { CreditCardData } from "../../types";
|
|
11
|
+
|
|
12
|
+
export type EditCreditCardDrawerProps = Omit<BasicDrawerProps, "children"> & {
|
|
13
|
+
readonly?: boolean;
|
|
14
|
+
creditCard: CreditCardData;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const EditCreditCardDrawer = ({
|
|
18
|
+
close,
|
|
19
|
+
readonly,
|
|
20
|
+
creditCard,
|
|
21
|
+
...props
|
|
22
|
+
}: EditCreditCardDrawerProps) => {
|
|
23
|
+
const { pushToast } = useUI();
|
|
24
|
+
|
|
25
|
+
const router = useRouter();
|
|
26
|
+
|
|
27
|
+
const [cardToModify, setCardToModify] = useState<CreditCardData>(creditCard);
|
|
28
|
+
const [onConfirmationStep, setOnConfirmationStep] = useState(false);
|
|
29
|
+
|
|
30
|
+
const drawerTitle = onConfirmationStep
|
|
31
|
+
? "Confirm credit card update"
|
|
32
|
+
: "Rename credit card";
|
|
33
|
+
|
|
34
|
+
const handleConfirmClick = () => {
|
|
35
|
+
if (onConfirmationStep) {
|
|
36
|
+
pushToast({
|
|
37
|
+
message: "Credit edited added successfully",
|
|
38
|
+
status: "INFO",
|
|
39
|
+
});
|
|
40
|
+
router.reload();
|
|
41
|
+
close();
|
|
42
|
+
} else {
|
|
43
|
+
setOnConfirmationStep(true);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const isEdited = cardToModify.nickname !== creditCard.nickname;
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<BasicDrawer data-fs-bp-edit-credit-card-drawer close={close} {...props}>
|
|
51
|
+
<BasicDrawer.Heading title={drawerTitle} onClose={close} />
|
|
52
|
+
<BasicDrawer.Body>
|
|
53
|
+
{onConfirmationStep ? (
|
|
54
|
+
<div>
|
|
55
|
+
<p>
|
|
56
|
+
Thid credit card may be used by multiple units. Updates will
|
|
57
|
+
affect all of them
|
|
58
|
+
</p>
|
|
59
|
+
<br />
|
|
60
|
+
<p>Proceed with the update?</p>
|
|
61
|
+
<br />
|
|
62
|
+
</div>
|
|
63
|
+
) : (
|
|
64
|
+
<InputText
|
|
65
|
+
label="Card nickname"
|
|
66
|
+
value={cardToModify.nickname}
|
|
67
|
+
wrapperProps={{ style: { marginTop: 16 } }}
|
|
68
|
+
onChange={(event) =>
|
|
69
|
+
setCardToModify({ ...cardToModify, nickname: event.target.value })
|
|
70
|
+
}
|
|
71
|
+
/>
|
|
72
|
+
)}
|
|
73
|
+
</BasicDrawer.Body>
|
|
74
|
+
|
|
75
|
+
<BasicDrawer.Footer>
|
|
76
|
+
<BasicDrawer.Button variant="ghost" onClick={close}>
|
|
77
|
+
Cancel
|
|
78
|
+
</BasicDrawer.Button>
|
|
79
|
+
<BasicDrawer.Button
|
|
80
|
+
variant="confirm"
|
|
81
|
+
disabled={!isEdited}
|
|
82
|
+
onClick={handleConfirmClick}
|
|
83
|
+
isLoading={false}
|
|
84
|
+
>
|
|
85
|
+
{onConfirmationStep ? "Confirm" : "Save"}
|
|
86
|
+
</BasicDrawer.Button>
|
|
87
|
+
</BasicDrawer.Footer>
|
|
88
|
+
</BasicDrawer>
|
|
89
|
+
);
|
|
90
|
+
};
|