@homefile/components-v2 2.19.0 → 2.20.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/badge/CustomBadge.d.ts +3 -4
- package/dist/components/badge/CustomBadge.js +14 -2
- package/dist/components/homeAssistant/monitorAlerts/BackendAlert.d.ts +1 -1
- package/dist/components/homeAssistant/monitorAlerts/BackendAlert.js +2 -2
- package/dist/components/homeAssistant/monitorAlerts/alertDetails/AlertFields.js +3 -1
- package/dist/components/homeAssistant/monitorAlerts/alertDetails/PurchaseProduct.d.ts +2 -0
- package/dist/components/homeAssistant/monitorAlerts/alertDetails/PurchaseProduct.js +26 -0
- package/dist/components/homeAssistant/monitorAlerts/alertDetails/VideoDetail.js +1 -1
- package/dist/components/homeAssistant/monitorAlerts/alertDetails/index.d.ts +1 -0
- package/dist/components/homeAssistant/monitorAlerts/alertDetails/index.js +1 -0
- package/dist/interfaces/forms/dynamicForm/DynamicForm.interface.d.ts +1 -1
- package/dist/interfaces/homeAssistant/BackendAlert.interface.d.ts +1 -1
- package/dist/mocks/forms/dynamicForm.mock.js +56 -0
- package/dist/stories/homeAssistant/monitorAlerts/BackendAlert.stories.js +2 -0
- package/package.json +1 -1
- package/src/components/badge/CustomBadge.tsx +4 -2
- package/src/components/homeAssistant/monitorAlerts/BackendAlert.tsx +4 -2
- package/src/components/homeAssistant/monitorAlerts/alertDetails/AlertFields.tsx +8 -1
- package/src/components/homeAssistant/monitorAlerts/alertDetails/PurchaseProduct.tsx +78 -0
- package/src/components/homeAssistant/monitorAlerts/alertDetails/VideoDetail.tsx +1 -1
- package/src/components/homeAssistant/monitorAlerts/alertDetails/index.ts +1 -0
- package/src/interfaces/forms/dynamicForm/DynamicForm.interface.ts +1 -0
- package/src/interfaces/homeAssistant/BackendAlert.interface.ts +1 -1
- package/src/mocks/forms/dynamicForm.mock.ts +56 -0
- package/src/stories/homeAssistant/monitorAlerts/BackendAlert.stories.tsx +2 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
label?: string | undefined;
|
|
1
|
+
import { CenterProps } from '@chakra-ui/react';
|
|
2
|
+
export declare const CustomBadge: ({ bg, color, label, ...props }: CenterProps & {
|
|
3
|
+
label?: string;
|
|
5
4
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
1
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
13
|
import { Center } from '@chakra-ui/react';
|
|
3
|
-
export const CustomBadge = (
|
|
4
|
-
|
|
14
|
+
export const CustomBadge = (_a) => {
|
|
15
|
+
var { bg = 'neutral.white', color = 'neutral.white', label = '' } = _a, props = __rest(_a, ["bg", "color", "label"]);
|
|
16
|
+
return (_jsx(Center, Object.assign({ bg: bg, fontSize: "xxs", color: color, fontWeight: "bold", py: "1", px: "2", rounded: "md", textTransform: "uppercase" }, props, { children: label })));
|
|
5
17
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { BackendAlertI } from '../../../interfaces';
|
|
2
|
-
export declare const BackendAlert: ({ category, form }: BackendAlertI) => import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare const BackendAlert: ({ category, form, callback }: BackendAlertI) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { AlertFields, BackendAlertCard, TabsHeader } from '../..';
|
|
3
3
|
import { getCategoryStyles } from '../../../utils/Alerts.utils';
|
|
4
4
|
import { Divider } from '@chakra-ui/react';
|
|
5
|
-
export const BackendAlert = ({ category, form }) => {
|
|
5
|
+
export const BackendAlert = ({ category, form, callback }) => {
|
|
6
6
|
var _a, _b, _c, _d, _e;
|
|
7
7
|
const { headerBg, alertIcon, alertIconBg, alertTitle } = getCategoryStyles(category);
|
|
8
8
|
const alert = form === null || form === void 0 ? void 0 : form.find((item) => item.type === 'alert');
|
|
@@ -10,7 +10,7 @@ export const BackendAlert = ({ category, form }) => {
|
|
|
10
10
|
var _a;
|
|
11
11
|
return ({
|
|
12
12
|
label: tab.name,
|
|
13
|
-
component: _jsx(AlertFields, { fields: (_a = tab.children) !== null && _a !== void 0 ? _a : [] }),
|
|
13
|
+
component: (_jsx(AlertFields, { fields: (_a = tab.children) !== null && _a !== void 0 ? _a : [], callback: callback })),
|
|
14
14
|
});
|
|
15
15
|
})) !== null && _b !== void 0 ? _b : [];
|
|
16
16
|
return (_jsxs(BackendAlertCard, { alertBg: headerBg, alertIcon: alertIcon, alertTitle: alertTitle, bg: alertIconBg, icon: (_c = alert === null || alert === void 0 ? void 0 : alert.icon) !== null && _c !== void 0 ? _c : '', title: (_d = alert === null || alert === void 0 ? void 0 : alert.label) !== null && _d !== void 0 ? _d : '', description: (_e = alert === null || alert === void 0 ? void 0 : alert.description) !== null && _e !== void 0 ? _e : '', children: [_jsx(Divider, {}), _jsx(TabsHeader, { tabList: tabs })] }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createElement as _createElement } from "react";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { Stack, Text } from '@chakra-ui/react';
|
|
4
|
-
import { FilterSize, SearchField, VideoDetail } from '../../..';
|
|
4
|
+
import { FilterSize, PurchaseProduct, SearchField, VideoDetail, } from '../../..';
|
|
5
5
|
import { fieldIcons } from '../../../../helpers';
|
|
6
6
|
export const AlertFields = ({ fields, callback }) => {
|
|
7
7
|
return (_jsx(Stack, { spacing: "base", p: "base", children: fields === null || fields === void 0 ? void 0 : fields.map((field) => {
|
|
@@ -16,6 +16,8 @@ export const AlertFields = ({ fields, callback }) => {
|
|
|
16
16
|
return _createElement(FilterSize, Object.assign({}, field, { key: id, icon: mappedIcon }));
|
|
17
17
|
case 'search':
|
|
18
18
|
return _createElement(SearchField, Object.assign({}, field, { key: id, callback: callback }));
|
|
19
|
+
case 'purchase-product':
|
|
20
|
+
return _createElement(PurchaseProduct, Object.assign({}, field, { key: id, callback: callback }));
|
|
19
21
|
default:
|
|
20
22
|
return null;
|
|
21
23
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { CustomBadge, Plus } from '../../..';
|
|
14
|
+
import { colors } from '../../../../theme/colors';
|
|
15
|
+
import { AspectRatio, Container, Flex, IconButton, Image, Stack, Text, } from '@chakra-ui/react';
|
|
16
|
+
export const PurchaseProduct = (_a) => {
|
|
17
|
+
var _b;
|
|
18
|
+
var { name, label, icon, comments, value, callback } = _a, rest = __rest(_a, ["name", "label", "icon", "comments", "value", "callback"]);
|
|
19
|
+
const bgs = {
|
|
20
|
+
best: '#232669',
|
|
21
|
+
better: '#424CBF',
|
|
22
|
+
good: '#5C81C7',
|
|
23
|
+
};
|
|
24
|
+
const bg = bgs[(_b = label === null || label === void 0 ? void 0 : label.toLowerCase()) !== null && _b !== void 0 ? _b : 'best'];
|
|
25
|
+
return (_jsxs(Container, { p: "base", position: "relative", boxShadow: "md", children: [_jsx(CustomBadge, { label: label, bg: bg, position: "absolute", top: "2", left: "-1", zIndex: "3" }), _jsxs(Flex, { gap: "base", ml: "6", children: [_jsx(AspectRatio, { ratio: 1, minW: "70px", h: "auto", children: _jsx(Image, { src: icon, alt: name, objectFit: "cover", w: "100%", h: "100%" }) }), _jsxs(Stack, { spacing: "0", children: [_jsx(Text, { fontWeight: "semibold", fontSize: "sm", noOfLines: 2, overflow: "hidden", textOverflow: "ellipsis", children: name }), _jsxs(Flex, { alignSelf: "end", gap: "base", align: "center", children: [_jsxs(Stack, { spacing: "0", align: "end", children: [_jsx(Text, { fontSize: "xs", fontFamily: "secondary", color: "red", children: comments }), _jsx(Text, { fontSize: "sm", fontWeight: "bold", lineHeight: "1.2", children: value })] }), _jsx(IconButton, { w: "2rem", h: "2rem", "aria-label": "Add product", variant: "iconOutlined", icon: _jsx(Plus, { size: 20, stroke: colors.blue['3'] }), onClick: () => callback === null || callback === void 0 ? void 0 : callback(Object.assign({ name, icon, value: String(value) }, rest)) })] })] })] })] }));
|
|
26
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { AspectRatio, Box, Container, Flex, Text } from '@chakra-ui/react';
|
|
3
3
|
export const VideoDetail = ({ name, label, link, description }) => {
|
|
4
|
-
return (_jsx(Container, { p: "base", children: _jsxs(Flex, { gap: "base", children: [_jsx(AspectRatio, { w: "140px", ratio: 16 / 9, children: _jsx("iframe", { title: name, src: link, allowFullScreen: true }) }), _jsxs(Box, { children: [_jsx(Text, { fontWeight: "semibold", children: name }), _jsx(Text, { fontSize: "sm", fontFamily: "secondary", children: `${label} | ${description}` })] })] }) }));
|
|
4
|
+
return (_jsx(Container, { p: "base", boxShadow: "md", children: _jsxs(Flex, { gap: "base", children: [_jsx(AspectRatio, { w: "140px", ratio: 16 / 9, children: _jsx("iframe", { title: name, src: link, allowFullScreen: true }) }), _jsxs(Box, { children: [_jsx(Text, { fontWeight: "semibold", children: name }), _jsx(Text, { fontSize: "sm", fontFamily: "secondary", children: `${label} | ${description}` })] })] }) }));
|
|
5
5
|
};
|
|
@@ -2,6 +2,7 @@ export * from './AlertFields';
|
|
|
2
2
|
export * from './ChangeAirFilter';
|
|
3
3
|
export * from './CustomDivider';
|
|
4
4
|
export * from './FilterSize';
|
|
5
|
+
export * from './PurchaseProduct';
|
|
5
6
|
export * from './SearchField';
|
|
6
7
|
export * from './SmokeDetectorBattery';
|
|
7
8
|
export * from './SmokeDetectorExpired';
|
|
@@ -2,6 +2,7 @@ export * from './AlertFields';
|
|
|
2
2
|
export * from './ChangeAirFilter';
|
|
3
3
|
export * from './CustomDivider';
|
|
4
4
|
export * from './FilterSize';
|
|
5
|
+
export * from './PurchaseProduct';
|
|
5
6
|
export * from './SearchField';
|
|
6
7
|
export * from './SmokeDetectorBattery';
|
|
7
8
|
export * from './SmokeDetectorExpired';
|
|
@@ -3,7 +3,7 @@ export type KindTypes = 'ai-image' | 'ai-grid' | 'checkbox' | 'checkbox-agreemen
|
|
|
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' | 'goldbars' | 'heart' | 'image' | 'notes' | 'palette' | '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' | UIIconTypes;
|
|
6
|
-
export type UIIconTypes = 'sh-pressure' | 'sh-window' | 'sh-roof' | 'sh-lights' | 'sh-gutter' | 'sh-home' | 'sh-house' | 'aa-mowing' | 'aa-fertilization' | 'aa-disease' | 'aa-weed' | 'aa-dressing' | 'aa-pest' | 'filter-size';
|
|
6
|
+
export type UIIconTypes = 'sh-pressure' | 'sh-window' | 'sh-roof' | 'sh-lights' | 'sh-gutter' | 'sh-home' | 'sh-house' | 'aa-mowing' | 'aa-fertilization' | 'aa-disease' | 'aa-weed' | 'aa-dressing' | 'aa-pest' | 'filter-size' | string;
|
|
7
7
|
export type ValueTypes = string | string[] | number | boolean;
|
|
8
8
|
export type OptionsTypes = string[] | number[] | null;
|
|
9
9
|
export interface ReportI {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DynamicFormI } from '..';
|
|
2
2
|
export type AlertCategory = 'safeguard' | 'maintain' | 'budget' | 'improve';
|
|
3
3
|
export type AlertTabType = 'details' | 'filter-size' | 'purchase' | 'hire-out';
|
|
4
|
-
export type AlertFieldType = 'alert' | 'search';
|
|
4
|
+
export type AlertFieldType = 'alert' | 'search' | 'purchase-product';
|
|
5
5
|
export interface BackendAlertI extends DynamicFormI {
|
|
6
6
|
category: AlertCategory;
|
|
7
7
|
}
|
|
@@ -925,6 +925,62 @@ export const alertFieldsMock = [
|
|
|
925
925
|
},
|
|
926
926
|
],
|
|
927
927
|
},
|
|
928
|
+
{
|
|
929
|
+
id: faker.database.mongodbObjectId(),
|
|
930
|
+
name: 'Purchase',
|
|
931
|
+
label: '',
|
|
932
|
+
description: faker.lorem.sentence(),
|
|
933
|
+
comments: faker.lorem.sentence(),
|
|
934
|
+
value: '',
|
|
935
|
+
type: 'purchase',
|
|
936
|
+
visible: true,
|
|
937
|
+
children: [
|
|
938
|
+
{
|
|
939
|
+
id: faker.database.mongodbObjectId(),
|
|
940
|
+
name: 'Filtrete™ Allergen Defense Furnace AC Air Filter 1000 MPR',
|
|
941
|
+
label: 'best',
|
|
942
|
+
description: '',
|
|
943
|
+
icon: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT50sebT9p-twQB-DdM2tlRo12In8F09QCsmg&s',
|
|
944
|
+
comments: 'Save 20% off Retail',
|
|
945
|
+
value: '$22.99',
|
|
946
|
+
type: 'purchase-product',
|
|
947
|
+
visible: true,
|
|
948
|
+
},
|
|
949
|
+
{
|
|
950
|
+
id: faker.database.mongodbObjectId(),
|
|
951
|
+
name: 'Filtrete™ Smart Allergen Bacteria & Virus Furnace AC Air Filter MPR 1500',
|
|
952
|
+
label: 'better',
|
|
953
|
+
description: '',
|
|
954
|
+
icon: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSbFpjG3kybZDb6psqPIlQSoXgp9OjOR672kg&s',
|
|
955
|
+
comments: 'Save 28% off Retail',
|
|
956
|
+
value: '$16.99',
|
|
957
|
+
type: 'purchase-product',
|
|
958
|
+
visible: true,
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
id: faker.database.mongodbObjectId(),
|
|
962
|
+
name: 'Filtrete™ 700 MPR Dust Pollen and Pet Dander Electrostatic Air Filter',
|
|
963
|
+
label: 'good',
|
|
964
|
+
description: '',
|
|
965
|
+
icon: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ7j1KYfPZqPnFmTgyx7b9pp78N6RForQfZFQ&s',
|
|
966
|
+
comments: 'Save 24% off Retail',
|
|
967
|
+
value: '$10.99',
|
|
968
|
+
type: 'purchase-product',
|
|
969
|
+
visible: true,
|
|
970
|
+
},
|
|
971
|
+
],
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
id: faker.database.mongodbObjectId(),
|
|
975
|
+
name: 'Hire out',
|
|
976
|
+
label: '',
|
|
977
|
+
description: faker.lorem.sentence(),
|
|
978
|
+
comments: faker.lorem.sentence(),
|
|
979
|
+
value: faker.image.urlPicsumPhotos(),
|
|
980
|
+
type: 'hire-out',
|
|
981
|
+
visible: true,
|
|
982
|
+
children: [],
|
|
983
|
+
},
|
|
928
984
|
],
|
|
929
985
|
},
|
|
930
986
|
];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { action } from '@storybook/addon-actions';
|
|
2
3
|
import { BackendAlert } from '../../../components';
|
|
3
4
|
import { alertFieldsMock } from '../../../mocks';
|
|
4
5
|
export default {
|
|
@@ -7,6 +8,7 @@ export default {
|
|
|
7
8
|
args: {
|
|
8
9
|
category: 'budget',
|
|
9
10
|
form: alertFieldsMock,
|
|
11
|
+
callback: action('onClick'),
|
|
10
12
|
},
|
|
11
13
|
};
|
|
12
14
|
export const BackendAlertComponent = (args) => {
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { Center } from '@chakra-ui/react'
|
|
1
|
+
import { Center, CenterProps } from '@chakra-ui/react'
|
|
2
2
|
|
|
3
3
|
export const CustomBadge = ({
|
|
4
4
|
bg = 'neutral.white',
|
|
5
5
|
color = 'neutral.white',
|
|
6
6
|
label = '',
|
|
7
|
-
|
|
7
|
+
...props
|
|
8
|
+
}: CenterProps & { label?: string }) => {
|
|
8
9
|
return (
|
|
9
10
|
<Center
|
|
10
11
|
bg={bg}
|
|
@@ -15,6 +16,7 @@ export const CustomBadge = ({
|
|
|
15
16
|
px="2"
|
|
16
17
|
rounded="md"
|
|
17
18
|
textTransform="uppercase"
|
|
19
|
+
{...props}
|
|
18
20
|
>
|
|
19
21
|
{label}
|
|
20
22
|
</Center>
|
|
@@ -3,7 +3,7 @@ import { BackendAlertI, TabI } from '@/interfaces'
|
|
|
3
3
|
import { getCategoryStyles } from '@/utils/Alerts.utils'
|
|
4
4
|
import { Divider } from '@chakra-ui/react'
|
|
5
5
|
|
|
6
|
-
export const BackendAlert = ({ category, form }: BackendAlertI) => {
|
|
6
|
+
export const BackendAlert = ({ category, form, callback }: BackendAlertI) => {
|
|
7
7
|
const { headerBg, alertIcon, alertIconBg, alertTitle } =
|
|
8
8
|
getCategoryStyles(category)
|
|
9
9
|
const alert = form?.find((item) => item.type === 'alert')
|
|
@@ -13,7 +13,9 @@ export const BackendAlert = ({ category, form }: BackendAlertI) => {
|
|
|
13
13
|
(tab) =>
|
|
14
14
|
({
|
|
15
15
|
label: tab.name,
|
|
16
|
-
component:
|
|
16
|
+
component: (
|
|
17
|
+
<AlertFields fields={tab.children ?? []} callback={callback} />
|
|
18
|
+
),
|
|
17
19
|
} as TabI)
|
|
18
20
|
) ?? []
|
|
19
21
|
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { FieldTypesI, IconTypes } from '@/interfaces'
|
|
2
2
|
import { Box, Stack, Text } from '@chakra-ui/react'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
FilterSize,
|
|
5
|
+
PurchaseProduct,
|
|
6
|
+
SearchField,
|
|
7
|
+
VideoDetail,
|
|
8
|
+
} from '@/components'
|
|
4
9
|
import { fieldIcons } from '@/helpers'
|
|
5
10
|
|
|
6
11
|
export const AlertFields = ({ fields, callback }: FieldTypesI) => {
|
|
@@ -28,6 +33,8 @@ export const AlertFields = ({ fields, callback }: FieldTypesI) => {
|
|
|
28
33
|
return <FilterSize {...field} key={id} icon={mappedIcon} />
|
|
29
34
|
case 'search':
|
|
30
35
|
return <SearchField {...field} key={id} callback={callback} />
|
|
36
|
+
case 'purchase-product':
|
|
37
|
+
return <PurchaseProduct {...field} key={id} callback={callback} />
|
|
31
38
|
default:
|
|
32
39
|
return null
|
|
33
40
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { CustomBadge, Plus } from '@/components'
|
|
2
|
+
import { FieldTypesI, ReportI } from '@/interfaces'
|
|
3
|
+
import { colors } from '@/theme/colors'
|
|
4
|
+
import {
|
|
5
|
+
AspectRatio,
|
|
6
|
+
Container,
|
|
7
|
+
Flex,
|
|
8
|
+
IconButton,
|
|
9
|
+
Image,
|
|
10
|
+
Stack,
|
|
11
|
+
Text,
|
|
12
|
+
} from '@chakra-ui/react'
|
|
13
|
+
|
|
14
|
+
export const PurchaseProduct = ({
|
|
15
|
+
name,
|
|
16
|
+
label,
|
|
17
|
+
icon,
|
|
18
|
+
comments,
|
|
19
|
+
value,
|
|
20
|
+
callback,
|
|
21
|
+
...rest
|
|
22
|
+
}: ReportI & Pick<FieldTypesI, 'callback'>) => {
|
|
23
|
+
const bgs = {
|
|
24
|
+
best: '#232669',
|
|
25
|
+
better: '#424CBF',
|
|
26
|
+
good: '#5C81C7',
|
|
27
|
+
}
|
|
28
|
+
const bg = bgs[(label?.toLowerCase() as keyof typeof bgs) ?? 'best']
|
|
29
|
+
return (
|
|
30
|
+
<Container p="base" position="relative" boxShadow="md">
|
|
31
|
+
<CustomBadge
|
|
32
|
+
label={label}
|
|
33
|
+
bg={bg}
|
|
34
|
+
position="absolute"
|
|
35
|
+
top="2"
|
|
36
|
+
left="-1"
|
|
37
|
+
zIndex="3"
|
|
38
|
+
/>
|
|
39
|
+
<Flex gap="base" ml="6">
|
|
40
|
+
<AspectRatio ratio={1} minW="70px" h="auto">
|
|
41
|
+
<Image src={icon} alt={name} objectFit="cover" w="100%" h="100%" />
|
|
42
|
+
</AspectRatio>
|
|
43
|
+
|
|
44
|
+
<Stack spacing="0">
|
|
45
|
+
<Text
|
|
46
|
+
fontWeight="semibold"
|
|
47
|
+
fontSize="sm"
|
|
48
|
+
noOfLines={2}
|
|
49
|
+
overflow="hidden"
|
|
50
|
+
textOverflow="ellipsis"
|
|
51
|
+
>
|
|
52
|
+
{name}
|
|
53
|
+
</Text>
|
|
54
|
+
<Flex alignSelf="end" gap="base" align="center">
|
|
55
|
+
<Stack spacing="0" align="end">
|
|
56
|
+
<Text fontSize="xs" fontFamily="secondary" color="red">
|
|
57
|
+
{comments}
|
|
58
|
+
</Text>
|
|
59
|
+
<Text fontSize="sm" fontWeight="bold" lineHeight="1.2">
|
|
60
|
+
{value}
|
|
61
|
+
</Text>
|
|
62
|
+
</Stack>
|
|
63
|
+
<IconButton
|
|
64
|
+
w="2rem"
|
|
65
|
+
h="2rem"
|
|
66
|
+
aria-label="Add product"
|
|
67
|
+
variant="iconOutlined"
|
|
68
|
+
icon={<Plus size={20} stroke={colors.blue['3']} />}
|
|
69
|
+
onClick={() =>
|
|
70
|
+
callback?.({ name, icon, value: String(value), ...rest })
|
|
71
|
+
}
|
|
72
|
+
/>
|
|
73
|
+
</Flex>
|
|
74
|
+
</Stack>
|
|
75
|
+
</Flex>
|
|
76
|
+
</Container>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
@@ -3,7 +3,7 @@ import { AspectRatio, Box, Container, Flex, Text } from '@chakra-ui/react'
|
|
|
3
3
|
|
|
4
4
|
export const VideoDetail = ({ name, label, link, description }: ReportI) => {
|
|
5
5
|
return (
|
|
6
|
-
<Container p="base">
|
|
6
|
+
<Container p="base" boxShadow="md">
|
|
7
7
|
<Flex gap="base">
|
|
8
8
|
<AspectRatio w="140px" ratio={16 / 9}>
|
|
9
9
|
<iframe title={name} src={link} allowFullScreen />
|
|
@@ -2,6 +2,7 @@ export * from './AlertFields'
|
|
|
2
2
|
export * from './ChangeAirFilter'
|
|
3
3
|
export * from './CustomDivider'
|
|
4
4
|
export * from './FilterSize'
|
|
5
|
+
export * from './PurchaseProduct'
|
|
5
6
|
export * from './SearchField'
|
|
6
7
|
export * from './SmokeDetectorBattery'
|
|
7
8
|
export * from './SmokeDetectorExpired'
|
|
@@ -4,7 +4,7 @@ export type AlertCategory = 'safeguard' | 'maintain' | 'budget' | 'improve'
|
|
|
4
4
|
|
|
5
5
|
export type AlertTabType = 'details' | 'filter-size' | 'purchase' | 'hire-out'
|
|
6
6
|
|
|
7
|
-
export type AlertFieldType = 'alert' | 'search'
|
|
7
|
+
export type AlertFieldType = 'alert' | 'search' | 'purchase-product'
|
|
8
8
|
|
|
9
9
|
export interface BackendAlertI extends DynamicFormI {
|
|
10
10
|
category: AlertCategory
|
|
@@ -945,6 +945,62 @@ export const alertFieldsMock: ReportI[] = [
|
|
|
945
945
|
},
|
|
946
946
|
],
|
|
947
947
|
},
|
|
948
|
+
{
|
|
949
|
+
id: faker.database.mongodbObjectId(),
|
|
950
|
+
name: 'Purchase',
|
|
951
|
+
label: '',
|
|
952
|
+
description: faker.lorem.sentence(),
|
|
953
|
+
comments: faker.lorem.sentence(),
|
|
954
|
+
value: '',
|
|
955
|
+
type: 'purchase',
|
|
956
|
+
visible: true,
|
|
957
|
+
children: [
|
|
958
|
+
{
|
|
959
|
+
id: faker.database.mongodbObjectId(),
|
|
960
|
+
name: 'Filtrete™ Allergen Defense Furnace AC Air Filter 1000 MPR',
|
|
961
|
+
label: 'best',
|
|
962
|
+
description: '',
|
|
963
|
+
icon: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT50sebT9p-twQB-DdM2tlRo12In8F09QCsmg&s',
|
|
964
|
+
comments: 'Save 20% off Retail',
|
|
965
|
+
value: '$22.99',
|
|
966
|
+
type: 'purchase-product',
|
|
967
|
+
visible: true,
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
id: faker.database.mongodbObjectId(),
|
|
971
|
+
name: 'Filtrete™ Smart Allergen Bacteria & Virus Furnace AC Air Filter MPR 1500',
|
|
972
|
+
label: 'better',
|
|
973
|
+
description: '',
|
|
974
|
+
icon: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSbFpjG3kybZDb6psqPIlQSoXgp9OjOR672kg&s',
|
|
975
|
+
comments: 'Save 28% off Retail',
|
|
976
|
+
value: '$16.99',
|
|
977
|
+
type: 'purchase-product',
|
|
978
|
+
visible: true,
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
id: faker.database.mongodbObjectId(),
|
|
982
|
+
name: 'Filtrete™ 700 MPR Dust Pollen and Pet Dander Electrostatic Air Filter',
|
|
983
|
+
label: 'good',
|
|
984
|
+
description: '',
|
|
985
|
+
icon: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ7j1KYfPZqPnFmTgyx7b9pp78N6RForQfZFQ&s',
|
|
986
|
+
comments: 'Save 24% off Retail',
|
|
987
|
+
value: '$10.99',
|
|
988
|
+
type: 'purchase-product',
|
|
989
|
+
visible: true,
|
|
990
|
+
},
|
|
991
|
+
],
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
id: faker.database.mongodbObjectId(),
|
|
995
|
+
name: 'Hire out',
|
|
996
|
+
label: '',
|
|
997
|
+
description: faker.lorem.sentence(),
|
|
998
|
+
comments: faker.lorem.sentence(),
|
|
999
|
+
value: faker.image.urlPicsumPhotos(),
|
|
1000
|
+
type: 'hire-out',
|
|
1001
|
+
visible: true,
|
|
1002
|
+
children: [],
|
|
1003
|
+
},
|
|
948
1004
|
],
|
|
949
1005
|
},
|
|
950
1006
|
]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Meta } from '@storybook/react'
|
|
2
|
+
import { action } from '@storybook/addon-actions'
|
|
2
3
|
import { BackendAlert } from '@/components'
|
|
3
4
|
import { BackendAlertI } from '@/interfaces'
|
|
4
5
|
import { alertFieldsMock } from '@/mocks'
|
|
@@ -9,6 +10,7 @@ export default {
|
|
|
9
10
|
args: {
|
|
10
11
|
category: 'budget',
|
|
11
12
|
form: alertFieldsMock,
|
|
13
|
+
callback: action('onClick'),
|
|
12
14
|
},
|
|
13
15
|
} as Meta<BackendAlertI>
|
|
14
16
|
|