@widergy/utilitygo-smart-bill-web 3.11.0 → 3.13.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/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # [3.13.0](https://github.com/widergy/UtilityGO-Smart-Bill-Web/compare/v3.12.0...v3.13.0) (2025-09-29)
2
+
3
+
4
+ ### Features
5
+
6
+ * [CX-1171] widi fav smartbill ([#63](https://github.com/widergy/UtilityGO-Smart-Bill-Web/issues/63)) ([e1cc5ce](https://github.com/widergy/UtilityGO-Smart-Bill-Web/commit/e1cc5ceb238a6d5ef236fbeacd46ae2d8093e93c))
7
+
8
+ # [3.12.0](https://github.com/widergy/UtilityGO-Smart-Bill-Web/compare/v3.11.0...v3.12.0) (2025-08-27)
9
+
10
+
11
+ ### Features
12
+
13
+ * [EVEP-27] smartbill onboarding ([#62](https://github.com/widergy/UtilityGO-Smart-Bill-Web/issues/62)) ([d7bdeac](https://github.com/widergy/UtilityGO-Smart-Bill-Web/commit/d7bdeac4050d6ebf615a00a05eddae36de48fa07)), closes [#60](https://github.com/widergy/UtilityGO-Smart-Bill-Web/issues/60) [#60](https://github.com/widergy/UtilityGO-Smart-Bill-Web/issues/60) [#59](https://github.com/widergy/UtilityGO-Smart-Bill-Web/issues/59) [#59](https://github.com/widergy/UtilityGO-Smart-Bill-Web/issues/59)
14
+ * updates readme ([cc9caa2](https://github.com/widergy/UtilityGO-Smart-Bill-Web/commit/cc9caa29601d5052e9b260e057184f6f8d39d3c8))
15
+
1
16
  # [3.11.0](https://github.com/widergy/UtilityGO-Smart-Bill-Web/compare/v3.10.0...v3.11.0) (2025-08-25)
2
17
 
3
18
 
package/README.md CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  # react-package-bootstrap ![Logo](https://funkyimg.com/i/2VY6U.png)
2
3
 
3
4
  ![WidergyWeb](https://img.shields.io/badge/WIDERGY-WEB-00d564.svg)
@@ -18,6 +18,7 @@ const AIPanel = _ref => {
18
18
  aiQuestionsListError,
19
19
  aiQuestionsListLoading,
20
20
  answer,
21
+ colors = {},
21
22
  error,
22
23
  getAnswer,
23
24
  handlers = {},
@@ -92,7 +93,10 @@ const AIPanel = _ref => {
92
93
  key: id,
93
94
  onClick: () => toggleCard(id, question)
94
95
  }, renderAnswer ? /*#__PURE__*/_react.default.createElement("div", {
95
- className: `${_stylesModule.default.answer} ${errorContent && !isLoading ? notEnoughBills ? _stylesModule.default.notEnoughBillsContainer : _stylesModule.default.errorAnswer : ''}`
96
+ className: `${_stylesModule.default.answer} ${errorContent && !isLoading ? notEnoughBills ? _stylesModule.default.notEnoughBillsContainer : _stylesModule.default.errorAnswer : ''}`,
97
+ style: {
98
+ background: colors?.widyAnswerColorBg
99
+ }
96
100
  }, isLoading ? /*#__PURE__*/_react.default.createElement("section", null, /*#__PURE__*/_react.default.createElement(_reactLoadingSkeleton.default, {
97
101
  containerClassName: _stylesModule.default.skeletonContainer,
98
102
  count: 3,
@@ -135,6 +139,7 @@ AIPanel.propTypes = {
135
139
  aiQuestionsListLoading: _propTypes.bool,
136
140
  aiQuestionsListError: _propTypes.bool,
137
141
  answer: _propTypes.object,
142
+ colors: _propTypes.object,
138
143
  error: _propTypes.object,
139
144
  getAnswer: _propTypes.func,
140
145
  handlers: _propTypes.object,
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TAB_COMPONENT_MAPPER = exports.BIMESTRAL_PERIODICITY = void 0;
6
+ exports.TAB_VALUE_REGEX = exports.TAB_SELECTOR = exports.TAB_COMPONENT_MAPPER = exports.ONBOARDING_OPTIONS = exports.CAPTURED_VALUE_REGEX = exports.BIMESTRAL_PERIODICITY = void 0;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _tabs = require("../../shared/constants/tabs");
9
9
  var _Consumptions = _interopRequireDefault(require("./tabs/Consumptions"));
@@ -12,6 +12,17 @@ var _Billing = _interopRequireDefault(require("./tabs/Billing"));
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } /* eslint-disable react/prop-types */
14
14
  const BIMESTRAL_PERIODICITY = exports.BIMESTRAL_PERIODICITY = 'BIMESTRAL';
15
+ const TAB_SELECTOR = exports.TAB_SELECTOR = '[data-tab-value=';
16
+ const TAB_VALUE_REGEX = exports.TAB_VALUE_REGEX = /\[data-tab-value="([^"]+)"\]/;
17
+ const CAPTURED_VALUE_REGEX = exports.CAPTURED_VALUE_REGEX = 1;
18
+ const ONBOARDING_OPTIONS = exports.ONBOARDING_OPTIONS = {
19
+ overlayOpacity: 1,
20
+ positionPrecedence: ['top', 'left', 'bottom', 'right'],
21
+ scrollPadding: 5,
22
+ scrollTo: 'tooltip',
23
+ scrollToElement: false,
24
+ tooltipPosition: 'top'
25
+ };
15
26
  const renderComponentWithProps = (Component, tab) => props => /*#__PURE__*/_react.default.createElement(Component, _extends({}, props, {
16
27
  assets: props?.assets?.[tab] || {},
17
28
  translations: props?.translations?.[tab] || {}
@@ -23,10 +23,14 @@ const SmartBillSummary = _ref => {
23
23
  annex,
24
24
  assets,
25
25
  billingLayout,
26
- constants,
26
+ colors,
27
27
  components,
28
+ constants,
28
29
  handlers,
29
30
  loading,
31
+ showOnboarding = false,
32
+ onCloseOnboarding,
33
+ onboardingSteps,
30
34
  reverseRow,
31
35
  smartBill,
32
36
  tabOptions,
@@ -57,10 +61,37 @@ const SmartBillSummary = _ref => {
57
61
  trackAIFloatingButtonClick,
58
62
  trackTabChange
59
63
  } = handlers;
60
- const filteredTabOptions = loading ? [] : (0, _utils.getTabOptions)(isDesktopSize, tabOptions, smartBill);
61
- const defaultCurrentTab = (0, _utils.getDefaultCurrentTab)(filteredTabOptions);
64
+ const {
65
+ AIPanel: {
66
+ widyTooltipContent = ''
67
+ } = {}
68
+ } = translations || {};
69
+ const {
70
+ AIPanel: {
71
+ widyFab
72
+ } = {}
73
+ } = assets || {};
74
+ const {
75
+ tabs,
76
+ onboardingSteps: filteredOnboardingSteps
77
+ } = loading ? {
78
+ tabs: [],
79
+ onboardingSteps: []
80
+ } : (0, _utils.getTabOptions)(isDesktopSize, onboardingSteps, tabOptions, smartBill);
81
+ const defaultCurrentTab = (0, _utils.getDefaultCurrentTab)(tabs);
62
82
  const [currentTab, setCurrentTab] = (0, _react.useState)(defaultCurrentTab);
63
83
  const [aiPanelIsOpen, setAiPanelIsOpen] = (0, _react.useState)(false);
84
+ const [stableLoading, setStableLoading] = (0, _react.useState)(true);
85
+ (0, _react.useEffect)(() => {
86
+ if (loading) {
87
+ setStableLoading(true);
88
+ } else {
89
+ const timer = setTimeout(() => {
90
+ setStableLoading(false);
91
+ }, 200);
92
+ return () => clearTimeout(timer);
93
+ }
94
+ }, [loading]);
64
95
  const changeCurrentTab = newTab => setCurrentTab(newTab);
65
96
  const openAIPanel = () => {
66
97
  trackAIFloatingButtonClick();
@@ -82,25 +113,31 @@ const SmartBillSummary = _ref => {
82
113
  return /*#__PURE__*/_react.default.createElement(_energyUi.UTLoading, {
83
114
  className: _stylesModule.default.loadingContainer,
84
115
  loading: loading
116
+ }, /*#__PURE__*/_react.default.createElement("div", {
117
+ className: showOnboarding ? _stylesModule.default.tabs : ''
85
118
  }, /*#__PURE__*/_react.default.createElement(_energyUi.UTTabs, {
86
119
  classNames: {
87
120
  baseLabel: _stylesModule.default.tabLabel,
88
121
  baseSelected: _stylesModule.default.baseSelected,
89
- flexContainer: _stylesModule.default.tabsContainer
122
+ flexContainer: _stylesModule.default.tabsContainer,
123
+ tabRoot: 'smartbill-tab'
90
124
  },
91
125
  onChange: newTab => {
92
126
  trackTabChange(newTab);
93
127
  changeCurrentTab(newTab);
94
128
  },
95
- options: filteredTabOptions,
129
+ options: tabs.map(tab => ({
130
+ ...tab,
131
+ 'data-tab-value': tab.value
132
+ })),
96
133
  tabsProps: {
97
134
  orientation: 'horizontal',
98
135
  variant: 'fullWidth'
99
136
  },
100
137
  value: currentTab
101
- }), /*#__PURE__*/_react.default.createElement("div", {
138
+ })), /*#__PURE__*/_react.default.createElement("div", {
102
139
  className: _stylesModule.default.contentContainer
103
- }, filteredTabOptions.find(tab => tab.value === currentTab)?.header && /*#__PURE__*/_react.default.createElement(_BillHeader.default, {
140
+ }, tabs.find(tab => tab.value === currentTab)?.header && /*#__PURE__*/_react.default.createElement(_BillHeader.default, {
104
141
  annex,
105
142
  UtilityLogo: assets.billingTab.UtilityLogo,
106
143
  billNumber: smartBill.bill_number,
@@ -127,18 +164,25 @@ const SmartBillSummary = _ref => {
127
164
  smartBill,
128
165
  translations,
129
166
  utils
130
- })), aiQuestionsPanelEnabled && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_energyUi.UTTouchableWithoutFeedback, {
131
- className: _stylesModule.default.AIFloatButton,
132
- onClick: openAIPanel,
133
- withRipple: true
134
- }, /*#__PURE__*/_react.default.createElement(_energyUi.UTIcon, {
135
- colorTheme: "negative",
136
- name: "EnergyIconChatSparkFilled"
137
- })), /*#__PURE__*/_react.default.createElement(_AIPanel.default, {
167
+ })), aiQuestionsPanelEnabled && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_energyUi.UTTooltip, {
168
+ arrow: false,
169
+ content: isDesktopSize ? widyTooltipContent : '',
170
+ tippyProps: {
171
+ placement: 'left'
172
+ }
173
+ }, /*#__PURE__*/_react.default.createElement("div", {
174
+ className: `${_stylesModule.default.AIFloatButton} smartbill-ai-float-button`
175
+ }, /*#__PURE__*/_react.default.createElement(_energyUi.UTTouchableWithoutFeedback, {
176
+ onClick: openAIPanel
177
+ }, /*#__PURE__*/_react.default.createElement("img", {
178
+ alt: "widy",
179
+ src: widyFab
180
+ })))), /*#__PURE__*/_react.default.createElement(_AIPanel.default, {
138
181
  aiQuestionsList: aiQuestionsList,
139
182
  aiQuestionsListError: aiQuestionsListError,
140
183
  aiQuestionsListLoading: aiQuestionsListLoading,
141
184
  answer: smartBillAIAnswer,
185
+ colors: colors,
142
186
  error: smartBillAIAnswerError,
143
187
  getAnswer: getSmartBillAIAnswer,
144
188
  handlers: handlers,
@@ -147,20 +191,30 @@ const SmartBillSummary = _ref => {
147
191
  notEnoughBillsErrorType: notEnoughBillsErrorType,
148
192
  onClose: closeAIPanel,
149
193
  translations: translations
150
- })));
194
+ })), !stableLoading && showOnboarding && /*#__PURE__*/_react.default.createElement(_energyUi.UTOnboarding, {
195
+ options: _constants.ONBOARDING_OPTIONS,
196
+ enabled: showOnboarding,
197
+ handleComplete: onCloseOnboarding,
198
+ handleOnClose: onCloseOnboarding,
199
+ steps: filteredOnboardingSteps
200
+ }));
151
201
  };
152
202
  SmartBillSummary.propTypes = {
153
203
  annex: _propTypes.bool,
154
204
  assets: _propTypes.object,
155
205
  billingLayout: (0, _propTypes.arrayOf)(_propTypes.object),
156
- constants: _propTypes.object,
206
+ colors: _propTypes.object,
157
207
  components: (0, _propTypes.shape)({
158
208
  [_propTypes.string]: _propTypes.elementType
159
209
  }),
210
+ constants: _propTypes.object,
160
211
  handlers: (0, _propTypes.shape)({
161
212
  [_propTypes.string]: _propTypes.func
162
213
  }),
163
214
  loading: _propTypes.bool,
215
+ showOnboarding: _propTypes.bool,
216
+ onCloseOnboarding: _propTypes.func,
217
+ onboardingSteps: (0, _propTypes.arrayOf)(_propTypes.object),
164
218
  reverseRow: _propTypes.object,
165
219
  smartBill: _billDataTypes.billDataTypes,
166
220
  tabOptions: (0, _propTypes.arrayOf)((0, _propTypes.shape)({
@@ -12,6 +12,11 @@ $tab-height: 48px;
12
12
  }
13
13
  }
14
14
 
15
+ .tabs {
16
+ margin: 0 auto;
17
+ width: 96%;
18
+ }
19
+
15
20
  .contentContainer {
16
21
  flex: 1;
17
22
  margin: 0 auto;
@@ -49,12 +54,17 @@ $tab-height: 48px;
49
54
 
50
55
  .AIFloatButton {
51
56
  align-items: center;
52
- background-color: var(--actionAccent04);
53
- border-radius: 100px;
54
- bottom: 32px;
57
+ bottom: 20px;
55
58
  display: flex;
59
+ height: 78px;
56
60
  justify-content: center;
57
- padding: 16px;
58
61
  position: fixed;
59
- right: 32px;
62
+ right: 20px;
63
+ width: 78px;
64
+
65
+ img {
66
+ height: 78px;
67
+ object-fit: contain;
68
+ width: 78px;
69
+ }
60
70
  }
@@ -26,7 +26,7 @@ const Billing = _ref => {
26
26
  clarification,
27
27
  periodDetail
28
28
  } = texts?.billing || {};
29
- const currentPeriod = smartBill?.periods.find(period => period.current);
29
+ const currentPeriod = smartBill?.periods?.find(period => period.current);
30
30
  const billingsToShow = (0, _utils.getBillingsToShow)(currentPeriod?.settlements);
31
31
  return /*#__PURE__*/_react.default.createElement("div", {
32
32
  className: _stylesModule.default.container
@@ -6,13 +6,13 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getTabOptions = exports.getDefaultCurrentTab = void 0;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _energyUi = require("@widergy/energy-ui");
9
- var _lodash = require("lodash");
9
+ var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
10
10
  var _tabs = require("../../shared/constants/tabs");
11
11
  var _constants = require("./constants");
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
- const getTabOptions = (isDesktopSize, tabOptions, smartBill) => {
13
+ const getTabOptions = (isDesktopSize, onboardingSteps, tabOptions, smartBill) => {
14
14
  const hasBimestralPeriodicity = smartBill?.periods?.some(period => period.settlements?.periodicity === _constants.BIMESTRAL_PERIODICITY);
15
- return tabOptions.map(tab => ({
15
+ const filteredTabs = tabOptions.map(tab => ({
16
16
  ...tab,
17
17
  icon: isDesktopSize ? /*#__PURE__*/_react.default.createElement(_energyUi.UTIcon, {
18
18
  name: tab.icon
@@ -24,7 +24,33 @@ const getTabOptions = (isDesktopSize, tabOptions, smartBill) => {
24
24
  } = _ref;
25
25
  return enabled && (value !== _tabs.SMARTBILL_TABS.CONSUMPTIONS || hasBimestralPeriodicity);
26
26
  });
27
+ if (!(0, _isEmpty.default)(onboardingSteps)) {
28
+ const tabPositions = {};
29
+ filteredTabs.forEach((tab, index) => {
30
+ tabPositions[tab.value] = index + 1;
31
+ });
32
+ const filteredOnboardingSteps = [...onboardingSteps].reduce((acc, step) => {
33
+ if (step.element && step.element.includes(_constants.TAB_SELECTOR)) {
34
+ const match = step.element.match(_constants.TAB_VALUE_REGEX);
35
+ if (match && tabPositions[match[_constants.CAPTURED_VALUE_REGEX]]) {
36
+ return [...acc, {
37
+ ...step,
38
+ element: `.smartbill-tab:nth-child(${tabPositions[match[_constants.CAPTURED_VALUE_REGEX]]})`
39
+ }];
40
+ }
41
+ }
42
+ return [...acc, step];
43
+ }, []);
44
+ return {
45
+ tabs: filteredTabs,
46
+ onboardingSteps: filteredOnboardingSteps
47
+ };
48
+ }
49
+ return {
50
+ tabs: filteredTabs,
51
+ onboardingSteps
52
+ };
27
53
  };
28
54
  exports.getTabOptions = getTabOptions;
29
- const getDefaultCurrentTab = tabOptions => !(0, _lodash.isEmpty)(tabOptions) && (tabOptions.find(tab => tab?.defaultSelected) || tabOptions?.[0])?.value;
55
+ const getDefaultCurrentTab = tabOptions => !(0, _isEmpty.default)(tabOptions) && (tabOptions.find(tab => tab?.defaultSelected) || tabOptions?.[0])?.value;
30
56
  exports.getDefaultCurrentTab = getDefaultCurrentTab;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@widergy/utilitygo-smart-bill-web",
3
- "version": "3.11.0",
3
+ "version": "3.13.0",
4
4
  "description": "UtilityGO SmartBill Web",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",