@homefile/components-v2 1.0.15 → 1.1.0
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/dist/assets/locales/en/index.json +23 -1
- package/dist/components/headers/TabsHeader.js +1 -1
- package/dist/components/myProfile/MyProfileBody.d.ts +1 -1
- package/dist/components/myProfile/MyProfileBody.js +6 -2
- package/dist/components/myProfile/index.d.ts +1 -0
- package/dist/components/myProfile/index.js +1 -0
- package/dist/components/myProfile/permissions/ActionCheckbox.d.ts +2 -0
- package/dist/components/myProfile/permissions/ActionCheckbox.js +6 -0
- package/dist/components/myProfile/permissions/ActionLabel.d.ts +5 -0
- package/dist/components/myProfile/permissions/ActionLabel.js +17 -0
- package/dist/components/myProfile/permissions/PermissionsBanner.d.ts +5 -0
- package/dist/components/myProfile/permissions/PermissionsBanner.js +23 -0
- package/dist/components/myProfile/permissions/RoleButton.d.ts +2 -0
- package/dist/components/myProfile/permissions/RoleButton.js +11 -0
- package/dist/components/myProfile/permissions/RolePermissionsTab.d.ts +2 -0
- package/dist/components/myProfile/permissions/RolePermissionsTab.js +19 -0
- package/dist/components/myProfile/permissions/index.d.ts +5 -0
- package/dist/components/myProfile/permissions/index.js +5 -0
- package/dist/helpers/HomeRoles.helper.d.ts +3 -1
- package/dist/helpers/HomeRoles.helper.js +6 -1
- package/dist/helpers/myProfile/RolePermissions.helper.d.ts +2 -0
- package/dist/helpers/myProfile/RolePermissions.helper.js +72 -0
- package/dist/helpers/myProfile/index.d.ts +1 -0
- package/dist/helpers/myProfile/index.js +1 -0
- package/dist/hooks/myProfile/index.d.ts +1 -0
- package/dist/hooks/myProfile/index.js +1 -0
- package/dist/hooks/myProfile/useRolePermissionsTab.d.ts +11 -0
- package/dist/hooks/myProfile/useRolePermissionsTab.js +64 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/interfaces/myProfile/MyProfileBody.interface.d.ts +5 -4
- package/dist/interfaces/myProfile/index.d.ts +1 -0
- package/dist/interfaces/myProfile/index.js +1 -0
- package/dist/interfaces/myProfile/permissions/ActionCheckbox.interface.d.ts +8 -0
- package/dist/interfaces/myProfile/permissions/ActionCheckbox.interface.js +1 -0
- package/dist/interfaces/myProfile/permissions/RoleButton.interface.d.ts +7 -0
- package/dist/interfaces/myProfile/permissions/RoleButton.interface.js +1 -0
- package/dist/interfaces/myProfile/permissions/RolePermissionsTab.interface.d.ts +12 -0
- package/dist/interfaces/myProfile/permissions/RolePermissionsTab.interface.js +1 -0
- package/dist/interfaces/myProfile/permissions/index.d.ts +3 -0
- package/dist/interfaces/myProfile/permissions/index.js +3 -0
- package/dist/mocks/myProfile/Permissions.mock.d.ts +2 -0
- package/dist/mocks/myProfile/Permissions.mock.js +68 -0
- package/dist/mocks/myProfile/index.d.ts +1 -0
- package/dist/mocks/myProfile/index.js +1 -0
- package/dist/stories/myProfile/MyProfilePanel.stories.js +3 -4
- package/dist/stories/myProfile/permissions/RolePermissionsTab.stories.d.ts +5 -0
- package/dist/stories/myProfile/permissions/RolePermissionsTab.stories.js +16 -0
- package/package.json +1 -1
- package/src/assets/locales/en/index.json +23 -1
- package/src/components/headers/TabsHeader.tsx +1 -0
- package/src/components/myProfile/MyProfileBody.tsx +6 -1
- package/src/components/myProfile/index.ts +1 -0
- package/src/components/myProfile/permissions/ActionCheckbox.tsx +22 -0
- package/src/components/myProfile/permissions/ActionLabel.tsx +18 -0
- package/src/components/myProfile/permissions/PermissionsBanner.tsx +35 -0
- package/src/components/myProfile/permissions/RoleButton.tsx +39 -0
- package/src/components/myProfile/permissions/RolePermissionsTab.tsx +111 -0
- package/src/components/myProfile/permissions/index.ts +5 -0
- package/src/helpers/HomeRoles.helper.ts +16 -1
- package/src/helpers/myProfile/RolePermissions.helper.ts +74 -0
- package/src/helpers/myProfile/index.ts +1 -0
- package/src/hooks/myProfile/index.ts +2 -1
- package/src/hooks/myProfile/useRolePermissionsTab.ts +104 -0
- package/src/index.ts +2 -1
- package/src/interfaces/myProfile/MyProfileBody.interface.ts +5 -4
- package/src/interfaces/myProfile/index.ts +1 -0
- package/src/interfaces/myProfile/permissions/ActionCheckbox.interface.ts +9 -0
- package/src/interfaces/myProfile/permissions/RoleButton.interface.ts +8 -0
- package/src/interfaces/myProfile/permissions/RolePermissionsTab.interface.ts +19 -0
- package/src/interfaces/myProfile/permissions/index.ts +3 -0
- package/src/mocks/myProfile/Permissions.mock.ts +70 -0
- package/src/mocks/myProfile/index.ts +2 -1
- package/src/stories/myProfile/MyProfilePanel.stories.tsx +8 -8
- package/src/stories/myProfile/permissions/RolePermissionsTab.stories.tsx +23 -0
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { t } from 'i18next';
|
|
3
2
|
import { Box, Divider, DrawerBody } from '@chakra-ui/react';
|
|
4
|
-
import { ActiveSubscription, CancelAccount, CreditCardContainer, CreditCardError,
|
|
3
|
+
import { ActiveSubscription, CancelAccount, CreditCardContainer, CreditCardError, MonthlyCharge, MyProfileBody, MyProfileHeader, MyProfilePanel, NewCreditCard, NewCreditCardHeader, PaymentReceipts, RightPanel, RolePermissionsTab, TwoFactorSetting, UserDetails, } from '../../components';
|
|
5
4
|
import { action } from '@storybook/addon-actions';
|
|
6
|
-
import { menuMock, receiptsMock } from '../../mocks';
|
|
5
|
+
import { featuresSelectedMock, menuMock, receiptsMock } from '../../mocks';
|
|
7
6
|
import { useState } from 'react';
|
|
8
7
|
export default {
|
|
9
8
|
title: 'Components/MyProfile',
|
|
@@ -15,5 +14,5 @@ export const MyProfilePanelComponent = () => {
|
|
|
15
14
|
const handleCloseNewCreditCardPanel = () => setIsNewCreditCardPanelOpen(false);
|
|
16
15
|
const handleOpenNewCreditCardPanel = () => setIsNewCreditCardPanelOpen(true);
|
|
17
16
|
const handleError = () => setHasError(true);
|
|
18
|
-
return (_jsxs(_Fragment, { children: [_jsx(RightPanel, { isOpen: true, onClose: action('onCloseClick'), children: _jsxs(MyProfilePanel, { children: [_jsx(MyProfileHeader, { onClose: action('onCloseClick') }), _jsx(MyProfileBody, { isLoading: false, account: _jsxs(_Fragment, { children: [_jsx(ActiveSubscription, { nextCharge: "2024-12-01", subscriptionPrice: 36, totalStorage: 2, totalUsed: 1, availableStorage: 200, state: 'trial' }), _jsx(Divider, { width: "calc(100% - 26px)", mx: "auto" }), _jsx(MonthlyCharge, { additionalPrice: 36, monthlyCharge: 36, monthDate: "03/01/2023", nextCharge: "01/12/2024", taxPercentage: 8.5, taxValue: 3.06, subtotal: 36.0 }), _jsx(CancelAccount, { label: "Contact Homefile", onClick: action('onCancelAccountClick') })] }), details: _jsxs(_Fragment, { children: [_jsx(UserDetails, { email: "gary.edmunds@gmail.com", firstName: "Gary", lastName: "Edmunds", onSave: action('onSaveClick'), bg: "#4CC35A" }), _jsx(TwoFactorSetting, { email: "gary.edmunds@gmail.com", sms: "2032409108", onChange: action('on2FAChangeClick'), onSave: action('onSaveClick'), defaultValue: "email", twoFactor: 'active' })] }),
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsx(RightPanel, { isOpen: true, onClose: action('onCloseClick'), children: _jsxs(MyProfilePanel, { children: [_jsx(MyProfileHeader, { onClose: action('onCloseClick') }), _jsx(MyProfileBody, { isLoading: false, account: _jsxs(_Fragment, { children: [_jsx(ActiveSubscription, { nextCharge: "2024-12-01", subscriptionPrice: 36, totalStorage: 2, totalUsed: 1, availableStorage: 200, state: 'trial' }), _jsx(Divider, { width: "calc(100% - 26px)", mx: "auto" }), _jsx(MonthlyCharge, { additionalPrice: 36, monthlyCharge: 36, monthDate: "03/01/2023", nextCharge: "01/12/2024", taxPercentage: 8.5, taxValue: 3.06, subtotal: 36.0 }), _jsx(CancelAccount, { label: "Contact Homefile", onClick: action('onCancelAccountClick') })] }), details: _jsxs(_Fragment, { children: [_jsx(UserDetails, { email: "gary.edmunds@gmail.com", firstName: "Gary", lastName: "Edmunds", onSave: action('onSaveClick'), bg: "#4CC35A" }), _jsx(TwoFactorSetting, { email: "gary.edmunds@gmail.com", sms: "2032409108", onChange: action('on2FAChangeClick'), onSave: action('onSaveClick'), defaultValue: "email", twoFactor: 'active' })] }), payment: _jsxs(Box, { bg: "lightBlue.2", h: "inherit", children: [_jsx(CreditCardContainer, { cardNumber: "1234 5678 9012 3456", brand: "visa", onAddCard: action('onAddCard'), onDeleteCard: handleOpenNewCreditCardPanel, onSubmit: (data) => action('onDeleteCard')(data), cardHolder: "Gary Edmunds", cvv: "123", expirationMonth: "12", expirationYear: "2024" }), _jsx(PaymentReceipts, { receipts: receiptsMock, menuItems: menuMock })] }), rolePermissions: _jsx(RolePermissionsTab, { selected: featuresSelectedMock, onSelect: action('onSelect') }) })] }) }), _jsx(RightPanel, { isOpen: isNewCreditCardPanelOpen, onClose: handleCloseNewCreditCardPanel, children: _jsxs(MyProfilePanel, { children: [_jsx(MyProfileHeader, { onClose: handleCloseNewCreditCardPanel }), _jsxs(DrawerBody, { p: "0", children: [_jsx(NewCreditCardHeader, { onClick: handleCloseNewCreditCardPanel }), hasError && _jsx(CreditCardError, {}), _jsx(NewCreditCard, { hasError: hasError, onSubmit: handleError })] })] }) })] }));
|
|
19
18
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Meta } from '@storybook/react';
|
|
2
|
+
import { RolePermissionsTabI } from '../../../interfaces';
|
|
3
|
+
declare const _default: Meta<RolePermissionsTabI>;
|
|
4
|
+
export default _default;
|
|
5
|
+
export declare const RolePermissionsTabComponent: (args: RolePermissionsTabI) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from '@chakra-ui/react';
|
|
3
|
+
import { action } from '@storybook/addon-actions';
|
|
4
|
+
import { RolePermissionsTab } from '../../../components';
|
|
5
|
+
import { featuresSelectedMock } from '../../../mocks';
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Components/MyProfile',
|
|
8
|
+
component: RolePermissionsTab,
|
|
9
|
+
args: {
|
|
10
|
+
selected: featuresSelectedMock,
|
|
11
|
+
onSelect: action('onSelect'),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export const RolePermissionsTabComponent = (args) => {
|
|
15
|
+
return (_jsx(Box, { w: ['full', '500px'], bg: "white", children: _jsx(RolePermissionsTab, Object.assign({}, args)) }));
|
|
16
|
+
};
|
package/package.json
CHANGED
|
@@ -448,6 +448,13 @@
|
|
|
448
448
|
"title": "My Homes"
|
|
449
449
|
},
|
|
450
450
|
"myProfile": {
|
|
451
|
+
"actions": {
|
|
452
|
+
"add": "Add",
|
|
453
|
+
"can": "Can",
|
|
454
|
+
"edit": "Edit",
|
|
455
|
+
"delete": "Delete",
|
|
456
|
+
"view": "View"
|
|
457
|
+
},
|
|
451
458
|
"account": {
|
|
452
459
|
"cancel": "Cancel Account",
|
|
453
460
|
"cancelInfo": "To cancel your Homefile account, please contact Homefile below.",
|
|
@@ -477,6 +484,20 @@
|
|
|
477
484
|
"receiptsTitle": "Receipts",
|
|
478
485
|
"toDelete": "To delete a card, you must first add a new card."
|
|
479
486
|
},
|
|
487
|
+
"permissions": {
|
|
488
|
+
"contributor": {
|
|
489
|
+
"description": "Can view, add, and edit the information when you share a home.",
|
|
490
|
+
"title": "Contributor Permissions"
|
|
491
|
+
},
|
|
492
|
+
"manager": {
|
|
493
|
+
"description": "Can view, add, and edit all home information within a home.",
|
|
494
|
+
"title": "Manager Permissions"
|
|
495
|
+
},
|
|
496
|
+
"member": {
|
|
497
|
+
"description": "Can only view information when you share a home.",
|
|
498
|
+
"title": "Member Permissions"
|
|
499
|
+
}
|
|
500
|
+
},
|
|
480
501
|
"placeholders": {
|
|
481
502
|
"cardHolder": "Name on card",
|
|
482
503
|
"cardNumber": "Card number",
|
|
@@ -491,7 +512,8 @@
|
|
|
491
512
|
"tab2": "Subscription",
|
|
492
513
|
"tab3": "Payment",
|
|
493
514
|
"tab4": "Email",
|
|
494
|
-
"tab5": "Sharing"
|
|
515
|
+
"tab5": "Sharing",
|
|
516
|
+
"tab6": "Role Permissions"
|
|
495
517
|
}
|
|
496
518
|
},
|
|
497
519
|
"newPassword": {
|
|
@@ -10,6 +10,7 @@ export const MyProfileBody = ({
|
|
|
10
10
|
email,
|
|
11
11
|
isLoading,
|
|
12
12
|
payment,
|
|
13
|
+
rolePermissions,
|
|
13
14
|
}: MyProfileBodyI) => {
|
|
14
15
|
const tabs = [
|
|
15
16
|
{
|
|
@@ -28,7 +29,11 @@ export const MyProfileBody = ({
|
|
|
28
29
|
label: t('myProfile.tabs.tab4'),
|
|
29
30
|
component: email,
|
|
30
31
|
},
|
|
31
|
-
|
|
32
|
+
{
|
|
33
|
+
label: t('myProfile.tabs.tab6'),
|
|
34
|
+
component: rolePermissions,
|
|
35
|
+
},
|
|
36
|
+
].filter((tab) => tab.component)
|
|
32
37
|
return (
|
|
33
38
|
<DrawerBody p="0">
|
|
34
39
|
{isLoading ? (
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Stack, Checkbox } from '@chakra-ui/react'
|
|
2
|
+
import { ActionLabel } from '@/components'
|
|
3
|
+
import { ActionCheckboxI } from '@/interfaces'
|
|
4
|
+
|
|
5
|
+
export const ActionCheckbox = ({
|
|
6
|
+
action,
|
|
7
|
+
isChecked,
|
|
8
|
+
isDisabled,
|
|
9
|
+
label,
|
|
10
|
+
onChange,
|
|
11
|
+
}: ActionCheckboxI) => {
|
|
12
|
+
return (
|
|
13
|
+
<Stack spacing="1" align="center" w="33px">
|
|
14
|
+
{label && <ActionLabel label={label} />}
|
|
15
|
+
<Checkbox
|
|
16
|
+
isChecked={isChecked}
|
|
17
|
+
onChange={() => onChange(action)}
|
|
18
|
+
isDisabled={isDisabled}
|
|
19
|
+
/>
|
|
20
|
+
</Stack>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Text, TextProps } from '@chakra-ui/react'
|
|
2
|
+
|
|
3
|
+
export interface ActionLabelI extends TextProps {
|
|
4
|
+
label: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const ActionLabel = ({ label, ...props }: ActionLabelI) => {
|
|
8
|
+
return (
|
|
9
|
+
<Text
|
|
10
|
+
fontSize="10px"
|
|
11
|
+
fontWeight="semibold"
|
|
12
|
+
textTransform="uppercase"
|
|
13
|
+
{...props}
|
|
14
|
+
>
|
|
15
|
+
{label}
|
|
16
|
+
</Text>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { t } from 'i18next'
|
|
2
|
+
import { RoleType, homeRoles } from '@/helpers'
|
|
3
|
+
import { Stack, Text } from '@chakra-ui/react'
|
|
4
|
+
|
|
5
|
+
export interface PermissionsBannerI {
|
|
6
|
+
role: RoleType
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const PermissionsBanner = ({ role }: PermissionsBannerI) => {
|
|
10
|
+
const bgColor = homeRoles[role].bg
|
|
11
|
+
const { title, description } = textsByRole[role as keyof typeof textsByRole]
|
|
12
|
+
return (
|
|
13
|
+
<Stack spacing="1" bg={bgColor} px="base" py="6">
|
|
14
|
+
<Text fontWeight="semibold" color="neutral.white">
|
|
15
|
+
{title}
|
|
16
|
+
</Text>
|
|
17
|
+
<Text color="neutral.white">{description}</Text>
|
|
18
|
+
</Stack>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const textsByRole = {
|
|
23
|
+
member: {
|
|
24
|
+
title: t('myProfile.permissions.member.title'),
|
|
25
|
+
description: t('myProfile.permissions.member.description'),
|
|
26
|
+
},
|
|
27
|
+
contributor: {
|
|
28
|
+
title: t('myProfile.permissions.contributor.title'),
|
|
29
|
+
description: t('myProfile.permissions.contributor.description'),
|
|
30
|
+
},
|
|
31
|
+
manager: {
|
|
32
|
+
title: t('myProfile.permissions.manager.title'),
|
|
33
|
+
description: t('myProfile.permissions.manager.description'),
|
|
34
|
+
},
|
|
35
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { homeRoles } from '@/helpers'
|
|
2
|
+
import { RoleButtonI } from '@/interfaces'
|
|
3
|
+
import { Center, Text } from '@chakra-ui/react'
|
|
4
|
+
|
|
5
|
+
export const RoleButton = ({
|
|
6
|
+
role,
|
|
7
|
+
onClick,
|
|
8
|
+
isSelected,
|
|
9
|
+
showBorder,
|
|
10
|
+
}: RoleButtonI) => {
|
|
11
|
+
const bgColor = homeRoles[role].bg
|
|
12
|
+
const borderColor = showBorder ? 'lightBlue.2' : 'transparent'
|
|
13
|
+
return (
|
|
14
|
+
<Center
|
|
15
|
+
as="button"
|
|
16
|
+
w="62px"
|
|
17
|
+
bg={isSelected ? 'lightGreen.1' : 'neutral.white'}
|
|
18
|
+
transition="all 0.4s"
|
|
19
|
+
_hover={{
|
|
20
|
+
bg: 'lightGreen.1',
|
|
21
|
+
cursor: 'pointer',
|
|
22
|
+
}}
|
|
23
|
+
onClick={onClick}
|
|
24
|
+
>
|
|
25
|
+
<Center py="base" w="40px" borderY="1px solid" borderColor={borderColor}>
|
|
26
|
+
<Center bg={bgColor} borderRadius="4px" h="26px" w="26px">
|
|
27
|
+
<Text
|
|
28
|
+
fontWeight="semibold"
|
|
29
|
+
color={'neutral.white'}
|
|
30
|
+
fontSize="md"
|
|
31
|
+
textTransform="uppercase"
|
|
32
|
+
>
|
|
33
|
+
{role.charAt(0).toUpperCase()}
|
|
34
|
+
</Text>
|
|
35
|
+
</Center>
|
|
36
|
+
</Center>
|
|
37
|
+
</Center>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { t } from 'i18next'
|
|
2
|
+
import { Box, Center, Flex, Stack, Text } from '@chakra-ui/react'
|
|
3
|
+
import {
|
|
4
|
+
RoleButton,
|
|
5
|
+
PermissionsBanner,
|
|
6
|
+
ActionLabel,
|
|
7
|
+
ActionCheckbox,
|
|
8
|
+
} from '@/components'
|
|
9
|
+
|
|
10
|
+
import { rolePermissions } from '@/helpers'
|
|
11
|
+
import { RolePermissionsTabI } from '@/interfaces'
|
|
12
|
+
import { useRolePermissionsTab } from '@/hooks'
|
|
13
|
+
|
|
14
|
+
export const RolePermissionsTab = ({
|
|
15
|
+
selected,
|
|
16
|
+
onSelect,
|
|
17
|
+
}: RolePermissionsTabI) => {
|
|
18
|
+
const {
|
|
19
|
+
actions,
|
|
20
|
+
callback,
|
|
21
|
+
selectedRole,
|
|
22
|
+
selectedActions,
|
|
23
|
+
handleRoleChange,
|
|
24
|
+
handleFeatureChange,
|
|
25
|
+
handleActionChange,
|
|
26
|
+
} = useRolePermissionsTab({ selected, onSelect })
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Flex h="100%">
|
|
30
|
+
<Box bg="neutral.white">
|
|
31
|
+
<RoleButton
|
|
32
|
+
role="member"
|
|
33
|
+
isSelected={selectedRole === 'member'}
|
|
34
|
+
onClick={() => handleRoleChange('member')}
|
|
35
|
+
showBorder
|
|
36
|
+
/>
|
|
37
|
+
<RoleButton
|
|
38
|
+
role="contributor"
|
|
39
|
+
isSelected={selectedRole === 'contributor'}
|
|
40
|
+
onClick={() => handleRoleChange('contributor')}
|
|
41
|
+
/>
|
|
42
|
+
<RoleButton
|
|
43
|
+
role="manager"
|
|
44
|
+
isSelected={selectedRole === 'manager'}
|
|
45
|
+
onClick={() => handleRoleChange('manager')}
|
|
46
|
+
showBorder
|
|
47
|
+
/>
|
|
48
|
+
</Box>
|
|
49
|
+
<Box>
|
|
50
|
+
<PermissionsBanner role={selectedRole} />
|
|
51
|
+
<Center bg="lightBlue.6" py="base">
|
|
52
|
+
<Flex w="100%">
|
|
53
|
+
<Flex flex="1" gap="base" justify="flex-end" align="start">
|
|
54
|
+
<ActionLabel
|
|
55
|
+
label={t('myProfile.actions.can')}
|
|
56
|
+
color="neutral.white"
|
|
57
|
+
/>
|
|
58
|
+
<Box w="1px" bg="neutral.white" h="100%" />
|
|
59
|
+
</Flex>
|
|
60
|
+
<Flex flex="1" justify="space-evenly">
|
|
61
|
+
{actions.map((action) => {
|
|
62
|
+
const disabledAllCheckbox =
|
|
63
|
+
selectedRole === 'member' && action !== 'view'
|
|
64
|
+
return (
|
|
65
|
+
<ActionCheckbox
|
|
66
|
+
key={action}
|
|
67
|
+
label={action}
|
|
68
|
+
action={action}
|
|
69
|
+
isChecked={selectedActions.includes(action)}
|
|
70
|
+
isDisabled={disabledAllCheckbox}
|
|
71
|
+
onChange={handleActionChange}
|
|
72
|
+
/>
|
|
73
|
+
)
|
|
74
|
+
})}
|
|
75
|
+
</Flex>
|
|
76
|
+
</Flex>
|
|
77
|
+
</Center>
|
|
78
|
+
<Stack spacing="base" py="base">
|
|
79
|
+
{rolePermissions.map(({ id, label, permissions }) => {
|
|
80
|
+
return (
|
|
81
|
+
<Flex key={id} w="100%">
|
|
82
|
+
<Flex flex="1">
|
|
83
|
+
<Text fontFamily="secondary" ml="base">
|
|
84
|
+
{label}
|
|
85
|
+
</Text>
|
|
86
|
+
</Flex>
|
|
87
|
+
<Flex flex="1" justify="space-evenly">
|
|
88
|
+
{actions.map((action) => {
|
|
89
|
+
const isDisabled =
|
|
90
|
+
!permissions[action].includes(selectedRole)
|
|
91
|
+
const isChecked =
|
|
92
|
+
callback[selectedRole][action].includes(id)
|
|
93
|
+
return (
|
|
94
|
+
<ActionCheckbox
|
|
95
|
+
key={action}
|
|
96
|
+
action={action}
|
|
97
|
+
isChecked={isChecked}
|
|
98
|
+
isDisabled={isDisabled}
|
|
99
|
+
onChange={() => handleFeatureChange(action, id)}
|
|
100
|
+
/>
|
|
101
|
+
)
|
|
102
|
+
})}
|
|
103
|
+
</Flex>
|
|
104
|
+
</Flex>
|
|
105
|
+
)
|
|
106
|
+
})}
|
|
107
|
+
</Stack>
|
|
108
|
+
</Box>
|
|
109
|
+
</Flex>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type RoleType =
|
|
2
|
+
| 'guest'
|
|
3
|
+
| 'member'
|
|
4
|
+
| 'partner'
|
|
5
|
+
| 'contributor'
|
|
6
|
+
| 'manager'
|
|
7
|
+
| 'homeowner'
|
|
8
|
+
|
|
9
|
+
export type ReducedRoleType = 'member' | 'contributor' | 'manager'
|
|
10
|
+
|
|
11
|
+
export const homeRoleTypes: RoleType[] = [
|
|
12
|
+
'member',
|
|
13
|
+
'contributor',
|
|
14
|
+
'manager',
|
|
15
|
+
'homeowner',
|
|
16
|
+
]
|
|
2
17
|
|
|
3
18
|
export const homeRoles: { [key: string]: { [key: string]: string } } = {
|
|
4
19
|
guest: {
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { RolePermissionI } from '@/interfaces'
|
|
2
|
+
|
|
3
|
+
export const rolePermissions: RolePermissionI[] = [
|
|
4
|
+
{
|
|
5
|
+
id: 'property-data',
|
|
6
|
+
label: 'Property Data',
|
|
7
|
+
permissions: {
|
|
8
|
+
view: ['member', 'contributor', 'manager'],
|
|
9
|
+
add: ['manager'],
|
|
10
|
+
edit: ['manager'],
|
|
11
|
+
delete: ['manager'],
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'financial-data',
|
|
16
|
+
label: 'Financial Data',
|
|
17
|
+
permissions: {
|
|
18
|
+
view: ['member', 'contributor', 'manager'],
|
|
19
|
+
add: ['contributor', 'manager'],
|
|
20
|
+
edit: ['manager'],
|
|
21
|
+
delete: ['manager'],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'partners',
|
|
26
|
+
label: 'Partners',
|
|
27
|
+
permissions: {
|
|
28
|
+
view: ['member', 'contributor', 'manager'],
|
|
29
|
+
add: ['contributor', 'manager'],
|
|
30
|
+
edit: ['manager'],
|
|
31
|
+
delete: ['manager'],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'folders',
|
|
36
|
+
label: 'Folders',
|
|
37
|
+
permissions: {
|
|
38
|
+
view: ['member', 'contributor', 'manager'],
|
|
39
|
+
add: ['manager'],
|
|
40
|
+
edit: ['contributor', 'manager'],
|
|
41
|
+
delete: ['manager'],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 'home-items',
|
|
46
|
+
label: 'Home items',
|
|
47
|
+
permissions: {
|
|
48
|
+
view: ['member', 'contributor', 'manager'],
|
|
49
|
+
add: ['contributor', 'manager'],
|
|
50
|
+
edit: ['manager'],
|
|
51
|
+
delete: ['manager'],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'rooms',
|
|
56
|
+
label: 'Rooms',
|
|
57
|
+
permissions: {
|
|
58
|
+
view: ['member', 'contributor', 'manager'],
|
|
59
|
+
add: ['contributor', 'manager'],
|
|
60
|
+
edit: ['contributor', 'manager'],
|
|
61
|
+
delete: ['manager'],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'rooms-items',
|
|
66
|
+
label: 'Rooms items',
|
|
67
|
+
permissions: {
|
|
68
|
+
view: ['member', 'contributor', 'manager'],
|
|
69
|
+
add: ['contributor', 'manager'],
|
|
70
|
+
edit: ['contributor', 'manager'],
|
|
71
|
+
delete: ['contributor', 'manager'],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
]
|
|
@@ -3,4 +3,5 @@ export * from './usePaymentFormProvider'
|
|
|
3
3
|
export * from './useMyProfileContent'
|
|
4
4
|
export * from './usePaymentMethod'
|
|
5
5
|
export * from './useProfileDetail'
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './useRolePermissionsTab'
|
|
7
|
+
export * from './useTwoFactorSetting'
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react'
|
|
2
|
+
import { rolePermissions, ReducedRoleType } from '@/helpers'
|
|
3
|
+
import {
|
|
4
|
+
ActionsPermitted,
|
|
5
|
+
RolePermissionObject,
|
|
6
|
+
RolePermissionsTabI,
|
|
7
|
+
} from '@/interfaces'
|
|
8
|
+
|
|
9
|
+
export const useRolePermissionsTab = ({
|
|
10
|
+
selected,
|
|
11
|
+
onSelect,
|
|
12
|
+
}: RolePermissionsTabI) => {
|
|
13
|
+
const actions: ActionsPermitted[] = ['view', 'add', 'edit', 'delete']
|
|
14
|
+
const selectedActionsFromSelected = () => {
|
|
15
|
+
const selectedActions: ActionsPermitted[] = []
|
|
16
|
+
actions.forEach((action) => {
|
|
17
|
+
const featuresByRoleByAction = selected[selectedRole][action]
|
|
18
|
+
if (featuresByRoleByAction.length === rolePermissions.length) {
|
|
19
|
+
selectedActions.push(action)
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
return selectedActions
|
|
23
|
+
}
|
|
24
|
+
const [callback, setCallback] = useState<RolePermissionObject>(selected)
|
|
25
|
+
const [selectedRole, setSelectedRole] = useState<ReducedRoleType>('member')
|
|
26
|
+
const [selectedActions, setSelectedActions] = useState<ActionsPermitted[]>(
|
|
27
|
+
selectedActionsFromSelected
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
const handleRoleChange = (role: ReducedRoleType) => setSelectedRole(role)
|
|
31
|
+
|
|
32
|
+
const checkIfHasFeature = (action: ActionsPermitted, feature: string) => {
|
|
33
|
+
const features = callback[selectedRole][action]
|
|
34
|
+
const hasFeature = features.includes(feature)
|
|
35
|
+
|
|
36
|
+
if (hasFeature) {
|
|
37
|
+
return features.filter((f) => f !== feature)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return [...features, feature]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const handleFeatureChange = (action: ActionsPermitted, feature: string) => {
|
|
44
|
+
const newCallback = {
|
|
45
|
+
...callback,
|
|
46
|
+
[selectedRole]: {
|
|
47
|
+
...callback[selectedRole],
|
|
48
|
+
[action]: checkIfHasFeature(action, feature),
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
setCallback(newCallback)
|
|
52
|
+
onSelect(newCallback)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const handleActionChange = (action: ActionsPermitted) => {
|
|
56
|
+
if (selectedActions.includes(action)) {
|
|
57
|
+
const newCallback = {
|
|
58
|
+
...callback,
|
|
59
|
+
[selectedRole]: {
|
|
60
|
+
...callback[selectedRole],
|
|
61
|
+
[action]: [],
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
setCallback(newCallback)
|
|
65
|
+
onSelect(newCallback)
|
|
66
|
+
const filteredActions = selectedActions.filter((a) => a !== action)
|
|
67
|
+
return setSelectedActions(filteredActions)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const newCallback = {
|
|
71
|
+
...callback,
|
|
72
|
+
[selectedRole]: {
|
|
73
|
+
...callback[selectedRole],
|
|
74
|
+
[action]: rolePermissions
|
|
75
|
+
.map(({ id, permissions }) => {
|
|
76
|
+
if (permissions[action].includes(selectedRole)) {
|
|
77
|
+
return id
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return ''
|
|
81
|
+
})
|
|
82
|
+
.filter((id) => id),
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
setCallback(newCallback)
|
|
87
|
+
onSelect(newCallback)
|
|
88
|
+
|
|
89
|
+
setSelectedActions([...selectedActions, action])
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
setSelectedActions(selectedActionsFromSelected)
|
|
94
|
+
}, [selectedRole])
|
|
95
|
+
return {
|
|
96
|
+
actions,
|
|
97
|
+
callback,
|
|
98
|
+
selectedRole,
|
|
99
|
+
selectedActions,
|
|
100
|
+
handleRoleChange,
|
|
101
|
+
handleFeatureChange,
|
|
102
|
+
handleActionChange,
|
|
103
|
+
}
|
|
104
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -138,6 +138,7 @@ export {
|
|
|
138
138
|
ResetPassword,
|
|
139
139
|
ReviewBanner,
|
|
140
140
|
RightPanel,
|
|
141
|
+
RolePermissionsTab,
|
|
141
142
|
RoomHeader,
|
|
142
143
|
RoomsBoardTour,
|
|
143
144
|
RoomsMenu,
|
|
@@ -197,7 +198,7 @@ export {
|
|
|
197
198
|
recordsInputsProxy,
|
|
198
199
|
recordsInputsToDBProxy,
|
|
199
200
|
userDetailsProxy,
|
|
200
|
-
confirmAddressProxy
|
|
201
|
+
confirmAddressProxy,
|
|
201
202
|
} from './proxies'
|
|
202
203
|
|
|
203
204
|
import theme from './theme'
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ReactNode } from 'react'
|
|
2
2
|
|
|
3
3
|
export interface MyProfileBodyI {
|
|
4
|
-
account
|
|
5
|
-
details
|
|
6
|
-
email
|
|
4
|
+
account?: ReactNode
|
|
5
|
+
details?: ReactNode
|
|
6
|
+
email?: ReactNode
|
|
7
7
|
isLoading: boolean
|
|
8
|
-
payment
|
|
8
|
+
payment?: ReactNode
|
|
9
|
+
rolePermissions?: ReactNode
|
|
9
10
|
}
|