@tuya-sat/sdf-main-sdk 0.0.1-beta.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.
Files changed (147) hide show
  1. package/.vscode/settings.json +5 -0
  2. package/README.md +1 -0
  3. package/antd.less.overwrite.js +56 -0
  4. package/color.js +140 -0
  5. package/dark-variable.less +1449 -0
  6. package/package.json +74 -0
  7. package/scripts/gen-localize-file.mjs +56 -0
  8. package/src/App.less +156 -0
  9. package/src/App.tsx +87 -0
  10. package/src/api/index.ts +52 -0
  11. package/src/api/req.ts +23 -0
  12. package/src/api/res.ts +29 -0
  13. package/src/api/urls.ts +30 -0
  14. package/src/api/utils.ts +41 -0
  15. package/src/assets/imgs/404.svg +194 -0
  16. package/src/assets/imgs/reLogin.png +0 -0
  17. package/src/components/404/index.tsx +44 -0
  18. package/src/components/500/index.tsx +49 -0
  19. package/src/components/BCustomNav/index.module.less +17 -0
  20. package/src/components/BCustomNav/index.tsx +108 -0
  21. package/src/components/BForgot/index.module.less +5 -0
  22. package/src/components/BForgot/index.tsx +96 -0
  23. package/src/components/BHeaderUser/account.png +0 -0
  24. package/src/components/BHeaderUser/app-scan-en.png +0 -0
  25. package/src/components/BHeaderUser/app-scan-zh.png +0 -0
  26. package/src/components/BHeaderUser/app-scan.png +0 -0
  27. package/src/components/BHeaderUser/components/BSwitchLang/index.module.less +6 -0
  28. package/src/components/BHeaderUser/components/BSwitchLang/index.tsx +56 -0
  29. package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/Content.tsx +199 -0
  30. package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/index.module.less +11 -0
  31. package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/index.tsx +27 -0
  32. package/src/components/BHeaderUser/components/Badge/components/Notice/hooks.ts +104 -0
  33. package/src/components/BHeaderUser/components/Badge/components/Notice/index.module.less +70 -0
  34. package/src/components/BHeaderUser/components/Badge/components/Notice/index.tsx +184 -0
  35. package/src/components/BHeaderUser/components/Badge/components/Notice/table/index.tsx +184 -0
  36. package/src/components/BHeaderUser/components/Badge/components/Notice/table/read.tsx +67 -0
  37. package/src/components/BHeaderUser/components/Badge/components/Notice/tools/index.tsx +116 -0
  38. package/src/components/BHeaderUser/components/Badge/index.module.less +99 -0
  39. package/src/components/BHeaderUser/components/Badge/index.tsx +179 -0
  40. package/src/components/BHeaderUser/index.module.less +105 -0
  41. package/src/components/BHeaderUser/index.tsx +261 -0
  42. package/src/components/BHeaderUser/logout.tsx +26 -0
  43. package/src/components/BLayout/components/Header/index.module.less +27 -0
  44. package/src/components/BLayout/components/Header/index.tsx +36 -0
  45. package/src/components/BLayout/components/Layout/empty.tsx +35 -0
  46. package/src/components/BLayout/components/Layout/emptyPage.png +0 -0
  47. package/src/components/BLayout/components/Layout/index.tsx +72 -0
  48. package/src/components/BLayout/components/Logo.tsx +6 -0
  49. package/src/components/BLayout/components/Menu/collapse.tsx +41 -0
  50. package/src/components/BLayout/components/Menu/image/close.tsx +26 -0
  51. package/src/components/BLayout/components/Menu/image/closedefault.tsx +26 -0
  52. package/src/components/BLayout/components/Menu/image/open.tsx +38 -0
  53. package/src/components/BLayout/components/Menu/image/opendefault.tsx +38 -0
  54. package/src/components/BLayout/components/Menu/index.module.less +125 -0
  55. package/src/components/BLayout/components/Menu/index.tsx +244 -0
  56. package/src/components/BLayout/components/MenuIcon.module.less +5 -0
  57. package/src/components/BLayout/components/MenuIcon.tsx +46 -0
  58. package/src/components/BLayout/components/MultiSider/index.module.less +104 -0
  59. package/src/components/BLayout/components/MultiSider/index.tsx +172 -0
  60. package/src/components/BLayout/components/Sider/index.less +64 -0
  61. package/src/components/BLayout/components/Sider/index.module.less +17 -0
  62. package/src/components/BLayout/components/Sider/index.tsx +34 -0
  63. package/src/components/BLayout/index.tsx +78 -0
  64. package/src/components/BLayoutLogin/index.module.less +65 -0
  65. package/src/components/BLayoutLogin/index.tsx +68 -0
  66. package/src/components/BLayoutLogin/login.jpg +0 -0
  67. package/src/components/BLogin/component/Clause/index.module.less +25 -0
  68. package/src/components/BLogin/component/Clause/index.tsx +58 -0
  69. package/src/components/BLogin/component/ForgotBtn/index.module.less +9 -0
  70. package/src/components/BLogin/component/ForgotBtn/index.tsx +18 -0
  71. package/src/components/BLogin/component/Password/index.tsx +39 -0
  72. package/src/components/BLogin/component/SubmitBtn/index.tsx +30 -0
  73. package/src/components/BLogin/component/TenanSpace/index.tsx +28 -0
  74. package/src/components/BLogin/component/Title/index.module.less +6 -0
  75. package/src/components/BLogin/component/Title/index.tsx +12 -0
  76. package/src/components/BLogin/component/UserName/index.tsx +48 -0
  77. package/src/components/BLogin/component/VerifyCode/index.module.less +11 -0
  78. package/src/components/BLogin/component/VerifyCode/index.tsx +165 -0
  79. package/src/components/BLogin/index.module.less +31 -0
  80. package/src/components/BLogin/index.tsx +210 -0
  81. package/src/components/BRegister/components/TenantName/index.tsx +26 -0
  82. package/src/components/BRegister/index.module.less +5 -0
  83. package/src/components/BRegister/index.tsx +71 -0
  84. package/src/components/Back/index.tsx +25 -0
  85. package/src/components/IconFont/font.js +66 -0
  86. package/src/components/IconFont/index.tsx +18 -0
  87. package/src/components/MicroComponent/Header/index.module.less +7 -0
  88. package/src/components/MicroComponent/Header/index.tsx +220 -0
  89. package/src/components/PForgot/index.tsx +10 -0
  90. package/src/components/PLogin/index.tsx +12 -0
  91. package/src/components/PRegister/index.tsx +10 -0
  92. package/src/components/PSetting/index.module.less +53 -0
  93. package/src/components/PSetting/index.tsx +420 -0
  94. package/src/constant/chargeStatus.ts +6 -0
  95. package/src/constant/imgs.ts +6 -0
  96. package/src/constant/index.ts +293 -0
  97. package/src/dark-variable.less +1449 -0
  98. package/src/global.d.ts +54 -0
  99. package/src/hooks/index.ts +133 -0
  100. package/src/index.css +1493 -0
  101. package/src/index.tsx +105 -0
  102. package/src/lang/en.json +266 -0
  103. package/src/lang/index.ts +44 -0
  104. package/src/lang/utils.ts +285 -0
  105. package/src/lang/zh.json +270 -0
  106. package/src/micro-script/theme/index.ts +29 -0
  107. package/src/micro-script/theme/theme-css/static.js +73 -0
  108. package/src/micro-script/theme/theme-css/subscriber.ts +201 -0
  109. package/src/micro-script/theme/util/index.ts +58 -0
  110. package/src/mqtt/index.ts +121 -0
  111. package/src/pages/403.tsx +18 -0
  112. package/src/pages/404.tsx +17 -0
  113. package/src/pages/expiration.tsx +23 -0
  114. package/src/pages/forgot.tsx +9 -0
  115. package/src/pages/home/index.tsx +172 -0
  116. package/src/pages/home/setting/index.tsx +7 -0
  117. package/src/pages/index.ts +50 -0
  118. package/src/pages/login.tsx +46 -0
  119. package/src/pages/register.tsx +9 -0
  120. package/src/pages/relogin/index.module.less +0 -0
  121. package/src/pages/relogin/index.tsx +54 -0
  122. package/src/plugins/index.ts +11 -0
  123. package/src/public-path.js +8 -0
  124. package/src/qiankun/globalState.ts +6 -0
  125. package/src/qiankun/index.ts +174 -0
  126. package/src/qiankun/utils/index.ts +69 -0
  127. package/src/qiankun/xhook/index.ts +193 -0
  128. package/src/reportWebVitals.ts +15 -0
  129. package/src/sentry/index.ts +33 -0
  130. package/src/sky/index.ts +57 -0
  131. package/src/theme/custom-dark.less +64 -0
  132. package/src/theme/custom-light.less +48 -0
  133. package/src/theme/index.less +327 -0
  134. package/src/theme/variable.less +13 -0
  135. package/src/utils/checkPass.ts +21 -0
  136. package/src/utils/common.ts +195 -0
  137. package/src/utils/eventBus.ts +112 -0
  138. package/src/utils/gt.js +293 -0
  139. package/src/utils/index.ts +89 -0
  140. package/src/utils/theme/base.ts +110 -0
  141. package/src/utils/theme/changeCssVariable.ts +157 -0
  142. package/src/utils/theme/changeMenuCssVariable.ts +176 -0
  143. package/src/utils/theme/index.ts +85 -0
  144. package/src/utils/theme/store.ts +37 -0
  145. package/tsconfig.json +28 -0
  146. package/typings.d.ts +10 -0
  147. package/webpack.config.js +103 -0
@@ -0,0 +1,420 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { Modal, Form, Input, message, Typography, Divider, Select } from 'antd';
3
+ import { useTranslation } from 'react-i18next';
4
+ import styles from './index.module.less';
5
+ import { api, URLS } from '@/api';
6
+ import { sha256 } from 'js-sha256';
7
+ import { useHistory } from 'react-router-dom';
8
+ import { getCurrentUser, safeLogout } from '@/utils/common';
9
+ import { checkPassWord } from '@/utils/checkPass';
10
+ import Back from '../Back';
11
+ import cx from 'classnames';
12
+ import { EMAIL_REGEXP, US_TELE_REGEXP, COUNTRY_LIST } from '@/constant';
13
+ import { getI18n } from 'react-i18next';
14
+ import { eventEmiter, eventNames } from '@/utils';
15
+
16
+ const { Link, Text } = Typography;
17
+
18
+ const SettingPage = () => {
19
+ const [visible, setVisible] = useState(false);
20
+ const [isModalVisible, setIsModalVisible] = useState(false);
21
+ const [modalType, setModalType] = useState('');
22
+ const [modalTitle, setModalTitle] = useState('');
23
+ const { t, i18n } = useTranslation();
24
+ const [nickname, setNickName] = useState(
25
+ window._SDF?.user?.user_nick_name || ''
26
+ );
27
+ const [username, setUsername] = useState(window._SDF?.user?.user_name || '');
28
+ const [phone, setPhone] = useState(window._SDF?.user?.mobile || '');
29
+ const [email, setEmail] = useState(window._SDF?.user?.email || '');
30
+ const [regionCode, setRegionCode] = useState(
31
+ window._SDF?.user?.country_code || ''
32
+ );
33
+ const history = useHistory();
34
+ const currentUser = getCurrentUser();
35
+
36
+ const ModifyPwdModal = () => {
37
+ const [form] = Form.useForm();
38
+ const handleSubmit = () => {
39
+ form
40
+ .validateFields()
41
+ .then(async (values) => {
42
+ const res = await api.put(URLS.RESET_PWD, {
43
+ user_name: currentUser?.user_name,
44
+ current_password: sha256(values.oldPassword),
45
+ new_password: sha256(values.newPassword),
46
+ });
47
+
48
+ if (res) {
49
+ form.resetFields();
50
+ setVisible(false);
51
+ message.success(t('setting.modifySuccess'));
52
+ safeLogout(history);
53
+ }
54
+ })
55
+ .catch(() => {});
56
+ };
57
+ return (
58
+ <Modal
59
+ title={t('setting.modify')}
60
+ visible={visible}
61
+ closable={true}
62
+ onOk={handleSubmit}
63
+ onCancel={() => {
64
+ setVisible(false);
65
+ form.resetFields();
66
+ }}
67
+ destroyOnClose
68
+ >
69
+ <Form
70
+ form={form}
71
+ layout="vertical"
72
+ labelCol={{ span: i18n.language === 'zh' ? 5 : 9 }}
73
+ >
74
+ <Form.Item
75
+ label={t('setting.form.oldPassword.label')}
76
+ required
77
+ name="oldPassword"
78
+ rules={[
79
+ {
80
+ required: true,
81
+ message: t('setting.form.oldPassword.validate.require'),
82
+ },
83
+ ]}
84
+ >
85
+ <Input.Password
86
+ placeholder={t('setting.form.oldPassword.validate.require')}
87
+ />
88
+ </Form.Item>
89
+ <Form.Item
90
+ label={t('setting.form.newPassword.label')}
91
+ required
92
+ name="newPassword"
93
+ rules={[
94
+ {
95
+ required: true,
96
+ message: t('setting.form.newPassword.validate.require'),
97
+ },
98
+ () => ({
99
+ validator(_, value: string) {
100
+ const result = checkPassWord(value);
101
+ if (result) return Promise.resolve();
102
+ const tip = t('setting.form.newPassword.validate.pattern');
103
+ return Promise.reject(new Error(tip));
104
+ },
105
+ }),
106
+ ]}
107
+ >
108
+ <Input.Password
109
+ placeholder={t('setting.form.newPassword.validate.require')}
110
+ />
111
+ </Form.Item>
112
+ <Form.Item
113
+ label={t('setting.form.confirm.label')}
114
+ required
115
+ dependencies={['newPassword']}
116
+ name="confirmPassword"
117
+ rules={[
118
+ {
119
+ required: true,
120
+ message: t('setting.form.confirm.validate.require'),
121
+ },
122
+ ({ getFieldValue }) => ({
123
+ validator(_, value) {
124
+ if (value && getFieldValue('newPassword') === value) {
125
+ return Promise.resolve();
126
+ }
127
+ return Promise.reject(
128
+ new Error(t('setting.form.confirm.validate.unanimous'))
129
+ );
130
+ },
131
+ }),
132
+ ]}
133
+ >
134
+ <Input.Password
135
+ placeholder={t('setting.form.confirm.validate.require')}
136
+ />
137
+ </Form.Item>
138
+ </Form>
139
+ </Modal>
140
+ );
141
+ };
142
+
143
+ const CommonModal = ({ title, type }) => {
144
+ const [selectValue, setSelectValue] = useState<string>('86');
145
+ const [form] = Form.useForm();
146
+
147
+ const rules = [
148
+ () => ({
149
+ validator(_, value) {
150
+ if (!value) {
151
+ return Promise.reject(
152
+ new Error(
153
+ type.includes('Phone')
154
+ ? t('setting.phoneLable')
155
+ : t('setting.emailLable')
156
+ )
157
+ );
158
+ }
159
+ if (type.includes('Phone')) {
160
+ if (US_TELE_REGEXP.test(value)) {
161
+ return Promise.resolve();
162
+ } else {
163
+ return Promise.reject(
164
+ new Error(t('login.form.username.validate.phonePattern'))
165
+ );
166
+ }
167
+ } else {
168
+ if (EMAIL_REGEXP.test(value)) {
169
+ return Promise.resolve();
170
+ } else {
171
+ return Promise.reject(
172
+ new Error(t('login.form.username.validate.emailPattern'))
173
+ );
174
+ }
175
+ }
176
+ },
177
+ }),
178
+ ];
179
+ const handleOk = () => {
180
+ form.validateFields().then(async (values) => {
181
+ const params = type.includes('Phone')
182
+ ? {
183
+ mobile: values.val.phone,
184
+ email: email || '',
185
+ country_code: values.val.region || '86',
186
+ }
187
+ : {
188
+ mobile: phone || '',
189
+ email: values.val,
190
+ };
191
+
192
+ api.put(URLS.ModifyPhoneAndEmail, { ...params }).then((res) => {
193
+ api.get(URLS.USER_INFO).then((res) => {
194
+ setUsername(res.user_name);
195
+ setPhone(res.mobile);
196
+ setEmail(res.email);
197
+ eventEmiter.emit(eventNames.USER_NAME, res.user_name);
198
+ });
199
+ setIsModalVisible(false);
200
+ });
201
+ });
202
+ };
203
+ const handleCancel = () => {
204
+ setIsModalVisible(false);
205
+ };
206
+ return (
207
+ <Modal
208
+ title={title}
209
+ visible={isModalVisible}
210
+ onOk={handleOk}
211
+ onCancel={handleCancel}
212
+ >
213
+ <Form form={form}>
214
+ {type.includes('Phone') ? (
215
+ <Form.Item label={t('setting.phone')}>
216
+ <Input.Group compact>
217
+ <Form.Item name={['val', 'region']} noStyle>
218
+ <Select
219
+ dropdownMatchSelectWidth={false}
220
+ defaultValue={'86'}
221
+ labelInValue={false}
222
+ value={selectValue}
223
+ style={{ width: '22%' }}
224
+ optionLabelProp="lable"
225
+ onChange={(value: string) => {
226
+ setSelectValue(`+${value}`);
227
+ }}
228
+ >
229
+ {COUNTRY_LIST.map((country) => (
230
+ <Select.Option
231
+ key={country.countryCode}
232
+ value={country.countryCode}
233
+ lable={`+${country.countryCode}`}
234
+ >
235
+ {getI18n().language === 'zh'
236
+ ? country.cnName
237
+ : country.enName}
238
+ (+
239
+ {country.countryCode})
240
+ </Select.Option>
241
+ ))}
242
+ </Select>
243
+ </Form.Item>
244
+ <Form.Item name={['val', 'phone']} noStyle rules={rules}>
245
+ <Input style={{ width: '78%' }} />
246
+ </Form.Item>
247
+ </Input.Group>
248
+ </Form.Item>
249
+ ) : (
250
+ <Form.Item
251
+ name="val"
252
+ label={t('setting.email')}
253
+ rules={rules}
254
+ labelAlign="right"
255
+ >
256
+ <Input />
257
+ </Form.Item>
258
+ )}
259
+ </Form>
260
+ </Modal>
261
+ );
262
+ };
263
+ const Header = () => {
264
+ return (
265
+ <div className={styles.header}>
266
+ <Back />
267
+ <h3>{t('setting.title')}</h3>
268
+ </div>
269
+ );
270
+ };
271
+ const NickName = ({ nickname }) => {
272
+ return (
273
+ <div>
274
+ <div className={styles['setting-item']}>
275
+ <div style={{ width: '360px', marginLeft: '10px' }}>
276
+ {t('setting.name')}
277
+ </div>
278
+ <div style={{ width: '360px' }}> {nickname || '-'}</div>
279
+ </div>
280
+ <Divider style={{ marginTop: '0', marginBottom: '0' }} />
281
+ </div>
282
+ );
283
+ };
284
+
285
+ const Account = ({ username }) => {
286
+ return (
287
+ <div>
288
+ <div className={styles['setting-item']}>
289
+ <div style={{ width: '360px', marginLeft: '10px' }}>
290
+ {t('setting.accountLable')}
291
+ </div>
292
+ <div style={{ width: '360px' }}> {username}</div>
293
+ </div>
294
+ <Divider style={{ marginTop: '0', marginBottom: '0' }} />
295
+ </div>
296
+ );
297
+ };
298
+
299
+ const Phone = ({ phone }) => {
300
+ return (
301
+ <div>
302
+ <div className={styles['setting-item']}>
303
+ <div style={{ width: '360px', marginLeft: '10px' }}>
304
+ {t('setting.phone')}
305
+ </div>
306
+ {phone ? (
307
+ <div style={{ width: '360px' }}> {phone}</div>
308
+ ) : (
309
+ <Text type="warning" style={{ width: '360px' }}>
310
+ {t('setting.unBind')}
311
+ </Text>
312
+ )}
313
+
314
+ <Link
315
+ style={{ marginLeft: '10px' }}
316
+ onClick={() => {
317
+ if (phone) {
318
+ setModalTitle(t('setting.modifyPhone'));
319
+ setModalType('modifyPhone');
320
+ } else {
321
+ setModalTitle(t('setting.bindPhone'));
322
+ setModalType('bindPhone');
323
+ }
324
+ setIsModalVisible(true);
325
+ }}
326
+ >
327
+ {phone ? t('setting.modify') : t('setting.bind')}
328
+ </Link>
329
+ </div>
330
+ <Divider style={{ marginTop: '0', marginBottom: '0' }} />
331
+ </div>
332
+ );
333
+ };
334
+
335
+ const Email = ({ email }) => {
336
+ return (
337
+ <div>
338
+ <div className={styles['setting-item']}>
339
+ <div style={{ width: '360px', marginLeft: '10px' }}>
340
+ {t('setting.email')}
341
+ </div>
342
+ {email ? (
343
+ <div style={{ width: '360px' }}> {email}</div>
344
+ ) : (
345
+ <Text type="warning" style={{ width: '360px' }}>
346
+ {t('setting.unBind')}
347
+ </Text>
348
+ )}
349
+ <Link
350
+ style={{ marginLeft: '10px' }}
351
+ onClick={() => {
352
+ if (email) {
353
+ setModalTitle(t('setting.modifyEmail'));
354
+ setModalType('modifyEmail');
355
+ } else {
356
+ setModalTitle(t('setting.bindEmail'));
357
+ setModalType('bindEmail');
358
+ }
359
+ setIsModalVisible(true);
360
+ }}
361
+ >
362
+ {email ? t('setting.modify') : t('setting.bind')}
363
+ </Link>
364
+ </div>
365
+ <Divider style={{ marginTop: '0', marginBottom: '0' }} />
366
+ </div>
367
+ );
368
+ };
369
+ const ModifyPwd = () => {
370
+ return (
371
+ <div>
372
+ <div className={styles['setting-item']}>
373
+ <div style={{ width: '360px', marginLeft: '10px' }}>
374
+ {t('setting.password')}
375
+ </div>
376
+ <div style={{ width: '360px' }}> ******</div>
377
+ <Link
378
+ style={{ marginLeft: '10px' }}
379
+ onClick={() => {
380
+ setVisible(true);
381
+ }}
382
+ >
383
+ {t('setting.modify')}
384
+ </Link>
385
+ </div>
386
+ <Divider style={{ marginTop: '0', marginBottom: '0' }} />
387
+ </div>
388
+ );
389
+ };
390
+
391
+ useEffect(() => {
392
+ api.get(URLS.USER_INFO).then((res) => {
393
+ setNickName(res.user_nick_name);
394
+ setUsername(res.user_name);
395
+ setPhone(res.mobile);
396
+ setEmail(res.email);
397
+ setRegionCode(res.country_code);
398
+ });
399
+ }, []);
400
+
401
+ return (
402
+ <div className={styles['page-container']}>
403
+ <div className={cx(styles['page-content'], 'main-app-setting')}>
404
+ <Header />
405
+ <NickName nickname={nickname} />
406
+ <Account username={username} />
407
+ {window._SDF_CONFIG?.features.is_edgecloud !== true && (
408
+ <>
409
+ <Phone phone={phone} />
410
+ <Email email={email} />
411
+ </>
412
+ )}
413
+ <ModifyPwd />
414
+ </div>
415
+ <ModifyPwdModal />
416
+ <CommonModal title={modalTitle} type={modalType} />
417
+ </div>
418
+ );
419
+ };
420
+ export default SettingPage;
@@ -0,0 +1,6 @@
1
+ export const CHARGE_STATUS = {
2
+ PERMANENT: 'PERMANENT', // 长期有效
3
+ TRIAL: 'TRIAL', // 试用中
4
+ STABLE: 'STABLE', // 已开通
5
+ EXPIRED: 'EXPIRED', // 已过期
6
+ };
@@ -0,0 +1,6 @@
1
+ const TuyaLogo =
2
+ 'https://images.tuyacn.com/rms-static/3bb090e0-d7e2-11eb-815d-e39234ce96ff-1624865222894.png?tyName=tuyalogo.png';
3
+ const ExpirationLogo =
4
+ 'https://images.tuyacn.com/rms-static/f522c5e0-c056-11ec-838b-296cc196f8cc-1650424025406.png?tyName=%E7%BC%BA%E7%9C%81%E9%A1%B5%E9%85%8D%E5%9B%BE%402x.png';
5
+
6
+ export { TuyaLogo, ExpirationLogo };