1
|
|
|
import React, { useContext, useState } from 'react'; |
2
|
|
|
import PropTypes from 'prop-types'; |
3
|
|
|
import { Badge, Col, Row } from 'reactstrap'; |
4
|
|
|
import { isIterableArray } from '../../../helpers/utils'; |
5
|
|
|
import Slider from 'react-slick/lib'; |
6
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
7
|
|
|
import Flex from '../../common/Flex'; |
8
|
|
|
import classNames from 'classnames'; |
9
|
|
|
import ButtonIcon from '../../common/ButtonIcon'; |
10
|
|
|
import AppContext, { ProductContext } from '../../../context/Context'; |
11
|
|
|
import { withTranslation } from 'react-i18next'; |
12
|
|
|
|
13
|
|
|
|
14
|
|
|
|
15
|
|
|
const EquipmentList = ({ |
16
|
|
|
id, |
17
|
|
|
files, |
18
|
|
|
title, |
19
|
|
|
category, |
20
|
|
|
features, |
21
|
|
|
parameter1, |
22
|
|
|
parameter2, |
23
|
|
|
parameter3, |
24
|
|
|
parameter4, |
25
|
|
|
parameter5, |
26
|
|
|
parameter6, |
27
|
|
|
parameter7, |
28
|
|
|
alarms, |
29
|
|
|
isOnline, |
30
|
|
|
isRunning, |
31
|
|
|
sliderSettings, |
32
|
|
|
index, |
33
|
|
|
t |
34
|
|
|
}) => { |
35
|
|
|
const { isDark } = useContext(AppContext); |
36
|
|
|
const { favouriteItemsDispatch } = useContext(ProductContext); |
37
|
|
|
const [cartLoading, setCartLoading] = useState(false); |
38
|
|
|
|
39
|
|
|
const handleAddToCart = () => { |
40
|
|
|
setCartLoading(true); |
41
|
|
|
setTimeout(() => { |
42
|
|
|
setCartLoading(false); |
43
|
|
|
}, 1000); |
44
|
|
|
}; |
45
|
|
|
|
46
|
|
|
return ( |
47
|
|
|
<Col xs={12} className={classNames('p-3', { 'bg-100': isDark && index % 2 !== 0 })}> |
48
|
|
|
<div className="p-1"> |
49
|
|
|
<Row> |
50
|
|
|
<Col sm={5} md={4}> |
51
|
|
|
<div className="position-relative h-sm-100"> |
52
|
|
|
{isIterableArray(files) && files.length === 1 && ( |
53
|
|
|
<img |
54
|
|
|
className="img-fluid fit-cover w-sm-100 h-sm-100 rounded absolute-sm-centered" |
55
|
|
|
src={files[0]['src'] || files[0]['base64']} |
56
|
|
|
alt={files[0].path} |
57
|
|
|
/> |
58
|
|
|
)} |
59
|
|
|
{isIterableArray(files) && files.length > 1 && ( |
60
|
|
|
<Slider {...sliderSettings}> |
61
|
|
|
{files.map(file => ( |
62
|
|
|
<img |
63
|
|
|
className="img-fluid fit-cover w-sm-100 h-sm-100 rounded" |
64
|
|
|
src={file['src'] || file['base64']} |
65
|
|
|
alt={file.path} |
66
|
|
|
/> |
67
|
|
|
))} |
68
|
|
|
</Slider> |
69
|
|
|
)} |
70
|
|
|
|
71
|
|
|
{isRunning && ( |
72
|
|
|
<Badge color="success" pill className="position-absolute t-0 r-0 mr-2 mt-2 fs--2 z-index-2"> |
73
|
|
|
运行 |
74
|
|
|
</Badge> |
75
|
|
|
)} |
76
|
|
|
</div> |
77
|
|
|
</Col> |
78
|
|
|
<Col sm={7} md={8}> |
79
|
|
|
<Row> |
80
|
|
|
<Col lg={8}> |
81
|
|
|
<h5 className="mt-3 mt-sm-0"> |
82
|
|
|
{title} |
83
|
|
|
</h5> |
84
|
|
|
<p className="fs--1 mb-2 mb-md-3"> |
85
|
|
|
<a className="text-500" href="#!"> |
86
|
|
|
{category} |
87
|
|
|
</a> |
88
|
|
|
</p> |
89
|
|
|
{isIterableArray(features) && ( |
90
|
|
|
<ul className="list-unstyled d-none d-lg-block"> |
91
|
|
|
{features.map((feature, index) => ( |
92
|
|
|
<li key={index}> |
93
|
|
|
<FontAwesomeIcon icon="circle" transform="shrink-12" /> |
94
|
|
|
<span>{feature}</span> |
95
|
|
|
</li> |
96
|
|
|
))} |
97
|
|
|
</ul> |
98
|
|
|
)} |
99
|
|
|
</Col> |
100
|
|
|
<Col lg={4} tag={Flex} justify="between" column> |
101
|
|
|
<div> |
102
|
|
|
<h4 className="fs-1 fs-md-2 text-warning mb-0"> |
103
|
|
|
{t('Instantaneous Efficiency VALUE UNIT', {'VALUE': parameter1, 'UNIT': '(kWh/kWh)'} )} |
104
|
|
|
</h4> |
105
|
|
|
<div className="d-none d-lg-block"> |
106
|
|
|
<p className="fs--1 mb-1">累计效率:<strong>{parameter2} kW/kW</strong></p> |
107
|
|
|
<p className="fs--1 mb-1">总瞬时功率:<strong>{parameter3} kW</strong></p> |
108
|
|
|
<p className="fs--1 mb-1">总功率因数:<strong>{parameter4}</strong></p> |
109
|
|
|
<p className="fs--1 mb-1">有功功率:<strong>{parameter5} kW</strong></p> |
110
|
|
|
<p className="fs--1 mb-1">冷冻水出水温度:<strong>{parameter6} degree C</strong></p> |
111
|
|
|
<p className="fs--1 mb-1">冷冻水回水温度:<strong>{parameter7} degree C</strong></p> |
112
|
|
|
<p className="fs--1 mb-1"> |
113
|
|
|
{t('Communication Status')}:{' '} |
114
|
|
|
<strong className={classNames({ 'text-success': isOnline, 'text-danger': !isOnline })}> |
115
|
|
|
{isOnline ? t('Communication Online') : t('Communication Offline')} |
116
|
|
|
</strong> |
117
|
|
|
</p> |
118
|
|
|
<p className="fs--1 mb-1"> |
119
|
|
|
{t('Equipment Status')}:{' '} |
120
|
|
|
<strong className={classNames({ 'text-success': isRunning, 'text-danger': !isRunning })}> |
121
|
|
|
{isRunning ? t('Equipment Running') : t('Equipment Stopped')} |
122
|
|
|
</strong> |
123
|
|
|
</p> |
124
|
|
|
</div> |
125
|
|
|
</div> |
126
|
|
|
<div className="mt-md-2"> |
127
|
|
|
<ButtonIcon |
128
|
|
|
color={isRunning ? 'outline-danger' : 'outline-secondary'} |
129
|
|
|
size="sm" |
130
|
|
|
className={classNames('w-lg-100 mt-2 mr-2 mr-lg-0', { |
131
|
|
|
'border-300': !isRunning |
132
|
|
|
})} |
133
|
|
|
icon={[isRunning ? 'fas' : 'far', 'exclamation-triangle']} |
134
|
|
|
onClick={() => |
135
|
|
|
isRunning |
136
|
|
|
? favouriteItemsDispatch({ type: 'REMOVE', id }) |
137
|
|
|
: favouriteItemsDispatch({ type: 'ADD', payload: { id } }) |
138
|
|
|
} |
139
|
|
|
> |
140
|
|
|
{t('Fault Alarms')}({alarms.length}) |
141
|
|
|
</ButtonIcon> |
142
|
|
|
{cartLoading ? ( |
143
|
|
|
<ButtonIcon |
144
|
|
|
color="primary" |
145
|
|
|
size="sm" |
146
|
|
|
icon="circle-notch" |
147
|
|
|
iconClassName="fa-spin ml-2 d-none d-md-inline-block" |
148
|
|
|
className="w-lg-100 mt-2" |
149
|
|
|
style={{ cursor: 'progress' }} |
150
|
|
|
disabled |
151
|
|
|
> |
152
|
|
|
Processing |
153
|
|
|
</ButtonIcon> |
154
|
|
|
) : ( |
155
|
|
|
<ButtonIcon |
156
|
|
|
color="primary" |
157
|
|
|
size="sm" |
158
|
|
|
icon="users" |
159
|
|
|
iconClassName="ml-2 d-none d-md-inline-block" |
160
|
|
|
className="w-lg-100 mt-2" |
161
|
|
|
onClick={handleAddToCart} |
162
|
|
|
> |
163
|
|
|
{t('Run Commands')} |
164
|
|
|
</ButtonIcon> |
165
|
|
|
)} |
166
|
|
|
</div> |
167
|
|
|
</Col> |
168
|
|
|
</Row> |
169
|
|
|
</Col> |
170
|
|
|
</Row> |
171
|
|
|
</div> |
172
|
|
|
</Col> |
173
|
|
|
); |
174
|
|
|
}; |
175
|
|
|
|
176
|
|
|
EquipmentList.propTypes = { |
177
|
|
|
title: PropTypes.string.isRequired, |
178
|
|
|
category: PropTypes.string.isRequired, |
179
|
|
|
sliderSettings: PropTypes.object.isRequired, |
180
|
|
|
files: PropTypes.array, |
181
|
|
|
parameter1: PropTypes.number, |
182
|
|
|
parameter2: PropTypes.number, |
183
|
|
|
parameter3: PropTypes.number, |
184
|
|
|
parameter4: PropTypes.number, |
185
|
|
|
parameter5: PropTypes.number, |
186
|
|
|
parameter6: PropTypes.number, |
187
|
|
|
parameter7: PropTypes.number, |
188
|
|
|
cumulativePerformance: PropTypes.number, |
189
|
|
|
alarms: PropTypes.array, |
190
|
|
|
isOnline: PropTypes.bool, |
191
|
|
|
isRunning: PropTypes.bool, |
192
|
|
|
features: PropTypes.array |
193
|
|
|
}; |
194
|
|
|
|
195
|
|
|
EquipmentList.defaultProps = { isRunning: false, isOnline: false, files: [] }; |
196
|
|
|
|
197
|
|
|
export default withTranslation()(EquipmentList); |
198
|
|
|
|