@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,172 @@
1
+ import { Layout } from 'antd';
2
+ import { CSSProperties, useEffect, useRef, useState } from 'react';
3
+ import cx from 'classnames';
4
+ import MenuIcon from '../MenuIcon';
5
+ import { useLocation, useHistory } from 'react-router-dom';
6
+ import Menu, { IMenu, MenuType } from '../Menu';
7
+ import { getDeepestPath } from '@/utils/common';
8
+ import styles from './index.module.less';
9
+ import { useTranslation } from 'react-i18next';
10
+ import { checkMenuVersion } from '@/utils';
11
+ import CollapseButton from '../Menu/collapse';
12
+ interface Noop {
13
+ (): void;
14
+ }
15
+
16
+ const { Sider } = Layout;
17
+
18
+ const Group = ({
19
+ name,
20
+ icon,
21
+ style = {},
22
+ isActive,
23
+ onActive,
24
+ onHover,
25
+ }: {
26
+ name: string;
27
+ icon: string;
28
+ style?: CSSProperties;
29
+ isActive: boolean;
30
+ onActive: Noop;
31
+ onHover: Noop;
32
+ }) => {
33
+ let timer = null;
34
+
35
+ return (
36
+ <li
37
+ style={style}
38
+ className={cx({
39
+ [styles['groupItem']]: true,
40
+ 'main-group-item': true,
41
+ 'main-group-active': isActive,
42
+ })}
43
+ onClick={onActive}
44
+ onMouseEnter={() => {
45
+ timer = setTimeout(onHover, 100);
46
+ }}
47
+ onMouseLeave={() => clearTimeout(timer)}
48
+ >
49
+ <MenuIcon src={icon} style={{ width: 16, height: 16, marginTop: 0 }} />
50
+ <div className={styles['groupName']}>{name}</div>
51
+ </li>
52
+ );
53
+ };
54
+
55
+ const findGroupByPath = (menus, pathname) => {
56
+ return menus.find(({ sub_entry_list }) => {
57
+ return sub_entry_list.some(({ path }) => pathname.includes(path));
58
+ });
59
+ };
60
+
61
+ export default function MultiSider({ menus }: { menus: Array<IMenu> }) {
62
+ const { pathname } = useLocation();
63
+ const [collapsed, setCollapsed] = useState<boolean>(false);
64
+ const [subMenus, setSubMenus] = useState<Array<IMenu>>([]);
65
+ const [groupName, setGroupName] = useState<string>();
66
+ const [groupId, setGroupId] = useState<string>();
67
+ const activeMenus = useRef<Array<IMenu>>();
68
+ const activeName = useRef<string>();
69
+
70
+ const history = useHistory();
71
+ const { i18n } = useTranslation();
72
+
73
+ useEffect(() => {
74
+ if (menus.length) {
75
+ let group = null;
76
+ if (pathname !== '/') {
77
+ group = findGroupByPath(menus, pathname) || menus[0];
78
+ }
79
+ setSubMenus(group.sub_entry_list);
80
+ setGroupName(group.entry_name);
81
+ setGroupId(group.entry_id);
82
+ activeMenus.current = group.sub_entry_list;
83
+ activeName.current = group.entry_name;
84
+ }
85
+ }, [menus, pathname]);
86
+
87
+ const handleGroupActive = (group: IMenu) => {
88
+ const { entry_id, entry_name, sub_entry_list } = group;
89
+ if (entry_id !== groupId) {
90
+ setGroupName(entry_name);
91
+ setSubMenus(sub_entry_list);
92
+ setGroupId(entry_id);
93
+ activeMenus.current = sub_entry_list;
94
+ activeName.current = entry_name;
95
+ setCollapsed(false);
96
+ history.push(getDeepestPath(sub_entry_list[0]));
97
+ }
98
+ };
99
+
100
+ const toggleCollapsed = () => {
101
+ setCollapsed((pre) => !pre);
102
+ };
103
+
104
+ return (
105
+ <Sider className={styles.sider}>
106
+ <ul className={cx(styles.group, 'main-group')}>
107
+ {menus.map((group, index) => {
108
+ const { entry_id, entry_name, icon, sub_entry_list } = group;
109
+ return (
110
+ <div key={index} className={styles['group-menu']}>
111
+ <Group
112
+ style={{ position: 'relative', zIndex: 4 }}
113
+ key={entry_id}
114
+ name={entry_name}
115
+ icon={icon}
116
+ isActive={groupId === entry_id}
117
+ onActive={() => handleGroupActive(group)}
118
+ onHover={() => {}}
119
+ />
120
+ {groupId !== entry_id && (
121
+ <div
122
+ className={cx(
123
+ styles.fakeMenu,
124
+ checkMenuVersion(menus)
125
+ ? styles.fakeMenu182
126
+ : i18n.language === 'zh'
127
+ ? styles.fakeMenu132
128
+ : styles.fakeMenu156,
129
+ 'main-fake-menu',
130
+ )}
131
+ >
132
+ <Menu
133
+ name={entry_name}
134
+ menus={sub_entry_list}
135
+ mode={MenuType.GROUP}
136
+ showCollapsed={false}
137
+ collapsed={false}
138
+ />
139
+ </div>
140
+ )}
141
+ <div className={cx(styles.groupCover, 'main-group-cover')}></div>
142
+ </div>
143
+ );
144
+ })}
145
+ </ul>
146
+ <div
147
+ className={cx(styles.menuContainer, 'main-app-menu-containter')}
148
+ style={{
149
+ width: collapsed
150
+ ? 0
151
+ : checkMenuVersion(menus)
152
+ ? 182
153
+ : i18n.language === 'zh'
154
+ ? 132
155
+ : 156,
156
+ }}
157
+ >
158
+ <Menu
159
+ name={groupName}
160
+ menus={subMenus}
161
+ mode={MenuType.GROUP}
162
+ showCollapsed={false}
163
+ collapsed={false}
164
+ />
165
+ <CollapseButton
166
+ collapsed={collapsed}
167
+ toggleCollapsed={toggleCollapsed}
168
+ />
169
+ </div>
170
+ </Sider>
171
+ );
172
+ }
@@ -0,0 +1,64 @@
1
+ .sider {
2
+ height: calc(100vh - 56px);
3
+ background-color: #fff !important;
4
+ :global {
5
+ .ant-layout-sider-children {
6
+ display: flex;
7
+ align-items: flex-start;
8
+ }
9
+ }
10
+ .group {
11
+ height: 100%;
12
+ padding: 8px 0;
13
+ border-right: 1px solid #f0f2f5;
14
+ overflow-y: auto;
15
+ min-width: 84px;
16
+ overflow-x: hidden;
17
+ &::-webkit-scrollbar-thumb {
18
+ border-radius: 10px;
19
+ box-shadow: inset 0 0 3px 3px #c1c1c1;
20
+ border: solid 2px transparent;
21
+ background: #fff;
22
+ &:hover {
23
+ box-shadow: inset 0 0 3px 3px #7d7d7d;
24
+ }
25
+ }
26
+ &::-webkit-scrollbar {
27
+ width: 7px;
28
+ }
29
+ &::-webkit-scrollbar-track {
30
+ width: 7px;
31
+ background: #fff;
32
+ }
33
+ .groupItem {
34
+ width: 84px;
35
+ height: 60px;
36
+ cursor: pointer;
37
+ display: flex;
38
+ flex-flow: column nowrap;
39
+ justify-content: space-around;
40
+ align-items: center;
41
+ padding: 6px 0;
42
+ box-sizing: content-box;
43
+ &:not(:last-child) {
44
+ margin-bottom: 8px;
45
+ }
46
+ .groupName {
47
+ text-align: center;
48
+ width: 100%;
49
+ white-space: nowrap;
50
+ overflow: hidden;
51
+ text-overflow: ellipsis;
52
+ }
53
+ &:hover {
54
+ color: #1890ff;
55
+ }
56
+ }
57
+ .groupActive {
58
+ background-color: #e6f7ff;
59
+ .groupName {
60
+ color: #1890ff;
61
+ }
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,17 @@
1
+ .sider {
2
+ height: calc(100vh - 48px);
3
+ background-color: #fff;
4
+ z-index: 9;
5
+ :global {
6
+ .main-layout-sider-children {
7
+ display: flex;
8
+ align-items: flex-start;
9
+ }
10
+ }
11
+ }
12
+ .group {
13
+ width: 100%;
14
+ height: 100%;
15
+ position: relative;
16
+ transition: all 0.3s;
17
+ }
@@ -0,0 +1,34 @@
1
+ import { Layout } from 'antd';
2
+ import { useState, useEffect } from 'react';
3
+ import Menu, { IMenu, MenuType } from '../Menu';
4
+ import CollapseButton from '../Menu/collapse';
5
+ import styles from './index.module.less';
6
+
7
+ const { Sider } = Layout;
8
+
9
+ // eslint-disable-next-line import/no-anonymous-default-export
10
+ export default function SingleSider({ menus }: { menus: Array<IMenu> }) {
11
+ const [collapsed, setCollapsed] = useState<boolean>(false);
12
+
13
+ const toggleCollapsed = () => {
14
+ setCollapsed((pre) => !pre);
15
+ };
16
+
17
+ return (
18
+ <Sider
19
+ width={208}
20
+ collapsed={collapsed}
21
+ collapsedWidth={48}
22
+ className={styles.sider}
23
+ >
24
+ <Menu
25
+ menus={menus}
26
+ mode={MenuType.NORMAL}
27
+ showCollapsed={true}
28
+ collapsed={collapsed}
29
+ />
30
+
31
+ <CollapseButton collapsed={collapsed} toggleCollapsed={toggleCollapsed} />
32
+ </Sider>
33
+ );
34
+ }
@@ -0,0 +1,78 @@
1
+ import ILayout from './components/Layout';
2
+ import { useEffect, useState } from 'react';
3
+ import { Spin } from 'antd';
4
+ import { useHistory, useLocation, Switch, Route } from 'react-router-dom';
5
+ import { getDeepestPath, findEntry } from '@/utils/common';
6
+ import { MenuType } from './components/Menu';
7
+ import { oemSaasAy } from '@/lang/utils';
8
+ import Page403 from '@/pages/403';
9
+ import Page404 from '@/pages/404';
10
+
11
+ //过滤小程序菜单
12
+ const fileterMinApp = (entryInfo, apps) => {
13
+ const { entry_mode, entries } = entryInfo;
14
+ if (entry_mode === MenuType.GROUP) {
15
+ return entries.map((group) => {
16
+ const { sub_entry_list, ...others } = group;
17
+ return {
18
+ ...others,
19
+ sub_entry_list: filtor(sub_entry_list, apps),
20
+ };
21
+ });
22
+ } else if (entry_mode === MenuType.NORMAL) {
23
+ return filtor(entries, apps);
24
+ }
25
+ };
26
+
27
+ const filtor = (entries, apps) => {
28
+ return entries?.filter((menu) => {
29
+ const { oem_micro_app_id } = menu;
30
+ const { ext_info } = apps.find(
31
+ ({ oem_micro_app_id: id }) => id === oem_micro_app_id
32
+ );
33
+ if (!ext_info || !ext_info['sdf.main-app.menu.hide_in_menu']) {
34
+ return menu;
35
+ }
36
+ });
37
+ };
38
+
39
+ // eslint-disable-next-line import/no-anonymous-default-export
40
+ export default ({ entryInfo, isMicroApp, apps, children }) => {
41
+ const { entry_mode, entries } = entryInfo;
42
+ const [entry, setEntry] = useState([]);
43
+ const { pathname } = useLocation();
44
+ const history = useHistory();
45
+ const { title } = oemSaasAy();
46
+ useEffect(() => {
47
+ if (entries && apps.length) {
48
+ const entry = fileterMinApp(entryInfo, apps) || [];
49
+ setEntry(entry);
50
+ if (entry.length > 0 && pathname === '/') {
51
+ history.replace(getDeepestPath(entry[0]));
52
+ }
53
+ }
54
+ }, [entries, apps]);
55
+
56
+ useEffect(() => {
57
+ if (entries?.length) {
58
+ const entry = findEntry(entries, pathname);
59
+ if (entry) {
60
+ document.title = `${entry.entry_name} - ${title}`;
61
+ }
62
+ }
63
+ }, [entries, pathname]);
64
+
65
+ return (
66
+ <Spin spinning={!entry_mode} style={{ marginTop: 100 }}>
67
+ <ILayout entries={entries} mode={entry_mode} menus={entry}>
68
+ {children}
69
+ <Switch>
70
+ <Route path="/403" exact>
71
+ <Page403 />
72
+ </Route>
73
+ <Route path="*">{isMicroApp ? null : <Page404 />}</Route>
74
+ </Switch>
75
+ </ILayout>
76
+ </Spin>
77
+ );
78
+ };
@@ -0,0 +1,65 @@
1
+ .container {
2
+ display: flex;
3
+ align-items: center;
4
+ justify-content: space-between;
5
+ width: 100%;
6
+ height: 100vh;
7
+ min-width: 1200px;
8
+ overflow: auto;
9
+ position: relative;
10
+ .left {
11
+ width: 60%;
12
+ flex: 1;
13
+ height: 100%;
14
+ background-repeat: no-repeat;
15
+ background-position: center right;
16
+ background-size: cover;
17
+ }
18
+ .right {
19
+ width: 40%;
20
+ display: flex;
21
+ justify-content: center;
22
+ .login {
23
+ position: relative;
24
+ width: 70%;
25
+ min-width: 400px;
26
+ max-width: 500px;
27
+ .loading {
28
+ position: absolute;
29
+ left: 0;
30
+ right: 0;
31
+ }
32
+ }
33
+ }
34
+
35
+ .top-container {
36
+ position: absolute;
37
+ top: 20px;
38
+ right: 40px;
39
+ display: flex;
40
+ flex-wrap: nowrap;
41
+ align-items: center;
42
+ }
43
+
44
+ :global {
45
+ .main-select-selection-search {
46
+ left: auto !important;
47
+ }
48
+
49
+ .main-select-selection-search-input {
50
+ width: auto !important;
51
+ text-align: right;
52
+ }
53
+ }
54
+ }
55
+
56
+ @media screen and (min-width: 1440px) {
57
+ .container {
58
+ min-height: 760px;
59
+ }
60
+ }
61
+ @media screen and (min-width: 1920px) {
62
+ .container {
63
+ min-height: 870px;
64
+ }
65
+ }
@@ -0,0 +1,68 @@
1
+ import { useState } from 'react';
2
+ import { Select } from 'antd';
3
+ import BSwitchLang from '@/components/BHeaderUser/components/BSwitchLang';
4
+ import { COUNTRY_LIST } from '@/constant';
5
+ import { getI18n } from 'react-i18next';
6
+ import styles from './index.module.less';
7
+ import { switchLang, oemSaasAy } from '@/lang/utils';
8
+
9
+ const BLayoutLogin = (props) => {
10
+ const [region, setRegionCode] = useState('86');
11
+ const { background_image: bg } = oemSaasAy();
12
+
13
+ const handleRegionChange = (value: string) => {
14
+ setRegionCode(value);
15
+ localStorage.setItem('regionCode', value);
16
+ };
17
+
18
+ const toChangeLang = (lang) => {
19
+ switchLang(lang);
20
+ };
21
+
22
+ return (
23
+ <div className={styles.container}>
24
+ <div
25
+ className={styles.left}
26
+ style={{ backgroundImage: `url("${bg}")` }}
27
+ />
28
+ <div className={styles.right}>
29
+ <div className={styles.login}>{props.children}</div>
30
+ </div>
31
+ <div className={styles['top-container']}>
32
+ {window._SDF_CONFIG?.saas?.PHONE_REGION_NUM_ENABLE !== false && (
33
+ <Select
34
+ showSearch
35
+ className="countryCode"
36
+ value={region}
37
+ labelInValue={false}
38
+ bordered={false}
39
+ optionFilterProp="children"
40
+ dropdownMatchSelectWidth={false}
41
+ dropdownAlign={{
42
+ points: ['tr', 'br'],
43
+ }}
44
+ dropdownClassName={styles.selectOptionsWrap}
45
+ style={{ width: 'auto', minWidth: 100 }}
46
+ onChange={handleRegionChange}
47
+ >
48
+ {COUNTRY_LIST.map((country) => (
49
+ <Select.Option
50
+ key={country.countryCode}
51
+ value={country.countryCode}
52
+ >
53
+ {getI18n().language === 'zh' ? country.cnName : country.enName}
54
+ (+
55
+ {country.countryCode})
56
+ </Select.Option>
57
+ ))}
58
+ </Select>
59
+ )}
60
+ {window._SDF_CONFIG?.saas?.MULTI_LANG.ENABLE !== false && (
61
+ <BSwitchLang toChangeLang={toChangeLang} />
62
+ )}
63
+ </div>
64
+ </div>
65
+ );
66
+ };
67
+
68
+ export default BLayoutLogin;
@@ -0,0 +1,25 @@
1
+ .wrap {
2
+ padding-top: 8px;
3
+ .clause_check {
4
+ height: 22px;
5
+ line-height: 22px;
6
+ }
7
+ .clause_text {
8
+ height: 22px;
9
+ line-height: 22px;
10
+ margin-left: 8px;
11
+ cursor: pointer;
12
+ user-select: none;
13
+ }
14
+ .clause {
15
+ margin-left: 8px;
16
+
17
+ height: 22px;
18
+ line-height: 22px !important;
19
+ padding: 0;
20
+ span {
21
+ height: 22px;
22
+ line-height: 22px;
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,58 @@
1
+ import { Button, Checkbox, Row } from 'antd';
2
+ import { useTranslation } from 'react-i18next';
3
+ import styles from './index.module.less';
4
+ import { oemSaasAy } from '@/lang/utils';
5
+ // @link-color
6
+ const Clause = ({
7
+ toggleAgreed,
8
+ }: {
9
+ toggleAgreed: React.Dispatch<React.SetStateAction<boolean>>;
10
+ }) => {
11
+ const { t } = useTranslation();
12
+ const { legal_notice, privacy_policy, service_terms } = oemSaasAy();
13
+
14
+ return (
15
+ <Row className={styles.wrap}>
16
+ <Checkbox
17
+ id="agree"
18
+ className={styles.clause_check}
19
+ defaultChecked={true}
20
+ onChange={(e) => toggleAgreed(e.target.checked)}
21
+ />
22
+ <label className={styles.clause_text} htmlFor={'agree'}>
23
+ {t('login.text')}
24
+ </label>
25
+ {!!service_terms && (
26
+ <Button
27
+ className={styles.clause}
28
+ type="link"
29
+ target="blank"
30
+ href={service_terms}
31
+ >
32
+ {`${t('login.service')}`}
33
+ </Button>
34
+ )}
35
+ {!!legal_notice && (
36
+ <Button
37
+ className={styles.clause}
38
+ type="link"
39
+ target="blank"
40
+ href={legal_notice}
41
+ >
42
+ {`${t('login.legal')}`}
43
+ </Button>
44
+ )}
45
+ {!!privacy_policy && (
46
+ <Button
47
+ className={styles.clause}
48
+ type="link"
49
+ target="blank"
50
+ href={privacy_policy}
51
+ >
52
+ {`${t('login.privacy')}`}
53
+ </Button>
54
+ )}
55
+ </Row>
56
+ );
57
+ };
58
+ export default Clause;
@@ -0,0 +1,9 @@
1
+ .wrap {
2
+ width: 100%;
3
+ display: flex;
4
+ justify-content: space-between;
5
+ align-items: center;
6
+ height: 22px;
7
+ line-height: 22px;
8
+ margin-top: 8px;
9
+ }
@@ -0,0 +1,18 @@
1
+ import { useTranslation } from 'react-i18next';
2
+ import { Link } from 'react-router-dom';
3
+ import styles from './index.module.less';
4
+ // eslint-disable-next-line import/no-anonymous-default-export
5
+ export default ({ showRegister = true }) => {
6
+ const { t } = useTranslation();
7
+ return (
8
+ <div className={styles.wrap}>
9
+ <Link to={{ pathname: '/forgot' }}>{t('login.forgot')}</Link>
10
+ {showRegister && (
11
+ <div>
12
+ {t('forgot.noAccount')}
13
+ <Link to="/register">{t('forgot.toRegister')}</Link>
14
+ </div>
15
+ )}
16
+ </div>
17
+ );
18
+ };
@@ -0,0 +1,39 @@
1
+ import { Form, Input } from 'antd';
2
+ import { LockOutlined } from '@ant-design/icons';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { checkPassWord } from '@/utils/checkPass';
5
+
6
+ // 首页登录和忘记密码
7
+ const Password = ({ isHide = false, name = 'login' }) => {
8
+ const { t } = useTranslation();
9
+ return (
10
+ <Form.Item
11
+ name="password"
12
+ label={t('login.form.password.label')}
13
+ required={false}
14
+ rules={[
15
+ {
16
+ required: true,
17
+ message: t('login.form.password.validate.require'),
18
+ },
19
+ name === 'password' &&
20
+ (() => ({
21
+ validator(_, value) {
22
+ const result = checkPassWord(value);
23
+ if (result) return Promise.resolve();
24
+ const tip = t('login.form.password.validate.pattern');
25
+ return Promise.reject(new Error(tip));
26
+ },
27
+ })),
28
+ ]}
29
+ >
30
+ <Input.Password
31
+ size="large"
32
+ prefix={<LockOutlined className="site-form-item-icon" />}
33
+ placeholder={t('login.form.password.placeholder')}
34
+ />
35
+ </Form.Item>
36
+ );
37
+ };
38
+
39
+ export default Password;
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { Button } from 'antd';
3
+
4
+ interface ISubmitProps {
5
+ top: number;
6
+ loading?: boolean;
7
+ disabled?: boolean;
8
+ btTx: string;
9
+ }
10
+ const SubmitBtn = ({
11
+ top,
12
+ loading = false,
13
+ disabled = true,
14
+ btTx,
15
+ }: ISubmitProps) => {
16
+ return (
17
+ <Button
18
+ type="primary"
19
+ loading={loading}
20
+ htmlType="submit"
21
+ size="large"
22
+ block
23
+ disabled={!disabled}
24
+ style={{ marginTop: `${top}px` }}
25
+ >
26
+ {btTx}
27
+ </Button>
28
+ );
29
+ };
30
+ export default SubmitBtn;