App.jsx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. import React, {Component} from 'react';
  2. import {Layout, Menu, Button, Spin, Icon, LocaleProvider} from 'antd';
  3. import {BrowserRouter as Router, Route, Link, Switch, Redirect} from "react-router-dom";
  4. import {Query} from "react-apollo";
  5. import gql from "graphql-tag";
  6. import moment from 'moment';
  7. import 'moment/locale/zh-cn';
  8. import {FormattedMessage} from 'react-intl';
  9. import zhCN from 'antd/lib/locale-provider/zh_CN';
  10. import WechatService from "./wechatService/WechatService";
  11. import QuantService from "./quantService/QuantService";
  12. import TrialCase from "./graphqlService/trialCase/TrialCase";
  13. import UserCreate from "./graphqlService/userCreate/UserCreate";
  14. import Login from "../login/Login";
  15. import './graphqlService/common/graphql/index.css';
  16. import './index.css'
  17. import Create from "./graphqlService/common/schema/Create";
  18. import WxCreate from "./wechatService/WxCreate";
  19. import {SHOW_ALL_SCHEMA, SHOW_ALL_WXCONFIG} from "../gql";
  20. import axios from 'axios';
  21. import {getCookie} from "../cookie";
  22. axios.defaults.withCredentials = true;
  23. const {SubMenu} = Menu;
  24. const {Header, Sider} = Layout;
  25. moment.locale('en');
  26. class App extends Component {
  27. constructor(props) {
  28. super(props);
  29. this.state = {
  30. menuLevel1: "graphql-service",
  31. sideBar: "ecommerce",
  32. collapsed: false,
  33. inlineCollapsed: false,
  34. language: props.language,
  35. locale: props.language === "中文" ? zhCN : undefined,
  36. languageButton: props.language === "中文" ? "English" : "中文",
  37. visible: false,
  38. wxVisible: false
  39. };
  40. }
  41. componentWillMount() {
  42. let urlList = window.location.pathname.split("/");
  43. let urlListLength = urlList.length;
  44. if (urlListLength > 2) {
  45. this.setState({menuLevel1: urlList[1]});
  46. if (urlList[3] !== 'index') {
  47. this.setState({sideBar: urlList[3]});
  48. }
  49. }
  50. }
  51. onCollapse = (collapsed) => {
  52. this.setState({collapsed});
  53. };
  54. switchMenu = (menuName, e) => {
  55. this.setState({
  56. [menuName]: e.key,
  57. });
  58. };
  59. switchMenuTab = (menuName, e) => {
  60. this.setState({
  61. [menuName]: e.key,
  62. });
  63. if (e.key === "graphql-service") {
  64. this.setState({sideBar: "ecommerce"});
  65. }
  66. };
  67. switchSidebar = (value) => {
  68. this.setState({
  69. sideBar: value,
  70. });
  71. };
  72. switchMenuLevel = (menuName, value) => {
  73. this.setState({
  74. [menuName]: value,
  75. });
  76. };
  77. showModal = () => {
  78. this.setState({
  79. visible: true,
  80. });
  81. };
  82. wxShowModal = () => {
  83. this.setState({
  84. wxVisible: true,
  85. });
  86. };
  87. hideModal = () => {
  88. this.setState({
  89. visible: false,
  90. });
  91. };
  92. wxHideModal = () => {
  93. this.setState({
  94. wxVisible: false,
  95. });
  96. };
  97. changeLocale = (e) => {
  98. e.stopPropagation();
  99. let {language} = this.state;
  100. // console.log('app language',language);
  101. let changeLanguage = language === "中文" ? "English" : "中文";
  102. let local = language === "中文" ? undefined : zhCN;
  103. let languageButton = language === "中文" ? "中文" : "English";
  104. sessionStorage.setItem("language", changeLanguage);
  105. this.props.changeLanguage(changeLanguage);
  106. this.setState({
  107. language: changeLanguage,
  108. locale: local,
  109. languageButton: languageButton
  110. });
  111. if (!local) {
  112. moment.locale('en');
  113. } else {
  114. moment.locale('zh-cn');
  115. }
  116. };
  117. render() {
  118. const {locale, languageButton, visible, wxVisible} = this.state;
  119. return (
  120. <Router>
  121. <Layout style={{minHeight: '100vh'}}>
  122. <Header className="header" style={{position: 'fixed', zIndex: 1, width: '100%'}}>
  123. <Link to="/"
  124. onClick={() => this.setState({menuLevel1: "graphql-service", sideBar: "ecommerce"})}>
  125. <div className="logo-wrapper">
  126. <div className='logo'/>
  127. </div>
  128. </Link>
  129. <Menu
  130. theme="dark"
  131. mode="horizontal"
  132. selectedKeys={[this.state.menuLevel1]}
  133. style={{lineHeight: '64px'}}
  134. onClick={(e) => this.switchMenuTab('menuLevel1', e)}
  135. >
  136. <Menu.Item key="graphql-service">
  137. <Link to="/graphql-service/trial-case/index"><FormattedMessage
  138. id="Graphql Service"/></Link>
  139. </Menu.Item>
  140. <Menu.Item key="wechat-service">
  141. <Link to="/wechat-service/trial-case/index"><FormattedMessage
  142. id="Wechat Service"/></Link>
  143. </Menu.Item>
  144. <Menu.Item key="quant-service">
  145. <Link to="/quant-service/trial-case/index"><FormattedMessage id="Quantization Service"/></Link>
  146. </Menu.Item>
  147. </Menu>
  148. <Link to="/login">
  149. <Button className='login-button' type='primary'
  150. onClick={() => this.switchMenuLevel('menuLevel1', 'user')}>Login</Button>
  151. </Link>
  152. <div className="change-locale">
  153. <Button size="small" onClick={(e) => this.changeLocale(e)}>{languageButton}</Button>
  154. </div>
  155. </Header>
  156. {(() => {
  157. switch (this.state.menuLevel1) {
  158. case 'graphql-service':
  159. return (
  160. <Sider
  161. width={200}
  162. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  163. collapsible
  164. collapsed={this.state.collapsed}
  165. onCollapse={this.onCollapse}
  166. >
  167. <GraphqlSidebar inlineCollapsed={this.state.inlineCollapsed}
  168. sideBar={this.state.sideBar} switchMenu={this.switchMenu}
  169. showModal={this.showModal}/>
  170. </Sider>
  171. );
  172. case 'wechat-service':
  173. return (
  174. <Sider
  175. width={200}
  176. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  177. collapsible
  178. collapsed={this.state.collapsed}
  179. onCollapse={this.onCollapse}
  180. >
  181. <WxConfigSiderbar inlineCollapsed={this.state.inlineCollapsed}
  182. sideBar={this.state.sideBar} switchMenu={this.switchMenu}
  183. wxShowModal={this.wxShowModal}/>
  184. </Sider>
  185. );
  186. case 'quant-service':
  187. return (
  188. <Sider
  189. width={200}
  190. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  191. collapsible
  192. collapsed={this.state.collapsed}
  193. onCollapse={this.onCollapse}
  194. >
  195. <Menu
  196. theme="dark"
  197. mode="inline"
  198. inlineCollapsed={this.state.inlineCollapsed}
  199. defaultSelectedKeys={['quant-service']}
  200. defaultOpenKeys={['trial-case']}
  201. // openKeys={['cloud-function']}
  202. onClick={(e) => this.switchMenu('sideBar', e)}
  203. selectedKeys={[this.state.sideBar]}
  204. style={{
  205. borderRight: 0,
  206. overflow: 'auto',
  207. height: '100vh',
  208. left: '0',
  209. width: '200px',
  210. position: 'fixed'
  211. }}
  212. >
  213. <SubMenu key="trial-case" title={<span><Icon type="appstore"
  214. theme="twoTone"/><span>Case Show</span></span>}>
  215. <Menu.Item key="quant-service">
  216. <Link to="/quant-service/trial-case/quant case">quant case</Link>
  217. </Menu.Item>
  218. </SubMenu>
  219. <Menu.Item key="instructions">
  220. <a href="https://ioobot-document.netlify.com/" title="instructions"
  221. target="instructions">
  222. <Icon type="file-text" theme="twoTone"/>
  223. <span>Instructions</span>
  224. </a>
  225. </Menu.Item>
  226. </Menu>
  227. </Sider>
  228. );
  229. case 'user':
  230. return (
  231. <Sider
  232. width={200}
  233. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  234. collapsible
  235. collapsed={this.state.collapsed}
  236. onCollapse={this.onCollapse}
  237. >
  238. <Menu
  239. theme="dark"
  240. defaultSelectedKeys={['cloud-settings']}
  241. onClick={(e) => this.switchMenu('sideBar', e)}
  242. selectedKeys={[this.state.sideBar]}
  243. style={{
  244. borderRight: 0,
  245. overflow: 'auto',
  246. height: '100vh',
  247. left: '0',
  248. width: '200px',
  249. position: 'fixed'
  250. }}
  251. >
  252. <Menu.Item key="account">
  253. <Icon type="setting" theme="twoTone"/>
  254. <span>Account center</span>
  255. <Link to="/login/account"/>
  256. </Menu.Item>
  257. <Menu.Item key="cloud-settings">
  258. <Icon type="cloud" theme="twoTone"/>
  259. <span>Cloud settings</span>
  260. <Link to="/login/cloud"/>
  261. </Menu.Item>
  262. </Menu>
  263. </Sider>
  264. );
  265. default:
  266. return (
  267. <Sider
  268. width={200}
  269. style={{background: '#fff', marginTop: '64px', zIndex: '0'}}
  270. collapsible
  271. collapsed={this.state.collapsed}
  272. onCollapse={this.onCollapse}
  273. >
  274. <GraphqlSidebar inlineCollapsed={this.state.inlineCollapsed}
  275. sideBar={this.state.sideBar} switchMenu={this.switchMenu}
  276. showModal={this.showModal}/>
  277. </Sider>
  278. );
  279. }
  280. })()}
  281. <Create visible={visible} hideModal={this.hideModal} switchSidebar={this.switchSidebar}/>
  282. <WxCreate visible={wxVisible} hideModal={this.wxHideModal} switchSidebar={this.switchSidebar}/>
  283. <LocaleProvider locale={locale}>
  284. <Layout style={{marginTop: '64px', zIndex: '0'}}
  285. key={locale ? locale.locale : 'en'/* Have to refresh for production environment */}>
  286. <Switch>
  287. <Route path="/" exact component={TrialCase}/>
  288. <Route path="/graphql-service/trial-case/:case" component={TrialCase}/>
  289. <Route path="/graphql-service/my-create/:case" component={UserCreate}/>
  290. <Route path="/wechat-service/:sidebar/:case" component={WechatService}/>
  291. <Route path="/quant-service/:sidebar/:case" component={QuantService}/>
  292. <Route path="/login/:setting" component={Login}/>
  293. <Route path="/login" component={Login}/>
  294. <Redirect path="*" to="/"/>
  295. </Switch>
  296. </Layout>
  297. </LocaleProvider>
  298. </Layout>
  299. </Router>
  300. );
  301. }
  302. }
  303. export default App;
  304. class GraphqlSidebar extends Component {
  305. constructor(props) {
  306. super(props);
  307. this.state = {
  308. userID: getCookie('user_id'),
  309. }
  310. }
  311. render() {
  312. return (
  313. <Query query={gql(SHOW_ALL_SCHEMA)} variables={{user_id: this.state.userID}}>
  314. {
  315. ({loading, error, data}) => {
  316. // console.log('user schema data',data);
  317. if (loading) return <Spin style={{marginLeft: 3}}/>;
  318. if (error) return 'error!';
  319. localStorage.setItem('ecommerce', data.caseSchema.find(obj => obj.schemaName === 'ecommerce').schemaData);
  320. localStorage.setItem('subscribe', data.caseSchema.find(obj => obj.schemaName === 'subscribe').schemaData);
  321. localStorage.setItem('bills', data.caseSchema.find(obj => obj.schemaName === 'bills').schemaData);
  322. return (
  323. <Menu
  324. theme="dark"
  325. mode="inline"
  326. inlineCollapsed={this.props.inlineCollapsed}
  327. defaultSelectedKeys={['ecommerce']}
  328. defaultOpenKeys={['trial-case', 'my-create']}
  329. // openKeys={['trial-case', 'my-create']}
  330. onClick={(e) => this.props.switchMenu('sideBar', e)}
  331. selectedKeys={[this.props.sideBar]}
  332. style={{
  333. borderRight: 0,
  334. overflow: 'auto',
  335. height: '100vh',
  336. left: '0',
  337. width: '200px',
  338. position: 'fixed'
  339. }}
  340. >
  341. <SubMenu key="trial-case" title={<span><Icon type="appstore" theme="twoTone"/><span>Case Show</span></span>}>
  342. {
  343. data.caseSchema.map((schema) =>
  344. <Menu.Item key={schema.schemaName}>
  345. <Link to={{
  346. pathname: `/graphql-service/trial-case/${schema.schemaName}`,
  347. state: {
  348. schemaName: schema.schemaName,
  349. schemaID: schema.id
  350. }
  351. }}>{schema.schemaName}</Link>
  352. </Menu.Item>)
  353. }
  354. </SubMenu>
  355. <Menu.Item key="create-graphql" onClick={this.props.showModal}>
  356. <Icon type="edit" theme="twoTone"/>
  357. <span>Create</span>
  358. <Icon type="plus" style={{
  359. position: 'absolute',
  360. top: '35%',
  361. right: '6px',
  362. color: 'white'
  363. }}/>
  364. </Menu.Item>
  365. <SubMenu key="my-create" title={<span><Icon type="user" theme="outlined"/><span>My Create</span></span>}>
  366. {
  367. data.userSchema.map((schema) =>
  368. <Menu.Item key={schema.schemaName}>
  369. <Link to={{
  370. pathname: `/graphql-service/my-create/${schema.schemaName}`,
  371. state: {
  372. schemaName: schema.schemaName,
  373. schemaID: schema.id
  374. }
  375. }}>{schema.schemaName}</Link>
  376. </Menu.Item>)
  377. }
  378. </SubMenu>
  379. <Menu.Item key="instructions">
  380. <a href="https://ioobot-document.netlify.com/" title="instructions" target="_blank"
  381. rel="noopener noreferrer">
  382. <Icon type="file-text" theme="twoTone"/>
  383. <span>Instructions</span>
  384. </a>
  385. </Menu.Item>
  386. </Menu>
  387. )
  388. }
  389. }
  390. </Query>
  391. )
  392. }
  393. }
  394. class WxConfigSiderbar extends Component {
  395. constructor(props) {
  396. super(props);
  397. this.state = {
  398. userID: getCookie('user_id'),
  399. }
  400. }
  401. render() {
  402. return (
  403. <Query query={gql(SHOW_ALL_WXCONFIG)} variables={{user_id: this.state.userID}}>
  404. {
  405. ({loading, error, data}) => {
  406. if (loading) return <Spin style={{marginLeft: 3}}/>;
  407. if (error) return 'error!';
  408. return (
  409. <Menu
  410. theme="dark"
  411. mode="inline"
  412. inlineCollapsed={this.props.inlineCollapsed}
  413. defaultSelectedKeys={['my-wechat']}
  414. defaultOpenKeys={['trial-case', 'my-create']}
  415. // openKeys={['trial-case', 'my-create']}
  416. onClick={(e) => this.props.switchMenu('sideBar', e)}
  417. selectedKeys={[this.props.sideBar]}
  418. style={{
  419. borderRight: 0,
  420. overflow: 'auto',
  421. height: '100vh',
  422. left: '0',
  423. width: '200px',
  424. position: 'fixed'
  425. }}
  426. >
  427. <SubMenu key="trial-case" title={<span><Icon type="appstore" theme="twoTone"/><span>Case Show</span></span>}>
  428. {
  429. data.caseWxConfig.map((config) =>
  430. <Menu.Item key={config.appName}>
  431. <Link to={{
  432. pathname: `/graphql-service/trial-case/${config.appName}`,
  433. state: {
  434. configName: config.appName,
  435. configID: config.id
  436. }
  437. }}>{config.appName}</Link>
  438. </Menu.Item>)
  439. }
  440. </SubMenu>
  441. <Menu.Item key="create-config" onClick={this.props.wxShowModal}>
  442. <Icon type="edit" theme="twoTone"/>
  443. <span>Create</span>
  444. <Icon type="plus" style={{
  445. position: 'absolute',
  446. top: '35%',
  447. right: '6px',
  448. color: 'white'
  449. }}/>
  450. </Menu.Item>
  451. <SubMenu key="my-create" title={<span><Icon type="user" theme="outlined"/><span>My Create</span></span>}>
  452. {
  453. data.userWxConfig.map((config) =>
  454. <Menu.Item key={config.appName}>
  455. <Link to={{
  456. pathname: `/wechat-service/my-create/${config.appName}`,
  457. state: {
  458. configName: config.appName,
  459. configID: config.id
  460. }
  461. }}>{config.appName}</Link>
  462. </Menu.Item>)
  463. }
  464. </SubMenu>
  465. <Menu.Item key="instructions">
  466. <a href="https://ioobot-document.netlify.com/" title="instructions" target="_blank"
  467. rel="noopener noreferrer">
  468. <Icon type="file-text" theme="twoTone"/>
  469. <span>Instructions</span>
  470. </a>
  471. </Menu.Item>
  472. </Menu>
  473. )
  474. }
  475. }
  476. </Query>
  477. )
  478. }
  479. }