@ledvance/group-ui-biz-bundle 1.0.161 → 1.0.164

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/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "@ledvance/group-ui-biz-bundle",
5
5
  "pid": [],
6
6
  "uiid": "",
7
- "version": "1.0.161",
7
+ "version": "1.0.164",
8
8
  "scripts": {},
9
9
  "dependencies": {
10
10
  "@ledvance/base": "^1.x",
@@ -0,0 +1,38 @@
1
+ import React from 'react'
2
+ import { Image, StyleSheet, Text, View } from 'react-native'
3
+ import { Utils } from 'tuya-panel-kit'
4
+ import ThemeType from '../../../base/src/config/themeType'
5
+ import { useUAGroupInfo } from "../../../base/src/models/modules/NativePropsSlice";
6
+ import IconList from '../modules/biorhythm/iconListData'
7
+
8
+ const cx = Utils.RatioUtils.convertX
9
+ const {withTheme} = Utils.ThemeUtils
10
+
11
+ interface LdvGroupTitleProps {
12
+ theme?: ThemeType
13
+ }
14
+
15
+ const LdvGroupTitle = (props: LdvGroupTitleProps) => {
16
+ const uaGroupInfo = useUAGroupInfo()
17
+ const styles = StyleSheet.create({
18
+ title: {
19
+ color: props.theme?.global.brand,
20
+ fontSize: cx(24),
21
+ },
22
+ headlineIcon: {
23
+ width: cx(24),
24
+ height: cx(24),
25
+ marginRight: cx(5),
26
+ tintColor: props.theme?.global.brand
27
+ },
28
+ })
29
+ const defaultIcon = IconList[uaGroupInfo.icon ?? 10] ?? IconList[10]
30
+ return (
31
+ <View style={{flexDirection: 'row', alignItems: 'center', flex: 1}}>
32
+ <Image source={{uri: defaultIcon.icon}} style={styles.headlineIcon}/>
33
+ <Text style={[styles.title, {flex: 1}]}>{uaGroupInfo.name}</Text>
34
+ </View>
35
+ )
36
+ }
37
+
38
+ export default withTheme(LdvGroupTitle)
@@ -25,6 +25,14 @@ const iconList = [
25
25
  {id: 22, icon: res.biorhythom_icon22, selectStatus: false, disabled: false},
26
26
  {id: 23, icon: res.biorhythom_icon23, selectStatus: false, disabled: false},
27
27
  {id: 24, icon: res.biorhythom_icon24, selectStatus: false, disabled: false},
28
+ {id: 25, icon: res.biorhythom_icon25, selectStatus: false, disabled: false},
29
+ {id: 26, icon: res.biorhythom_icon26, selectStatus: false, disabled: false},
30
+ {id: 27, icon: res.biorhythom_icon27, selectStatus: false, disabled: false},
31
+ {id: 28, icon: res.biorhythom_icon28, selectStatus: false, disabled: false},
32
+ {id: 29, icon: res.biorhythom_icon29, selectStatus: false, disabled: false},
33
+ {id: 30, icon: res.biorhythom_icon30, selectStatus: false, disabled: false},
34
+ {id: 31, icon: res.biorhythom_icon31, selectStatus: false, disabled: false},
35
+ {id: 32, icon: res.biorhythom_icon32, selectStatus: false, disabled: false},
28
36
  ]
29
37
 
30
38
  export default iconList
@@ -5,7 +5,7 @@ import { getStyles } from '@ledvance/group-ui-biz-bundle/src/modules/energyConsu
5
5
  import {
6
6
  useEnergyData
7
7
  } from '@ledvance/group-ui-biz-bundle/src/modules/energyConsumption/EnergyConsumptionChart/useEnergyData'
8
- import React, { useEffect, useMemo } from 'react';
8
+ import React, {useCallback, useEffect, useMemo, useRef} from 'react';
9
9
  import { ScrollView, StyleSheet, View, Text, Image, TouchableOpacity } from 'react-native';
10
10
  import { useNavigation } from '@react-navigation/core';
11
11
  import { useRoute } from '@react-navigation/core';
@@ -25,7 +25,7 @@ import {
25
25
  exchangeNumber,
26
26
  localeNumber,
27
27
  monthFormat,
28
- monthFormatShort,
28
+ monthFormatShort, showDialog,
29
29
  } from '@ledvance/base/src/utils/common';
30
30
  import {
31
31
  getEnergyGenerationValue,
@@ -88,6 +88,7 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
88
88
  const timeZoneCity = useTimeZoneCity();
89
89
  const [energyData, setEnergyData] = useEnergyConsumption()
90
90
  const [dynamicData, setDynamicData] = useDynamicPrice()
91
+ const savedDynamicUnitRef = useRef<string | undefined>(undefined)
91
92
 
92
93
  const parsePrice = (dynamicCosts: PriceSegment[], dynamicGenerates: PriceSegment[], fixedModel?: any): string => {
93
94
  const type = fixedModel?.energyType ?? 'fixed'
@@ -95,8 +96,8 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
95
96
  if (type === 'dynamic') {
96
97
  const usingIntervals = state.isSolarMode ? dynamicGenerates : dynamicCosts;
97
98
  const dynamicPrice = usingIntervals && usingIntervals.length > 0
98
- ? String(calculateAveragePrice(usingIntervals))
99
- : usingPrice;
99
+ ? String(calculateAveragePrice(usingIntervals))
100
+ : (usingPrice || state.price);
100
101
  return String(dynamicPrice ?? '0');
101
102
  } else {
102
103
  return String(usingPrice ?? '0');
@@ -109,10 +110,12 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
109
110
  if (type === 'dynamic') {
110
111
  const usingIntervals = !params.wifiPlugGroup.length ? (dynamicData?.generatePrices || []) : (dynamicData?.intervalPrices || []);
111
112
  const dynamicPrice = usingIntervals && usingIntervals.length > 0
112
- ? String(calculateAveragePrice(usingIntervals))
113
- : usingPrice;
113
+ ? String(calculateAveragePrice(usingIntervals))
114
+ : usingPrice;
115
+ // console.log("wayne_check_stateprice initialPrice dynamic", dynamicPrice)
114
116
  return String(dynamicPrice ?? '0');
115
117
  } else {
118
+ // console.log("wayne_check_stateprice initialPrice usingPrice", usingPrice)
116
119
  return String(usingPrice ?? '0');
117
120
  }
118
121
  }, [energyData, dynamicData, params.wifiPlugGroup.length])
@@ -138,7 +141,10 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
138
141
  useUpdateEffect(() => {
139
142
  state.pricingType = energyData.energyType ?? 'fixed'
140
143
  state.price = parsePrice(dynamicData?.intervalPrices || [], dynamicData?.generatePrices || [], energyData)
141
- state.unit = energyData.unit
144
+ // console.log("wayne_check_stateprice useUpdateEffect", state.price)
145
+ state.unit = state.pricingType === 'dynamic'
146
+ ? (savedDynamicUnitRef.current ?? energyData.unit)
147
+ : energyData.unit
142
148
  actions.setPriceAndUnit(state.price, state.unit)
143
149
  }, [JSON.stringify(energyData), JSON.stringify(dynamicData), state.isSolarMode])
144
150
 
@@ -146,8 +152,8 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
146
152
  const overview = state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList
147
153
  const len = overview.length;
148
154
  return overview?.length
149
- ? `${overview[len - 1].key} - ${overview[0].key}`
150
- : '';
155
+ ? `${overview[len - 1].key} - ${overview[0].key}`
156
+ : '';
151
157
  }, [state.solarOverviewList, state.wifiOverviewList, state.isSolarMode]);
152
158
 
153
159
  const chartParams = useMemo(() => {
@@ -167,7 +173,7 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
167
173
  dynamicData: dynamicData,
168
174
  }
169
175
  }, [backTitle, chartHeadline, state.price, state.unit, params.addEleDpCode, state.isSolarMode, params.wifiPlugGroup, params.solarPlugGroup, state.pricingType, dynamicData])
170
-
176
+
171
177
  const { state: chartState, actions } = useEnergyData(chartParams);
172
178
  const chartStyles = useMemo(() => getStyles(props.theme), [props.theme]);
173
179
 
@@ -184,16 +190,16 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
184
190
 
185
191
  const getElectricity = async () => {
186
192
  const solarPromise = params.solarPlugGroup.map(devId =>
187
- getDpResultByMonth(devId, params.addEleDpCode, 'sum').catch(error => ({ error }))
193
+ getDpResultByMonth(devId, params.addEleDpCode, 'sum').catch(error => ({ error }))
188
194
  );
189
195
  const solarEnergyGenerationPromise = params.solarPlugGroup.map(devId =>
190
- getEnergyGenerationValue(devId)
196
+ getEnergyGenerationValue(devId)
191
197
  );
192
198
  const wifiPromise = params.wifiPlugGroup.map(devId =>
193
- getDpResultByMonth(devId, params.addEleDpCode, 'sum').catch(error => ({ error }))
199
+ getDpResultByMonth(devId, params.addEleDpCode, 'sum').catch(error => ({ error }))
194
200
  );
195
201
  const wifiEnergyGenerationPromise = params.wifiPlugGroup.map(devId =>
196
- getEnergyGenerationValue(devId)
202
+ getEnergyGenerationValue(devId)
197
203
  );
198
204
  state.loading = true
199
205
  const solarRes = await Promise.all(solarPromise);
@@ -267,7 +273,17 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
267
273
  }
268
274
  }
269
275
 
270
- const updateEnergyData = (data: EnergyData) => {
276
+ const showAlerDialog = useCallback((content: string) => {
277
+ showDialog({
278
+ method: 'alert',
279
+ title: I18n.getLang('title_tips'),
280
+ subTitle: content,
281
+ onConfirm: async (_, { close }) => {
282
+ close()
283
+ }
284
+ })
285
+ }, [])
286
+ const updateEnergyData = async (data: EnergyData): Promise<boolean> => {
271
287
  const internationalPrice = exchangeNumber(data.price)
272
288
  const newEnergyData = {
273
289
  ...energyData,
@@ -275,11 +291,26 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
275
291
  energyType: 'fixed',
276
292
  [state.isSolarMode ? 'generatePrice' : 'price']: internationalPrice,
277
293
  }
278
- setEnergyData(newEnergyData).then()
279
- state.price = internationalPrice || '0'
280
- state.unit = data.unit
281
- state.pricingType = 'fixed'
282
- actions.setPriceAndUnit(state.price, data.unit)
294
+ state.loading = true
295
+ try {
296
+ const result = await setEnergyData(newEnergyData)
297
+ if (!result?.success) {
298
+ console.warn('Failed to update fixed energy price', result)
299
+ showAlerDialog(I18n.getLang('common_server_api_error'))
300
+ return false
301
+ }
302
+ state.price = internationalPrice || '0'
303
+ savedDynamicUnitRef.current = undefined
304
+ state.unit = data.unit
305
+ state.pricingType = 'fixed'
306
+ actions.setPriceAndUnit(state.price, data.unit)
307
+ return true
308
+ } catch (error) {
309
+ console.error('Failed to update fixed energy price', error)
310
+ return false
311
+ } finally {
312
+ state.loading = false
313
+ }
283
314
  };
284
315
 
285
316
  const backTitle = useMemo(() => {
@@ -356,383 +387,388 @@ const EnergyConsumptionPage = (props: { theme?: ThemeType }) => {
356
387
 
357
388
  const ConsumedEnergyItem = (props: { value: number; unit: string }) => {
358
389
  return (
359
- <View style={styles.subContent}>
360
- <Text style={styles.valueText}>{props.value || 0}</Text>
361
- <Spacer height={cx(4)} />
362
- <Text style={styles.titleText}>{unitDivision(props.unit)[0]}</Text>
363
- <Text style={styles.titleText}>{unitDivision(props.unit)[1]}</Text>
364
- </View>
390
+ <View style={styles.subContent}>
391
+ <Text style={styles.valueText}>{props.value || 0}</Text>
392
+ <Spacer height={cx(4)} />
393
+ <Text style={styles.titleText}>{unitDivision(props.unit)[0]}</Text>
394
+ <Text style={styles.titleText}>{unitDivision(props.unit)[1]}</Text>
395
+ </View>
365
396
  );
366
397
  };
367
398
 
368
399
  return (
369
- <Page
370
- style={{ position: 'relative' }}
371
- backText={backTitle}
372
- headlineText={I18n.getLang(
373
- state.isSolarMode
374
- ? 'sockets_headline_power'
375
- : 'consumption_data_annual_bar_chart_system_back_text'
376
- )}
377
- headlineIcon={(state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList).length ? res.download_icon : undefined}
378
- onHeadlineIconClick={() => {
379
- const headers = [I18n.getLang('date'), `${I18n.getLang('consumption_data_annual_bar_chart_system_back_text')} (kWh)`, `Price(${state.unit})`]
380
- const values = (state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList).map(item => [item.key, item.value, (Number(state.price) * Number(item.value)).toFixed(2)])
381
- exportEnergyCsv(headers, values)
382
- }}
383
- showGreenery={state.isSolarMode}
384
- greeneryIcon={res.energy_consumption_greenery}
385
- headlineTopContent={
386
- (params.solarPlugGroup.length && params.wifiPlugGroup.length) ?
387
- <View style={{ marginBottom: cx(5) }}>
388
- <SegmentControl
389
- marginHorizontal={cx(0)}
390
- title1={I18n.getLang('consumption_data_annual_bar_chart_system_back_text')}
391
- title2={I18n.getLang('sockets_headline_power')}
392
- isFirst={!state.isSolarMode}
393
- tabStyle={{paddingHorizontal: cx(15)}}
394
- setIsFirst={(v) => {
395
- state.isSolarMode = !v
396
- actions.setDisplayMode(!v ? 'generation' : 'consumption')
397
- }} />
398
- </View> : undefined
399
- }
400
- loading={state.loading}
401
- >
402
- <ScrollView nestedScrollEnabled={true}>
403
- <View>
404
- {/* tip */}
405
- <Spacer height={cx(15)} />
406
- <View style={styles.showTip}>
407
- <Text style={{ fontSize: cx(14), color: props.theme?.global.fontColor, }}>
408
- {I18n.getLang(
409
- state.isSolarMode
410
- ? 'generation_data_description_text'
411
- : 'consumption_data_description_text'
412
- )}
413
- </Text>
414
- </View>
415
- <Spacer />
416
- <Card
417
- style={styles.cardContainer}
418
- onPress={() => {
419
- navigation.navigate(ui_biz_routerKey.group_ui_biz_energy_consumption_chart, {
420
- backTitle,
421
- headlineText: chartHeadline,
422
- chartData: state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList,
423
- price: state.price,
424
- unit: state.unit,
425
- addEleDpCode: params.addEleDpCode,
426
- date: (new Date()).getFullYear().toString(),
427
- deviceIdGroup: state.isSolarMode ? params.solarPlugGroup : params.wifiPlugGroup,
428
- displayMode: (params.wifiPlugGroup.length && params.solarPlugGroup.length) ? 'both' : (params.wifiPlugGroup.length ? 'consumption' : 'generation'),
429
- consumptionDeviceIds: params.wifiPlugGroup,
430
- generationDeviceIds: params.solarPlugGroup,
431
- } as EnergyConsumptionChartProps)
432
- }}
433
- >
434
- <View style={{
435
- flexDirection: 'row',
436
- justifyContent: 'space-between',
437
- alignItems: 'center',
438
- }}>
439
- <Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field2_headline_text')}</Text>
440
- <Image
441
- source={{ uri: res.energy_consumption_chart}}
442
- style={{ width: cx(16), height: cx(16), marginLeft: cx(8) }}
443
- />
444
- </View>
400
+ <Page
401
+ style={{ position: 'relative' }}
402
+ backText={backTitle}
403
+ headlineText={I18n.getLang(
404
+ state.isSolarMode
405
+ ? 'sockets_headline_power'
406
+ : 'consumption_data_annual_bar_chart_system_back_text'
407
+ )}
408
+ headlineIcon={(state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList).length ? res.download_icon : undefined}
409
+ onHeadlineIconClick={() => {
410
+ const headers = [I18n.getLang('date'), `${I18n.getLang('consumption_data_annual_bar_chart_system_back_text')} (kWh)`, `Price(${state.unit})`]
411
+ const values = (state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList).map(item => [item.key, item.value, (Number(state.price) * Number(item.value)).toFixed(2)])
412
+ exportEnergyCsv(headers, values)
413
+ }}
414
+ showGreenery={state.isSolarMode}
415
+ greeneryIcon={res.energy_consumption_greenery}
416
+ headlineTopContent={
417
+ (params.solarPlugGroup.length && params.wifiPlugGroup.length) ?
418
+ <View style={{ marginBottom: cx(5) }}>
419
+ <SegmentControl
420
+ marginHorizontal={cx(0)}
421
+ title1={I18n.getLang('consumption_data_annual_bar_chart_system_back_text')}
422
+ title2={I18n.getLang('sockets_headline_power')}
423
+ isFirst={!state.isSolarMode}
424
+ tabStyle={{paddingHorizontal: cx(15)}}
425
+ setIsFirst={(v) => {
426
+ state.isSolarMode = !v
427
+ actions.setDisplayMode(!v ? 'generation' : 'consumption')
428
+ }} />
429
+ </View> : undefined
430
+ }
431
+ loading={state.loading}
432
+ >
433
+ <ScrollView nestedScrollEnabled={true}>
434
+ <View>
435
+ {/* tip */}
445
436
  <Spacer height={cx(15)} />
446
- <View style={styles.consumedEnergyContent}>
447
- <ConsumedEnergyItem
448
- value={state.isSolarMode ? params.solarPowerSum : params.wifiPowerSum}
449
- unit={I18n.getLang('consumption_data_field2_value_text1')}
450
- />
451
- <ConsumedEnergyItem
452
- value={state.isSolarMode ? params.solarCurrentSum : params.wifiCurrentSum}
453
- unit={I18n.getLang('consumption_data_field2_value_text2')}
454
- />
437
+ <View style={styles.showTip}>
438
+ <Text style={{ fontSize: cx(14), color: props.theme?.global.fontColor, }}>
439
+ {I18n.getLang(
440
+ state.isSolarMode
441
+ ? 'generation_data_description_text'
442
+ : 'consumption_data_description_text'
443
+ )}
444
+ </Text>
455
445
  </View>
456
- </Card>
457
- <Spacer />
458
- {/* pricing radio button*/}
459
- <View style={{ marginBottom: cx(5) }}>
460
- <SegmentControl
461
- marginHorizontal={cx(0)}
462
- title1={I18n.getLang('consumption_energy_type_fixed')}
463
- title2={I18n.getLang('consumption_energy_type_dynamic')}
464
- isFirst={state.pricingType === 'fixed'}
465
- tabStyle={{paddingHorizontal: cx(15)}}
466
- setIsFirst={(v) => {
467
- const value = v ? 'fixed' : 'dynamic'
468
- const fixedModel = energyData ?? {
469
- price: '0',
470
- unit: '$',
471
- energyType: 'fixed',
472
- generatePrice: '0',
473
- }
474
- state.loading = true
475
- setEnergyData({
476
- ...fixedModel,
477
- energyType: value,
478
- }).then((res) => {
479
- state.loading = false
480
- if (res && res.success) {
481
- state.pricingType = value
482
- if (value === 'fixed') {
483
- state.price = state.isSolarMode ? (fixedModel.generatePrice || fixedModel.price) : fixedModel.price
484
- } else {
485
- const segments = state.isSolarMode ? (dynamicData?.generatePrices || []) : (dynamicData?.intervalPrices || [])
486
- state.price = String(calculateAveragePrice(segments))
487
- }
488
- actions.setPriceAndUnit(state.price, state.unit)
489
- }
490
- })
491
- }} />
492
- </View>
493
- {/* 365 day */}
494
- <Card style={styles.cardContainer}>
495
- <View style={{ flexDirection: 'row', alignItems: 'center' }}>
496
- <View>
497
- <View style={{height: cx(35), justifyContent: 'center'}}>
498
- <Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field1_headline_text')}</Text>
499
- </View>
500
- <View style={{height: cx(35), justifyContent: 'center'}}>
501
- <Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field3_headline_text')}</Text>
502
- </View>
446
+ <Spacer />
447
+ <Card
448
+ style={styles.cardContainer}
449
+ onPress={() => {
450
+ navigation.navigate(ui_biz_routerKey.group_ui_biz_energy_consumption_chart, {
451
+ backTitle,
452
+ headlineText: chartHeadline,
453
+ chartData: state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList,
454
+ price: state.price,
455
+ unit: state.unit,
456
+ addEleDpCode: params.addEleDpCode,
457
+ date: (new Date()).getFullYear().toString(),
458
+ deviceIdGroup: state.isSolarMode ? params.solarPlugGroup : params.wifiPlugGroup,
459
+ displayMode: (params.wifiPlugGroup.length && params.solarPlugGroup.length) ? 'both' : (params.wifiPlugGroup.length ? 'consumption' : 'generation'),
460
+ consumptionDeviceIds: params.wifiPlugGroup,
461
+ generationDeviceIds: params.solarPlugGroup,
462
+ } as EnergyConsumptionChartProps)
463
+ }}
464
+ >
465
+ <View style={{
466
+ flexDirection: 'row',
467
+ justifyContent: 'space-between',
468
+ alignItems: 'center',
469
+ }}>
470
+ <Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field2_headline_text')}</Text>
471
+ <Image
472
+ source={{ uri: res.energy_consumption_chart}}
473
+ style={{ width: cx(16), height: cx(16), marginLeft: cx(8) }}
474
+ />
503
475
  </View>
504
- <View>
505
- <View style={{ flexDirection: 'row', alignItems: 'flex-end', marginLeft: cx(10) }}>
506
- <Text style={[styles.consumptionNum, { fontSize: cx(30), marginRight: cx(8) }]}>
507
- {localeNumber(state.isSolarMode ? state.solarTodayElectricity : state.wifiTodayElectricity)}
508
- </Text>
509
- <Text style={[styles.consumptionNum, { fontSize: cx(20), marginBottom: cx(4) }]}>kWh</Text>
510
- </View>
511
- <View style={{ flexDirection: 'row', alignItems: 'flex-end', marginLeft: cx(10) }}>
512
- <Text style={[styles.consumptionNum, { fontSize: cx(30), marginRight: cx(8) }]}>
513
- {localeNumber(state.isSolarMode ? state.solarTotalElectricity : state.wifiTotalElectricity)}
514
- </Text>
515
- <Text style={[styles.consumptionNum, { fontSize: cx(20), marginBottom: cx(4) }]}>kWh</Text>
516
- </View>
476
+ <Spacer height={cx(15)} />
477
+ <View style={styles.consumedEnergyContent}>
478
+ <ConsumedEnergyItem
479
+ value={state.isSolarMode ? params.solarPowerSum : params.wifiPowerSum}
480
+ unit={I18n.getLang('consumption_data_field2_value_text1')}
481
+ />
482
+ <ConsumedEnergyItem
483
+ value={state.isSolarMode ? params.solarCurrentSum : params.wifiCurrentSum}
484
+ unit={I18n.getLang('consumption_data_field2_value_text2')}
485
+ />
517
486
  </View>
518
- </View>
487
+ </Card>
519
488
  <Spacer />
520
- {/* CO2 */}
521
- {state.isSolarMode && (
522
- <>
523
- <View style={{ flexDirection: 'row', alignItems: 'center' }}>
524
- <View style={styles.priceBg}>
525
- <Image
526
- source={{ uri: res.energy_consumption_cash}}
527
- resizeMode="contain"
528
- style={{
529
- height: cx(20),
530
- width: cx(20),
531
- tintColor: props.theme?.button.primary,
532
- }}
533
- />
489
+ {/* pricing radio button*/}
490
+ <View style={{ marginBottom: cx(5) }}>
491
+ <SegmentControl
492
+ marginHorizontal={cx(24)}
493
+ title1={I18n.getLang('consumption_energy_type_fixed')}
494
+ title2={I18n.getLang('consumption_energy_type_dynamic')}
495
+ isFirst={state.pricingType === 'fixed'}
496
+ tabStyle={{paddingHorizontal: cx(15)}}
497
+ setIsFirst={(v) => {
498
+ const value = v ? 'fixed' : 'dynamic'
499
+ const fixedModel = energyData ?? {
500
+ price: '0',
501
+ unit: '$',
502
+ energyType: 'fixed',
503
+ generatePrice: '0',
504
+ }
505
+ state.loading = true
506
+ setEnergyData({
507
+ ...fixedModel,
508
+ energyType: value,
509
+ }).then((res) => {
510
+ state.loading = false
511
+ if (res && res.success) {
512
+ state.pricingType = value
513
+ if (value === 'fixed') {
514
+ savedDynamicUnitRef.current = undefined
515
+ state.price = state.isSolarMode ? (fixedModel.generatePrice || fixedModel.price) : fixedModel.price
516
+ } else {
517
+ // console.log("check isSolar -> ", state.isSolarMode)
518
+ // console.log("wayne_check_stateprice segment ->", JSON.stringify(dynamicData))
519
+ const segments = state.isSolarMode ? (dynamicData?.generatePrices || []) : (dynamicData?.intervalPrices || [])
520
+ state.price = String(calculateAveragePrice(segments))
521
+ }
522
+ actions.setPriceAndUnit(state.price, state.unit)
523
+ }
524
+ })
525
+ }} />
526
+ </View>
527
+ {/* 365 day */}
528
+ <Card style={styles.cardContainer}>
529
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
530
+ <View>
531
+ <View style={{height: cx(35), justifyContent: 'center'}}>
532
+ <Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field1_headline_text')}</Text>
534
533
  </View>
535
- <View style={styles.priceNum}>
536
- <View style={{ flexDirection: 'row' }}>
537
- <Text
538
- style={{ color: props.theme?.global.secondFontColor, marginRight: cx(5) }}
539
- >
540
- {I18n.getLang('consumption_data_field3_co2_topic_text')}
541
- </Text>
542
- <TouchableOpacity
543
- onPress={() => {
544
- state.showPopup = true;
545
- state.popupType = 'co2';
546
- }}
547
- >
548
- <Image
549
- source={{ uri: res.co2_icon}}
550
- resizeMode="contain"
551
- style={{
552
- height: cx(20),
553
- width: cx(20),
554
- tintColor: props.theme?.button.primary,
555
- }}
556
- />
557
- </TouchableOpacity>
558
- </View>
559
- <Text
560
- style={{ color: props.theme?.global.fontColor, fontWeight: 'bold' }}
561
- >{`${state.co2Saved} kg`}</Text>
534
+ <View style={{height: cx(35), justifyContent: 'center'}}>
535
+ <Text style={styles.cardTitle}>{I18n.getLang('consumption_data_field3_headline_text')}</Text>
536
+ </View>
537
+ </View>
538
+ <View>
539
+ <View style={{ flexDirection: 'row', alignItems: 'flex-end', marginLeft: cx(10) }}>
540
+ <Text style={[styles.consumptionNum, { fontSize: cx(30), marginRight: cx(8) }]}>
541
+ {localeNumber(state.isSolarMode ? state.solarTodayElectricity : state.wifiTodayElectricity)}
542
+ </Text>
543
+ <Text style={[styles.consumptionNum, { fontSize: cx(20), marginBottom: cx(4) }]}>kWh</Text>
544
+ </View>
545
+ <View style={{ flexDirection: 'row', alignItems: 'flex-end', marginLeft: cx(10) }}>
546
+ <Text style={[styles.consumptionNum, { fontSize: cx(30), marginRight: cx(8) }]}>
547
+ {localeNumber(state.isSolarMode ? state.solarTotalElectricity : state.wifiTotalElectricity)}
548
+ </Text>
549
+ <Text style={[styles.consumptionNum, { fontSize: cx(20), marginBottom: cx(4) }]}>kWh</Text>
562
550
  </View>
563
551
  </View>
564
- <Spacer height={cx(10)} />
565
- </>
566
- )}
567
- {/* money */}
568
- <View style={{ flexDirection: 'row', alignItems: 'center' }}>
569
- <View style={styles.priceBg}>
570
- <Image
571
- source={{ uri: res.energy_consumption_cash}}
572
- resizeMode="contain"
573
- style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
574
- />
575
552
  </View>
576
- <View>
577
- <View style={styles.priceNum}>
578
- <Text style={{ color: props.theme?.global.secondFontColor }}>
579
- {I18n.getLang(
580
- state.isSolarMode
581
- ? 'consumption_data_monthly_overview_field1_text2'
582
- : 'consumption_data_field3_value_text2'
583
- )}
584
- </Text>
585
- <Text style={{ color: props.theme?.global.fontColor, fontWeight: 'bold' }}>
586
- {state.price
587
- ? `${localeNumber(Number(state.price) * Number(state.isSolarMode ? state.solarTotalElectricity : state.wifiTotalElectricity), 2)} ${state.unit
588
- }`
589
- : '-'}
590
- </Text>
553
+ <Spacer />
554
+ {/* CO2 */}
555
+ {state.isSolarMode && (
556
+ <>
557
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
558
+ <View style={styles.priceBg}>
559
+ <Image
560
+ source={{ uri: res.energy_consumption_cash}}
561
+ resizeMode="contain"
562
+ style={{
563
+ height: cx(20),
564
+ width: cx(20),
565
+ tintColor: props.theme?.button.primary,
566
+ }}
567
+ />
568
+ </View>
569
+ <View style={styles.priceNum}>
570
+ <View style={{ flexDirection: 'row' }}>
571
+ <Text
572
+ style={{ color: props.theme?.global.secondFontColor, marginRight: cx(5) }}
573
+ >
574
+ {I18n.getLang('consumption_data_field3_co2_topic_text')}
575
+ </Text>
576
+ <TouchableOpacity
577
+ onPress={() => {
578
+ state.showPopup = true;
579
+ state.popupType = 'co2';
580
+ }}
581
+ >
582
+ <Image
583
+ source={{ uri: res.co2_icon}}
584
+ resizeMode="contain"
585
+ style={{
586
+ height: cx(20),
587
+ width: cx(20),
588
+ tintColor: props.theme?.button.primary,
589
+ }}
590
+ />
591
+ </TouchableOpacity>
592
+ </View>
593
+ <Text
594
+ style={{ color: props.theme?.global.fontColor, fontWeight: 'bold' }}
595
+ >{`${state.co2Saved} kg`}</Text>
596
+ </View>
597
+ </View>
598
+ <Spacer height={cx(10)} />
599
+ </>
600
+ )}
601
+ {/* money */}
602
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
603
+ <View style={styles.priceBg}>
604
+ <Image
605
+ source={{ uri: res.energy_consumption_cash}}
606
+ resizeMode="contain"
607
+ style={{ height: cx(20), width: cx(20), tintColor: props.theme?.button.primary }}
608
+ />
591
609
  </View>
592
- {state.pricingType === 'fixed' &&<TouchableOpacity
593
- onPress={() => {
594
- state.showPopup = true;
595
- state.popupType = 'money';
596
- }}
597
- >
598
- <View style={styles.priceButton}>
599
- <Text style={{ color: props.theme?.button.fontColor }}>
600
- {I18n.getLang('consumption_data_field3_button_text')}
610
+ <View>
611
+ <View style={styles.priceNum}>
612
+ <Text style={{ color: props.theme?.global.secondFontColor }}>
613
+ {I18n.getLang(
614
+ state.isSolarMode
615
+ ? 'consumption_data_monthly_overview_field1_text2'
616
+ : 'consumption_data_field3_value_text2'
617
+ )}
618
+ </Text>
619
+ <Text style={{ color: props.theme?.global.fontColor, fontWeight: 'bold' }}>
620
+ {state.price
621
+ ? `${localeNumber(Number(state.price) * Number(state.isSolarMode ? state.solarTotalElectricity : state.wifiTotalElectricity), 2)} ${state.unit
622
+ }`
623
+ : '-'}
601
624
  </Text>
602
625
  </View>
603
- </TouchableOpacity>
604
- }
605
- {state.pricingType === 'dynamic' && (
606
- <TouchableOpacity
607
- onPress={() => {
608
- navigation.navigate(ui_biz_routerKey.group_ui_biz_set_segmented_prices, {
609
- backTitle: backTitle,
610
- dynamicData: dynamicData ?? {
611
- intervalPrices: [],
612
- generatePrices: [],
613
- },
614
- priceUnit: state.unit,
615
- isGenerate: state.isSolarMode,
616
- onSetPriceSements: async (segments: PriceSegment[], currency: string): Promise<boolean> => {
617
- console.log("onSetPriceSements ", JSON.stringify(segments), currency)
618
- const fixedModel = energyData ?? {
619
- price: '0',
620
- unit: '$',
621
- energyType: 'fixed',
622
- generatePrice: '0',
623
- }
624
- const dynamicModel = {
625
- ...dynamicData,
626
- [state.isSolarMode ? 'generatePrices' : 'intervalPrices']: segments
627
- }
628
- const [fixedRes, dynamicRes] = await Promise.all([
629
- setEnergyData({ ...fixedModel, energyType: 'dynamic', unit: currency }),
630
- setDynamicData(dynamicModel)
631
- ])
632
- const isDynamicSuccess = dynamicRes && dynamicRes.success
633
- const isRegularSuccess = fixedRes && fixedRes.success
634
- const isAllSuccess = isDynamicSuccess && isRegularSuccess
635
- if (isAllSuccess) {
636
- state.price = String(calculateAveragePrice(segments)) // 价格
637
- state.pricingType = 'dynamic'
638
- state.unit = currency
639
- actions.setPriceAndUnit(state.price, currency)
640
- }
641
- return !!isAllSuccess
642
- }
643
- } as SetSegmentedPricesParams)
644
- }}
626
+ {state.pricingType === 'fixed' &&<TouchableOpacity
627
+ onPress={() => {
628
+ state.showPopup = true;
629
+ state.popupType = 'money';
630
+ }}
645
631
  >
646
632
  <View style={styles.priceButton}>
647
633
  <Text style={{ color: props.theme?.button.fontColor }}>
648
- {I18n.getLang('consumption_data_field_dynamic_money')}
634
+ {I18n.getLang('consumption_data_field3_button_text')}
649
635
  </Text>
650
636
  </View>
651
637
  </TouchableOpacity>
652
- )}
638
+ }
639
+ {state.pricingType === 'dynamic' && (
640
+ <TouchableOpacity
641
+ onPress={() => {
642
+ navigation.navigate(ui_biz_routerKey.group_ui_biz_set_segmented_prices, {
643
+ backTitle: backTitle,
644
+ dynamicData: dynamicData ?? {
645
+ intervalPrices: [],
646
+ generatePrices: [],
647
+ },
648
+ priceUnit: state.unit,
649
+ isGenerate: state.isSolarMode,
650
+ onSetPriceSements: async (segments: PriceSegment[], currency: string): Promise<boolean> => {
651
+ console.log("onSetPriceSements ", JSON.stringify(segments), currency)
652
+ const fixedModel = energyData ?? {
653
+ price: '0',
654
+ unit: '$',
655
+ energyType: 'fixed',
656
+ generatePrice: '0',
657
+ }
658
+ const dynamicModel = {
659
+ ...dynamicData,
660
+ [state.isSolarMode ? 'generatePrices' : 'intervalPrices']: segments
661
+ }
662
+ const [fixedRes, dynamicRes] = await Promise.all([
663
+ setEnergyData({ ...fixedModel, energyType: 'dynamic', unit: currency }),
664
+ setDynamicData(dynamicModel)
665
+ ])
666
+ const isDynamicSuccess = dynamicRes && dynamicRes.success
667
+ const isRegularSuccess = fixedRes && fixedRes.success
668
+ const isAllSuccess = isDynamicSuccess && isRegularSuccess
669
+ if (isAllSuccess) {
670
+ savedDynamicUnitRef.current = currency
671
+ state.price = String(calculateAveragePrice(segments)) // 价格
672
+ // console.log("wayne_check_stateprice onPress isAllSucess", state.price)
673
+ state.pricingType = 'dynamic'
674
+ state.unit = currency
675
+ actions.setPriceAndUnit(state.price, currency)
676
+ }
677
+ return !!isAllSuccess
678
+ }
679
+ } as SetSegmentedPricesParams)
680
+ }}
681
+ >
682
+ <View style={styles.priceButton}>
683
+ <Text style={{ color: props.theme?.button.fontColor }}>
684
+ {I18n.getLang('consumption_data_field_dynamic_money')}
685
+ </Text>
686
+ </View>
687
+ </TouchableOpacity>
688
+ )}
653
689
 
690
+ </View>
654
691
  </View>
692
+ </Card>
693
+ <Spacer height={cx(30)} />
694
+ <View style={{ marginHorizontal: cx(24) }}>
695
+ <ChartSection
696
+ state={chartState}
697
+ actions={actions}
698
+ params={chartParams}
699
+ styles={chartStyles}
700
+ theme={props.theme}
701
+ chartHeight={cx(400)}
702
+ />
655
703
  </View>
656
- </Card>
657
- <Spacer height={cx(30)} />
658
- <View style={{ marginHorizontal: cx(24) }}>
659
- <ChartSection
660
- state={chartState}
661
- actions={actions}
662
- params={chartParams}
663
- styles={chartStyles}
664
- theme={props.theme}
665
- chartHeight={cx(400)}
704
+ <Spacer height={cx(30)} />
705
+ {/* Annual overview */}
706
+ <OverView
707
+ style={{marginHorizontal: cx(24)}}
708
+ headlineText={I18n.getLang('consumption_data_field4_headline_text')}
709
+ headlineClick={() => {
710
+ navigation.navigate(ui_biz_routerKey.group_ui_biz_energy_consumption_chart, {
711
+ backTitle,
712
+ headlineText: chartHeadline,
713
+ chartData: state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList,
714
+ price: state.price,
715
+ unit: state.unit,
716
+ addEleDpCode: params.addEleDpCode,
717
+ date: (new Date()).getFullYear().toString(),
718
+ deviceIdGroup: state.isSolarMode ? params.solarPlugGroup : params.wifiPlugGroup,
719
+ displayMode: (params.wifiPlugGroup.length && params.solarPlugGroup.length) ? 'both' : (params.wifiPlugGroup.length ? 'consumption' : 'generation'),
720
+ consumptionDeviceIds: params.wifiPlugGroup,
721
+ generationDeviceIds: params.solarPlugGroup,
722
+ } as EnergyConsumptionChartProps)
723
+ }}
724
+ overviewItemClick={(item) => {
725
+ navigation.navigate(ui_biz_routerKey.group_ui_biz_energy_consumption_detail, {
726
+ backTitle,
727
+ addEleDpCode: params.addEleDpCode,
728
+ curMonth: item,
729
+ price: state.price,
730
+ unit: state.unit,
731
+ isSolarMode: state.isSolarMode,
732
+ deviceIdGroup: state.isSolarMode ? params.solarPlugGroup : params.wifiPlugGroup,
733
+ displayMode: (params.wifiPlugGroup.length && params.solarPlugGroup.length) ? 'both' : (params.wifiPlugGroup.length ? 'consumption' : 'generation'),
734
+ consumptionDeviceIds: params.wifiPlugGroup,
735
+ generationDeviceIds: params.solarPlugGroup,
736
+ updateEnergyData
737
+ } as EnergyConsumptionDetailProps)
738
+ }}
739
+ overViewList={state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList}
740
+ />
741
+ {/* modal */}
742
+ <EnergyPopup
743
+ visible={!!(state.popupType && state.showPopup)}
744
+ popupType={state.popupType || 'co2'}
745
+ title={
746
+ state.popupType === 'co2'
747
+ ? I18n.getLang('consumption_data_field3_co2_topic_text')
748
+ : ''
749
+ }
750
+ cancelText={state.popupType === 'co2' ? '' : I18n.getLang('auto_scan_system_cancel')}
751
+ confirmText={I18n.getLang(
752
+ state.popupType === 'co2'
753
+ ? 'home_screen_home_dialog_yes_con'
754
+ : 'auto_scan_system_wifi_confirm'
755
+ )}
756
+ energyData={{ price: state.price, unit: state.unit }}
757
+ onConfirm={async popupEnergyData => {
758
+ state.popupType = '';
759
+ state.showPopup = false;
760
+ if (popupEnergyData) {
761
+ await updateEnergyData(popupEnergyData)
762
+ }
763
+ }}
764
+ onCancel={() => {
765
+ state.popupType = '';
766
+ state.showPopup = false;
767
+ }}
666
768
  />
667
769
  </View>
668
- <Spacer height={cx(30)} />
669
- {/* Annual overview */}
670
- <OverView
671
- style={{marginHorizontal: cx(24)}}
672
- headlineText={I18n.getLang('consumption_data_field4_headline_text')}
673
- headlineClick={() => {
674
- navigation.navigate(ui_biz_routerKey.group_ui_biz_energy_consumption_chart, {
675
- backTitle,
676
- headlineText: chartHeadline,
677
- chartData: state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList,
678
- price: state.price,
679
- unit: state.unit,
680
- addEleDpCode: params.addEleDpCode,
681
- date: (new Date()).getFullYear().toString(),
682
- deviceIdGroup: state.isSolarMode ? params.solarPlugGroup : params.wifiPlugGroup,
683
- displayMode: (params.wifiPlugGroup.length && params.solarPlugGroup.length) ? 'both' : (params.wifiPlugGroup.length ? 'consumption' : 'generation'),
684
- consumptionDeviceIds: params.wifiPlugGroup,
685
- generationDeviceIds: params.solarPlugGroup,
686
- } as EnergyConsumptionChartProps)
687
- }}
688
- overviewItemClick={(item) => {
689
- navigation.navigate(ui_biz_routerKey.group_ui_biz_energy_consumption_detail, {
690
- backTitle,
691
- addEleDpCode: params.addEleDpCode,
692
- curMonth: item,
693
- price: state.price,
694
- unit: state.unit,
695
- isSolarMode: state.isSolarMode,
696
- deviceIdGroup: state.isSolarMode ? params.solarPlugGroup : params.wifiPlugGroup,
697
- displayMode: (params.wifiPlugGroup.length && params.solarPlugGroup.length) ? 'both' : (params.wifiPlugGroup.length ? 'consumption' : 'generation'),
698
- consumptionDeviceIds: params.wifiPlugGroup,
699
- generationDeviceIds: params.solarPlugGroup,
700
- updateEnergyData
701
- } as EnergyConsumptionDetailProps)
702
- }}
703
- overViewList={state.isSolarMode ? state.solarOverviewList : state.wifiOverviewList}
704
- />
705
- {/* modal */}
706
- <EnergyPopup
707
- visible={!!(state.popupType && state.showPopup)}
708
- popupType={state.popupType || 'co2'}
709
- title={
710
- state.popupType === 'co2'
711
- ? I18n.getLang('consumption_data_field3_co2_topic_text')
712
- : ''
713
- }
714
- cancelText={state.popupType === 'co2' ? '' : I18n.getLang('auto_scan_system_cancel')}
715
- confirmText={I18n.getLang(
716
- state.popupType === 'co2'
717
- ? 'home_screen_home_dialog_yes_con'
718
- : 'auto_scan_system_wifi_confirm'
719
- )}
720
- energyData={{ price: state.popupType === 'money' ? (state.isSolarMode ? (energyData?.generatePrice ?? '0') : (energyData?.price ?? '0')) : state.price, unit: state.unit }}
721
- onConfirm={energyData => {
722
- state.popupType = '';
723
- state.showPopup = false;
724
- if (energyData) {
725
- updateEnergyData(energyData);
726
- }
727
- }}
728
- onCancel={() => {
729
- state.popupType = '';
730
- state.showPopup = false;
731
- }}
732
- />
733
- </View>
734
- </ScrollView>
735
- </Page>
770
+ </ScrollView>
771
+ </Page>
736
772
  );
737
773
  };
738
774