@widergy/utilitygo-smart-bill-mobile 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-Mobile/compare/v3.5.0...v3.5.1) (2025-12-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* updates npm token ([4286fa0](https://github.com/widergy/UtilityGO-Smart-Bill-Mobile/commit/4286fa0d1ca078db19eea0589e7be615d01e79d6))
|
|
7
|
+
|
|
8
|
+
# [3.5.0](https://github.com/widergy/UtilityGO-Smart-Bill-Mobile/compare/v3.4.0...v3.5.0) (2025-12-03)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* [EVEP-52] onboarding ([#54](https://github.com/widergy/UtilityGO-Smart-Bill-Mobile/issues/54)) ([937db49](https://github.com/widergy/UtilityGO-Smart-Bill-Mobile/commit/937db4938f10e5f1de4e927585c0515cc6a4029f))
|
|
14
|
+
|
|
1
15
|
# [3.4.0](https://github.com/widergy/UtilityGO-Smart-Bill-Mobile/compare/v3.3.0...v3.4.0) (2025-11-07)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -19,3 +19,8 @@ export const TAB_COMPONENT_MAPPER = {
|
|
|
19
19
|
[SMARTBILL_TABS.BILLING]: renderComponentWithProps(Billing, SMARTBILL_TABS.BILLING),
|
|
20
20
|
[SMARTBILL_TABS.GLOSSARY]: renderComponentWithProps(Glossary, SMARTBILL_TABS.GLOSSARY)
|
|
21
21
|
};
|
|
22
|
+
|
|
23
|
+
export const CONSUMPTIONS_TAB = 'consumptionsTab';
|
|
24
|
+
export const BILLING_TAB = 'billingTab';
|
|
25
|
+
export const GLOSSARY_TAB = 'glossaryTab';
|
|
26
|
+
export const AI_BUTTON = 'aiButton';
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/* eslint-disable react/forbid-prop-types */
|
|
2
2
|
/* eslint-disable react/jsx-fragments */
|
|
3
|
-
import React, { Fragment, useEffect, useState, useMemo } from 'react';
|
|
3
|
+
import React, { Fragment, useEffect, useState, useMemo, useCallback } from 'react';
|
|
4
4
|
import { UTButton, UTLoading, UTTabs } from '@widergy/mobile-ui';
|
|
5
5
|
import { ScrollView, View } from 'react-native';
|
|
6
6
|
import { array, arrayOf, bool, func, object, shape, string } from 'prop-types';
|
|
7
7
|
import isEmpty from 'lodash/isEmpty';
|
|
8
8
|
import debounce from 'lodash/debounce';
|
|
9
9
|
|
|
10
|
-
import { TAB_COMPONENT_MAPPER } from './constants';
|
|
10
|
+
import { AI_BUTTON, BILLING_TAB, CONSUMPTIONS_TAB, GLOSSARY_TAB, TAB_COMPONENT_MAPPER } from './constants';
|
|
11
11
|
import { getDefaultCurrentTab, getTabOptions } from './utils';
|
|
12
|
-
import
|
|
12
|
+
import getStyles from './styles';
|
|
13
13
|
import AIDrawer from './components/AIDrawer';
|
|
14
14
|
import BillHeader from './tabs/Billing/components/BillHeader';
|
|
15
15
|
|
|
@@ -26,8 +26,10 @@ const SmartBillSummary = ({
|
|
|
26
26
|
tabOptions,
|
|
27
27
|
translations,
|
|
28
28
|
utils,
|
|
29
|
-
periodSpan
|
|
29
|
+
periodSpan,
|
|
30
|
+
walkthroughStep
|
|
30
31
|
}) => {
|
|
32
|
+
const styles = getStyles(colors);
|
|
31
33
|
const {
|
|
32
34
|
aiQuestionsList,
|
|
33
35
|
aiQuestionsListError,
|
|
@@ -84,6 +86,100 @@ const SmartBillSummary = ({
|
|
|
84
86
|
resetSmartBillAIAnswers();
|
|
85
87
|
};
|
|
86
88
|
|
|
89
|
+
const {
|
|
90
|
+
currentUserId,
|
|
91
|
+
LocalStorageService,
|
|
92
|
+
walkthroughEnabled,
|
|
93
|
+
useWalkthroughStep,
|
|
94
|
+
WalkthroughStep: WalkthroughComponent,
|
|
95
|
+
walkthroughSteps: walkthroughStepsConfig
|
|
96
|
+
} = walkthroughStep || {};
|
|
97
|
+
|
|
98
|
+
const OverlayComponent = useCallback(
|
|
99
|
+
props => {
|
|
100
|
+
if (isEmpty(walkthroughStepsConfig) || !WalkthroughComponent) return null;
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<WalkthroughComponent
|
|
104
|
+
{...props}
|
|
105
|
+
stepsConfig={walkthroughStepsConfig}
|
|
106
|
+
containerStyle={styles.tooltipContainer}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
},
|
|
110
|
+
[walkthroughStepsConfig, WalkthroughComponent, styles.tooltipContainer]
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const walkthroughStepNumber = name =>
|
|
114
|
+
(walkthroughStepsConfig?.steps.findIndex(step => step.name === name) ?? -1) + 1;
|
|
115
|
+
|
|
116
|
+
const {
|
|
117
|
+
onLayout: onLayoutTabBilling,
|
|
118
|
+
start,
|
|
119
|
+
isWalkthroughOn,
|
|
120
|
+
isVisible: isVisibleBillingTab
|
|
121
|
+
} = useWalkthroughStep({
|
|
122
|
+
number: walkthroughStepNumber(BILLING_TAB),
|
|
123
|
+
name: BILLING_TAB,
|
|
124
|
+
OverlayComponent
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const { onLayout: onLayoutTabConsumption, isVisible: isVisibleConsumptionTab } = useWalkthroughStep({
|
|
128
|
+
number: walkthroughStepNumber(CONSUMPTIONS_TAB),
|
|
129
|
+
name: CONSUMPTIONS_TAB,
|
|
130
|
+
OverlayComponent
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const { onLayout: onLayoutTabGlossary, isVisible: isVisibleGlossaryTab } = useWalkthroughStep({
|
|
134
|
+
number: walkthroughStepNumber(GLOSSARY_TAB),
|
|
135
|
+
name: GLOSSARY_TAB,
|
|
136
|
+
OverlayComponent
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const { onLayout: onLayoutAIButton, isVisible: isVisibleAIButton } = useWalkthroughStep({
|
|
140
|
+
number: walkthroughStepNumber(AI_BUTTON),
|
|
141
|
+
name: AI_BUTTON,
|
|
142
|
+
OverlayComponent
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const walkthroughLayouts = useMemo(
|
|
146
|
+
() => ({
|
|
147
|
+
billingTab: { onLayout: onLayoutTabBilling, isVisible: isVisibleBillingTab },
|
|
148
|
+
consumptionsTab: { onLayout: onLayoutTabConsumption, isVisible: isVisibleConsumptionTab },
|
|
149
|
+
glossaryTab: { onLayout: onLayoutTabGlossary, isVisible: isVisibleGlossaryTab }
|
|
150
|
+
}),
|
|
151
|
+
[
|
|
152
|
+
onLayoutTabBilling,
|
|
153
|
+
onLayoutTabConsumption,
|
|
154
|
+
onLayoutTabGlossary,
|
|
155
|
+
isVisibleBillingTab,
|
|
156
|
+
isVisibleConsumptionTab,
|
|
157
|
+
isVisibleGlossaryTab
|
|
158
|
+
]
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
const tabsWithWalkthrough = filteredTabOptions.map(tab => ({
|
|
162
|
+
...tab,
|
|
163
|
+
walkthrough: walkthroughLayouts[tab.value],
|
|
164
|
+
walkthroughStyle: [
|
|
165
|
+
isWalkthroughOn ? styles.borderContainer : null,
|
|
166
|
+
walkthroughLayouts[tab.value]?.isVisible ? styles.border : null
|
|
167
|
+
]
|
|
168
|
+
}));
|
|
169
|
+
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
const checkAndStartOnboarding = async () => {
|
|
172
|
+
const hasSeenOnboarding = await LocalStorageService.getSmartBillWalkthrough(currentUserId);
|
|
173
|
+
if (!isEmpty(smartBill) && walkthroughEnabled && hasSeenOnboarding !== 'true' && !isWalkthroughOn) {
|
|
174
|
+
start();
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
checkAndStartOnboarding();
|
|
179
|
+
|
|
180
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
181
|
+
}, [start, loading]);
|
|
182
|
+
|
|
87
183
|
useEffect(() => {
|
|
88
184
|
if (defaultCurrentTab && defaultCurrentTab !== currentTab) {
|
|
89
185
|
changeCurrentTab(defaultCurrentTab);
|
|
@@ -116,7 +212,7 @@ const SmartBillSummary = ({
|
|
|
116
212
|
key={tabsKey}
|
|
117
213
|
labelProps={{ weight: 'semibold' }}
|
|
118
214
|
onChange={onUserTabChange}
|
|
119
|
-
tabs={
|
|
215
|
+
tabs={tabsWithWalkthrough}
|
|
120
216
|
value={currentTab}
|
|
121
217
|
/>
|
|
122
218
|
<ScrollView>
|
|
@@ -153,12 +249,20 @@ const SmartBillSummary = ({
|
|
|
153
249
|
<FabComponent onPress={openAIDrawer} />
|
|
154
250
|
</View>
|
|
155
251
|
) : (
|
|
156
|
-
<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
252
|
+
<View
|
|
253
|
+
onLayout={onLayoutAIButton}
|
|
254
|
+
style={[
|
|
255
|
+
styles.AIContainer,
|
|
256
|
+
isWalkthroughOn && styles.borderContainerButton,
|
|
257
|
+
isVisibleAIButton && styles.border
|
|
258
|
+
]}>
|
|
259
|
+
<UTButton
|
|
260
|
+
colorTheme="primary"
|
|
261
|
+
Icon="EnergyIconChatSparkFilled"
|
|
262
|
+
onPress={openAIDrawer}
|
|
263
|
+
style={{ icon: styles.AIFloatButtonIcon, root: styles.AIFloatButton }}
|
|
264
|
+
/>
|
|
265
|
+
</View>
|
|
162
266
|
)}
|
|
163
267
|
|
|
164
268
|
<AIDrawer
|
|
@@ -204,7 +308,8 @@ SmartBillSummary.propTypes = {
|
|
|
204
308
|
),
|
|
205
309
|
translations: object,
|
|
206
310
|
utils: object,
|
|
207
|
-
periodSpan: string
|
|
311
|
+
periodSpan: string,
|
|
312
|
+
walkthroughStep: object
|
|
208
313
|
};
|
|
209
314
|
|
|
210
315
|
export default SmartBillSummary;
|
|
@@ -1,16 +1,35 @@
|
|
|
1
1
|
import { StyleSheet } from 'react-native';
|
|
2
2
|
|
|
3
|
-
export default
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
export default Colors =>
|
|
4
|
+
StyleSheet.create({
|
|
5
|
+
loading: {
|
|
6
|
+
flex: 1
|
|
7
|
+
},
|
|
8
|
+
AIFloatButton: {
|
|
9
|
+
borderRadius: 100
|
|
10
|
+
},
|
|
11
|
+
AIContainer: {
|
|
12
|
+
bottom: 16,
|
|
13
|
+
position: 'absolute',
|
|
14
|
+
right: 16
|
|
15
|
+
},
|
|
16
|
+
AIFloatButtonIcon: {
|
|
17
|
+
padding: 8
|
|
18
|
+
},
|
|
19
|
+
tooltipContainer: {
|
|
20
|
+
bottom: '40%',
|
|
21
|
+
left: '15%'
|
|
22
|
+
},
|
|
23
|
+
borderContainer: {
|
|
24
|
+
borderWidth: 4,
|
|
25
|
+
borderColor: 'transparent'
|
|
26
|
+
},
|
|
27
|
+
borderContainerButton: {
|
|
28
|
+
borderWidth: 4,
|
|
29
|
+
borderColor: 'transparent',
|
|
30
|
+
padding: 8
|
|
31
|
+
},
|
|
32
|
+
border: {
|
|
33
|
+
borderColor: Colors.semanticSuccess03
|
|
34
|
+
}
|
|
35
|
+
});
|