page.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. import React, { Component } from 'react';
  2. import { Link } from 'react-router-dom';
  3. import './index.less';
  4. import { Icon } from 'antd';
  5. import FileUpload from '@src/components/FileUpload';
  6. import Page from '@src/containers/Page';
  7. import Assets from '@src/components/Assets';
  8. import UserLayout from '../../../layouts/User';
  9. import Button from '../../../components/Button';
  10. import ProgressText from '../../../components/ProgressText';
  11. import { Icon as GIcon } from '../../../components/Icon';
  12. import menu from '../index';
  13. import Tabs from '../../../components/Tabs';
  14. import UserTable from '../../../components/UserTable';
  15. import More from '../../../components/More';
  16. import Modal from '../../../components/Modal';
  17. import Date from '../../../components/Date';
  18. export default class extends Page {
  19. initState() {
  20. return {
  21. tab1: '2',
  22. tab2: '1',
  23. data: [
  24. {
  25. status: 'ing',
  26. history: [{}],
  27. list: [
  28. { status: 'ing', type: '1' },
  29. { status: 'not', type: '2' },
  30. { status: 'end', type: '3' },
  31. { status: 'not', type: '4' },
  32. { status: 'end', type: '5' },
  33. { status: 'not', type: '6' },
  34. { status: 'end', type: '7' },
  35. ],
  36. },
  37. {
  38. status: 'not',
  39. history: [{}],
  40. list: [
  41. { status: 'ing', type: '1' },
  42. { status: 'not', type: '2' },
  43. { status: 'end', type: '3' },
  44. { status: 'not', type: '4' },
  45. { status: 'end', type: '5' },
  46. { status: 'not', type: '6' },
  47. { status: 'end', type: '7' },
  48. ],
  49. },
  50. { status: 'end', history: [{}], list: [] },
  51. ],
  52. };
  53. }
  54. onAction() {}
  55. refresh(tab1, tab2) {
  56. this.setState({ tab1, tab2 });
  57. }
  58. renderView() {
  59. const { config } = this.props;
  60. return <UserLayout active={config.key} menu={menu} center={this.renderDetail()} />;
  61. }
  62. renderDetail() {
  63. const { tab1, tab2 } = this.state;
  64. return (
  65. <div className="detail-layout">
  66. <div className="tip">
  67. <div className="text">理清备考思路,避开常见误区,让学习的每一分钟发光发热!</div>
  68. <Link to="">去填写 ></Link>
  69. <Icon type="close-circle" theme="filled" />
  70. </div>
  71. <Tabs
  72. type="division"
  73. theme="theme"
  74. size="small"
  75. space={2.5}
  76. width={100}
  77. active={tab1}
  78. tabs={[{ key: '1', title: '在线课程' }, { key: '2', title: '1V1私教' }]}
  79. onChange={key => this.refresh(key, tab2)}
  80. />
  81. <Tabs
  82. type="tag"
  83. theme="white"
  84. size="small"
  85. space={5}
  86. width={54}
  87. active={tab2}
  88. tabs={[
  89. { key: '1', title: '全部' },
  90. { key: '2', title: '未开通' },
  91. { key: '3', title: '学习中' },
  92. { key: '4', title: '已结束' },
  93. ]}
  94. onChange={key => this.refresh(tab1, key)}
  95. />
  96. {this[`renderTab${tab1}`]()}
  97. <Modal className="clock-modal" title="打卡表" width={460} onClose={() => {}}>
  98. <div>
  99. <div className="d-i-b w-3">
  100. <div className="t-2 t-s-14">听课频率</div>
  101. <div className="t-4 t-s-18">2天/课时</div>
  102. </div>
  103. <div className="d-i-b w-3">
  104. <div className="t-2 t-s-14">作业完成度</div>
  105. <div className="t-4 t-s-18">50%</div>
  106. </div>
  107. </div>
  108. <div className="b-b m-t-1 m-b-1" />
  109. <div className="m-b-1">
  110. <div className="tag d-i-b t-s-16">
  111. <i style={{ background: '#6865FD' }} />
  112. 听课
  113. </div>
  114. <div className="tag d-i-b t-s-16">
  115. <i style={{ background: '#4299FF' }} />
  116. 预习
  117. </div>
  118. <div className="tag d-i-b t-s-16">
  119. <i style={{ background: '#E7E7E7' }} />
  120. 停课
  121. </div>
  122. </div>
  123. <Date
  124. hideInput
  125. disabledDate={() => false}
  126. dateRender={current => (
  127. <div className="ant-calendar-date">
  128. {current.get('date')}
  129. <i className="s1" style={{ background: '#6865FD' }} />
  130. <i className="s2" style={{ background: '#4299FF' }} />
  131. </div>
  132. )}
  133. />
  134. <div className="t-2 t-s-12">*听课频率≤2天/课时,作业完成度≥90%,课程有效期可延长7-10天。</div>
  135. </Modal>
  136. <Modal title="恢复学习" onConfirm={() => {}} onCancel={() => {}}>
  137. <div className="t-2 t-s-18">恢复学习后,本课程的停课功能将无法使用。是否恢复学习?</div>
  138. </Modal>
  139. <Modal title="上传笔记" width={630} confirmText="提交" onConfirm={() => {}} onCancel={() => {}}>
  140. <textarea
  141. className="b-c-1 w-10 p-10 m-b-1"
  142. rows={6}
  143. placeholder="请输入留言内容,也可将文件拖动到这里上传。"
  144. />
  145. <div className="t-2 t-s-16 m-b-1">
  146. 上传文件 <FileUpload type="file" title="选择文件" />
  147. <span className="t-3 t-s-14">支持 docx, xls, PDF, rar, zip, PNG, JPG 等类型的文件</span>
  148. </div>
  149. <div className="b-b m-t-2" />
  150. </Modal>
  151. </div>
  152. );
  153. }
  154. renderTab1() {
  155. const { data = [] } = this.state;
  156. return data.map(item => {
  157. return <Course data={item} />;
  158. });
  159. }
  160. renderTab2() {
  161. const { data = [] } = this.state;
  162. return data.map(item => {
  163. return <Education data={item} />;
  164. });
  165. }
  166. }
  167. class Course extends Component {
  168. constructor(props) {
  169. super(props);
  170. this.columns = [
  171. { title: '学习内容' },
  172. { title: '预习作业' },
  173. { title: '进度' },
  174. { title: '最近学习' },
  175. { title: '笔记' },
  176. { title: '问答' },
  177. ];
  178. this.state = { open: false };
  179. }
  180. render() {
  181. const { data = {} } = this.props;
  182. switch (data.status) {
  183. case 'ing':
  184. return this.renderIng();
  185. case 'not':
  186. return this.renderNot();
  187. case 'end':
  188. return this.renderEnd();
  189. default:
  190. return <div />;
  191. }
  192. }
  193. renderIng() {
  194. const { data } = this.props;
  195. const { history = [] } = data;
  196. return (
  197. <div className="course-item ing">
  198. <div className="title">
  199. <div className="tag">学习中</div>
  200. <div className="text">OG20整合刷题-语法SC</div>
  201. </div>
  202. <div className="continue">
  203. <Assets name="notice" />
  204. 继续学习:课时 13:解读句子属性
  205. </div>
  206. <div className="detail">
  207. <div className="left">
  208. <Assets name="sun_blue" />
  209. <div className="info">
  210. <div className="t1">授课老师</div>
  211. <div className="t2">李小小</div>
  212. <div className="t1">有效期</div>
  213. <div className="t2">88Day</div>
  214. </div>
  215. </div>
  216. <div className="right">
  217. <div className="item">
  218. <Assets name="logic" />
  219. <div className="text">
  220. <span>12</span>/20
  221. </div>
  222. </div>
  223. <div className="item">
  224. <Assets name="logic" />
  225. <div className="text">
  226. <span>12</span>/20
  227. </div>
  228. </div>
  229. <div className="item">
  230. <Assets name="logic" />
  231. <div className="text">
  232. <span>12</span>/20
  233. </div>
  234. </div>
  235. <div className="item">
  236. <Assets name="logic" />
  237. <div className="text">
  238. <span>12</span>/20
  239. </div>
  240. </div>
  241. </div>
  242. </div>
  243. <UserTable size="small" columns={this.columns} data={history} />
  244. </div>
  245. );
  246. }
  247. renderNot() {
  248. return (
  249. <div className="course-item not">
  250. <div className="title">
  251. <div className="tag">未开通</div>
  252. <div className="text">OG20整合刷题-语法SC</div>
  253. </div>
  254. <div className="detail">
  255. <div className="left">
  256. <Assets name="sun_blue" />
  257. <div className="info">
  258. <div className="t1">授课老师</div>
  259. <div className="t2">李小小</div>
  260. <div className="t1">有效期</div>
  261. <div className="t2">88Day</div>
  262. </div>
  263. </div>
  264. <div className="right t-c">
  265. <div className="text">请于 2020-06-26 前开通</div>
  266. <Button size="lager" radius>
  267. 立即开通
  268. </Button>
  269. </div>
  270. </div>
  271. </div>
  272. );
  273. }
  274. renderEnd() {
  275. return (
  276. <div className="course-item end">
  277. <div className="title">
  278. <div className="tag">已结束</div>
  279. <div className="text">OG20整合刷题-语法SC</div>
  280. </div>
  281. <div className="detail">
  282. <div className="left">
  283. <Assets name="sun_blue" />
  284. <div className="info">
  285. <div className="t1">授课老师</div>
  286. <div className="t2">李小小</div>
  287. <div className="t1">有效期</div>
  288. <div className="t2">88Day</div>
  289. </div>
  290. </div>
  291. <div className="right">
  292. <div className="item">
  293. <Assets name="logic" />
  294. <div className="text">
  295. <span>12</span>/20
  296. </div>
  297. </div>
  298. <div className="item">
  299. <Assets name="logic" />
  300. <div className="text">
  301. <span>12</span>/20
  302. </div>
  303. </div>
  304. <div className="item">
  305. <Assets name="logic" />
  306. <div className="text">
  307. <span>12</span>/20
  308. </div>
  309. </div>
  310. <div className="item">
  311. <Assets name="logic" />
  312. <div className="text">
  313. <span>12</span>/20
  314. </div>
  315. </div>
  316. </div>
  317. </div>
  318. </div>
  319. );
  320. }
  321. }
  322. class Education extends Component {
  323. constructor(props) {
  324. super(props);
  325. this.columns = [
  326. { title: '学习内容' },
  327. { title: '预习作业' },
  328. { title: '授课时间' },
  329. { title: '课后笔记' },
  330. { title: '课后补充' },
  331. ];
  332. this.state = { open: true, tab: '1' };
  333. }
  334. render() {
  335. const { data = {} } = this.props;
  336. switch (data.status) {
  337. case 'ing':
  338. return this.renderIng();
  339. case 'not':
  340. return this.renderNot();
  341. case 'end':
  342. return this.renderEnd();
  343. default:
  344. return <div />;
  345. }
  346. }
  347. renderIng() {
  348. const { tab } = this.state;
  349. return (
  350. <div className="education-item ing">
  351. <div className="title">
  352. <div className="tag">学习中</div>
  353. <div className="text">OG20整合刷题-语法SC</div>
  354. <div className="right">
  355. <More menu={[{ label: '评价', key: '1' }, { label: '停课', key: '2' }]} />
  356. </div>
  357. </div>
  358. <div className="continue">
  359. <Assets name="notice" />
  360. 继续学习:课时 13:解读句子属性
  361. </div>
  362. <div className="detail">
  363. <div className="left">
  364. <div className="item">
  365. <div className="t1">授课老师</div>
  366. <div className="t2">李小小</div>
  367. </div>
  368. <div className="item">
  369. <div className="t1">有效期</div>
  370. <div className="t2">88Day</div>
  371. </div>
  372. </div>
  373. <div className="right">
  374. <div className="item">
  375. <Assets name="logic" />
  376. <div className="text">
  377. <span>12</span>/20
  378. </div>
  379. </div>
  380. <div className="item">
  381. <Assets name="logic" />
  382. <div className="text">
  383. <span>12</span>/20
  384. </div>
  385. </div>
  386. </div>
  387. </div>
  388. <Tabs
  389. className="t-l"
  390. type="line"
  391. theme="theme"
  392. size="small"
  393. width={80}
  394. active={tab}
  395. tabs={[{ key: '1', title: '在线课程' }, { key: '2', title: '1V1私教' }]}
  396. onChange={key => this.setState({ tab: key })}
  397. />
  398. <div className="class-hour">
  399. <div className="text">课时 5:解读句子属性</div>
  400. <div className="right">
  401. <GIcon name="prev" onClick={() => {}} />
  402. <span>上一课时</span>
  403. <span>下一课时</span>
  404. <GIcon name="next" onClick={() => {}} />
  405. </div>
  406. </div>
  407. {tab === '1' ? this.renderTimeLine() : this.renderTable()}
  408. </div>
  409. );
  410. }
  411. renderNot() {
  412. return (
  413. <div className="education-item not">
  414. <div className="title">
  415. <div className="tag">未开通</div>
  416. <div className="text">OG20整合刷题-语法SC</div>
  417. </div>
  418. <div className="detail">
  419. <div className="left">
  420. <Assets name="sun_blue" />
  421. <div className="info">
  422. <div className="t1">授课老师</div>
  423. <div className="t2">李小小</div>
  424. <div className="t1">有效期</div>
  425. <div className="t2">88Day</div>
  426. </div>
  427. </div>
  428. <div className="right">
  429. <div className="qr-code">
  430. <Assets name="qrcode" />
  431. <div className="i">
  432. <div className="t1">请尽快与老师预约上课时间</div>
  433. <div className="t2">请于 2019-07-25 前开通课程</div>
  434. </div>
  435. </div>
  436. </div>
  437. </div>
  438. {this.renderTimeLine()}
  439. </div>
  440. );
  441. }
  442. renderEnd() {
  443. const { open } = this.state;
  444. return (
  445. <div className="education-item end">
  446. <div className="title">
  447. <div className="tag">已结课</div>
  448. <div className="text">OG20整合刷题-语法SC</div>
  449. </div>
  450. <div className="detail">
  451. <div className="left">
  452. <div className="item">
  453. <div className="t1">授课老师</div>
  454. <div className="t2">李小小</div>
  455. </div>
  456. <div className="item">
  457. <div className="t1">有效期</div>
  458. <div className="t2">88Day</div>
  459. </div>
  460. </div>
  461. <div className="right">
  462. <div className="item">
  463. <Assets name="logic" />
  464. <div className="text">
  465. <span>12</span>/20
  466. </div>
  467. </div>
  468. <div className="item">
  469. <Assets name="logic" />
  470. <div className="text">
  471. <span>12</span>/20
  472. </div>
  473. </div>
  474. </div>
  475. <div className="open">
  476. <GIcon name={open ? 'up' : 'down'} onClick={() => this.setState({ open: !open })} />
  477. </div>
  478. </div>
  479. {open && this.renderTable()}
  480. </div>
  481. );
  482. }
  483. renderTimeLine() {
  484. const { data = {} } = this.props;
  485. const { list = [] } = data;
  486. return (
  487. <div className="time-line">
  488. {list.map(item => {
  489. return <TimeLineItem data={item} />;
  490. })}
  491. </div>
  492. );
  493. }
  494. renderTable() {
  495. const { data = {} } = this.props;
  496. const { history = [] } = data;
  497. return <UserTable size="small" columns={this.columns} data={history} />;
  498. }
  499. }
  500. class TimeLineItem extends Component {
  501. constructor(props) {
  502. super(props);
  503. this.titleMap = {
  504. 1: '预约时间',
  505. 2: '答疑文档',
  506. 3: '上课',
  507. 4: '课后笔记',
  508. 5: '课后补充',
  509. 6: '备考信息',
  510. 7: '完成作业',
  511. };
  512. }
  513. onClick(key) {
  514. const { data = {}, onClick } = this.props;
  515. const { status } = data;
  516. if (status === 'not') return;
  517. if (onClick) onClick(key);
  518. }
  519. render() {
  520. const { data = {} } = this.props;
  521. const { status, type } = data;
  522. return (
  523. <div className={`time-line-item ${status}`}>
  524. <div className="icon-title">
  525. <GIcon name="star" active={status !== 'not'} noHover />
  526. <div className="title">{this.titleMap[type]}</div>
  527. </div>
  528. <div className="time-line-detail">{this.renderDetail()}</div>
  529. </div>
  530. );
  531. }
  532. renderDetail() {
  533. const { data = {} } = this.props;
  534. const { type, status } = data;
  535. switch (type) {
  536. case '1':
  537. return status === 'not' ? (
  538. <span>请尽快与老师预约上课时间,扫码加微信</span>
  539. ) : (
  540. <span>2019-07-24 09:00 ~ 10:00</span>
  541. );
  542. case '2':
  543. return <span className="link">点此上传</span>;
  544. case '3':
  545. return status === 'end' ? (
  546. <span>
  547. CCtalk 频道号 :1234567 <span className="link">CC talk使用手册</span>
  548. </span>
  549. ) : (
  550. <input placeholder="请输入CCtalk用户名查看授课频道" />
  551. );
  552. case '4':
  553. return <span className="link">点此上传</span>;
  554. case '5':
  555. return <span className="link">写留言</span>;
  556. case '6':
  557. return [
  558. <div>
  559. <span>基本情况梳理</span>
  560. <span>2019-08-20 更新</span>
  561. <span className="link">修改</span>
  562. </div>,
  563. <div>
  564. <span>备考细节梳理</span>
  565. <span className="link">填写</span>
  566. </div>,
  567. ];
  568. case '7':
  569. return <ProgressText progress={10} size="small" />;
  570. default:
  571. return <div />;
  572. }
  573. }
  574. }