@homefile/components-v2 2.24.25 → 2.25.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/components/forms/Collapsible.d.ts +1 -1
- package/dist/components/forms/Collapsible.js +3 -3
- package/dist/components/forms/readOnly/ReadOnlyDynamicForm.js +4 -2
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyAppliances.js +16 -15
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyAppliances.tsx +40 -35
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyCollapsible.d.ts +2 -0
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyCollapsible.js +19 -0
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyCollapsible.tsx +34 -0
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyGuidelines.js +1 -1
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyGuidelines.tsx +2 -2
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyHomeItemText.js +1 -1
- package/dist/components/forms/readOnly/fields/homeItem/ReadOnlyHomeItemText.tsx +1 -1
- package/dist/components/forms/readOnly/fields/homeItem/index.d.ts +1 -0
- package/dist/components/forms/readOnly/fields/homeItem/index.js +1 -0
- package/dist/components/forms/readOnly/fields/homeItem/index.ts +1 -0
- package/dist/components/headers/CollapsibleHeader.js +1 -1
- package/dist/helpers/receipts/Receipts.helper.js +6 -5
- package/dist/interfaces/forms/Collapsible.interface.d.ts +2 -1
- package/dist/interfaces/forms/dynamicForm/DynamicForm.interface.d.ts +1 -1
- package/dist/interfaces/forms/readOnly/homeItem/ReadOnlyAppliances.interface.d.ts +1 -1
- package/dist/mocks/forms/dynamicForm.mock.js +36 -16
- package/dist/stories/forms/readOnly/ReadOnlyDynamicForm.stories.d.ts +1 -0
- package/dist/stories/forms/readOnly/ReadOnlyDynamicForm.stories.js +5 -1
- package/dist/stories/receipts/receipt/ReceiptDetails.stories.d.ts +1 -0
- package/dist/stories/receipts/receipt/ReceiptDetails.stories.js +1 -0
- package/package.json +1 -1
- package/src/components/forms/Collapsible.tsx +3 -2
- package/src/components/forms/readOnly/ReadOnlyDynamicForm.tsx +4 -1
- package/src/components/forms/readOnly/fields/homeItem/ReadOnlyAppliances.tsx +40 -35
- package/src/components/forms/readOnly/fields/homeItem/ReadOnlyCollapsible.tsx +34 -0
- package/src/components/forms/readOnly/fields/homeItem/ReadOnlyGuidelines.tsx +2 -2
- package/src/components/forms/readOnly/fields/homeItem/ReadOnlyHomeItemText.tsx +1 -1
- package/src/components/forms/readOnly/fields/homeItem/index.ts +1 -0
- package/src/components/headers/CollapsibleHeader.tsx +1 -1
- package/src/helpers/receipts/Receipts.helper.ts +7 -5
- package/src/interfaces/forms/Collapsible.interface.ts +2 -1
- package/src/interfaces/forms/dynamicForm/DynamicForm.interface.ts +1 -0
- package/src/interfaces/forms/readOnly/homeItem/ReadOnlyAppliances.interface.ts +1 -1
- package/src/mocks/forms/dynamicForm.mock.ts +36 -16
- package/src/stories/forms/readOnly/ReadOnlyDynamicForm.stories.tsx +13 -1
- package/src/stories/receipts/receipt/ReceiptDetails.stories.tsx +1 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
2
|
import { CollapsibleI } from '../../interfaces';
|
|
3
|
-
export declare const Collapsible: ({ children, icon, title, }: PropsWithChildren<CollapsibleI>) => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare const Collapsible: ({ children, icon, title, showShadow, }: PropsWithChildren<CollapsibleI>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Accordion, AccordionButton, AccordionItem, AccordionPanel, Box, Flex, } from '@chakra-ui/react';
|
|
3
3
|
import { ChevronRight, CollapsibleHeader } from '..';
|
|
4
|
-
export const Collapsible = ({ children, icon, title, }) => {
|
|
5
|
-
return (_jsx(Accordion, { flex: "1", allowMultiple: true, boxShadow:
|
|
6
|
-
boxShadow: 'lg',
|
|
4
|
+
export const Collapsible = ({ children, icon, title, showShadow = true, }) => {
|
|
5
|
+
return (_jsx(Accordion, { flex: "1", allowMultiple: true, boxShadow: showShadow ? 'md' : 'none', children: _jsx(AccordionItem, { border: "none", children: ({ isExpanded }) => (_jsxs(_Fragment, { children: [_jsx(AccordionButton, { w: "100%", p: "base", bg: "neutral.white", transition: "all .2s ease-in-out", borderBottom: "1px solid", borderColor: isExpanded ? 'lightBlue.2' : 'transparent', _hover: {
|
|
6
|
+
boxShadow: showShadow ? 'lg' : 'none',
|
|
7
7
|
}, _focus: {
|
|
8
8
|
outline: 'none',
|
|
9
9
|
}, children: _jsxs(Flex, { align: "center", justify: "space-between", flex: "1", children: [_jsx(CollapsibleHeader, { icon: icon, title: title }), _jsx(Box, { rounded: "full", border: "1px solid", padding: "1", borderColor: "blue.3", transition: "all .2s ease-in-out", transform: isExpanded ? 'rotate(-90deg)' : 'rotate(0)', children: _jsx(ChevronRight, {}) })] }) }), _jsx(AccordionPanel, { p: "base", bg: "neutral.white", children: children })] })) }) }));
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createElement as _createElement } from "react";
|
|
3
3
|
import { Box } from '@chakra-ui/react';
|
|
4
|
-
import { ReadOnlyAppliances, ReadOnlyDate, ReadOnlyGrid, ReadOnlyGroup, ReadOnlyInput, ReadOnlyNotes, ReadOnlyRating, ReadOnlyTextArea, } from '../..';
|
|
4
|
+
import { ReadOnlyAppliances, ReadOnlyCollapsible, ReadOnlyDate, ReadOnlyGrid, ReadOnlyGroup, ReadOnlyInput, ReadOnlyNotes, ReadOnlyRating, ReadOnlyTextArea, } from '../..';
|
|
5
5
|
import { fieldIcons } from '../../../helpers';
|
|
6
|
-
export const ReadOnlyDynamicForm = ({ form: fields, onClick, onEdit
|
|
6
|
+
export const ReadOnlyDynamicForm = ({ form: fields, onClick, onEdit, }) => {
|
|
7
7
|
return (_jsx(Box, { bg: "lightBlue.1", overflow: "scroll", children: fields === null || fields === void 0 ? void 0 : fields.map((field) => {
|
|
8
8
|
const { children = [], icon, id, name, type, value } = field;
|
|
9
9
|
const baseProps = {
|
|
@@ -33,6 +33,8 @@ export const ReadOnlyDynamicForm = ({ form: fields, onClick, onEdit = () => { },
|
|
|
33
33
|
return _jsx(ReadOnlyGroup, { children: children }, id);
|
|
34
34
|
case 'appliances':
|
|
35
35
|
return _createElement(ReadOnlyAppliances, Object.assign({}, field, { key: id, onEdit: onEdit }));
|
|
36
|
+
case 'collapsible':
|
|
37
|
+
return _createElement(ReadOnlyCollapsible, Object.assign({}, field, { key: id }));
|
|
36
38
|
case 'notes':
|
|
37
39
|
return _createElement(ReadOnlyNotes, Object.assign({}, field, { key: id }));
|
|
38
40
|
default:
|
|
@@ -5,19 +5,20 @@ import { colors } from '../../../../../theme/colors';
|
|
|
5
5
|
export const ReadOnlyAppliances = ({ description, id, name, children, onEdit, value, }) => {
|
|
6
6
|
const rating = children === null || children === void 0 ? void 0 : children.find(({ type }) => type === 'rating');
|
|
7
7
|
const images = children === null || children === void 0 ? void 0 : children.find(({ type }) => type === 'images');
|
|
8
|
-
return (_jsxs(Stack, { spacing: "base", p: "base", bg: "neutral.white", mt: "2px", children: [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
return (_jsxs(Stack, { spacing: "base", p: "base", bg: "neutral.white", mt: "2px", children: [name ||
|
|
9
|
+
(onEdit && (_jsxs(Flex, { justify: "space-between", children: [_jsx(Text, { fontSize: "xs", textTransform: "uppercase", children: name }), onEdit && (_jsx(IconButton, { "aria-label": "Edit appliance", variant: "ghost", w: "fit-content", icon: _jsx(Edit, { size: 18, stroke: colors.blue[3] }), onClick: () => onEdit(id) }))] }))), _jsxs(Flex, { gap: "base", children: [_jsx(ReadOnlyHomeItemImages, Object.assign({}, images)), _jsxs(Stack, { spacing: "4", flex: "1", children: [_jsx(ReadOnlyHomeItemRating, Object.assign({}, rating)), _jsxs(Stack, { spacing: "base", children: [_jsx(Text, { fontSize: "22px", fontWeight: "semibold", children: value }), _jsx(Box, { children: children === null || children === void 0 ? void 0 : children.map(({ id, name, value, type }) => {
|
|
10
|
+
const baseProps = {
|
|
11
|
+
key: `${id}-${name}-${value}-${type}`,
|
|
12
|
+
id,
|
|
13
|
+
value,
|
|
14
|
+
type,
|
|
15
|
+
name,
|
|
16
|
+
};
|
|
17
|
+
switch (type) {
|
|
18
|
+
case 'text':
|
|
19
|
+
return _jsx(ReadOnlyHomeItemText, Object.assign({}, baseProps));
|
|
20
|
+
default:
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}) }), _jsx(Box, { flex: "1", borderBottom: "1px dashed", borderColor: "lightBlue.6", h: "1px" }), _jsx(Text, { fontFamily: "secondary", fontSize: "sm", children: description })] })] })] })] }));
|
|
23
24
|
};
|
|
@@ -20,18 +20,23 @@ export const ReadOnlyAppliances = ({
|
|
|
20
20
|
const images = children?.find(({ type }) => type === 'images')
|
|
21
21
|
return (
|
|
22
22
|
<Stack spacing="base" p="base" bg="neutral.white" mt="2px">
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
{name ||
|
|
24
|
+
(onEdit && (
|
|
25
|
+
<Flex justify="space-between">
|
|
26
|
+
<Text fontSize="xs" textTransform="uppercase">
|
|
27
|
+
{name}
|
|
28
|
+
</Text>
|
|
29
|
+
{onEdit && (
|
|
30
|
+
<IconButton
|
|
31
|
+
aria-label="Edit appliance"
|
|
32
|
+
variant="ghost"
|
|
33
|
+
w="fit-content"
|
|
34
|
+
icon={<Edit size={18} stroke={colors.blue[3]} />}
|
|
35
|
+
onClick={() => onEdit(id)}
|
|
36
|
+
/>
|
|
37
|
+
)}
|
|
38
|
+
</Flex>
|
|
39
|
+
))}
|
|
35
40
|
<Flex gap="base">
|
|
36
41
|
<ReadOnlyHomeItemImages {...images} />
|
|
37
42
|
<Stack spacing="4" flex="1">
|
|
@@ -40,33 +45,33 @@ export const ReadOnlyAppliances = ({
|
|
|
40
45
|
<Text fontSize="22px" fontWeight="semibold">
|
|
41
46
|
{value}
|
|
42
47
|
</Text>
|
|
48
|
+
<Box>
|
|
49
|
+
{children?.map(({ id, name, value, type }) => {
|
|
50
|
+
const baseProps = {
|
|
51
|
+
key: `${id}-${name}-${value}-${type}`,
|
|
52
|
+
id,
|
|
53
|
+
value,
|
|
54
|
+
type,
|
|
55
|
+
name,
|
|
56
|
+
}
|
|
57
|
+
switch (type) {
|
|
58
|
+
case 'text':
|
|
59
|
+
return <ReadOnlyHomeItemText {...baseProps} />
|
|
60
|
+
default:
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
})}
|
|
64
|
+
</Box>
|
|
65
|
+
<Box
|
|
66
|
+
flex="1"
|
|
67
|
+
borderBottom="1px dashed"
|
|
68
|
+
borderColor="lightBlue.6"
|
|
69
|
+
h="1px"
|
|
70
|
+
/>
|
|
43
71
|
<Text fontFamily="secondary" fontSize="sm">
|
|
44
72
|
{description}
|
|
45
73
|
</Text>
|
|
46
74
|
</Stack>
|
|
47
|
-
<Box
|
|
48
|
-
flex="1"
|
|
49
|
-
borderBottom="1px dashed"
|
|
50
|
-
borderColor="lightBlue.6"
|
|
51
|
-
h="1px"
|
|
52
|
-
/>
|
|
53
|
-
<Box>
|
|
54
|
-
{children?.map(({ id, name, value, type }) => {
|
|
55
|
-
const baseProps = {
|
|
56
|
-
key: `${id}-${name}-${value}-${type}`,
|
|
57
|
-
id,
|
|
58
|
-
value,
|
|
59
|
-
type,
|
|
60
|
-
name,
|
|
61
|
-
}
|
|
62
|
-
switch (type) {
|
|
63
|
-
case 'text':
|
|
64
|
-
return <ReadOnlyHomeItemText {...baseProps} />
|
|
65
|
-
default:
|
|
66
|
-
return null
|
|
67
|
-
}
|
|
68
|
-
})}
|
|
69
|
-
</Box>
|
|
70
75
|
</Stack>
|
|
71
76
|
</Flex>
|
|
72
77
|
</Stack>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Stack } from '@chakra-ui/react';
|
|
3
|
+
import { Collapsible, ReadOnlyTextArea } from '../../../..';
|
|
4
|
+
export const ReadOnlyCollapsible = ({ children, }) => {
|
|
5
|
+
return (_jsx(Stack, { bg: "lightBlue.2", spacing: "2px", children: children === null || children === void 0 ? void 0 : children.map(({ id, name = '', value, type }) => {
|
|
6
|
+
const baseProps = {
|
|
7
|
+
id,
|
|
8
|
+
value,
|
|
9
|
+
type,
|
|
10
|
+
name,
|
|
11
|
+
};
|
|
12
|
+
switch (type) {
|
|
13
|
+
case 'text':
|
|
14
|
+
return (_jsx(Collapsible, { title: name, showShadow: false, children: _jsx(ReadOnlyTextArea, Object.assign({}, baseProps)) }, `${id}-${name}-${value}-${type}`));
|
|
15
|
+
default:
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}) }));
|
|
19
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Stack } from '@chakra-ui/react'
|
|
2
|
+
import { Collapsible, ReadOnlyTextArea } from '@/components'
|
|
3
|
+
import { ReportI } from '@/interfaces'
|
|
4
|
+
|
|
5
|
+
export const ReadOnlyCollapsible = ({
|
|
6
|
+
children,
|
|
7
|
+
}: Pick<ReportI, 'children'>) => {
|
|
8
|
+
return (
|
|
9
|
+
<Stack bg="lightBlue.2" spacing="2px">
|
|
10
|
+
{children?.map(({ id, name = '', value, type }) => {
|
|
11
|
+
const baseProps = {
|
|
12
|
+
id,
|
|
13
|
+
value,
|
|
14
|
+
type,
|
|
15
|
+
name,
|
|
16
|
+
}
|
|
17
|
+
switch (type) {
|
|
18
|
+
case 'text':
|
|
19
|
+
return (
|
|
20
|
+
<Collapsible
|
|
21
|
+
title={name}
|
|
22
|
+
showShadow={false}
|
|
23
|
+
key={`${id}-${name}-${value}-${type}`}
|
|
24
|
+
>
|
|
25
|
+
<ReadOnlyTextArea {...baseProps} />
|
|
26
|
+
</Collapsible>
|
|
27
|
+
)
|
|
28
|
+
default:
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
})}
|
|
32
|
+
</Stack>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -3,7 +3,7 @@ import { Text, Stack, Grid } from '@chakra-ui/react';
|
|
|
3
3
|
import { HiddenField } from '../../../..';
|
|
4
4
|
import { fieldIcons } from '../../../../../helpers';
|
|
5
5
|
export const ReadOnlyGuidelines = ({ name, children, onClick, }) => {
|
|
6
|
-
return (_jsxs(Stack, { spacing: "base", children: [_jsx(Text, { fontSize: "xs", textTransform: "uppercase", children: name }), _jsx(Grid, { templateColumns: "repeat(
|
|
6
|
+
return (_jsxs(Stack, { spacing: "base", flex: "1", width: "100%", children: [_jsx(Text, { fontSize: "xs", textTransform: "uppercase", children: name }), _jsx(Grid, { templateColumns: "repeat(auto-fit, minmax(0, 75px))", gap: "base", children: children === null || children === void 0 ? void 0 : children.map((child) => {
|
|
7
7
|
const { id, icon, value } = child;
|
|
8
8
|
const btnIcon = icon ? fieldIcons[icon] : '';
|
|
9
9
|
return (_jsx(HiddenField, { id: id, icon: btnIcon, name: value, onClick: () => onClick === null || onClick === void 0 ? void 0 : onClick(id) }, id));
|
|
@@ -9,11 +9,11 @@ export const ReadOnlyGuidelines = ({
|
|
|
9
9
|
onClick,
|
|
10
10
|
}: ReadOnlyGuidelinesI) => {
|
|
11
11
|
return (
|
|
12
|
-
<Stack spacing="base">
|
|
12
|
+
<Stack spacing="base" flex="1" width="100%">
|
|
13
13
|
<Text fontSize="xs" textTransform="uppercase">
|
|
14
14
|
{name}
|
|
15
15
|
</Text>
|
|
16
|
-
<Grid templateColumns="repeat(
|
|
16
|
+
<Grid templateColumns="repeat(auto-fit, minmax(0, 75px))" gap="base">
|
|
17
17
|
{children?.map((child) => {
|
|
18
18
|
const { id, icon, value } = child
|
|
19
19
|
const btnIcon = icon ? fieldIcons[icon] : ''
|
|
@@ -3,7 +3,7 @@ import { Box, Flex, Text } from '@chakra-ui/react';
|
|
|
3
3
|
export const ReadOnlyHomeItemText = ({ name, value }) => {
|
|
4
4
|
if (!name)
|
|
5
5
|
return null;
|
|
6
|
-
return (_jsxs(Flex, { gap: "base", children: [_jsx(Box, { w: "
|
|
6
|
+
return (_jsxs(Flex, { gap: "base", children: [_jsx(Box, { w: "30%", children: _jsx(CustomText, { children: `${name}:` }) }), _jsx(CustomText, { children: String(value) })] }));
|
|
7
7
|
};
|
|
8
8
|
const CustomText = ({ children = '' }) => {
|
|
9
9
|
return (_jsx(Text, { fontSize: "sm", fontFamily: "secondary", children: children }));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Flex, Image, Text } from '@chakra-ui/react';
|
|
3
3
|
export const CollapsibleHeader = ({ icon, title, }) => {
|
|
4
|
-
return (_jsxs(Flex, { align: "center", gap: "base", children: [_jsx(Image, { h: "auto", w: "icon.md", src: icon }), _jsx(Text, { fontSize: "sm", textTransform: "uppercase", children: title })] }));
|
|
4
|
+
return (_jsxs(Flex, { align: "center", gap: "base", children: [icon && _jsx(Image, { h: "auto", w: "icon.md", src: icon }), _jsx(Text, { fontSize: "sm", textTransform: "uppercase", children: title })] }));
|
|
5
5
|
};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { HomeDepot, Lowes, Walmart, DefaultReceipt } from '../../assets/images';
|
|
2
2
|
export const receiptOrigins = {
|
|
3
|
-
|
|
4
|
-
HomeDepot: HomeDepot,
|
|
3
|
+
homedepot: HomeDepot,
|
|
5
4
|
lowes: Lowes,
|
|
6
|
-
Lowes: Lowes,
|
|
7
5
|
walmart: Walmart,
|
|
8
|
-
Walmart: Walmart,
|
|
9
6
|
"": DefaultReceipt
|
|
10
7
|
};
|
|
8
|
+
function normalize(input) {
|
|
9
|
+
return input.trim().toLowerCase().replace(/['\s]+/g, '');
|
|
10
|
+
}
|
|
11
11
|
export const getReceiptOrigin = (key) => {
|
|
12
12
|
var _a;
|
|
13
|
-
|
|
13
|
+
const normalizedKey = normalize(key);
|
|
14
|
+
return (_a = receiptOrigins[normalizedKey]) !== null && _a !== void 0 ? _a : DefaultReceipt;
|
|
14
15
|
};
|
|
15
16
|
export const receipts = [
|
|
16
17
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AIGridFieldI, AlertFieldType, AlertTabType, FolderFileI, MenuItemI, PartnerFooterI, TileCtaI } from '../..';
|
|
2
|
-
export type KindTypes = 'ai-image' | 'ai-grid' | 'checkbox' | 'checkbox-agreement' | 'checkbox-group' | 'currency' | 'date' | 'email' | 'file' | 'grid' | 'group' | 'hidden' | 'notes' | 'number' | 'radio' | 'rating' | 'select' | 'string' | 'switch' | 'telephone' | 'text' | 'textarea' | 'default' | 'video' | UIKindTypes | HomeItemTypes | AlertTabType | AlertFieldType;
|
|
2
|
+
export type KindTypes = 'ai-image' | 'ai-grid' | 'checkbox' | 'checkbox-agreement' | 'checkbox-group' | 'collapsible' | 'currency' | 'date' | 'email' | 'file' | 'grid' | 'group' | 'hidden' | 'notes' | 'number' | 'radio' | 'rating' | 'select' | 'string' | 'switch' | 'telephone' | 'text' | 'textarea' | 'default' | 'video' | UIKindTypes | HomeItemTypes | AlertTabType | AlertFieldType;
|
|
3
3
|
export type UIKindTypes = 'tile-body' | 'tile-body-logo' | 'tile-body-header' | 'tile-body-section' | 'tile-body-section-grid' | 'tile-body-partner-image' | 'tile-body-description' | 'tile-form' | 'tile-body-action' | 'vertical-icon' | 'primary-cta' | 'secondary-cta';
|
|
4
4
|
export type HomeItemTypes = 'appliances' | 'images' | 'guidelines' | 'item-related' | 'item-icon-btn';
|
|
5
5
|
export type IconTypes = 'barcode' | 'battery' | 'billing' | 'book' | 'book-opened' | 'calc' | 'calendar' | 'check' | 'co2' | 'contact' | 'date' | 'default' | 'detector' | 'electricity' | 'fire' | 'goldbars' | 'heart' | 'image' | 'life-preserver' | 'notes' | 'palette' | 'plant' | 'people' | 'price' | 'rating' | 'receipt' | 'registry' | 'sprinkler' | 'tools' | 'wind' | '68' | 'calendar2' | 'water' | 'calendar-drop' | 'umbrella' | 'heater' | 'roof' | 'foundation' | 'solar-panel' | 'pool' | 'drop' | 'mobile-drop' | 'light' | 'plate' | 'pressure-washer' | 'house' | 'target' | 'title' | 'company' | 'wallet' | UIIconTypes;
|
|
@@ -673,7 +673,7 @@ export const tileUIMock = [
|
|
|
673
673
|
export const viewingHomeItemMock = [
|
|
674
674
|
{
|
|
675
675
|
id: faker.database.mongodbObjectId(),
|
|
676
|
-
name: '
|
|
676
|
+
name: '',
|
|
677
677
|
description: 'KitchenAid Counter-depth 20-cu ft French Door Refrigerator with Ice Maker and Water dispenser (Stainless Steel) ENERGY STAR',
|
|
678
678
|
comments: faker.lorem.sentence(),
|
|
679
679
|
value: 'Refrigerator',
|
|
@@ -687,21 +687,13 @@ export const viewingHomeItemMock = [
|
|
|
687
687
|
description: '',
|
|
688
688
|
comments: '',
|
|
689
689
|
value: [
|
|
690
|
-
faker.image.
|
|
691
|
-
faker.image.
|
|
692
|
-
faker.image.
|
|
693
|
-
faker.image.
|
|
690
|
+
faker.image.urlPicsumPhotos(),
|
|
691
|
+
faker.image.urlPicsumPhotos(),
|
|
692
|
+
faker.image.urlPicsumPhotos(),
|
|
693
|
+
faker.image.urlPicsumPhotos(),
|
|
694
694
|
],
|
|
695
695
|
type: 'images',
|
|
696
696
|
},
|
|
697
|
-
{
|
|
698
|
-
id: faker.database.mongodbObjectId(),
|
|
699
|
-
name: '',
|
|
700
|
-
description: '',
|
|
701
|
-
comments: '',
|
|
702
|
-
value: 4,
|
|
703
|
-
type: 'rating',
|
|
704
|
-
},
|
|
705
697
|
{
|
|
706
698
|
id: faker.database.mongodbObjectId(),
|
|
707
699
|
name: 'Brand',
|
|
@@ -772,13 +764,41 @@ export const viewingHomeItemMock = [
|
|
|
772
764
|
},
|
|
773
765
|
{
|
|
774
766
|
id: faker.database.mongodbObjectId(),
|
|
775
|
-
name: '
|
|
767
|
+
name: 'Collapsible',
|
|
776
768
|
description: '',
|
|
777
769
|
comments: faker.lorem.sentence(),
|
|
778
770
|
value: faker.lorem.paragraphs(),
|
|
779
|
-
type: '
|
|
771
|
+
type: 'collapsible',
|
|
780
772
|
visible: true,
|
|
781
|
-
|
|
773
|
+
children: [
|
|
774
|
+
{
|
|
775
|
+
id: faker.database.mongodbObjectId(),
|
|
776
|
+
name: 'Care Instructions',
|
|
777
|
+
description: faker.lorem.sentence(),
|
|
778
|
+
comments: faker.lorem.sentence(),
|
|
779
|
+
value: faker.lorem.paragraphs(),
|
|
780
|
+
type: 'text',
|
|
781
|
+
visible: true,
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
id: faker.database.mongodbObjectId(),
|
|
785
|
+
name: 'OVERVIEW',
|
|
786
|
+
description: faker.lorem.sentence(),
|
|
787
|
+
comments: faker.lorem.sentence(),
|
|
788
|
+
value: faker.lorem.paragraphs(),
|
|
789
|
+
type: 'text',
|
|
790
|
+
visible: true,
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
id: faker.database.mongodbObjectId(),
|
|
794
|
+
name: 'Dimensions',
|
|
795
|
+
description: faker.lorem.sentence(),
|
|
796
|
+
comments: faker.lorem.sentence(),
|
|
797
|
+
value: faker.lorem.paragraphs(),
|
|
798
|
+
type: 'text',
|
|
799
|
+
visible: true,
|
|
800
|
+
},
|
|
801
|
+
],
|
|
782
802
|
},
|
|
783
803
|
];
|
|
784
804
|
export const unknownFormMock = {
|
|
@@ -3,3 +3,4 @@ import { DynamicFormI } from '../../../interfaces';
|
|
|
3
3
|
declare const _default: Meta;
|
|
4
4
|
export default _default;
|
|
5
5
|
export declare const ReadOnlyDynamicFormComponent: (args: DynamicFormI) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare const ReadOnlyAddItem: (args: DynamicFormI) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box } from '@chakra-ui/react';
|
|
3
|
+
import { action } from '@storybook/addon-actions';
|
|
3
4
|
import { ReadOnlyDynamicForm } from '../../../components';
|
|
4
|
-
import { unknownFormMock } from '../../../mocks';
|
|
5
|
+
import { unknownFormMock, viewingHomeItemMock } from '../../../mocks';
|
|
5
6
|
import { mapApiObjectToFormFields } from '../../../utils';
|
|
6
7
|
export default {
|
|
7
8
|
title: 'Components/Forms/ReadOnlyDynamicForm',
|
|
@@ -13,3 +14,6 @@ export const ReadOnlyDynamicFormComponent = (args) => {
|
|
|
13
14
|
});
|
|
14
15
|
return (_jsx(Box, { p: "base", bg: "neutral.white", w: ['full', '500px'], children: _jsx(ReadOnlyDynamicForm, { form: unknownForm }) }));
|
|
15
16
|
};
|
|
17
|
+
export const ReadOnlyAddItem = (args) => {
|
|
18
|
+
return (_jsx(Box, { p: "base", bg: "#EFECF7", w: ['full', '433px'], children: _jsx(ReadOnlyDynamicForm, { form: viewingHomeItemMock, onClick: action('onClick') }) }));
|
|
19
|
+
};
|
package/package.json
CHANGED
|
@@ -14,9 +14,10 @@ export const Collapsible = ({
|
|
|
14
14
|
children,
|
|
15
15
|
icon,
|
|
16
16
|
title,
|
|
17
|
+
showShadow = true,
|
|
17
18
|
}: PropsWithChildren<CollapsibleI>) => {
|
|
18
19
|
return (
|
|
19
|
-
<Accordion flex="1" allowMultiple boxShadow=
|
|
20
|
+
<Accordion flex="1" allowMultiple boxShadow={showShadow ? 'md' : 'none'}>
|
|
20
21
|
<AccordionItem border="none">
|
|
21
22
|
{({ isExpanded }) => (
|
|
22
23
|
<>
|
|
@@ -28,7 +29,7 @@ export const Collapsible = ({
|
|
|
28
29
|
borderBottom="1px solid"
|
|
29
30
|
borderColor={isExpanded ? 'lightBlue.2' : 'transparent'}
|
|
30
31
|
_hover={{
|
|
31
|
-
boxShadow: 'lg',
|
|
32
|
+
boxShadow: showShadow ? 'lg' : 'none',
|
|
32
33
|
}}
|
|
33
34
|
_focus={{
|
|
34
35
|
outline: 'none',
|
|
@@ -2,6 +2,7 @@ import { Box } from '@chakra-ui/react'
|
|
|
2
2
|
import { ReadOnlyDynamicFormI, IconTypes } from '@/interfaces'
|
|
3
3
|
import {
|
|
4
4
|
ReadOnlyAppliances,
|
|
5
|
+
ReadOnlyCollapsible,
|
|
5
6
|
ReadOnlyDate,
|
|
6
7
|
ReadOnlyGrid,
|
|
7
8
|
ReadOnlyGroup,
|
|
@@ -15,7 +16,7 @@ import { fieldIcons } from '@/helpers'
|
|
|
15
16
|
export const ReadOnlyDynamicForm = ({
|
|
16
17
|
form: fields,
|
|
17
18
|
onClick,
|
|
18
|
-
onEdit
|
|
19
|
+
onEdit,
|
|
19
20
|
}: ReadOnlyDynamicFormI) => {
|
|
20
21
|
return (
|
|
21
22
|
<Box bg="lightBlue.1" overflow="scroll">
|
|
@@ -74,6 +75,8 @@ export const ReadOnlyDynamicForm = ({
|
|
|
74
75
|
return <ReadOnlyGroup key={id}>{children}</ReadOnlyGroup>
|
|
75
76
|
case 'appliances':
|
|
76
77
|
return <ReadOnlyAppliances {...field} key={id} onEdit={onEdit} />
|
|
78
|
+
case 'collapsible':
|
|
79
|
+
return <ReadOnlyCollapsible {...field} key={id} />
|
|
77
80
|
case 'notes':
|
|
78
81
|
return <ReadOnlyNotes {...field} key={id} />
|
|
79
82
|
default:
|
|
@@ -20,18 +20,23 @@ export const ReadOnlyAppliances = ({
|
|
|
20
20
|
const images = children?.find(({ type }) => type === 'images')
|
|
21
21
|
return (
|
|
22
22
|
<Stack spacing="base" p="base" bg="neutral.white" mt="2px">
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
{name ||
|
|
24
|
+
(onEdit && (
|
|
25
|
+
<Flex justify="space-between">
|
|
26
|
+
<Text fontSize="xs" textTransform="uppercase">
|
|
27
|
+
{name}
|
|
28
|
+
</Text>
|
|
29
|
+
{onEdit && (
|
|
30
|
+
<IconButton
|
|
31
|
+
aria-label="Edit appliance"
|
|
32
|
+
variant="ghost"
|
|
33
|
+
w="fit-content"
|
|
34
|
+
icon={<Edit size={18} stroke={colors.blue[3]} />}
|
|
35
|
+
onClick={() => onEdit(id)}
|
|
36
|
+
/>
|
|
37
|
+
)}
|
|
38
|
+
</Flex>
|
|
39
|
+
))}
|
|
35
40
|
<Flex gap="base">
|
|
36
41
|
<ReadOnlyHomeItemImages {...images} />
|
|
37
42
|
<Stack spacing="4" flex="1">
|
|
@@ -40,33 +45,33 @@ export const ReadOnlyAppliances = ({
|
|
|
40
45
|
<Text fontSize="22px" fontWeight="semibold">
|
|
41
46
|
{value}
|
|
42
47
|
</Text>
|
|
48
|
+
<Box>
|
|
49
|
+
{children?.map(({ id, name, value, type }) => {
|
|
50
|
+
const baseProps = {
|
|
51
|
+
key: `${id}-${name}-${value}-${type}`,
|
|
52
|
+
id,
|
|
53
|
+
value,
|
|
54
|
+
type,
|
|
55
|
+
name,
|
|
56
|
+
}
|
|
57
|
+
switch (type) {
|
|
58
|
+
case 'text':
|
|
59
|
+
return <ReadOnlyHomeItemText {...baseProps} />
|
|
60
|
+
default:
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
})}
|
|
64
|
+
</Box>
|
|
65
|
+
<Box
|
|
66
|
+
flex="1"
|
|
67
|
+
borderBottom="1px dashed"
|
|
68
|
+
borderColor="lightBlue.6"
|
|
69
|
+
h="1px"
|
|
70
|
+
/>
|
|
43
71
|
<Text fontFamily="secondary" fontSize="sm">
|
|
44
72
|
{description}
|
|
45
73
|
</Text>
|
|
46
74
|
</Stack>
|
|
47
|
-
<Box
|
|
48
|
-
flex="1"
|
|
49
|
-
borderBottom="1px dashed"
|
|
50
|
-
borderColor="lightBlue.6"
|
|
51
|
-
h="1px"
|
|
52
|
-
/>
|
|
53
|
-
<Box>
|
|
54
|
-
{children?.map(({ id, name, value, type }) => {
|
|
55
|
-
const baseProps = {
|
|
56
|
-
key: `${id}-${name}-${value}-${type}`,
|
|
57
|
-
id,
|
|
58
|
-
value,
|
|
59
|
-
type,
|
|
60
|
-
name,
|
|
61
|
-
}
|
|
62
|
-
switch (type) {
|
|
63
|
-
case 'text':
|
|
64
|
-
return <ReadOnlyHomeItemText {...baseProps} />
|
|
65
|
-
default:
|
|
66
|
-
return null
|
|
67
|
-
}
|
|
68
|
-
})}
|
|
69
|
-
</Box>
|
|
70
75
|
</Stack>
|
|
71
76
|
</Flex>
|
|
72
77
|
</Stack>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Stack } from '@chakra-ui/react'
|
|
2
|
+
import { Collapsible, ReadOnlyTextArea } from '@/components'
|
|
3
|
+
import { ReportI } from '@/interfaces'
|
|
4
|
+
|
|
5
|
+
export const ReadOnlyCollapsible = ({
|
|
6
|
+
children,
|
|
7
|
+
}: Pick<ReportI, 'children'>) => {
|
|
8
|
+
return (
|
|
9
|
+
<Stack bg="lightBlue.2" spacing="2px">
|
|
10
|
+
{children?.map(({ id, name = '', value, type }) => {
|
|
11
|
+
const baseProps = {
|
|
12
|
+
id,
|
|
13
|
+
value,
|
|
14
|
+
type,
|
|
15
|
+
name,
|
|
16
|
+
}
|
|
17
|
+
switch (type) {
|
|
18
|
+
case 'text':
|
|
19
|
+
return (
|
|
20
|
+
<Collapsible
|
|
21
|
+
title={name}
|
|
22
|
+
showShadow={false}
|
|
23
|
+
key={`${id}-${name}-${value}-${type}`}
|
|
24
|
+
>
|
|
25
|
+
<ReadOnlyTextArea {...baseProps} />
|
|
26
|
+
</Collapsible>
|
|
27
|
+
)
|
|
28
|
+
default:
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
})}
|
|
32
|
+
</Stack>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -9,11 +9,11 @@ export const ReadOnlyGuidelines = ({
|
|
|
9
9
|
onClick,
|
|
10
10
|
}: ReadOnlyGuidelinesI) => {
|
|
11
11
|
return (
|
|
12
|
-
<Stack spacing="base">
|
|
12
|
+
<Stack spacing="base" flex="1" width="100%">
|
|
13
13
|
<Text fontSize="xs" textTransform="uppercase">
|
|
14
14
|
{name}
|
|
15
15
|
</Text>
|
|
16
|
-
<Grid templateColumns="repeat(
|
|
16
|
+
<Grid templateColumns="repeat(auto-fit, minmax(0, 75px))" gap="base">
|
|
17
17
|
{children?.map((child) => {
|
|
18
18
|
const { id, icon, value } = child
|
|
19
19
|
const btnIcon = icon ? fieldIcons[icon] : ''
|
|
@@ -7,7 +7,7 @@ export const CollapsibleHeader = ({
|
|
|
7
7
|
}: Pick<CollapsibleI, 'icon' | 'title'>) => {
|
|
8
8
|
return (
|
|
9
9
|
<Flex align="center" gap="base">
|
|
10
|
-
<Image h="auto" w="icon.md" src={icon} />
|
|
10
|
+
{icon && <Image h="auto" w="icon.md" src={icon} />}
|
|
11
11
|
<Text fontSize="sm" textTransform="uppercase">
|
|
12
12
|
{title}
|
|
13
13
|
</Text>
|
|
@@ -2,17 +2,19 @@ import { ReceiptCardItemI } from '@/interfaces'
|
|
|
2
2
|
import { HomeDepot, Lowes, Walmart, DefaultReceipt } from '@/assets/images'
|
|
3
3
|
|
|
4
4
|
export const receiptOrigins: Record<string, string> = {
|
|
5
|
-
|
|
6
|
-
HomeDepot: HomeDepot,
|
|
5
|
+
homedepot: HomeDepot,
|
|
7
6
|
lowes: Lowes,
|
|
8
|
-
Lowes: Lowes,
|
|
9
7
|
walmart: Walmart,
|
|
10
|
-
Walmart: Walmart,
|
|
11
8
|
"" : DefaultReceipt
|
|
12
9
|
}
|
|
13
10
|
|
|
11
|
+
function normalize(input: string) {
|
|
12
|
+
return input.trim().toLowerCase().replace(/['\s]+/g, '');
|
|
13
|
+
}
|
|
14
|
+
|
|
14
15
|
export const getReceiptOrigin = (key: string): string => {
|
|
15
|
-
|
|
16
|
+
const normalizedKey = normalize(key)
|
|
17
|
+
return receiptOrigins[normalizedKey] ?? DefaultReceipt;
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
export const receipts: ReceiptCardItemI[] = [
|
|
@@ -681,7 +681,7 @@ export const tileUIMock: ReportI[] = [
|
|
|
681
681
|
export const viewingHomeItemMock: ReportI[] = [
|
|
682
682
|
{
|
|
683
683
|
id: faker.database.mongodbObjectId(),
|
|
684
|
-
name: '
|
|
684
|
+
name: '',
|
|
685
685
|
description:
|
|
686
686
|
'KitchenAid Counter-depth 20-cu ft French Door Refrigerator with Ice Maker and Water dispenser (Stainless Steel) ENERGY STAR',
|
|
687
687
|
comments: faker.lorem.sentence(),
|
|
@@ -696,21 +696,13 @@ export const viewingHomeItemMock: ReportI[] = [
|
|
|
696
696
|
description: '',
|
|
697
697
|
comments: '',
|
|
698
698
|
value: [
|
|
699
|
-
faker.image.
|
|
700
|
-
faker.image.
|
|
701
|
-
faker.image.
|
|
702
|
-
faker.image.
|
|
699
|
+
faker.image.urlPicsumPhotos(),
|
|
700
|
+
faker.image.urlPicsumPhotos(),
|
|
701
|
+
faker.image.urlPicsumPhotos(),
|
|
702
|
+
faker.image.urlPicsumPhotos(),
|
|
703
703
|
],
|
|
704
704
|
type: 'images',
|
|
705
705
|
},
|
|
706
|
-
{
|
|
707
|
-
id: faker.database.mongodbObjectId(),
|
|
708
|
-
name: '',
|
|
709
|
-
description: '',
|
|
710
|
-
comments: '',
|
|
711
|
-
value: 4,
|
|
712
|
-
type: 'rating',
|
|
713
|
-
},
|
|
714
706
|
{
|
|
715
707
|
id: faker.database.mongodbObjectId(),
|
|
716
708
|
name: 'Brand',
|
|
@@ -781,13 +773,41 @@ export const viewingHomeItemMock: ReportI[] = [
|
|
|
781
773
|
},
|
|
782
774
|
{
|
|
783
775
|
id: faker.database.mongodbObjectId(),
|
|
784
|
-
name: '
|
|
776
|
+
name: 'Collapsible',
|
|
785
777
|
description: '',
|
|
786
778
|
comments: faker.lorem.sentence(),
|
|
787
779
|
value: faker.lorem.paragraphs(),
|
|
788
|
-
type: '
|
|
780
|
+
type: 'collapsible',
|
|
789
781
|
visible: true,
|
|
790
|
-
|
|
782
|
+
children: [
|
|
783
|
+
{
|
|
784
|
+
id: faker.database.mongodbObjectId(),
|
|
785
|
+
name: 'Care Instructions',
|
|
786
|
+
description: faker.lorem.sentence(),
|
|
787
|
+
comments: faker.lorem.sentence(),
|
|
788
|
+
value: faker.lorem.paragraphs(),
|
|
789
|
+
type: 'text',
|
|
790
|
+
visible: true,
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
id: faker.database.mongodbObjectId(),
|
|
794
|
+
name: 'OVERVIEW',
|
|
795
|
+
description: faker.lorem.sentence(),
|
|
796
|
+
comments: faker.lorem.sentence(),
|
|
797
|
+
value: faker.lorem.paragraphs(),
|
|
798
|
+
type: 'text',
|
|
799
|
+
visible: true,
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
id: faker.database.mongodbObjectId(),
|
|
803
|
+
name: 'Dimensions',
|
|
804
|
+
description: faker.lorem.sentence(),
|
|
805
|
+
comments: faker.lorem.sentence(),
|
|
806
|
+
value: faker.lorem.paragraphs(),
|
|
807
|
+
type: 'text',
|
|
808
|
+
visible: true,
|
|
809
|
+
},
|
|
810
|
+
],
|
|
791
811
|
},
|
|
792
812
|
]
|
|
793
813
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Meta } from '@storybook/react'
|
|
2
2
|
import { Box } from '@chakra-ui/react'
|
|
3
|
+
import { action } from '@storybook/addon-actions'
|
|
3
4
|
import { ReadOnlyDynamicForm } from '@/components'
|
|
4
|
-
import { unknownFormMock } from '@/mocks'
|
|
5
|
+
import { unknownFormMock, viewingHomeItemMock } from '@/mocks'
|
|
5
6
|
import { DynamicFormI } from '@/interfaces'
|
|
6
7
|
import { mapApiObjectToFormFields } from '@/utils'
|
|
7
8
|
|
|
@@ -20,3 +21,14 @@ export const ReadOnlyDynamicFormComponent = (args: DynamicFormI) => {
|
|
|
20
21
|
</Box>
|
|
21
22
|
)
|
|
22
23
|
}
|
|
24
|
+
|
|
25
|
+
export const ReadOnlyAddItem = (args: DynamicFormI) => {
|
|
26
|
+
return (
|
|
27
|
+
<Box p="base" bg="#EFECF7" w={['full', '433px']}>
|
|
28
|
+
<ReadOnlyDynamicForm
|
|
29
|
+
form={viewingHomeItemMock}
|
|
30
|
+
onClick={action('onClick')}
|
|
31
|
+
/>
|
|
32
|
+
</Box>
|
|
33
|
+
)
|
|
34
|
+
}
|