lib-pixelbuild 0.1.4 → 0.2.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/README.md +102 -127
- package/dist/builders/PageBuilder.d.ts +3 -2
- package/dist/builders/PageBuilder.js +41 -33
- package/dist/components/CardComponent.d.ts +3 -3
- package/dist/components/CardComponent.js +65 -41
- package/dist/components/FormComponent.d.ts +3 -3
- package/dist/components/FormComponent.js +8 -14
- package/dist/components/ListComponent.d.ts +3 -2
- package/dist/components/ListComponent.js +20 -15
- package/dist/components/LoadingComponent.js +1 -1
- package/dist/components/MapComponent.js +18 -4
- package/dist/components/SliderComponent.js +59 -15
- package/dist/components/SocialIconsComponent.js +1 -1
- package/dist/components/TextComponent.d.ts +3 -3
- package/dist/components/TextComponent.js +6 -7
- package/dist/elements/AlertElement.js +4 -3
- package/dist/elements/ButtonElement.js +19 -17
- package/dist/elements/IconElement.d.ts +1 -2
- package/dist/elements/IconElement.js +8 -9
- package/dist/elements/IconMap.d.ts +2 -0
- package/dist/elements/IconMap.js +30 -0
- package/dist/elements/InputElement.js +16 -16
- package/dist/factories/ButtonActionFactory.d.ts +6 -1
- package/dist/factories/ButtonActionFactory.js +14 -4
- package/dist/index.d.ts +2 -6
- package/dist/index.js +1 -4
- package/dist/layouts/Header.d.ts +2 -1
- package/dist/layouts/Header.js +33 -5
- package/dist/layouts/SiteLayout.d.ts +2 -1
- package/dist/layouts/SiteLayout.js +2 -2
- package/dist/renderers/SectionRenderer.d.ts +3 -3
- package/dist/renderers/SectionRenderer.js +45 -29
- package/dist/services/EmailService.d.ts +10 -2
- package/dist/services/EmailService.js +25 -25
- package/dist/types/RawWebsiteType.d.ts +8 -184
- package/dist/utils/InputValidators.js +11 -11
- package/dist/utils/propertyUtils.d.ts +3 -0
- package/dist/utils/propertyUtils.js +28 -0
- package/package.json +32 -19
- package/dist/elements/FileElement.d.ts +0 -4
- package/dist/elements/FileElement.js +0 -6
- package/dist/services/ApiService.d.ts +0 -5
- package/dist/services/ApiService.js +0 -17
- package/dist/services/CacheService.d.ts +0 -5
- package/dist/services/CacheService.js +0 -16
- package/dist/services/ConstructorService.d.ts +0 -12
- package/dist/services/ConstructorService.js +0 -33
- package/dist/types/AuthenticateResponseType.d.ts +0 -5
- package/dist/types/AuthenticateResponseType.js +0 -1
- package/dist/types/ButtonPropertiesType.d.ts +0 -11
- package/dist/types/ButtonPropertiesType.js +0 -1
- package/dist/types/FilePropertiesType.d.ts +0 -4
- package/dist/types/FilePropertiesType.js +0 -1
- package/dist/types/ImagePropertiesType.d.ts +0 -4
- package/dist/types/ImagePropertiesType.js +0 -1
- package/dist/types/InputPropertiesType.d.ts +0 -7
- package/dist/types/InputPropertiesType.js +0 -1
- package/dist/types/LinkPropertiesType.d.ts +0 -4
- package/dist/types/LinkPropertiesType.js +0 -1
- package/dist/types/PlanWebsiteType.d.ts +0 -9
- package/dist/types/PlanWebsiteType.js +0 -1
- package/dist/types/UserType.d.ts +0 -10
- package/dist/types/UserType.js +0 -1
|
@@ -1,14 +1,3 @@
|
|
|
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
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
2
|
import { useEffect, useState } from 'react';
|
|
14
3
|
import { useKeenSlider } from 'keen-slider/react.js';
|
|
@@ -17,8 +6,8 @@ import { orderBySort } from '../utils/orderBySort.js';
|
|
|
17
6
|
import 'keen-slider/keen-slider.min.css';
|
|
18
7
|
const elementFactory = new ElementFactory();
|
|
19
8
|
function cleanComponentStyles(styles) {
|
|
20
|
-
const
|
|
21
|
-
return
|
|
9
|
+
const exclude = new Set(['minHeight', 'display', 'alignItems', 'justifyContent', 'flexDirection']);
|
|
10
|
+
return Object.fromEntries(Object.entries(styles).filter(([key]) => !exclude.has(key)));
|
|
22
11
|
}
|
|
23
12
|
function StaticSliderComponent({ component }) {
|
|
24
13
|
const firstSlide = orderBySort(component.elements)[0];
|
|
@@ -46,7 +35,7 @@ function InteractiveSliderComponent({ component }) {
|
|
|
46
35
|
if (!properties.autoplay || slides.length < 2)
|
|
47
36
|
return;
|
|
48
37
|
const interval = Number(properties.interval) > 0 ? Number(properties.interval) : 5000;
|
|
49
|
-
const timer = window.setInterval(() => { var
|
|
38
|
+
const timer = window.setInterval(() => { var _a; return (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.moveToIdx(instanceRef.current.track.details.rel + 1); }, interval);
|
|
50
39
|
return () => window.clearInterval(timer);
|
|
51
40
|
}, [instanceRef, properties.autoplay, properties.interval, slides.length]);
|
|
52
41
|
const fixedHeight = Number(properties.height) > 0 ? Number(properties.height) : 0;
|
|
@@ -56,7 +45,62 @@ function InteractiveSliderComponent({ component }) {
|
|
|
56
45
|
return (_jsxs("div", { style: Object.assign({ position: 'relative' }, cleanComponentStyles(component.styles)), children: [_jsx("div", { ref: ref, className: "keen-slider", style: fixedHeight ? { height: fixedHeight } : undefined, children: slides.map((element) => (_jsx("div", { className: "keen-slider__slide", style: { overflow: 'hidden' }, children: elementFactory.build(Object.assign(Object.assign({}, element), { styles: element.elementType === 'image' || element.elementType === 'video'
|
|
57
46
|
? fixedHeight
|
|
58
47
|
? Object.assign({ width: '100%', height: '100%', objectFit: 'cover' }, element.styles) : Object.assign({ width: '100%' }, element.styles)
|
|
59
|
-
: element.styles })) }, element.id))) }), showArrows && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", "aria-label": "Slide anterior", onClick: () => { var
|
|
48
|
+
: element.styles })) }, element.id))) }), showArrows && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", "aria-label": "Slide anterior", onClick: () => { var _a; return (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.moveToIdx(instanceRef.current.track.details.rel - 1); }, style: {
|
|
49
|
+
position: 'absolute',
|
|
50
|
+
left: 8,
|
|
51
|
+
top: '50%',
|
|
52
|
+
transform: 'translateY(-50%)',
|
|
53
|
+
zIndex: 10,
|
|
54
|
+
width: 40,
|
|
55
|
+
height: 40,
|
|
56
|
+
borderRadius: '50%',
|
|
57
|
+
border: 'none',
|
|
58
|
+
background: 'rgba(0,0,0,0.45)',
|
|
59
|
+
color: '#fff',
|
|
60
|
+
fontSize: 18,
|
|
61
|
+
fontWeight: 700,
|
|
62
|
+
lineHeight: 1,
|
|
63
|
+
cursor: 'pointer',
|
|
64
|
+
display: 'flex',
|
|
65
|
+
alignItems: 'center',
|
|
66
|
+
justifyContent: 'center',
|
|
67
|
+
transition: 'background 0.2s',
|
|
68
|
+
}, children: _jsx("svg", { width: "10", height: "16", viewBox: "0 0 10 16", fill: "none", children: _jsx("path", { d: "M8.5 1L1.5 8L8.5 15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), _jsx("button", { type: "button", "aria-label": "Proximo slide", onClick: () => { var _a; return (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.moveToIdx(instanceRef.current.track.details.rel + 1); }, style: {
|
|
69
|
+
position: 'absolute',
|
|
70
|
+
right: 8,
|
|
71
|
+
top: '50%',
|
|
72
|
+
transform: 'translateY(-50%)',
|
|
73
|
+
zIndex: 10,
|
|
74
|
+
width: 40,
|
|
75
|
+
height: 40,
|
|
76
|
+
borderRadius: '50%',
|
|
77
|
+
border: 'none',
|
|
78
|
+
background: 'rgba(0,0,0,0.45)',
|
|
79
|
+
color: '#fff',
|
|
80
|
+
fontSize: 18,
|
|
81
|
+
fontWeight: 700,
|
|
82
|
+
lineHeight: 1,
|
|
83
|
+
cursor: 'pointer',
|
|
84
|
+
display: 'flex',
|
|
85
|
+
alignItems: 'center',
|
|
86
|
+
justifyContent: 'center',
|
|
87
|
+
transition: 'background 0.2s',
|
|
88
|
+
}, children: _jsx("svg", { width: "10", height: "16", viewBox: "0 0 10 16", fill: "none", children: _jsx("path", { d: "M1.5 1L8.5 8L1.5 15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })), showDots && (_jsx("div", { "aria-label": "Navegacao do slider", style: { display: 'flex', justifyContent: 'center', gap: 6, marginTop: 12 }, children: slides.map((element, index) => (_jsx("button", { type: "button", "aria-label": `Ir para o slide ${index + 1}`, "aria-current": currentSlide === index ? 'true' : undefined, onClick: () => { var _a; return (_a = instanceRef.current) === null || _a === void 0 ? void 0 : _a.moveToIdx(index); }, style: {
|
|
89
|
+
width: 28,
|
|
90
|
+
height: 28,
|
|
91
|
+
borderRadius: '50%',
|
|
92
|
+
border: 'none',
|
|
93
|
+
background: currentSlide === index ? '#333' : 'rgba(0,0,0,0.15)',
|
|
94
|
+
color: currentSlide === index ? '#fff' : '#666',
|
|
95
|
+
fontSize: 12,
|
|
96
|
+
fontWeight: 600,
|
|
97
|
+
lineHeight: 1,
|
|
98
|
+
cursor: 'pointer',
|
|
99
|
+
display: 'flex',
|
|
100
|
+
alignItems: 'center',
|
|
101
|
+
justifyContent: 'center',
|
|
102
|
+
transition: 'all 0.2s',
|
|
103
|
+
}, children: index + 1 }, element.id))) }))] }));
|
|
60
104
|
}
|
|
61
105
|
export function SliderComponent({ component, editionMode = false }) {
|
|
62
106
|
if (editionMode)
|
|
@@ -15,5 +15,5 @@ export function SocialIconsComponent({ social }) {
|
|
|
15
15
|
}
|
|
16
16
|
if (all.length === 0)
|
|
17
17
|
return null;
|
|
18
|
-
return (_jsx(Row, { children: all.map((element) => (_jsx(Col, { className: "text-center social-icons", style: { color: '#FFCC00' }, children: _jsx("a", { href: element.url, target: "_blank", rel: "noreferrer", "aria-label": element.description, children: _jsx(element.icon, {}) }) }, element.id))) }));
|
|
18
|
+
return (_jsx(Row, { children: all.map((element) => (_jsx(Col, { className: "text-center social-icons", style: { color: '#FFCC00' }, children: _jsx("a", { href: element.url, target: "_blank", rel: "noopener noreferrer", "aria-label": element.description, children: _jsx(element.icon, {}) }) }, element.id))) }));
|
|
19
19
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import type { ComponentType } from '../types/ComponentType.js';
|
|
3
|
-
|
|
2
|
+
declare const TextComponent: import("react").NamedExoticComponent<{
|
|
4
3
|
readonly component: ComponentType;
|
|
5
|
-
}
|
|
4
|
+
}>;
|
|
5
|
+
export { TextComponent };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import { memo, useMemo } from 'react';
|
|
3
3
|
import { Row, Container } from 'react-bootstrap';
|
|
4
4
|
import { ElementFactory } from '../factories/ElementFactory.js';
|
|
5
5
|
import { orderBySort } from '../utils/orderBySort.js';
|
|
6
6
|
const elementFactory = new ElementFactory();
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
7
|
+
const TextComponent = memo(function TextComponent({ component }) {
|
|
8
|
+
const elements = useMemo(() => orderBySort(component.elements), [component.elements]);
|
|
9
|
+
return (_jsx(Container, { style: component.styles, children: _jsx(Row, { id: "element-row", children: elements.map((element) => elementFactory.build(element)) }) }));
|
|
10
|
+
});
|
|
11
|
+
export { TextComponent };
|
|
@@ -3,20 +3,21 @@ import { useEffect } from 'react';
|
|
|
3
3
|
import { Alert } from 'react-bootstrap';
|
|
4
4
|
import { UseFormStore } from '../stores/UseFormStore.js';
|
|
5
5
|
import { ElementColWrapper } from './ElementColWrapper.js';
|
|
6
|
+
import { getString, getNumber, getBoolean } from '../utils/propertyUtils.js';
|
|
6
7
|
export function AlertElement({ element, formId }) {
|
|
7
8
|
const properties = element.properties;
|
|
8
|
-
const resolvedFormId = formId !== null && formId !== void 0 ? formId : properties
|
|
9
|
+
const resolvedFormId = formId !== null && formId !== void 0 ? formId : getNumber(properties, 'componentId');
|
|
9
10
|
const hidden = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.hidden; });
|
|
10
11
|
const registerElement = UseFormStore((state) => state.registerElement);
|
|
11
12
|
const unregisterElement = UseFormStore((state) => state.unregisterElement);
|
|
12
13
|
useEffect(() => {
|
|
13
14
|
registerElement(element.id, resolvedFormId, {
|
|
14
15
|
type: 'alert',
|
|
15
|
-
hidden:
|
|
16
|
+
hidden: getBoolean(properties, 'startHidden')
|
|
16
17
|
});
|
|
17
18
|
return () => unregisterElement(element.id);
|
|
18
19
|
}, [element.id, properties.startHidden, registerElement, resolvedFormId, unregisterElement]);
|
|
19
20
|
if (hidden)
|
|
20
21
|
return null;
|
|
21
|
-
return (_jsx(ElementColWrapper, { element: element, children: _jsxs(Alert, {
|
|
22
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsxs(Alert, { variant: getString(properties, 'type', 'info'), style: element.styles, children: [_jsx(Alert.Heading, { children: getString(properties, 'title') }), _jsx("p", { className: "mb-0", children: getString(properties, 'message') })] }) }));
|
|
22
23
|
}
|
|
@@ -3,11 +3,11 @@ import { useEffect } from 'react';
|
|
|
3
3
|
import { Button, Spinner } from 'react-bootstrap';
|
|
4
4
|
import { ElementColWrapper } from './ElementColWrapper.js';
|
|
5
5
|
import { UseFormStore } from '../stores/UseFormStore.js';
|
|
6
|
-
import {
|
|
6
|
+
import { buttonActionFactory } from '../factories/ButtonActionFactory.js';
|
|
7
|
+
import { getString, getNumber, getBoolean } from '../utils/propertyUtils.js';
|
|
7
8
|
export function ButtonElement({ element, formId }) {
|
|
8
|
-
var _a;
|
|
9
9
|
const properties = element.properties;
|
|
10
|
-
const resolvedFormId = formId !== null && formId !== void 0 ? formId : properties
|
|
10
|
+
const resolvedFormId = formId !== null && formId !== void 0 ? formId : getNumber(properties, 'componentId');
|
|
11
11
|
const hidden = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.hidden; });
|
|
12
12
|
const loading = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.loading; });
|
|
13
13
|
const showElement = UseFormStore((state) => state.showElement);
|
|
@@ -17,7 +17,7 @@ export function ButtonElement({ element, formId }) {
|
|
|
17
17
|
useEffect(() => {
|
|
18
18
|
registerElement(element.id, resolvedFormId, {
|
|
19
19
|
type: 'button',
|
|
20
|
-
hidden:
|
|
20
|
+
hidden: getBoolean(properties, 'startHidden')
|
|
21
21
|
});
|
|
22
22
|
return () => unregisterElement(element.id);
|
|
23
23
|
}, [element.id, properties.startHidden, registerElement, resolvedFormId, unregisterElement]);
|
|
@@ -35,25 +35,27 @@ export function ButtonElement({ element, formId }) {
|
|
|
35
35
|
if (hasErrors)
|
|
36
36
|
return false;
|
|
37
37
|
UseFormStore.getState().setElementState(element.id, { loading: true });
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
await buttonActionFactory.build(
|
|
38
|
+
const actionId = getNumber(properties, 'actionId');
|
|
39
|
+
if (actionId) {
|
|
40
|
+
await buttonActionFactory.build(actionId, formData);
|
|
41
41
|
}
|
|
42
|
+
const loadingTime = (_a = getNumber(properties, 'loadingTime')) !== null && _a !== void 0 ? _a : 0;
|
|
42
43
|
setTimeout(() => {
|
|
43
|
-
if (properties
|
|
44
|
+
if (getBoolean(properties, 'hideOnClick'))
|
|
44
45
|
hideElement(element.id);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
showElement(
|
|
46
|
+
const successMessageId = getNumber(properties, 'successMessageId');
|
|
47
|
+
const successActionId = getNumber(properties, 'successActionId');
|
|
48
|
+
if (successMessageId)
|
|
49
|
+
showElement(successMessageId);
|
|
50
|
+
if (successActionId)
|
|
51
|
+
showElement(successActionId);
|
|
49
52
|
UseFormStore.getState().setElementState(element.id, { loading: false });
|
|
50
|
-
},
|
|
53
|
+
}, loadingTime);
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
if (hidden)
|
|
54
57
|
return null;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
: properties.type || 'primary')), href: String(properties.path || ''), target: properties.path ? '_blank' : undefined, rel: properties.path ? 'noopener noreferrer' : undefined, disabled: loading, onClick: handleClick, style: element.styles, children: loading ? (_jsxs(_Fragment, { children: [_jsx("output", { "aria-busy": "true", children: _jsx(Spinner, { as: "span", animation: "border", size: "sm", "aria-hidden": "true" }) }), ' ' + (String((_a = properties.message) !== null && _a !== void 0 ? _a : ''))] })) : (String(properties.text || properties.title || '')) }) }));
|
|
58
|
+
const buttonType = properties.type === 'button' || properties.type === 'submit' || properties.type === 'reset'
|
|
59
|
+
? properties.type : undefined;
|
|
60
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsx(Button, { as: properties.path ? 'a' : 'button', type: buttonType, variant: getString(properties, 'variant', buttonType ? 'primary' : getString(properties, 'type', 'primary')), href: getString(properties, 'path'), target: properties.path ? '_blank' : undefined, rel: properties.path ? 'noopener noreferrer' : undefined, disabled: loading, onClick: handleClick, style: element.styles, children: loading ? (_jsxs(_Fragment, { children: [_jsx("output", { "aria-busy": "true", children: _jsx(Spinner, { as: "span", animation: "border", size: "sm", "aria-hidden": "true" }) }), ' ' + getString(properties, 'message')] })) : (getString(properties, 'text') || getString(properties, 'title')) }) }));
|
|
59
61
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Suspense, useMemo } from 'react';
|
|
3
|
+
import { iconMap } from './IconMap.js';
|
|
3
4
|
import { ElementColWrapper } from './ElementColWrapper.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
FaTwitter, FaUser, FaWhatsapp, FaYoutube,
|
|
9
|
-
};
|
|
5
|
+
function FallbackIcon({ name }) {
|
|
6
|
+
const Icon = iconMap[name] || iconMap.FaQuestionCircle;
|
|
7
|
+
return _jsx(Icon, { size: "1em", "aria-label": name || 'Icon' });
|
|
8
|
+
}
|
|
10
9
|
export function IconElement({ element }) {
|
|
11
10
|
var _a;
|
|
12
11
|
const name = String(element.properties.name || '');
|
|
13
|
-
const Icon = icons[name] || FaQuestionCircle;
|
|
14
12
|
const iconSize = ((_a = element.styles) === null || _a === void 0 ? void 0 : _a.fontSize) || '1.25rem';
|
|
15
|
-
|
|
13
|
+
const Icon = useMemo(() => iconMap[name] || iconMap.FaQuestionCircle, [name]);
|
|
14
|
+
return (_jsx(ElementColWrapper, { element: element, children: _jsx("span", { style: { fontSize: iconSize, display: 'inline-flex' }, children: _jsx(Suspense, { fallback: _jsx(FallbackIcon, { name: name }), children: _jsx(Icon, { size: "1em", style: element.styles, "aria-label": name || 'Icon' }) }) }) }));
|
|
16
15
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FaArrowRight, FaBars, FaCalendar, FaCheck, FaChevronLeft, FaChevronRight, FaClock, FaEnvelope, FaFacebookF, FaGlobe, FaHeart, FaHome, FaInfoCircle, FaInstagram, FaLink, FaMapMarkerAlt, FaPhone, FaQuestionCircle, FaQuoteLeft, FaSearch, FaShoppingCart, FaStar, FaTimes, FaTwitter, FaUser, FaWhatsapp, FaYoutube, } from 'react-icons/fa';
|
|
2
|
+
export const iconMap = {
|
|
3
|
+
FaArrowRight,
|
|
4
|
+
FaBars,
|
|
5
|
+
FaCalendar,
|
|
6
|
+
FaCheck,
|
|
7
|
+
FaChevronLeft,
|
|
8
|
+
FaChevronRight,
|
|
9
|
+
FaClock,
|
|
10
|
+
FaEnvelope,
|
|
11
|
+
FaFacebookF,
|
|
12
|
+
FaGlobe,
|
|
13
|
+
FaHeart,
|
|
14
|
+
FaHome,
|
|
15
|
+
FaInfoCircle,
|
|
16
|
+
FaInstagram,
|
|
17
|
+
FaLink,
|
|
18
|
+
FaMapMarkerAlt,
|
|
19
|
+
FaPhone,
|
|
20
|
+
FaQuestionCircle,
|
|
21
|
+
FaQuoteLeft,
|
|
22
|
+
FaSearch,
|
|
23
|
+
FaShoppingCart,
|
|
24
|
+
FaStar,
|
|
25
|
+
FaTimes,
|
|
26
|
+
FaTwitter,
|
|
27
|
+
FaUser,
|
|
28
|
+
FaWhatsapp,
|
|
29
|
+
FaYoutube,
|
|
30
|
+
};
|
|
@@ -5,9 +5,10 @@ import { IMaskInput } from 'react-imask';
|
|
|
5
5
|
import { ElementColWrapper } from './ElementColWrapper.js';
|
|
6
6
|
import { UseFormStore } from '../stores/UseFormStore.js';
|
|
7
7
|
import { ElementTypeEnum } from '../constants/ElementEnum.js';
|
|
8
|
+
import { getString, getNumber, getBoolean } from '../utils/propertyUtils.js';
|
|
8
9
|
export function InputElement({ element, formId }) {
|
|
9
10
|
const properties = element.properties;
|
|
10
|
-
const resolvedFormId = formId !== null && formId !== void 0 ? formId : properties
|
|
11
|
+
const resolvedFormId = formId !== null && formId !== void 0 ? formId : getNumber(properties, 'componentId');
|
|
11
12
|
const hidden = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.hidden; });
|
|
12
13
|
const error = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.error; });
|
|
13
14
|
const errorMessage = UseFormStore((state) => { var _a; return (_a = state.elements[element.id]) === null || _a === void 0 ? void 0 : _a.errorMessage; });
|
|
@@ -15,12 +16,12 @@ export function InputElement({ element, formId }) {
|
|
|
15
16
|
const unregisterElement = UseFormStore((state) => state.unregisterElement);
|
|
16
17
|
const validateFormData = UseFormStore((state) => state.validateFormData);
|
|
17
18
|
useEffect(() => {
|
|
18
|
-
var _a
|
|
19
|
+
var _a;
|
|
19
20
|
registerElement(element.id, resolvedFormId, {
|
|
20
|
-
name:
|
|
21
|
+
name: getString(properties, 'name'),
|
|
21
22
|
type: element.elementType,
|
|
22
|
-
value: properties
|
|
23
|
-
inputValidateId: (
|
|
23
|
+
value: getBoolean(properties, 'checked') ? getString(properties, 'value', 'on') : getString(properties, 'value'),
|
|
24
|
+
inputValidateId: (_a = getNumber(properties, 'inputValidateId')) !== null && _a !== void 0 ? _a : null
|
|
24
25
|
});
|
|
25
26
|
return () => unregisterElement(element.id);
|
|
26
27
|
}, [
|
|
@@ -37,10 +38,10 @@ export function InputElement({ element, formId }) {
|
|
|
37
38
|
if (hidden)
|
|
38
39
|
return null;
|
|
39
40
|
const hasMask = element.elementType === ElementTypeEnum.Input && Boolean(properties.mask);
|
|
40
|
-
const label =
|
|
41
|
-
const name =
|
|
41
|
+
const label = getString(properties, 'label') || getString(properties, 'title');
|
|
42
|
+
const name = getString(properties, 'name');
|
|
42
43
|
const controlId = name || `element-${element.id}`;
|
|
43
|
-
const inputValidateId = properties
|
|
44
|
+
const inputValidateId = getNumber(properties, 'inputValidateId');
|
|
44
45
|
const options = Array.isArray(properties.options) ? properties.options : [];
|
|
45
46
|
const handleAccept = (value) => {
|
|
46
47
|
UseFormStore.getState().setElementState(element.id, { value });
|
|
@@ -65,12 +66,11 @@ export function InputElement({ element, formId }) {
|
|
|
65
66
|
store.setElementState(element.id, { value: checked ? value : '' });
|
|
66
67
|
};
|
|
67
68
|
const renderControl = () => {
|
|
68
|
-
var _a, _b, _c, _d, _e;
|
|
69
69
|
if (element.elementType === ElementTypeEnum.Textarea) {
|
|
70
|
-
return (_jsx("textarea", { defaultValue:
|
|
70
|
+
return (_jsx("textarea", { defaultValue: getString(properties, 'value'), rows: getNumber(properties, 'rows') || 4, onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `form-control${error ? ' is-invalid' : ''}`, style: element.styles }));
|
|
71
71
|
}
|
|
72
72
|
if (element.elementType === ElementTypeEnum.Select) {
|
|
73
|
-
return (_jsx("select", { defaultValue:
|
|
73
|
+
return (_jsx("select", { defaultValue: getString(properties, 'value'), onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, className: `form-select${error ? ' is-invalid' : ''}`, style: element.styles, children: options.map((option, index) => {
|
|
74
74
|
var _a, _b, _c, _d;
|
|
75
75
|
const data = typeof option === 'object' && option !== null ? option : null;
|
|
76
76
|
const value = String((_a = data === null || data === void 0 ? void 0 : data.value) !== null && _a !== void 0 ? _a : option);
|
|
@@ -79,16 +79,16 @@ export function InputElement({ element, formId }) {
|
|
|
79
79
|
}) }));
|
|
80
80
|
}
|
|
81
81
|
if (element.elementType === ElementTypeEnum.Checkbox || element.elementType === ElementTypeEnum.Radio) {
|
|
82
|
-
const value =
|
|
83
|
-
return (_jsxs("div", { className: "form-check", children: [_jsx("input", { id: controlId, type: element.elementType, defaultChecked:
|
|
82
|
+
const value = getString(properties, 'value', 'on');
|
|
83
|
+
return (_jsxs("div", { className: "form-check", children: [_jsx("input", { id: controlId, type: element.elementType, defaultChecked: getBoolean(properties, 'checked'), value: value, onChange: (e) => setCheckedValue(e.target.checked, value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, className: `form-check-input${error ? ' is-invalid' : ''}`, style: element.styles }), label && _jsx("label", { className: "form-check-label", htmlFor: controlId, children: label })] }));
|
|
84
84
|
}
|
|
85
85
|
if (element.elementType === ElementTypeEnum.File) {
|
|
86
|
-
return (_jsx("div", { className: "alert alert-secondary", role: "status", style: element.styles, children: "
|
|
86
|
+
return (_jsx("div", { className: "alert alert-secondary", role: "status", style: element.styles, children: "File upload not available in this form." }));
|
|
87
87
|
}
|
|
88
88
|
if (hasMask) {
|
|
89
|
-
return (_jsx(IMaskInput, { mask:
|
|
89
|
+
return (_jsx(IMaskInput, { mask: getString(properties, 'mask'), defaultValue: getString(properties, 'value'), onAccept: handleAccept, onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `form-control${error ? ' is-invalid' : ''}`, style: element.styles }));
|
|
90
90
|
}
|
|
91
|
-
return (_jsx("input", { type:
|
|
91
|
+
return (_jsx("input", { type: getString(properties, 'type', 'text'), defaultValue: getString(properties, 'value'), onChange: (e) => setValue(e.target.value), onBlur: handleBlur, required: getBoolean(properties, 'required'), name: name, placeholder: getString(properties, 'placeholder'), className: `form-control${error ? ' is-invalid' : ''}`, style: element.styles }));
|
|
92
92
|
};
|
|
93
93
|
return (_jsx(ElementColWrapper, { element: element, children: _jsxs(Form.Group, { className: "mb-3", controlId: controlId, children: [label && element.elementType !== ElementTypeEnum.Checkbox && element.elementType !== ElementTypeEnum.Radio && (_jsx(Form.Label, { children: label })), renderControl(), error && (_jsx("div", { className: "invalid-feedback", style: { display: 'block' }, children: errorMessage }))] }) }));
|
|
94
94
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
import { type EmailServiceConfig } from '../services/EmailService.js';
|
|
1
2
|
import type { FormFieldsType } from '../types/FormFieldsType.js';
|
|
2
3
|
import type { MailBodyType } from '../types/MailBodyType.js';
|
|
3
|
-
|
|
4
|
+
declare class ButtonActionFactory {
|
|
5
|
+
private emailService;
|
|
6
|
+
configureEmail(config: EmailServiceConfig): void;
|
|
4
7
|
build(actionId: number, data: FormFieldsType[]): Promise<MailBodyType | boolean>;
|
|
5
8
|
}
|
|
9
|
+
export declare const buttonActionFactory: ButtonActionFactory;
|
|
10
|
+
export type { EmailServiceConfig } from '../services/EmailService.js';
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { EmailService } from '../services/EmailService.js';
|
|
2
2
|
import { ButtonActionEnum } from '../constants/ButtonActionEnum.js';
|
|
3
|
-
|
|
3
|
+
class ButtonActionFactory {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.emailService = null;
|
|
6
|
+
}
|
|
7
|
+
configureEmail(config) {
|
|
8
|
+
this.emailService = new EmailService(config);
|
|
9
|
+
}
|
|
4
10
|
async build(actionId, data) {
|
|
5
|
-
const emailService = new EmailService('https://api.example.com');
|
|
6
11
|
switch (actionId) {
|
|
7
|
-
case ButtonActionEnum.SendMail:
|
|
8
|
-
|
|
12
|
+
case ButtonActionEnum.SendMail: {
|
|
13
|
+
if (!this.emailService) {
|
|
14
|
+
throw new Error('EmailService not configured. Call configureEmail() before using SendMail action.');
|
|
15
|
+
}
|
|
16
|
+
return this.emailService.sendMail(data);
|
|
17
|
+
}
|
|
9
18
|
default:
|
|
10
19
|
throw new Error('Invalid button action: ' + actionId);
|
|
11
20
|
}
|
|
12
21
|
}
|
|
13
22
|
}
|
|
23
|
+
export const buttonActionFactory = new ButtonActionFactory();
|
package/dist/index.d.ts
CHANGED
|
@@ -8,8 +8,6 @@ export type { ComponentType } from './types/ComponentType.js';
|
|
|
8
8
|
export type { ElementType } from './types/ElementType.js';
|
|
9
9
|
export type { PropertiesType } from './types/PropertiesType.js';
|
|
10
10
|
export type { StylesType } from './types/StylesType.js';
|
|
11
|
-
export type { UserType } from './types/UserType.js';
|
|
12
|
-
export type { AuthenticateResponseType } from './types/AuthenticateResponseType.js';
|
|
13
11
|
export { Header } from './layouts/Header.js';
|
|
14
12
|
export { Footer } from './layouts/Footer.js';
|
|
15
13
|
export { SiteLayout } from './layouts/SiteLayout.js';
|
|
@@ -20,8 +18,6 @@ export { ComponentFactory } from './factories/ComponentFactory.js';
|
|
|
20
18
|
export { ElementFactory } from './factories/ElementFactory.js';
|
|
21
19
|
export { ComponentTypeEnum } from './constants/ComponentEnum.js';
|
|
22
20
|
export { ElementTypeEnum } from './constants/ElementEnum.js';
|
|
23
|
-
export { ApiService } from './services/ApiService.js';
|
|
24
21
|
export { analyticsService } from './services/AnalyticsService.js';
|
|
25
|
-
export {
|
|
26
|
-
export {
|
|
27
|
-
export { EmailService } from './services/EmailService.js';
|
|
22
|
+
export { buttonActionFactory } from './factories/ButtonActionFactory.js';
|
|
23
|
+
export type { EmailServiceConfig } from './services/EmailService.js';
|
package/dist/index.js
CHANGED
|
@@ -8,8 +8,5 @@ export { ComponentFactory } from './factories/ComponentFactory.js';
|
|
|
8
8
|
export { ElementFactory } from './factories/ElementFactory.js';
|
|
9
9
|
export { ComponentTypeEnum } from './constants/ComponentEnum.js';
|
|
10
10
|
export { ElementTypeEnum } from './constants/ElementEnum.js';
|
|
11
|
-
export { ApiService } from './services/ApiService.js';
|
|
12
11
|
export { analyticsService } from './services/AnalyticsService.js';
|
|
13
|
-
export {
|
|
14
|
-
export { ConstructorService } from './services/ConstructorService.js';
|
|
15
|
-
export { EmailService } from './services/EmailService.js';
|
|
12
|
+
export { buttonActionFactory } from './factories/ButtonActionFactory.js';
|
package/dist/layouts/Header.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WebsiteType } from '../types/WebsiteType.js';
|
|
2
|
-
export declare function Header({ website }: {
|
|
2
|
+
export declare function Header({ website, imageBaseUrl }: {
|
|
3
3
|
readonly website: WebsiteType;
|
|
4
|
+
readonly imageBaseUrl?: string;
|
|
4
5
|
}): import("react").JSX.Element;
|
package/dist/layouts/Header.js
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useCallback } from 'react';
|
|
3
|
+
import { useLocation } from 'react-router-dom';
|
|
4
|
+
import { Container, Navbar, Nav } from 'react-bootstrap';
|
|
5
|
+
export function Header({ website, imageBaseUrl }) {
|
|
4
6
|
const headerProperties = website.header.properties;
|
|
5
7
|
const headerStyles = website.header.styles;
|
|
6
|
-
const domain = website.domain.replaceAll('.', '');
|
|
7
|
-
|
|
8
|
+
const domain = (website.domain || '').replaceAll('.', '');
|
|
9
|
+
const location = useLocation();
|
|
10
|
+
const menuPages = useMemo(() => (website.pages || [])
|
|
11
|
+
.filter((p) => p.menu === true)
|
|
12
|
+
.sort((a, b) => (a.menuOrder || 0) - (b.menuOrder || 0)), [website.pages]);
|
|
13
|
+
const isActive = useCallback((path) => {
|
|
14
|
+
const currentPath = location.pathname;
|
|
15
|
+
if (path === '/')
|
|
16
|
+
return currentPath === '/' || currentPath === '';
|
|
17
|
+
return currentPath === path || currentPath.startsWith(path + '/');
|
|
18
|
+
}, [location.pathname]);
|
|
19
|
+
const showMenu = headerProperties.showMenu !== false && menuPages.length > 0;
|
|
20
|
+
const logoUrl = useMemo(() => imageBaseUrl
|
|
21
|
+
? `${imageBaseUrl.replace(/\/+$/, '')}/${domain}/${website.logo}`
|
|
22
|
+
: `https://noisdev-website-images.s3.sa-east-1.amazonaws.com/${domain}/${website.logo}`, [imageBaseUrl, domain, website.logo]);
|
|
23
|
+
return (_jsx(Navbar, { expand: "lg", collapseOnSelect: true, className: "py-3", style: { backgroundColor: headerStyles.backgroundColor || undefined, width: '100%' }, children: _jsxs(Container, { fluid: headerStyles.fluid || undefined, children: [headerProperties.showLogo && (_jsx(Navbar.Brand, { style: { marginRight: showMenu ? 'auto' : 0, padding: 0 }, children: _jsx("img", { src: logoUrl, width: "200", className: "d-inline-block align-top", alt: "Logo" }) })), showMenu && (_jsxs(_Fragment, { children: [_jsx(Navbar.Toggle, { "aria-controls": "header-navbar-nav" }), _jsx(Navbar.Collapse, { id: "header-navbar-nav", children: _jsx(Nav, { className: `mx-auto ${headerProperties.showLogo ? '' : 'w-100 justify-content-center'}`, children: menuPages.map((p) => {
|
|
24
|
+
const active = isActive(p.path);
|
|
25
|
+
return (_jsx(Nav.Link, { href: p.path, style: {
|
|
26
|
+
color: active ? '#c0ad5b' : '#a4a4a4',
|
|
27
|
+
fontSize: '0.9rem',
|
|
28
|
+
letterSpacing: '0.05em',
|
|
29
|
+
textTransform: 'uppercase',
|
|
30
|
+
margin: '0 12px',
|
|
31
|
+
paddingBottom: '4px',
|
|
32
|
+
borderBottom: active ? '2px solid #c0ad5b' : '2px solid transparent',
|
|
33
|
+
transition: 'color 0.3s, border-color 0.3s',
|
|
34
|
+
}, children: p.title }, p.id));
|
|
35
|
+
}) }) })] }))] }) }));
|
|
8
36
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WebsiteType } from '../types/WebsiteType.js';
|
|
2
|
-
export declare function SiteLayout({ website }: {
|
|
2
|
+
export declare function SiteLayout({ website, imageBaseUrl }: {
|
|
3
3
|
readonly website: WebsiteType;
|
|
4
|
+
readonly imageBaseUrl?: string;
|
|
4
5
|
}): import("react").JSX.Element;
|
|
@@ -2,6 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Outlet } from 'react-router-dom';
|
|
3
3
|
import { Header } from './Header.js';
|
|
4
4
|
import { Footer } from './Footer.js';
|
|
5
|
-
export function SiteLayout({ website }) {
|
|
6
|
-
return (_jsxs("div", { id: "site-layout", style: { backgroundColor: website.styles.backgroundColor, color: website.styles.color }, children: [_jsx(Header, { website: website }), _jsx(Outlet, {}), _jsx(Footer, { website: website })] }));
|
|
5
|
+
export function SiteLayout({ website, imageBaseUrl }) {
|
|
6
|
+
return (_jsxs("div", { id: "site-layout", style: { backgroundColor: website.styles.backgroundColor, color: website.styles.color }, children: [_jsx(Header, { website: website, imageBaseUrl: imageBaseUrl }), _jsx(Outlet, {}), _jsx(Footer, { website: website })] }));
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import type { SectionType } from '../types/SectionType.js';
|
|
3
|
-
|
|
2
|
+
declare const SectionRenderer: import("react").NamedExoticComponent<{
|
|
4
3
|
readonly sections: SectionType[];
|
|
5
4
|
readonly editionMode?: boolean;
|
|
6
|
-
}
|
|
5
|
+
}>;
|
|
6
|
+
export { SectionRenderer };
|