@widergy/utilitygo-smart-bill-web 3.4.0 → 3.5.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [3.5.1](https://github.com/widergy/UtilityGO-Smart-Bill-Web/compare/v3.5.0...v3.5.1) (2025-04-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * download bill icon smartbill ([#47](https://github.com/widergy/UtilityGO-Smart-Bill-Web/issues/47)) ([d10ec3c](https://github.com/widergy/UtilityGO-Smart-Bill-Web/commit/d10ec3cb2930dafe5df11361158eb78fc4ffc505))
7
+
8
+ # [3.5.0](https://github.com/widergy/UtilityGO-Smart-Bill-Web/compare/v3.4.0...v3.5.0) (2025-04-21)
9
+
10
+
11
+ ### Features
12
+
13
+ * [CX-245] smartbill ai panel ([#45](https://github.com/widergy/UtilityGO-Smart-Bill-Web/issues/45)) ([e321c69](https://github.com/widergy/UtilityGO-Smart-Bill-Web/commit/e321c694ba59000740a049325f59661f46510e22))
14
+
1
15
  # [3.4.0](https://github.com/widergy/UtilityGO-Smart-Bill-Web/compare/v3.3.0...v3.4.0) (2025-03-25)
2
16
 
3
17
 
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _energyUi = require("@widergy/energy-ui");
9
+ var _propTypes = require("prop-types");
10
+ var _i18next = _interopRequireDefault(require("i18next"));
11
+ var _reactLoadingSkeleton = _interopRequireDefault(require("react-loading-skeleton"));
12
+ var _stylesModule = _interopRequireDefault(require("./styles.module.scss"));
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
15
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
16
+ const AIPanel = _ref => {
17
+ let {
18
+ aiQuestionsList,
19
+ answer,
20
+ error,
21
+ getAnswer,
22
+ isOpen,
23
+ loading,
24
+ notEnoughBillsErrorType,
25
+ onClose
26
+ } = _ref;
27
+ const [openCards, setOpenCards] = (0, _react.useState)([]);
28
+ const toggleCard = id => {
29
+ if (!answer?.[id] && !openCards.includes(id)) {
30
+ getAnswer(id);
31
+ }
32
+ setOpenCards(prevOpenCards => prevOpenCards.includes(id) ? prevOpenCards.filter(openId => openId !== id) : [...prevOpenCards, id]);
33
+ };
34
+ const handleClose = () => {
35
+ onClose?.();
36
+ setOpenCards([]);
37
+ };
38
+ return /*#__PURE__*/_react.default.createElement(_energyUi.UTPanel, {
39
+ classes: {
40
+ paper: _stylesModule.default.paper,
41
+ perfectScrollbar: _stylesModule.default.panelScrollbar
42
+ },
43
+ onClose: handleClose,
44
+ open: isOpen,
45
+ panelSide: "right"
46
+ }, /*#__PURE__*/_react.default.createElement("div", {
47
+ className: _stylesModule.default.container
48
+ }, /*#__PURE__*/_react.default.createElement(_energyUi.UTLabel, {
49
+ weight: "medium",
50
+ variant: "title2"
51
+ }, _i18next.default.t('IAPanel:title')), /*#__PURE__*/_react.default.createElement("div", {
52
+ className: _stylesModule.default.questionsContainer
53
+ }, aiQuestionsList.map(_ref2 => {
54
+ let {
55
+ id,
56
+ title
57
+ } = _ref2;
58
+ const isLoading = loading?.[id];
59
+ const errorContent = error?.[id];
60
+ const answerContent = answer?.[id];
61
+ const renderAnswer = isLoading || errorContent || answerContent;
62
+ const notEnoughBills = errorContent?.errorType === notEnoughBillsErrorType;
63
+ const notEnoughBillsContent = errorContent?.error;
64
+ return /*#__PURE__*/_react.default.createElement(_energyUi.UTCard, {
65
+ classNames: {
66
+ base: _stylesModule.default.card,
67
+ expandableContent: _stylesModule.default.expandableContent,
68
+ expandableContentActive: _stylesModule.default.activeCard
69
+ },
70
+ header: title,
71
+ isCollapsible: true,
72
+ isOpen: openCards.includes(id),
73
+ key: id,
74
+ onClick: () => toggleCard(id)
75
+ }, renderAnswer ? /*#__PURE__*/_react.default.createElement("div", {
76
+ className: `${_stylesModule.default.answer} ${errorContent && !isLoading ? notEnoughBills ? _stylesModule.default.notEnoughBillsContainer : _stylesModule.default.errorAnswer : ''}`
77
+ }, isLoading ? /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactLoadingSkeleton.default, {
78
+ containerClassName: _stylesModule.default.skeletonContainer,
79
+ count: 3,
80
+ height: 22
81
+ }), /*#__PURE__*/_react.default.createElement("div", {
82
+ className: _stylesModule.default.generatedByLabel
83
+ }, /*#__PURE__*/_react.default.createElement(_energyUi.UTLabel, {
84
+ colorTheme: "gray",
85
+ variant: "small"
86
+ }, "Generado con AI"), /*#__PURE__*/_react.default.createElement(_energyUi.UTIcon, {
87
+ colorTheme: "neutral",
88
+ name: "IconSparkles",
89
+ size: 18
90
+ }))) : errorContent ? /*#__PURE__*/_react.default.createElement("div", {
91
+ className: _stylesModule.default.errorCard
92
+ }, /*#__PURE__*/_react.default.createElement(_energyUi.UTIcon, {
93
+ colorTheme: notEnoughBills ? 'gray' : 'error',
94
+ name: notEnoughBills ? 'IconFileX' : 'IconCircleX',
95
+ shade: "04"
96
+ }), /*#__PURE__*/_react.default.createElement(_energyUi.UTLabel, null, notEnoughBills ? notEnoughBillsContent : errorContent)) : answerContent ? /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_energyUi.UTLabel, {
97
+ withMarkdown: true
98
+ }, answerContent), /*#__PURE__*/_react.default.createElement("div", {
99
+ className: _stylesModule.default.generatedByLabel
100
+ }, /*#__PURE__*/_react.default.createElement(_energyUi.UTLabel, {
101
+ colorTheme: "gray",
102
+ variant: "small"
103
+ }, "Generado con AI"), /*#__PURE__*/_react.default.createElement(_energyUi.UTIcon, {
104
+ colorTheme: "neutral",
105
+ name: "IconSparkles",
106
+ size: 18
107
+ }))) : null) : null);
108
+ }))));
109
+ };
110
+ AIPanel.propTypes = {
111
+ aiQuestionsList: (0, _propTypes.arrayOf)((0, _propTypes.shape)({
112
+ id: _propTypes.string,
113
+ title: _propTypes.string
114
+ })),
115
+ answer: _propTypes.object,
116
+ error: _propTypes.object,
117
+ getAnswer: _propTypes.func,
118
+ isOpen: _propTypes.bool,
119
+ loading: _propTypes.object,
120
+ notEnoughBillsErrorType: _propTypes.string,
121
+ onClose: _propTypes.func
122
+ };
123
+ var _default = exports.default = AIPanel;
@@ -0,0 +1,82 @@
1
+ $ia-panel-width: 600px;
2
+
3
+ .paper {
4
+ height: 100%;
5
+ max-width: 100%;
6
+ padding: 0;
7
+ width: $ia-panel-width;
8
+ }
9
+
10
+ .panelScrollbar {
11
+ display: contents;
12
+ margin: 0;
13
+ }
14
+
15
+ .container {
16
+ display: flex;
17
+ flex-direction: column;
18
+ grid-gap: 24px;
19
+ height: 100%;
20
+ padding: 8px 24px;
21
+ }
22
+
23
+ .questionsContainer {
24
+ display: flex;
25
+ flex-direction: column;
26
+ grid-gap: 12px;
27
+ }
28
+
29
+ .card {
30
+ background-color: var(--light01);
31
+ border: none;
32
+ border-radius: 8px;
33
+ box-shadow: var(--shadowGrayBottom1);
34
+ padding: 12px 16px;
35
+ }
36
+
37
+ .expandableContent {
38
+ margin: 0 -16px 0;
39
+ }
40
+
41
+ .activeCard {
42
+ border-top: 1px solid var(--light04);
43
+ margin: 12px -16px 0 !important;
44
+ padding: 24px 0 12px;
45
+ }
46
+
47
+ .answer {
48
+ background-color: var(--semanticInformation01);
49
+ border-radius: 8px;
50
+ margin: 0 16px;
51
+ padding: 8px 12px;
52
+ }
53
+
54
+ .errorAnswer {
55
+ background-color: var(--semanticError01);
56
+ }
57
+
58
+ .notEnoughBillsContainer {
59
+ background-color: var(--light02);
60
+ }
61
+
62
+ .skeletonContainer {
63
+ span {
64
+ margin: 4px 0;
65
+ }
66
+
67
+ span:nth-child(5) {
68
+ width: 50%;
69
+ }
70
+ }
71
+
72
+ .generatedByLabel {
73
+ align-items: center;
74
+ display: flex;
75
+ grid-gap: 8px;
76
+ margin-top: 4px;
77
+ }
78
+
79
+ .errorCard {
80
+ display: flex;
81
+ grid-gap: 8px;
82
+ }
@@ -10,6 +10,7 @@ var _propTypes = require("prop-types");
10
10
  var _billDataTypes = require("../../shared/types/billDataTypes");
11
11
  var _constants = require("./constants");
12
12
  var _utils = require("./utils");
13
+ var _AIPanel = _interopRequireDefault(require("./components/AIPanel"));
13
14
  var _stylesModule = _interopRequireDefault(require("./styles.module.scss"));
14
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
16
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -32,10 +33,27 @@ const SmartBillSummary = _ref => {
32
33
  translations,
33
34
  utils
34
35
  } = _ref;
36
+ const {
37
+ aiQuestionsList,
38
+ notEnoughBillsErrorType,
39
+ smartBillAIAnswer = {},
40
+ smartBillAIAnswerError,
41
+ smartBillAIAnswerLoading
42
+ } = constants;
43
+ const {
44
+ getSmartBillAIAnswer,
45
+ resetSmartBillAIAnswers
46
+ } = handlers;
35
47
  const filteredTabOptions = loading ? [] : (0, _utils.getTabOptions)(tabOptions, smartBill);
36
48
  const defaultCurrentTab = (0, _utils.getDefaultCurrentTab)(filteredTabOptions);
37
49
  const [currentTab, setCurrentTab] = (0, _react.useState)(defaultCurrentTab);
50
+ const [aiPanelIsOpen, setAiPanelIsOpen] = (0, _react.useState)(false);
38
51
  const changeCurrentTab = newTab => setCurrentTab(newTab);
52
+ const openAIPanel = () => setAiPanelIsOpen(true);
53
+ const closeAIPanel = () => {
54
+ setAiPanelIsOpen(false);
55
+ resetSmartBillAIAnswers();
56
+ };
39
57
  (0, _react.useEffect)(() => {
40
58
  if (defaultCurrentTab) changeCurrentTab(defaultCurrentTab);
41
59
  }, [defaultCurrentTab]);
@@ -72,7 +90,23 @@ const SmartBillSummary = _ref => {
72
90
  smartBill,
73
91
  translations,
74
92
  utils
75
- })));
93
+ })), /*#__PURE__*/_react.default.createElement(_energyUi.UTTouchableWithoutFeedback, {
94
+ className: _stylesModule.default.AIFloatButton,
95
+ onClick: openAIPanel,
96
+ withRipple: true
97
+ }, /*#__PURE__*/_react.default.createElement(_energyUi.UTIcon, {
98
+ colorTheme: "negative",
99
+ name: "EnergyIconChatSparkFilled"
100
+ })), /*#__PURE__*/_react.default.createElement(_AIPanel.default, {
101
+ aiQuestionsList: aiQuestionsList,
102
+ answer: smartBillAIAnswer,
103
+ error: smartBillAIAnswerError,
104
+ getAnswer: getSmartBillAIAnswer,
105
+ isOpen: aiPanelIsOpen,
106
+ loading: smartBillAIAnswerLoading,
107
+ notEnoughBillsErrorType: notEnoughBillsErrorType,
108
+ onClose: closeAIPanel
109
+ }));
76
110
  };
77
111
  SmartBillSummary.propTypes = {
78
112
  assets: _propTypes.object,
@@ -46,3 +46,15 @@ $tab-height: 48px;
46
46
  justify-content: center;
47
47
  width: 100%;
48
48
  }
49
+
50
+ .AIFloatButton {
51
+ align-items: center;
52
+ background-color: var(--actionAccent04);
53
+ border-radius: 100px;
54
+ bottom: 32px;
55
+ display: flex;
56
+ justify-content: center;
57
+ padding: 16px;
58
+ position: fixed;
59
+ right: 32px;
60
+ }
@@ -127,7 +127,7 @@ const Billing = _ref => {
127
127
  showStatus: true,
128
128
  title: automaticDebitTitle
129
129
  }, {
130
- leftIcon: 'IconInfoCircle',
130
+ leftIcon: 'IconReceipt2',
131
131
  leftIconProps: {
132
132
  area: true,
133
133
  size: 28
@@ -11,7 +11,7 @@ require("dayjs/locale/es");
11
11
  var _constants = require("./constants");
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  _dayjs.default.locale('es');
14
- const getMaxValue = consumptionData => Math.max(...consumptionData.map(d => d.consumptions?.[0]?.value || 0));
14
+ const getMaxValue = consumptionData => Math.max(...consumptionData.map(d => d?.consumptions?.[0]?.value || 0));
15
15
  exports.getMaxValue = getMaxValue;
16
16
  const getBarHeight = (maxValue, value) => {
17
17
  const adjustedValue = value ** _constants.SCALE_FACTOR;
@@ -15,7 +15,7 @@ const getConsumptionPeriodsToCompare = function () {
15
15
  if (!(0, _lodash.isEmpty)(periods)) {
16
16
  const currentPeriod = periods.find(period => period.current);
17
17
  const previousYearPeriod = periods.find(period => period.number === currentPeriod.number && parseInt(period.year, 10) === parseInt(currentPeriod.year, 10) - 1);
18
- return [currentPeriod, previousYearPeriod];
18
+ return [currentPeriod, previousYearPeriod].filter(Boolean);
19
19
  }
20
20
  };
21
21
  exports.getConsumptionPeriodsToCompare = getConsumptionPeriodsToCompare;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@widergy/utilitygo-smart-bill-web",
3
- "version": "3.4.0",
3
+ "version": "3.5.1",
4
4
  "description": "UtilityGO SmartBill Web",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -62,6 +62,7 @@
62
62
  "node-sass": "^8.0.0",
63
63
  "numeral": ">=2.0.6",
64
64
  "react-jss": "^8.6.1",
65
+ "react-loading-skeleton": "^3.3.1",
65
66
  "react-perfect-scrollbar": "^1.5.3",
66
67
  "react-responsive": "^4.1.0",
67
68
  "sass-loader": "^10.0.5",