@vtex/faststore-plugin-buyer-portal 1.0.3 → 1.0.4
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 +4 -8
- package/plugin.config.js +1 -1
- package/src/components/AddressesCard/AddressesCard.tsx +87 -0
- package/src/components/Card/Card.scss +159 -0
- package/src/components/Card/Card.tsx +16 -0
- package/src/components/Card/CardBody.tsx +7 -0
- package/src/components/Card/CardFooter.tsx +5 -0
- package/src/components/Card/CardHeader.tsx +7 -0
- package/src/components/Card/index.ts +4 -0
- package/src/components/ContractsCard/ContractsCard.tsx +88 -0
- package/src/components/OrganizationalUnitsCard/OrganizationalUnitsCard.tsx +66 -0
- package/src/components/ProfileCard/ProfileCard.tsx +48 -0
- package/src/components/UsersCard/UsersCard.tsx +89 -0
- package/src/components/index.ts +6 -1
- package/src/mock/profile-data.ts +48 -0
- package/src/pages/buyer-portal.tsx +25 -1
- package/src/themes/index.scss +75 -0
package/package.json
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vtex/faststore-plugin-buyer-portal",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "A plugin for faststore with buyer portal",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"dependencies": {
|
|
7
|
-
"react": "^18.2.0",
|
|
8
|
-
"react-dom": "^18.2.0"
|
|
9
|
-
},
|
|
6
|
+
"dependencies": {},
|
|
10
7
|
"devDependencies": {
|
|
11
8
|
"@faststore/core": "^3.0.147",
|
|
12
9
|
"@faststore/ui": "^3.0.147",
|
|
@@ -15,9 +12,8 @@
|
|
|
15
12
|
"typescript": "4.7.3"
|
|
16
13
|
},
|
|
17
14
|
"peerDependencies": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"next": "13.5.6"
|
|
15
|
+
"react": "^18.2.0",
|
|
16
|
+
"react-dom": "^18.2.0"
|
|
21
17
|
},
|
|
22
18
|
"license": "MIT"
|
|
23
19
|
}
|
package/plugin.config.js
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IconButton, Icon, Toggle, Dropdown,
|
|
3
|
+
DropdownItem,
|
|
4
|
+
DropdownMenu,
|
|
5
|
+
DropdownButton,
|
|
6
|
+
} from '@faststore/ui'
|
|
7
|
+
|
|
8
|
+
import { Card, CardBody, CardFooter, CardHeader } from '../Card'
|
|
9
|
+
import Link from "next/link";
|
|
10
|
+
|
|
11
|
+
export type AddressInformation = {
|
|
12
|
+
addressId: string,
|
|
13
|
+
street: string,
|
|
14
|
+
addressType: string,
|
|
15
|
+
isActive: boolean,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type AddressesCardProps = {
|
|
19
|
+
addresses: AddressInformation[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default function AddressesCard({ addresses }: AddressesCardProps) {
|
|
23
|
+
return (
|
|
24
|
+
<section data-fs-home-card>
|
|
25
|
+
<Card>
|
|
26
|
+
<CardHeader>
|
|
27
|
+
<div data-fs-card-title>Addresses <span data-fs-card-title-counter>{addresses.length}</span></div>
|
|
28
|
+
<IconButton icon={<Icon name="PlusCircle" width={20} height={20} />}
|
|
29
|
+
aria-label={`$addresses action`} onClick={() => { }} />
|
|
30
|
+
</CardHeader>
|
|
31
|
+
<CardBody>
|
|
32
|
+
{addresses.length && addresses.map((address: AddressInformation) => {
|
|
33
|
+
return (
|
|
34
|
+
<div>
|
|
35
|
+
<hr data-fs-divider />
|
|
36
|
+
|
|
37
|
+
<div data-fs-card-row key={address.addressId}>
|
|
38
|
+
<div data-fs-card-information-row>
|
|
39
|
+
<Icon name="House" weight='bold' data-fs-card-information-icon />
|
|
40
|
+
<span data-fs-card-information-title>{address.street}</span>
|
|
41
|
+
<div data-fs-card-information-type>
|
|
42
|
+
<span data-fs-shipping-tag>{address.addressType}</span>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<div data-fs-card-action-row>
|
|
46
|
+
<Toggle id="addressActive" defaultChecked={address.isActive} />
|
|
47
|
+
|
|
48
|
+
<Dropdown>
|
|
49
|
+
<DropdownButton><Icon name='DotsThree' data-fs-menu-action-button /></DropdownButton>
|
|
50
|
+
<DropdownMenu>
|
|
51
|
+
<DropdownItem>
|
|
52
|
+
<Icon name="ArrowSquareOut" />Open
|
|
53
|
+
</DropdownItem>
|
|
54
|
+
<DropdownItem>
|
|
55
|
+
{/* TODO: Replace Icon */}
|
|
56
|
+
<Icon name='User' />Edit
|
|
57
|
+
</DropdownItem>
|
|
58
|
+
<DropdownItem>
|
|
59
|
+
{/* TODO: Replace Icon */}
|
|
60
|
+
<Icon name="XCircle" /> Delete
|
|
61
|
+
</DropdownItem>
|
|
62
|
+
{/* TODO: Replace Icon */}
|
|
63
|
+
<DropdownItem>
|
|
64
|
+
<div data-fs-dropdown-active-item>
|
|
65
|
+
<div data-fs-dropdown-active-item-label>
|
|
66
|
+
<Icon name="Checked" />Active
|
|
67
|
+
</div>
|
|
68
|
+
<Toggle id="addressActiveMenu" defaultChecked={address.isActive} data-fs-internal-toggle />
|
|
69
|
+
</div>
|
|
70
|
+
</DropdownItem>
|
|
71
|
+
</DropdownMenu>
|
|
72
|
+
</Dropdown>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>)
|
|
76
|
+
})}
|
|
77
|
+
</CardBody>
|
|
78
|
+
<CardFooter>
|
|
79
|
+
<Link href="/" data-fs-card-footer-link>
|
|
80
|
+
<span>Manage addresses</span>
|
|
81
|
+
</Link>
|
|
82
|
+
<IconButton icon={<Icon name="CaretRight" data-fs-card-footer-icon />} aria-label="manage-addresses" />
|
|
83
|
+
</CardFooter>
|
|
84
|
+
</Card>
|
|
85
|
+
</section>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
[data-fs-card] {
|
|
2
|
+
// --------------------------------------------------------
|
|
3
|
+
// Design Tokens for Card
|
|
4
|
+
// --------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
// Default properties
|
|
7
|
+
--fs-card-border-width : var(--fs-border-width);
|
|
8
|
+
|
|
9
|
+
// Header
|
|
10
|
+
--fs-card-header-padding : var(--fs-spacing-3);
|
|
11
|
+
--fs-card-header-bkg-color : var(--fs-color-neutral-bkg);
|
|
12
|
+
--fs-card-header-font-weight : var(--fs-text-weight-bold);
|
|
13
|
+
--fs-card-header-icon-color : var(--fs-color-main-2);
|
|
14
|
+
|
|
15
|
+
// Body
|
|
16
|
+
--fs-card-body-padding : var(--fs-spacing-3);
|
|
17
|
+
|
|
18
|
+
// --------------------------------------------------------
|
|
19
|
+
// Structural Styles
|
|
20
|
+
// --------------------------------------------------------
|
|
21
|
+
border: var(--fs-card-border-width) solid rgba(224, 224, 224, 1);
|
|
22
|
+
border-radius: 12px;
|
|
23
|
+
|
|
24
|
+
[data-fs-card-header] {
|
|
25
|
+
border-top-left-radius: 12px;
|
|
26
|
+
border-top-right-radius: 12px;
|
|
27
|
+
padding-bottom: 0px !important;
|
|
28
|
+
background-color: white;
|
|
29
|
+
align-items: center;
|
|
30
|
+
|
|
31
|
+
padding: var(--fs-card-header-padding);
|
|
32
|
+
font-weight: var(--fs-card-header-font-weight);
|
|
33
|
+
display: flex;
|
|
34
|
+
justify-content: space-between;
|
|
35
|
+
|
|
36
|
+
[data-fs-button]{
|
|
37
|
+
--fs-button-height: var(--fs-spacing-4);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
[data-fs-icon]{
|
|
41
|
+
color: var(--fs-card-header-icon-color);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[data-fs-card-title-counter]{
|
|
45
|
+
font-weight: 600;
|
|
46
|
+
margin-left: 0.75rem;
|
|
47
|
+
color: #ADADAD;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
[data-fs-card-body] {
|
|
52
|
+
padding: var(--fs-card-body-padding);
|
|
53
|
+
padding-bottom: 0px;
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
[data-fs-profile-card-row] {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: row;
|
|
59
|
+
gap: 2.5rem;
|
|
60
|
+
padding-top: 1.25rem;
|
|
61
|
+
padding-bottom: 1.25rem;
|
|
62
|
+
|
|
63
|
+
[data-fs-card-row-label]{
|
|
64
|
+
font-weight: 500;
|
|
65
|
+
width: 100px;
|
|
66
|
+
color: gray;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
[data-fs-card-row]{
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-direction: row;
|
|
73
|
+
gap: 2.5rem;
|
|
74
|
+
padding-top: 0.5rem;
|
|
75
|
+
padding-bottom: 0.5rem;
|
|
76
|
+
|
|
77
|
+
[data-fs-card-row-label]{
|
|
78
|
+
font-weight: 500;
|
|
79
|
+
width: 100px;
|
|
80
|
+
color: gray;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
[data-fs-card-information-row] {
|
|
85
|
+
display: flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
width: 70%;
|
|
88
|
+
justify-content: space-around;
|
|
89
|
+
|
|
90
|
+
[data-fs-card-information-icon] {
|
|
91
|
+
width: 50px
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
[data-fs-card-information-title] {
|
|
95
|
+
width: 200px
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
[data-fs-card-information-type] {
|
|
99
|
+
width: 100px;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
[data-fs-card-action-row] {
|
|
104
|
+
display: flex;
|
|
105
|
+
width: 50%;
|
|
106
|
+
justify-content: flex-end;
|
|
107
|
+
align-items: center;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
[data-fs-menu-action-button] {
|
|
112
|
+
rotate: 90deg;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
[data-fs-shipping-tag] {
|
|
116
|
+
background: #C2C2C2;
|
|
117
|
+
padding: 5px 10px 5px 10px;
|
|
118
|
+
border-radius: 100px;
|
|
119
|
+
font-weight: 500;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
[data-fs-card-body-empty-state] {
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-direction: column;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: 10px;
|
|
127
|
+
padding: 100px;
|
|
128
|
+
|
|
129
|
+
[data-fs-button]{
|
|
130
|
+
--fs-border-radius: 999px;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
[data-fs-divider] {
|
|
136
|
+
border: 1px solid #E0E0E0
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
[data-fs-card-footer] {
|
|
140
|
+
border-top-width: var(--fs-card-border-width);
|
|
141
|
+
border-top-color: rgba(224, 224, 224, 1);
|
|
142
|
+
border-top-style: solid;
|
|
143
|
+
padding: var(--fs-spacing-1) var(--fs-spacing-3);
|
|
144
|
+
display: flex;
|
|
145
|
+
justify-content: space-between;
|
|
146
|
+
align-items: center;
|
|
147
|
+
|
|
148
|
+
[data-fs-card-footer-link] {
|
|
149
|
+
font-weight: 500;
|
|
150
|
+
line-height: 14px;
|
|
151
|
+
color: #0366DD;
|
|
152
|
+
text-decoration: none;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
[data-fs-card-footer-icon] {
|
|
156
|
+
color: grey
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react";
|
|
2
|
+
import React, { forwardRef } from 'react'
|
|
3
|
+
|
|
4
|
+
export interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'role'> {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const Card = forwardRef<HTMLDivElement, CardProps>(function Card({
|
|
8
|
+
children,
|
|
9
|
+
...otherProps
|
|
10
|
+
}, ref) {
|
|
11
|
+
return (
|
|
12
|
+
<section data-testid="fs-card" ref={ref} data-fs-card {...otherProps}>
|
|
13
|
+
{children}
|
|
14
|
+
</section >
|
|
15
|
+
)
|
|
16
|
+
})
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Icon, IconButton, Toggle, Dropdown,
|
|
3
|
+
DropdownItem,
|
|
4
|
+
DropdownMenu,
|
|
5
|
+
DropdownButton,
|
|
6
|
+
} from '@faststore/ui'
|
|
7
|
+
|
|
8
|
+
import { Card, CardBody, CardFooter, CardHeader } from '../Card'
|
|
9
|
+
import Link from "next/link";
|
|
10
|
+
|
|
11
|
+
export type ContractInformation = {
|
|
12
|
+
id: string
|
|
13
|
+
name: string
|
|
14
|
+
isActive: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type ContractsCardProps = {
|
|
18
|
+
contracts: ContractInformation[]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export default function ContractsCard({ contracts }: ContractsCardProps) {
|
|
23
|
+
return (
|
|
24
|
+
<section data-fs-home-card>
|
|
25
|
+
<Card>
|
|
26
|
+
<CardHeader>
|
|
27
|
+
<div data-fs-card-title>Contracts <span data-fs-card-title-counter>{contracts.length}</span></div>
|
|
28
|
+
{/* TODO: CHANGE ICON */}
|
|
29
|
+
<IconButton icon={<Icon name="PlusCircle" width={20} height={20} />}
|
|
30
|
+
aria-label={`$profile action`} onClick={() => { }} />
|
|
31
|
+
</CardHeader>
|
|
32
|
+
<CardBody>
|
|
33
|
+
{contracts.length && contracts.map((contract: ContractInformation) => {
|
|
34
|
+
return (
|
|
35
|
+
<div>
|
|
36
|
+
<hr data-fs-divider />
|
|
37
|
+
|
|
38
|
+
<div data-fs-card-row key={contract.id}>
|
|
39
|
+
<div data-fs-card-information-row>
|
|
40
|
+
<Icon data-fs-card-information-icon name="User" weight='bold' />
|
|
41
|
+
<h1 data-fs-card-information-title>{contract.name}</h1>
|
|
42
|
+
</div>
|
|
43
|
+
<div data-fs-card-action-row>
|
|
44
|
+
<Toggle id="contractActive" defaultChecked={contract.isActive} />
|
|
45
|
+
|
|
46
|
+
<Dropdown>
|
|
47
|
+
<DropdownButton>
|
|
48
|
+
<Icon name="DotsThree" data-fs-menu-action-button />
|
|
49
|
+
</DropdownButton>
|
|
50
|
+
<DropdownMenu align="right" data-fs-dropdown-menu>
|
|
51
|
+
<DropdownItem>
|
|
52
|
+
<Icon name="ArrowSquareOut" />Open
|
|
53
|
+
</DropdownItem>
|
|
54
|
+
<DropdownItem>
|
|
55
|
+
{/* TODO: Replace Icon */}
|
|
56
|
+
<Icon name='User' />Edit
|
|
57
|
+
</DropdownItem>
|
|
58
|
+
<DropdownItem>
|
|
59
|
+
{/* TODO: Replace Icon */}
|
|
60
|
+
<Icon name="XCircle" /> Delete
|
|
61
|
+
</DropdownItem>
|
|
62
|
+
{/* TODO: Replace Icon */}
|
|
63
|
+
<DropdownItem>
|
|
64
|
+
<div data-fs-dropdown-active-item>
|
|
65
|
+
<div data-fs-dropdown-active-item-label>
|
|
66
|
+
<Icon name="Checked" />Active
|
|
67
|
+
</div>
|
|
68
|
+
<Toggle id="contractActiveMenu" defaultChecked={contract.isActive} data-fs-internal-toggle />
|
|
69
|
+
</div>
|
|
70
|
+
</DropdownItem>
|
|
71
|
+
</DropdownMenu>
|
|
72
|
+
</Dropdown>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
</div>
|
|
76
|
+
</div>)
|
|
77
|
+
})}
|
|
78
|
+
</CardBody>
|
|
79
|
+
<CardFooter>
|
|
80
|
+
<Link href="/" data-fs-card-footer-link>
|
|
81
|
+
<span>View contracts</span>
|
|
82
|
+
</Link>
|
|
83
|
+
<IconButton icon={<Icon name="CaretRight" data-fs-card-footer-icon />} aria-label="view-contracts" />
|
|
84
|
+
</CardFooter>
|
|
85
|
+
</Card>
|
|
86
|
+
</section>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Icon, Toggle, IconButton, Button } from '@faststore/ui'
|
|
2
|
+
|
|
3
|
+
import { Card, CardBody, CardFooter, CardHeader } from '../Card'
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export type OrganizationalUnitInformation = {
|
|
8
|
+
organizationalUnitId: string
|
|
9
|
+
organizationalUnitName: string
|
|
10
|
+
isActive: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type OrganizationalUnitsCardProps = {
|
|
14
|
+
organizationalUnits: OrganizationalUnitInformation[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export default function OrganizationalUnitsCard({ organizationalUnits = [] }: OrganizationalUnitsCardProps) {
|
|
19
|
+
return (
|
|
20
|
+
<section data-fs-home-card>
|
|
21
|
+
<Card>
|
|
22
|
+
<CardHeader>
|
|
23
|
+
<div data-fs-card-title>Organizational Units {organizationalUnits.length > 0 && (<span data-fs-card-title-counter>{organizationalUnits.length}</span>)} </div>
|
|
24
|
+
<IconButton icon={<Icon name="PlusCircle" width={20} height={20} />}
|
|
25
|
+
aria-label={`$profile action`} onClick={() => { }} />
|
|
26
|
+
</CardHeader>
|
|
27
|
+
|
|
28
|
+
<CardBody>
|
|
29
|
+
{organizationalUnits.length > 0 ? (
|
|
30
|
+
organizationalUnits.map((orgUnit: OrganizationalUnitInformation) => {
|
|
31
|
+
return (
|
|
32
|
+
<div key={orgUnit.organizationalUnitId}>
|
|
33
|
+
<hr data-fs-divider />
|
|
34
|
+
|
|
35
|
+
<div data-fs-card-row key={orgUnit.organizationalUnitId}>
|
|
36
|
+
<div data-fs-card-information-row>
|
|
37
|
+
<Icon name="ShoppingCart" weight='bold' data-fs-card-information-icon />
|
|
38
|
+
<span data-fs-card-information-title>{orgUnit.organizationalUnitName}</span>
|
|
39
|
+
</div>
|
|
40
|
+
<div data-fs-card-action-row>
|
|
41
|
+
<Toggle id="orgUnitActive" defaultChecked={orgUnit.isActive} />
|
|
42
|
+
<IconButton icon={<Icon name="DotsThree" />} aria-label="org-actions" data-fs-menu-action-button />
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>)
|
|
46
|
+
})
|
|
47
|
+
) : (
|
|
48
|
+
<div data-fs-card-body-empty-state>
|
|
49
|
+
<Icon name="ShoppingCart" width={50} height={50} />
|
|
50
|
+
<span> No child organizational units yet </span>
|
|
51
|
+
<Button variant="primary">+ Add New</Button>
|
|
52
|
+
</div>
|
|
53
|
+
)}
|
|
54
|
+
</CardBody>
|
|
55
|
+
{organizationalUnits.length > 0 && (
|
|
56
|
+
<CardFooter>
|
|
57
|
+
<Link href="/" data-fs-card-footer-link>
|
|
58
|
+
<span>Manage organizational units</span>
|
|
59
|
+
</Link>
|
|
60
|
+
<IconButton icon={<Icon name="CaretRight" data-fs-card-footer-icon />} aria-label="manage-organizational-units" />
|
|
61
|
+
</CardFooter>
|
|
62
|
+
)}
|
|
63
|
+
</Card>
|
|
64
|
+
</section>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Card, CardBody, CardFooter, CardHeader } from '../Card'
|
|
2
|
+
import { Icon, IconButton } from '@faststore/ui'
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
type ProfileCardProps = {
|
|
7
|
+
name: string
|
|
8
|
+
email: string
|
|
9
|
+
id: string
|
|
10
|
+
|
|
11
|
+
imageUrl?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function ProfileCard({ name, email, id, imageUrl }: ProfileCardProps) {
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<section data-fs-home-card>
|
|
18
|
+
<Card>
|
|
19
|
+
<CardHeader>
|
|
20
|
+
<div data-fs-card-title>Profile</div>
|
|
21
|
+
</CardHeader>
|
|
22
|
+
<CardBody>
|
|
23
|
+
<hr data-fs-divider />
|
|
24
|
+
<div data-fs-profile-card-row>
|
|
25
|
+
<h1 data-fs-card-row-label>Name</h1>
|
|
26
|
+
<h1>{name}</h1>
|
|
27
|
+
</div>
|
|
28
|
+
<hr data-fs-divider />
|
|
29
|
+
<div data-fs-profile-card-row>
|
|
30
|
+
<h1 data-fs-card-row-label>Email</h1>
|
|
31
|
+
<h1>{email}</h1>
|
|
32
|
+
</div>
|
|
33
|
+
<hr data-fs-divider />
|
|
34
|
+
<div data-fs-profile-card-row>
|
|
35
|
+
<h1 data-fs-card-row-label>ID</h1>
|
|
36
|
+
<h1>{id}</h1>
|
|
37
|
+
</div>
|
|
38
|
+
</CardBody>
|
|
39
|
+
<CardFooter>
|
|
40
|
+
<Link href="/" data-fs-card-footer-link>
|
|
41
|
+
<span>View Profile</span>
|
|
42
|
+
</Link>
|
|
43
|
+
<IconButton icon={<Icon name="CaretRight" data-fs-card-footer-icon />} aria-label="view-profile" />
|
|
44
|
+
</CardFooter>
|
|
45
|
+
</Card>
|
|
46
|
+
</section>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Icon, IconButton, Toggle, Dropdown,
|
|
3
|
+
DropdownItem,
|
|
4
|
+
DropdownMenu,
|
|
5
|
+
DropdownButton,
|
|
6
|
+
} from '@faststore/ui'
|
|
7
|
+
|
|
8
|
+
import { Card, CardBody, CardFooter, CardHeader } from '../Card'
|
|
9
|
+
import Link from "next/link";
|
|
10
|
+
|
|
11
|
+
export type UserInformation = {
|
|
12
|
+
userId: string
|
|
13
|
+
name: string
|
|
14
|
+
userType: string
|
|
15
|
+
isActive: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type UsersCardProps = {
|
|
19
|
+
users: UserInformation[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export default function UsersCard({ users }: UsersCardProps) {
|
|
24
|
+
return (
|
|
25
|
+
<section data-fs-home-card>
|
|
26
|
+
<Card>
|
|
27
|
+
<CardHeader>
|
|
28
|
+
<div data-fs-card-title>Users <span data-fs-card-title-counter>{users.length}</span></div>
|
|
29
|
+
<IconButton icon={<Icon name="PlusCircle" width={20} height={20} />}
|
|
30
|
+
aria-label={`$profile action`} onClick={() => { }} />
|
|
31
|
+
</CardHeader>
|
|
32
|
+
<CardBody>
|
|
33
|
+
{users.length && users.map((user: UserInformation) => {
|
|
34
|
+
return (
|
|
35
|
+
<div>
|
|
36
|
+
<hr data-fs-divider />
|
|
37
|
+
|
|
38
|
+
<div data-fs-card-row key={user.userId}>
|
|
39
|
+
<div data-fs-card-information-row>
|
|
40
|
+
<Icon name="User" weight='bold' />
|
|
41
|
+
<h1>{user.name}</h1>
|
|
42
|
+
<h1 data-fs-card-row-label>{user.userType}</h1>
|
|
43
|
+
</div>
|
|
44
|
+
<div data-fs-card-action-row>
|
|
45
|
+
<Toggle id="userActive" defaultChecked={user.isActive} />
|
|
46
|
+
|
|
47
|
+
<Dropdown>
|
|
48
|
+
<DropdownButton>
|
|
49
|
+
<Icon name="DotsThree" data-fs-menu-action-button />
|
|
50
|
+
</DropdownButton>
|
|
51
|
+
<DropdownMenu align="right" data-fs-dropdown-menu>
|
|
52
|
+
<DropdownItem>
|
|
53
|
+
<Icon name="ArrowSquareOut" />Open
|
|
54
|
+
</DropdownItem>
|
|
55
|
+
<DropdownItem>
|
|
56
|
+
{/* TODO: Replace Icon */}
|
|
57
|
+
<Icon name='User' />Edit User Profile
|
|
58
|
+
</DropdownItem>
|
|
59
|
+
<DropdownItem>
|
|
60
|
+
{/* TODO: Replace Icon */}
|
|
61
|
+
<Icon name="XCircle" /> Delete
|
|
62
|
+
</DropdownItem>
|
|
63
|
+
{/* TODO: Replace Icon */}
|
|
64
|
+
<DropdownItem>
|
|
65
|
+
<div data-fs-dropdown-active-item>
|
|
66
|
+
<div data-fs-dropdown-active-item-label>
|
|
67
|
+
<Icon name="Checked" />Active
|
|
68
|
+
</div>
|
|
69
|
+
<Toggle id="userActiveMenu" defaultChecked={user.isActive} data-fs-internal-toggle />
|
|
70
|
+
</div>
|
|
71
|
+
</DropdownItem>
|
|
72
|
+
</DropdownMenu>
|
|
73
|
+
</Dropdown>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
</div>
|
|
77
|
+
</div>)
|
|
78
|
+
})}
|
|
79
|
+
</CardBody>
|
|
80
|
+
<CardFooter>
|
|
81
|
+
<Link href="/" data-fs-card-footer-link>
|
|
82
|
+
<span>Manage users</span>
|
|
83
|
+
</Link>
|
|
84
|
+
<IconButton icon={<Icon name="CaretRight" data-fs-card-footer-icon />} aria-label="manage-users" />
|
|
85
|
+
</CardFooter>
|
|
86
|
+
</Card>
|
|
87
|
+
</section>
|
|
88
|
+
)
|
|
89
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import ProfileCard from "./ProfileCard/ProfileCard";
|
|
2
|
+
import UsersCard from "./UsersCard/UsersCard";
|
|
3
|
+
import AddressesCard from './AddressesCard/AddressesCard'
|
|
4
|
+
import OrganizationalUnitsCard from "./OrganizationalUnitsCard/OrganizationalUnitsCard";
|
|
5
|
+
|
|
6
|
+
const sections = { ProfileCard, UsersCard, AddressesCard, OrganizationalUnitsCard };
|
|
2
7
|
|
|
3
8
|
export default sections;
|
package/src/mock/profile-data.ts
CHANGED
|
@@ -5,3 +5,51 @@ export const profileData = {
|
|
|
5
5
|
},
|
|
6
6
|
orgName: "Bytech Inc.",
|
|
7
7
|
};
|
|
8
|
+
|
|
9
|
+
export const organizationResponse = {
|
|
10
|
+
displayName: 'ByTech Inc.',
|
|
11
|
+
// Uncomment to test with a single contract
|
|
12
|
+
// contracts: [{
|
|
13
|
+
// name: 'ByTech',
|
|
14
|
+
// email: 'bytech@demo.com',
|
|
15
|
+
// id: '12-32-DDDD',
|
|
16
|
+
// isActive: false,
|
|
17
|
+
// }],
|
|
18
|
+
|
|
19
|
+
// Comment to test with single contract
|
|
20
|
+
contracts: [{
|
|
21
|
+
name: 'ByTech',
|
|
22
|
+
email: 'bytech@demo.com',
|
|
23
|
+
id: '12-32-DDDD',
|
|
24
|
+
isActive: false,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'ByTech South',
|
|
28
|
+
email: 'bytech@demo.com',
|
|
29
|
+
id: '12-32-AAAA',
|
|
30
|
+
isActive: true,
|
|
31
|
+
}],
|
|
32
|
+
users: [{
|
|
33
|
+
name: 'Everton',
|
|
34
|
+
userType: 'Admin',
|
|
35
|
+
isActive: true,
|
|
36
|
+
userId: '1234'
|
|
37
|
+
}, {
|
|
38
|
+
name: 'Arthur',
|
|
39
|
+
userType: 'Buyer',
|
|
40
|
+
isActive: false,
|
|
41
|
+
userId: '32141'
|
|
42
|
+
}],
|
|
43
|
+
addresses: [{
|
|
44
|
+
addressId: '123-1421',
|
|
45
|
+
addressType: 'Shipping',
|
|
46
|
+
street: 'Rua Morretes',
|
|
47
|
+
isActive: true
|
|
48
|
+
}, {
|
|
49
|
+
addressId: '123-1321',
|
|
50
|
+
addressType: 'Billing',
|
|
51
|
+
street: 'Rua Maranhão',
|
|
52
|
+
isActive: false
|
|
53
|
+
}],
|
|
54
|
+
organizationalUnits: []
|
|
55
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { Navbar } from "../components/Navbar/Navbar";
|
|
2
|
+
import AddressesCard from "../components/AddressesCard/AddressesCard";
|
|
3
|
+
import OrganizationalUnitsCard from "../components/OrganizationalUnitsCard/OrganizationalUnitsCard";
|
|
4
|
+
import ProfileCard from "../components/ProfileCard/ProfileCard";
|
|
5
|
+
import UsersCard from "../components/UsersCard/UsersCard";
|
|
6
|
+
import ContractsCard from "../components/ContractsCard/ContractsCard";
|
|
7
|
+
import { organizationResponse } from "../mock/profile-data";
|
|
2
8
|
|
|
3
9
|
export type PageLoader = { page: string };
|
|
4
10
|
|
|
@@ -7,5 +13,23 @@ export async function loader(): Promise<PageLoader> {
|
|
|
7
13
|
}
|
|
8
14
|
|
|
9
15
|
export default function MyAccount(data: PageLoader) {
|
|
10
|
-
return
|
|
16
|
+
return (
|
|
17
|
+
<section>
|
|
18
|
+
<Navbar />
|
|
19
|
+
<div data-fs-buyer-portal-home-grid>
|
|
20
|
+
<h1 data-fs-buyer-portal-title>{organizationResponse.displayName}</h1>
|
|
21
|
+
<div data-fs-buyer-portal-home-row>
|
|
22
|
+
{organizationResponse.contracts.length === 1 ? (<ProfileCard {...organizationResponse.contracts[0]} />) : (<ContractsCard contracts={organizationResponse.contracts} />)}
|
|
23
|
+
<UsersCard users={organizationResponse.users} />
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div data-fs-buyer-portal-home-row>
|
|
27
|
+
{organizationResponse.contracts.length === 1 && (<AddressesCard addresses={organizationResponse.addresses} />)}
|
|
28
|
+
<OrganizationalUnitsCard organizationalUnits={organizationResponse.organizationalUnits} />
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
</section>
|
|
34
|
+
)
|
|
11
35
|
}
|
package/src/themes/index.scss
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
@import "@faststore/ui/src/components/atoms/Logo/styles.scss";
|
|
3
3
|
@import "@faststore/ui/src/components/organisms/SlideOver/styles.scss";
|
|
4
4
|
@import "@faststore/ui/src/components/molecules/Dropdown/styles.scss";
|
|
5
|
+
@import '@faststore/ui/src/components/molecules/Toggle/styles.scss';
|
|
5
6
|
@import "../components/CustomerSwitch/customer-switch.scss";
|
|
6
7
|
@import "../components/Navbar/navbar.scss";
|
|
7
8
|
@import "../components/SelfManagementDrawer/self-management-drawer.scss";
|
|
8
9
|
@import "../components/SelfManagementDrawer/self-management-drawer.scss";
|
|
9
10
|
@import "../components/ProfileSummary/profile-summary.scss";
|
|
11
|
+
@import "../components/Card/Card.scss";
|
|
10
12
|
|
|
11
13
|
// ----------------------------------------------------------
|
|
12
14
|
// GLOBAL TOKENS
|
|
@@ -43,5 +45,78 @@
|
|
|
43
45
|
// FS UI Components
|
|
44
46
|
// --------------------------------------------------------
|
|
45
47
|
// Add here the customizations for FastStore UI components.
|
|
48
|
+
|
|
49
|
+
[data-fs-dropdown-menu]{
|
|
50
|
+
z-index: 99999;
|
|
51
|
+
width: 12.5rem;
|
|
52
|
+
[data-fs-dropdown-item] {
|
|
53
|
+
--fs-dropdown-item-color: black !important;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
[data-fs-home-card]{
|
|
58
|
+
@import '@faststore/ui/src/components/atoms/Button/styles.scss';
|
|
59
|
+
width: 49%;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[data-fs-buyer-portal-home-grid]{
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
gap: 2rem;
|
|
66
|
+
justify-content: space-between;
|
|
67
|
+
width: 90%;
|
|
68
|
+
margin-left: 5%;
|
|
69
|
+
margin-top: 2rem;
|
|
70
|
+
|
|
71
|
+
[data-fs-buyer-portal-home-row] {
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: row;
|
|
74
|
+
width: 100%;
|
|
75
|
+
gap: 2rem;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
[data-fs-toggle] {
|
|
80
|
+
--fs-border-radius: 100px;
|
|
81
|
+
--fs-color-primary-bkg: white;
|
|
82
|
+
--fs-border-color-hover: white;
|
|
83
|
+
|
|
84
|
+
--fs-toggle-border-color-hover: #27BB36;
|
|
85
|
+
--fs-toggle-knob-checked-bkg-color:white;
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
--fs-border-radius-small: 100px;
|
|
89
|
+
--fs-color-primary-bkg-active: #27BB36;
|
|
90
|
+
--fs-color-primary-bkg-hover: #27BB36;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[data-fs-toggle] input:not(:checked){
|
|
94
|
+
background-color: #C2C2C2 !important;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
[data-fs-internal-toggle] {
|
|
98
|
+
align-self: flex-end;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
[data-fs-menu-action-button] {
|
|
102
|
+
rotate: 90deg;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
[data-fs-buyer-portal-title] {
|
|
106
|
+
font-size: large;
|
|
107
|
+
font-weight: 600;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
[data-fs-dropdown-active-item] {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
width: 100%;
|
|
114
|
+
justify-content: space-between;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
[data-fs-dropdown-active-item-label]{
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: center;
|
|
120
|
+
}
|
|
46
121
|
}
|
|
47
122
|
}
|