@ledvance/group-ui-biz-bundle 1.0.72 → 1.0.73

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.
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import ECharts from '@ledvance/react-native-echarts-pro';
4
+ import I18n from "@ledvance/base/src/i18n";
5
+
6
+ const BarChartWithTouch = ({ data, height, width }) => {
7
+ const dataX = data?.map(item => { return item.chartTitle });
8
+ const dataY = data?.map(item => { return item.value });
9
+ const option = {
10
+ title: {
11
+ text: I18n.getLang('consumption_data_annual_bar_chart_text'),
12
+ textStyle: {
13
+ fontSize: 14,
14
+ color: "#666666",
15
+ },
16
+ top: 10,
17
+ },
18
+ tooltip: {
19
+ show: false,
20
+ },
21
+ grid: {
22
+ width,
23
+ right: "20%",
24
+ left: '10%'
25
+ },
26
+ xAxis: {
27
+ data: dataX,
28
+ axisTick: {
29
+ show: false
30
+ },
31
+ axisLabel: {
32
+ show: true,
33
+ color: '#999999',
34
+ interval: 0,
35
+ }
36
+ },
37
+ yAxis: {
38
+ min: data?.length === 0 && 0.6 || 0
39
+ },
40
+ series: [
41
+ {
42
+ type: 'bar',
43
+ data: dataY,
44
+ itemStyle: {
45
+ emphasis: {
46
+ color: '#FF6600', // Color when bar is clicked
47
+ },
48
+ color: '#FFC2A9',
49
+ borderRadius: 2
50
+ },
51
+ barMaxWidth: 10,
52
+ label: {
53
+ show: false, // 开启显示
54
+ position: 'top', // 在上方显示
55
+ distance: 10, // 距离图形元素的距离。当 position 为字符描述值(如 'top'、'insideRight')时候有效。
56
+ verticalAlign: 'middle',
57
+ textStyle: { // 数值样式
58
+ color: 'black',
59
+ fontSize: 12
60
+ },
61
+ },
62
+ select: {
63
+ label: {
64
+ show: true,
65
+ align: "center",
66
+ verticalAlign: "bottom"
67
+ },
68
+ itemStyle: {
69
+ borderColor: '#FFC2A9'
70
+ }
71
+ },
72
+ selectedMode: "single"
73
+ },
74
+ ],
75
+ dataZoom: {
76
+ start: 0,
77
+ type: "inside",
78
+ maxValueSpan: 5
79
+ },
80
+ customMapData: {}
81
+ };
82
+
83
+ return (
84
+ <View style={{ flex: 1 }}>
85
+ <ECharts
86
+ option={option}
87
+ height={height}
88
+ />
89
+ </View>
90
+ );
91
+ };
92
+
93
+ export default BarChartWithTouch;
@@ -0,0 +1,285 @@
1
+ import React from "react";
2
+ import Card from "@ledvance/base/src/components/Card";
3
+ import Spacer from "@ledvance/base/src/components/Spacer";
4
+ import TextFieldStyleButton from "@ledvance/base/src/components/TextFieldStyleButton";
5
+ import I18n from "@ledvance/base/src/i18n";
6
+ import res from "@ledvance/base/src/res";
7
+ import { TouchableOpacity, View, Text, TextInput, StyleSheet, Linking, FlatList, Image, ScrollView } from "react-native";
8
+ import { Utils, Modal, Popup } from "tuya-panel-kit";
9
+ import { useReactive, useUpdateEffect } from "ahooks";
10
+ import { cloneDeep } from "lodash";
11
+
12
+ const { convertX: cx, height } = Utils.RatioUtils
13
+ const { withTheme } = Utils.ThemeUtils
14
+
15
+ export const UnitList = [
16
+ I18n.getLang('consumption_data_price_per_kwh_currency_value1'),
17
+ I18n.getLang('consumption_data_price_per_kwh_currency_value2'),
18
+ I18n.getLang('consumption_data_price_per_kwh_currency_value3'),
19
+ I18n.getLang('consumption_data_price_per_kwh_currency_value4')
20
+ ]
21
+
22
+ export interface EnergyData {
23
+ price: string
24
+ unit: string
25
+ }
26
+ interface EnergyModalProps {
27
+ theme?: any
28
+ visible: boolean
29
+ popupType: 'money' | 'co2' | 'unit'
30
+ title: string
31
+ confirmText?: string
32
+ cancelText?: string
33
+ energyData?: EnergyData
34
+ motionType?: 'none'
35
+ onConfirm?: (data?: EnergyData) => void
36
+ onCancel?: () => void
37
+ }
38
+ const EnergyModal = (props: EnergyModalProps) => {
39
+ const state = useReactive({
40
+ energyData: cloneDeep(props.energyData),
41
+ unitPopup: false
42
+ })
43
+ console.log('running ~~~~~')
44
+
45
+ const openLink = (url: string) => {
46
+ Linking.openURL(url).catch((error) => console.error('无法打开链接:', error));
47
+ };
48
+
49
+ const getDescription = (string: string) => {
50
+ const separators = /[.:]/;
51
+ const text = string.split(separators)
52
+ const length = text.length - 1
53
+ return <View>
54
+ <Text style={{ color: props.theme.global.fontColor }}>{text[length - 6] + '.'}</Text>
55
+ <Spacer />
56
+ <Text style={{ color: props.theme.global.fontColor }}>{text[length - 5] + '.'}</Text>
57
+ <Spacer />
58
+ <Text style={{ color: props.theme.global.fontColor }}>{text[length - 4] + text[length - 3] + ':'}</Text>
59
+ <Spacer />
60
+ <Text
61
+ style={{ textDecorationLine: 'underline', color: props.theme.button.active }}
62
+ onPress={() => openLink(`${text[length - 2]}:${text[length - 1]}${text[length]}`)}
63
+ >
64
+ {`${text[length - 2]}:${text[length - 1]}${text[length]}`}
65
+ </Text>
66
+ </View>
67
+ }
68
+
69
+ useUpdateEffect(() =>{
70
+ state.energyData = cloneDeep(props.energyData)
71
+ }, [props.energyData])
72
+
73
+ const styles = StyleSheet.create({
74
+ popupTip: {
75
+ fontSize: cx(16),
76
+ color: props.theme.global.fontColor,
77
+ fontWeight: 'bold'
78
+ },
79
+ textInput: {
80
+ flex: 1,
81
+ height: cx(44),
82
+ marginStart: cx(16),
83
+ marginEnd: cx(6),
84
+ fontSize: cx(16),
85
+ color: props.theme.textInput.fontColor,
86
+ fontFamily: 'helvetica_neue_lt_std_roman',
87
+ },
88
+ textInputGroup: {
89
+ flexDirection: 'row',
90
+ borderRadius: cx(4),
91
+ backgroundColor: props.theme.textInput.background,
92
+ alignItems: 'center',
93
+ },
94
+ iconTouchable: {
95
+ marginEnd: cx(18),
96
+ padding: cx(4),
97
+ },
98
+ line: {
99
+ height: 1,
100
+ position: 'absolute',
101
+ start: cx(4),
102
+ end: cx(4),
103
+ bottom: 0,
104
+ backgroundColor: props.theme.textInput.line,
105
+ },
106
+ unitItem: {
107
+ flexDirection: 'row',
108
+ justifyContent: 'space-between',
109
+ paddingHorizontal: cx(10),
110
+ alignItems: 'center',
111
+ height: cx(40),
112
+
113
+ }
114
+ })
115
+
116
+ const getContent = () => {
117
+ if (props.popupType === 'money') {
118
+ return (
119
+ <View>
120
+ <Spacer />
121
+ <Text style={styles.popupTip}>{I18n.getLang('consumption_data_price_per_kwh_headline_text')}</Text>
122
+ <Spacer height={cx(40)} />
123
+ <Text style={{ fontSize: cx(14), color: props.theme.global.fontColor }}>{I18n.getLang('consumption_data_price_per_kwh_description_text')}</Text>
124
+ <Spacer height={cx(15)} />
125
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
126
+ <View style={{ flex: 3 }}>
127
+ <Spacer height={cx(4)} />
128
+ <Text style={{ color: props.theme.global.secondFontColor, marginStart: cx(13), fontFamily: 'helvetica_neue_lt_std_bd' }}>{I18n.getLang('consumption_data_price_per_kwh_headline_text')}</Text>
129
+ <View style={styles.textInputGroup}>
130
+ <TextInput
131
+ value={state.energyData?.price}
132
+ onChangeText={(t: string) => {
133
+ const value = t.replace(/[^0-9.,]/g, '')
134
+ if (Number(value) > 999999) {
135
+ if (state.energyData) state.energyData.price = '999999'
136
+ } else {
137
+ if (state.energyData) state.energyData.price = value
138
+ }
139
+ }}
140
+ style={styles.textInput}
141
+ keyboardType="numeric"
142
+ />
143
+ <View style={styles.line} />
144
+ </View>
145
+ </View>
146
+ <View style={{ flex: 2, marginLeft: cx(20) }}>
147
+ <TextFieldStyleButton
148
+ text={state.energyData?.unit || ''}
149
+ placeholder={I18n.getLang('consumption_data_price_per_kwh_currency_headline_text')}
150
+ onPress={() => (
151
+ energyPopup({
152
+ energyData: state.energyData,
153
+ onItemClick: (title) => {
154
+ if (state.energyData) state.energyData.unit = title
155
+ }
156
+ })
157
+ )}
158
+ />
159
+ </View>
160
+ </View>
161
+ </View>
162
+ )
163
+ } else if (props.popupType === 'unit') {
164
+ return (
165
+ <View>
166
+ <Spacer />
167
+ <Card>
168
+ <FlatList
169
+ data={UnitList}
170
+ renderItem={({ item }) => (
171
+ <View style={styles.unitItem}>
172
+ <Text style={{ fontSize: cx(16), color: props.theme.global.fontColor }}>{item}</Text>
173
+ {props.energyData && props.energyData.unit === item && <Image
174
+ style={{ width: cx(16), height: cx(16) }}
175
+ source={res.app_music_check}
176
+ resizeMode="contain"
177
+ />}
178
+ </View>
179
+ )}
180
+ ItemSeparatorComponent={() => (
181
+ <View style={{ flex: 1, height: 1, backgroundColor: props.theme.card.background }}></View>
182
+ )}
183
+ keyExtractor={item => item}
184
+ />
185
+ </Card>
186
+ </View>
187
+ )
188
+ } else {
189
+ return (
190
+ <View>
191
+ <Spacer />
192
+ <Text style={styles.popupTip}>{I18n.getLang('consumption_data_field3_co2_topic_headline')}</Text>
193
+ <Spacer height={cx(40)} />
194
+ {getDescription(I18n.getLang('consumption_data_field3_co2_inforamtion_decription_text'))}
195
+ </View>
196
+ )
197
+ }
198
+
199
+ }
200
+
201
+ const energyPopup = ({energyData, onItemClick}: {
202
+ energyData?: EnergyData,
203
+ onItemClick: (unit: string) => void
204
+ }) => {
205
+ console.log('running ~~~~~')
206
+ return (
207
+ Popup.custom({
208
+ title: (
209
+ <View style={{ backgroundColor: props.theme.card.head, flexDirection: 'row', height: cx(60), justifyContent: 'space-between', alignItems: 'center', borderTopLeftRadius: cx(10), borderTopRightRadius: cx(10), paddingHorizontal: cx(8) }}>
210
+ <TouchableOpacity onPress={() => Popup.close()}>
211
+ <Text style={{ color: props.theme.global.secondBrand, fontSize: cx(16) }}>{I18n.getLang('auto_scan_system_cancel')}</Text>
212
+ </TouchableOpacity>
213
+ </View>
214
+ ),
215
+ wrapperStyle: {
216
+ height: height - cx(40),
217
+ backgroundColor: props.theme.global.background
218
+ },
219
+ footer: (<View style={{ backgroundColor: props.theme.global.background}}></View>),
220
+ onMaskPress: () => { },
221
+ motionType: 'none',
222
+ useKeyboardView: true,
223
+ content: (
224
+ <View
225
+ style={{ backgroundColor: props.theme.global.background, paddingHorizontal: cx(16) }}>
226
+ <Spacer />
227
+ <Card>
228
+ <FlatList
229
+ data={UnitList}
230
+ renderItem={({ item }) => (
231
+ <TouchableOpacity
232
+ onPress={() => {
233
+ onItemClick(item)
234
+ Popup.close()
235
+ }}
236
+ >
237
+ <View style={styles.unitItem}>
238
+ <Text style={{ fontSize: cx(16), color: props.theme.global.fontColor }}>{item}</Text>
239
+ {energyData && energyData.unit === item && <Image
240
+ style={{ width: cx(16), height: cx(16) }}
241
+ source={res.app_music_check}
242
+ resizeMode="contain"
243
+ />}
244
+ </View>
245
+ </TouchableOpacity>
246
+ )}
247
+ ItemSeparatorComponent={() => (
248
+ <View style={{ flex: 1, height: 1, backgroundColor: props.theme.card.background }}></View>
249
+ )}
250
+ keyExtractor={item => item}
251
+ />
252
+ </Card>
253
+ <Spacer />
254
+ </View>
255
+ )
256
+ })
257
+ )
258
+ }
259
+ return (
260
+ <Modal
261
+ visible={props.visible}
262
+ >
263
+ <ScrollView>
264
+ <View style={{ backgroundColor: props.theme.card.head, flexDirection: 'row', height: cx(60), justifyContent: 'space-between', alignItems: 'center', borderTopLeftRadius: cx(10), borderTopRightRadius: cx(10), paddingHorizontal: cx(8) }}>
265
+ <TouchableOpacity onPress={() => {
266
+ props.onCancel && props.onCancel()
267
+ }}>
268
+ <Text style={{ color: props.theme.global.brand, fontSize: cx(16) }}>{props.cancelText}</Text>
269
+ </TouchableOpacity>
270
+ <Text style={{ color: props.theme.global.fontColor, fontSize: cx(16), fontWeight: 'bold' }}>{props.title}</Text>
271
+ <TouchableOpacity onPress={() => {
272
+ props.onConfirm && props.onConfirm(state.energyData)
273
+ }}>
274
+ <Text style={{ color: props.theme.global.brand, fontSize: cx(16) }}>{props.confirmText}</Text>
275
+ </TouchableOpacity>
276
+ </View>
277
+ <View style={{ height: height - cx(100), paddingHorizontal: cx(16), backgroundColor: props.theme.global.background }}>
278
+ {getContent()}
279
+ </View>
280
+ </ScrollView>
281
+ </Modal>
282
+ )
283
+ }
284
+
285
+ export default withTheme(EnergyModal)
@@ -0,0 +1,118 @@
1
+ import React from "react";
2
+ import { View, Text, StyleProp, ViewStyle, TouchableOpacity, Image, FlatList, StyleSheet } from "react-native";
3
+ import { Utils } from "tuya-panel-kit";
4
+ import res from "@ledvance/base/src/res";
5
+ import Spacer from "@ledvance/base/src/components/Spacer";
6
+ import I18n from "@ledvance/base/src/i18n";
7
+ import { isEmpty } from "lodash";
8
+ import { OverviewItem } from "../EnergyConsumptionPage";
9
+ import { EnergyConsumptionChartProps } from "../EnergyConsumptionChart";
10
+ import { useRoute } from '@react-navigation/core'
11
+
12
+ const { convertX: cx } = Utils.RatioUtils
13
+ const { withTheme } = Utils.ThemeUtils
14
+
15
+ interface OverViewProps {
16
+ theme?: any
17
+ style?: StyleProp<ViewStyle>
18
+ headlineText?: string
19
+ headlineClick?: () => void
20
+ overviewItemClick?: (item: OverviewItem) => void
21
+ overViewList: OverviewItem[]
22
+ }
23
+ const OverView = (props: OverViewProps) => {
24
+ const { over365Days} = useRoute().params as EnergyConsumptionChartProps
25
+
26
+ const styles = StyleSheet.create({
27
+ listEmptyContainer: {
28
+ alignItems: 'center'
29
+ },
30
+ listEmptyImage: {
31
+ width: cx(200),
32
+ height: cx(200),
33
+ },
34
+ listEmptyTextIcon: {
35
+ width: cx(16),
36
+ height: cx(16),
37
+ tintColor: props.theme.global.fontColor,
38
+ },
39
+ listEmptyText: {
40
+ color: props.theme.global.fontColor,
41
+ fontSize: cx(12),
42
+ fontFamily: 'helvetica_neue_lt_std_roman',
43
+ },
44
+ overviewItemText: {
45
+ color: props.theme.global.fontColor,
46
+ fontSize: cx(14)
47
+ },
48
+ })
49
+ return (
50
+ <View style={[props.style]}>
51
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
52
+ <Text style={{ color: props.theme.global.fontColor, fontWeight: 'bold' }}>{props.headlineText}</Text>
53
+ {!isEmpty(props.overViewList) && <TouchableOpacity
54
+ onPress={() => {
55
+ props.headlineClick && props.headlineClick()
56
+ }}
57
+ >
58
+ <Image
59
+ source={res.energy_consumption_chart}
60
+ style={{ width: cx(16), height: cx(16), marginLeft: cx(8) }}
61
+ />
62
+ </TouchableOpacity>}
63
+ </View>
64
+ <Spacer />
65
+ <FlatList
66
+ data={props.overViewList}
67
+ renderItem={({ item }) => (
68
+ <View>
69
+ <TouchableOpacity
70
+ onPress={() => {
71
+ props.overviewItemClick && props.overviewItemClick(item)
72
+ }}
73
+ >
74
+ <View style={{ backgroundColor: props.theme.card.background, alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', }}>
75
+ <Text style={styles.overviewItemText}>{item.key}</Text>
76
+ <View style={{ flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
77
+ <View style={{ flexDirection: 'row' }}>
78
+ <Text style={[styles.overviewItemText, { color: props.theme.global.secondFontColor }]}>{item.value}</Text>
79
+ <Text style={[styles.overviewItemText, { color: props.theme.global.secondFontColor }]}> kWh</Text>
80
+ </View>
81
+ <Image
82
+ source={res.energy_consumption_right}
83
+ style={{ width: cx(16), height: cx(16), marginLeft: cx(8) }}
84
+ />
85
+ </View>
86
+ </View>
87
+ </TouchableOpacity>
88
+ </View>
89
+ )}
90
+ keyExtractor={(item) => item.key}
91
+ ItemSeparatorComponent={() => <Spacer height={cx(10)} />}
92
+ ListFooterComponent={() => <Spacer height={cx(30)} />}
93
+ ListEmptyComponent={() => (
94
+ <View style={styles.listEmptyContainer}>
95
+ <Image
96
+ style={styles.listEmptyImage}
97
+ source={res.energy_consumption_empty} />
98
+ <Spacer height={cx(10)} />
99
+ <View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: cx(25) }}>
100
+ <Image style={styles.listEmptyTextIcon} source={res.co2Icon} />
101
+ <Spacer width={cx(4)} height={0} />
102
+ <Text style={styles.listEmptyText}>
103
+ {
104
+ over365Days ?
105
+ I18n.getLang('energyconsumption_Daylimit')
106
+ :
107
+ I18n.getLang('history_overview_empty_information_text')
108
+ }
109
+ </Text>
110
+ </View>
111
+ </View>
112
+ )}
113
+ />
114
+ </View>
115
+ )
116
+ }
117
+
118
+ export default withTheme(OverView)
@@ -30,4 +30,7 @@ export const ui_biz_routerKey = {
30
30
  'group_ui_biz_light_mode': 'group_ui_biz_light_mode',
31
31
  'group_ui_biz_overcharge_switch': 'group_ui_biz_overcharge_switch',
32
32
  'group_ui_biz_switch_inching': 'group_ui_biz_switch_inching',
33
+ 'group_ui_biz_energy_consumption': 'group_ui_biz_energy_consumption',
34
+ 'group_ui_biz_energy_consumption_detail': 'group_ui_biz_energy_consumption_detail',
35
+ 'group_ui_biz_energy_consumption_chart': 'group_ui_biz_energy_consumption_chart'
33
36
  }