Browse Source

add start page

KaysonCui 5 years ago
parent
commit
5eb42f8db8
55 changed files with 960 additions and 36 deletions
  1. 8 4
      front/project/www/app.js
  2. 8 2
      front/project/www/app.less
  3. BIN
      front/project/www/assets/calculator_icon.png
  4. BIN
      front/project/www/assets/chooseed_icon.png
  5. BIN
      front/project/www/assets/chooser_icon.png
  6. BIN
      front/project/www/assets/collect_icon.png
  7. BIN
      front/project/www/assets/copy_icon.png
  8. BIN
      front/project/www/assets/cut_icon.png
  9. BIN
      front/project/www/assets/del_icon.png
  10. BIN
      front/project/www/assets/downturning_icon.png
  11. BIN
      front/project/www/assets/eliminate_icon.png
  12. BIN
      front/project/www/assets/fullscreen_icon.png
  13. BIN
      front/project/www/assets/help_icon.png
  14. BIN
      front/project/www/assets/information_icon.png
  15. BIN
      front/project/www/assets/meun_icon.png
  16. BIN
      front/project/www/assets/next_icon.png
  17. BIN
      front/project/www/assets/paste_icon.png
  18. BIN
      front/project/www/assets/redo_icon.png
  19. BIN
      front/project/www/assets/right_icon.png
  20. BIN
      front/project/www/assets/selected_icon.png
  21. BIN
      front/project/www/assets/subject_icon.png
  22. BIN
      front/project/www/assets/subjectnumber_icon.png
  23. BIN
      front/project/www/assets/time_icon.png
  24. BIN
      front/project/www/assets/timecost_icon.png
  25. BIN
      front/project/www/assets/timeleft_icon.png
  26. BIN
      front/project/www/assets/undo_icon.png
  27. BIN
      front/project/www/assets/unfold_icon.png
  28. BIN
      front/project/www/assets/upturning_icon.png
  29. BIN
      front/project/www/assets/wrong_icon.png
  30. BIN
      front/project/www/assets/yes_icon.png
  31. 59 0
      front/project/www/components/Answer/index.js
  32. 35 0
      front/project/www/components/Answer/index.less
  33. 55 0
      front/project/www/components/AnswerSelect/index.js
  34. 79 0
      front/project/www/components/AnswerSelect/index.less
  35. 45 0
      front/project/www/components/AnswerTable/index.js
  36. 29 0
      front/project/www/components/AnswerTable/index.less
  37. 5 6
      front/project/www/components/Button/index.less
  38. 50 0
      front/project/www/components/Calculator/index.js
  39. 65 0
      front/project/www/components/Calculator/index.less
  40. 1 1
      front/project/www/components/ListTable/index.js
  41. 0 3
      front/project/www/components/ListTable/index.less
  42. 19 0
      front/project/www/components/Navigation/index.js
  43. 76 0
      front/project/www/components/Navigation/index.less
  44. 4 4
      front/project/www/components/Radio/index.js
  45. 1 1
      front/project/www/components/Radio/index.less
  46. 9 0
      front/project/www/components/RadioItem/index.js
  47. 30 0
      front/project/www/components/RadioItem/index.less
  48. 2 2
      front/project/www/components/Select/index.js
  49. 2 0
      front/project/www/components/Select/index.less
  50. 2 2
      front/project/www/components/Table/index.js
  51. 6 10
      front/project/www/components/Table/index.less
  52. 2 1
      front/project/www/routes/page/index.js
  53. 10 0
      front/project/www/routes/page/start/index.js
  54. 211 0
      front/project/www/routes/page/start/index.less
  55. 147 0
      front/project/www/routes/page/start/page.js

+ 8 - 4
front/project/www/app.js

@@ -15,10 +15,14 @@ export default class extends Component {
     const { children, project, config } = this.props;
     return (
       <LocaleProvider locale={zhCN}>
-        <div className={`${config.tab}`} id="page">
-          <Header tabs={project.tabs} active={config.tab} />
-          {children}
-        </div>
+        {config.hideHeader ? (
+          <div id="full-page">{children}</div>
+        ) : (
+          <div className={`${config.tab}`} id="page">
+            <Header tabs={project.tabs} active={config.tab} />
+            {children}
+          </div>
+        )}
       </LocaleProvider>
     );
   }

+ 8 - 2
front/project/www/app.less

@@ -233,10 +233,16 @@ body,
 #root {
   margin: 0;
   padding: 0;
-  min-height: 100%;
+  height: 100%;
+  overflow: hidden;
+  overflow-y: auto;
 
   #page {
-    min-height: 100%;
+    height: 100%;
+  }
+
+  #full-page {
+    height: 100%;
   }
 
   .content {

BIN
front/project/www/assets/calculator_icon.png


BIN
front/project/www/assets/chooseed_icon.png


BIN
front/project/www/assets/chooser_icon.png


BIN
front/project/www/assets/collect_icon.png


BIN
front/project/www/assets/copy_icon.png


BIN
front/project/www/assets/cut_icon.png


BIN
front/project/www/assets/del_icon.png


BIN
front/project/www/assets/downturning_icon.png


BIN
front/project/www/assets/eliminate_icon.png


BIN
front/project/www/assets/fullscreen_icon.png


BIN
front/project/www/assets/help_icon.png


BIN
front/project/www/assets/information_icon.png


BIN
front/project/www/assets/meun_icon.png


BIN
front/project/www/assets/next_icon.png


BIN
front/project/www/assets/paste_icon.png


BIN
front/project/www/assets/redo_icon.png


BIN
front/project/www/assets/right_icon.png


BIN
front/project/www/assets/selected_icon.png


BIN
front/project/www/assets/subject_icon.png


BIN
front/project/www/assets/subjectnumber_icon.png


BIN
front/project/www/assets/time_icon.png


BIN
front/project/www/assets/timecost_icon.png


BIN
front/project/www/assets/timeleft_icon.png


BIN
front/project/www/assets/undo_icon.png


BIN
front/project/www/assets/unfold_icon.png


BIN
front/project/www/assets/upturning_icon.png


BIN
front/project/www/assets/wrong_icon.png


BIN
front/project/www/assets/yes_icon.png


+ 59 - 0
front/project/www/components/Answer/index.js

@@ -0,0 +1,59 @@
+import React, { Component } from 'react';
+import './index.less';
+import RadioItem from '../RadioItem';
+
+export default class Answer extends Component {
+  render() {
+    return <div className="answer">{this.renderTable()}</div>;
+  }
+
+  renderList() {
+    const { list = [] } = this.props;
+    return (
+      <div className="list">
+        {list.map(item => {
+          return (
+            <div className="item">
+              <RadioItem checked onClick={() => {}} />
+              <div className="text">{item}</div>
+            </div>
+          );
+        })}
+      </div>
+    );
+  }
+
+  renderTable() {
+    const { list = [] } = this.props;
+    return (
+      <table border="1" bordercolor="#d8d8d8">
+        <thead>
+          <tr className="bg">
+            <th align="center" width="100" className="t-c">
+              Both acce
+            </th>
+            <th align="center" width="100" className="t-c">
+              Otherwise
+            </th>
+            <th />
+          </tr>
+        </thead>
+        <tbody>
+          {list.map(item => {
+            return (
+              <tr>
+                <td align="center" className="bg">
+                  <RadioItem checked onClick={() => {}} />
+                </td>
+                <td align="center" className="bg">
+                  <RadioItem checked onClick={() => {}} />
+                </td>
+                <td>{item}</td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+    );
+  }
+}

+ 35 - 0
front/project/www/components/Answer/index.less

@@ -0,0 +1,35 @@
+@charset "utf-8";
+
+.answer {
+  .list {
+    .item {
+      margin-bottom: 10px;
+      position: relative;
+
+      .radio-item {
+        position: absolute;
+        top: 4px;
+      }
+
+      .text {
+        padding-left: 30px;
+      }
+    }
+  }
+
+  table {
+    .bg {
+      background: #f8f8f8;
+    }
+
+    tr {
+      th {
+        padding: 10px;
+      }
+
+      td {
+        padding: 10px;
+      }
+    }
+  }
+}

+ 55 - 0
front/project/www/components/AnswerSelect/index.js

@@ -0,0 +1,55 @@
+import React, { Component } from 'react';
+import './index.less';
+import Assets from '@src/components/Assets';
+
+export default class AnswerSelect extends Component {
+  constructor(props) {
+    super(props);
+    this.state = { selecting: false };
+  }
+
+  componentWillMount() {}
+
+  componentWillUnmount() {}
+
+  open() {
+    this.setState({ selecting: true });
+  }
+
+  close() {
+    this.setState({ selecting: false });
+  }
+
+  render() {
+    const { selecting } = this.state;
+    const { value, list = [] } = this.props;
+    let index = 0;
+    for (let i = 0; i < list.length; i += 1) {
+      if (list[i].key === value) {
+        index = i;
+        break;
+      }
+    }
+    const title = list.length > 0 ? list[index].title : '';
+    return (
+      <div className="answer-select">
+        <div hidden={!selecting} className="mask" onClick={() => this.close()} />
+        <div className="select-warp">
+          <div className="text" onClick={() => this.open()}>
+            {title}
+            <Assets name="chooser_icon" />
+          </div>
+          <div className={`select-body ${selecting ? 'select' : ''}`}>
+            {list.map(item => {
+              return (
+                <div className="select-option" onClick={() => this.close()}>
+                  {item.title}
+                </div>
+              );
+            })}
+          </div>
+        </div>
+      </div>
+    );
+  }
+}

+ 79 - 0
front/project/www/components/AnswerSelect/index.less

@@ -0,0 +1,79 @@
+@import '../../app.less';
+
+.answer-select {
+  position: relative;
+  display: inline-block;
+
+  .mask {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 1;
+  }
+
+  .select-warp {
+    line-height: 25px;
+    display: inline-block;
+    position: relative;
+
+    .text {
+      display: inline-block;
+      border: 1px solid rgba(216, 216, 216, 1);
+      background: rgba(248, 248, 248, 1);
+      border-radius: 6px;
+      cursor: pointer;
+      min-width: 100px;
+      padding-right: 20px;
+      text-align: right;
+
+      .assets {
+        position: absolute;
+        right: 5px;
+        top: 8px;
+      }
+    }
+  }
+
+  .select-body {
+    overflow: hidden;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    background: #fff;
+    border: 1px solid rgba(216, 216, 216, 1);
+    border-radius: 6px;
+    box-sizing: border-box;
+    opacity: 0;
+    z-index: 2;
+    transform: translateY(100%);
+
+    .select-option {
+      height: 0;
+      line-height: 25px;
+      padding-left: 10px;
+      font-size: 12px;
+      cursor: pointer;
+      transition: all 0.3s;
+    }
+
+    .select-option:hover {
+      color: #fff;
+      background: #006DAA;
+    }
+
+    .select-option:last-child {
+      border-bottom: none;
+    }
+  }
+
+  .select-body.select {
+    opacity: 1;
+
+    .select-option {
+      height: auto;
+    }
+  }
+}

+ 45 - 0
front/project/www/components/AnswerTable/index.js

@@ -0,0 +1,45 @@
+import React, { Component } from 'react';
+import './index.less';
+import Select from '../Select';
+
+export default class AnswerTable extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {};
+  }
+
+  componentWillMount() {}
+
+  componentWillUnmount() {}
+
+  render() {
+    const { columns = [], data = [], list = [] } = this.props;
+    return (
+      <div className="answer-table">
+        <div className="select-line">
+          <Select size="basic" theme="default" list={list} />
+        </div>
+        <table border="1" bordercolor="#d8d8d8">
+          <thead>
+            <tr className="bg">
+              {columns.map(item => {
+                return <th>{item.title}</th>;
+              })}
+            </tr>
+          </thead>
+          <tbody>
+            {data.map(row => {
+              return (
+                <tr>
+                  {columns.map(item => {
+                    return <td>{row[item.key]}</td>;
+                  })}
+                </tr>
+              );
+            })}
+          </tbody>
+        </table>
+      </div>
+    );
+  }
+}

+ 29 - 0
front/project/www/components/AnswerTable/index.less

@@ -0,0 +1,29 @@
+@import '../../app.less';
+
+.answer-table {
+  position: relative;
+
+  .select-line {
+    text-align: right;
+    margin-bottom: 10px;
+  }
+
+  table {
+    width: 100%;
+    margin-bottom: 10px;
+
+    .bg {
+      background: #f8f8f8;
+    }
+
+    tr {
+      th {
+        padding: 10px;
+      }
+
+      td {
+        padding: 10px;
+      }
+    }
+  }
+}

+ 5 - 6
front/project/www/components/Button/index.less

@@ -11,8 +11,8 @@
 
 .button.basic {
   padding: 4px 24px;
-  line-height: 30px;
-  font-size: 20px;
+  line-height: 20px;
+  font-size: 14px;
 }
 
 .button.small {
@@ -51,8 +51,8 @@
 
 .button.default {
   background: #fff;
-  color: @holder_color;
-  border: 1px solid @holder_color;
+  color: @base_color;
+  border: 1px solid @line_color;
 }
 
 .button.border {
@@ -69,6 +69,5 @@
 }
 
 .button.default:hover {
-  color: @theme_color;
-  border-color: @theme_color;
+  border-color: @base_color;
 }

+ 50 - 0
front/project/www/components/Calculator/index.js

@@ -0,0 +1,50 @@
+import React, { Component } from 'react';
+import Assets from '@src/components/Assets';
+import './index.less';
+
+export default class Calculator extends Component {
+  constructor(props) {
+    super(props);
+    this.state = { value: '' };
+  }
+
+  render() {
+    return (
+      <div className="calculator">
+        <div className="line">
+          <div className="block block-1 value">{this.state.value}</div>
+        </div>
+        <div className="line">
+          <div className="block block-2 left">
+            <Assets name="eliminate_icon" />
+          </div>
+          <div className="block block-3 right">Clear</div>
+        </div>
+        <div className="line">
+          <div className="block block-1 left">7</div>
+          <div className="block block-1 center">8</div>
+          <div className="block block-1 center">9</div>
+          <div className="block block-2 right">/</div>
+        </div>
+        <div className="line">
+          <div className="block block-1 left">4</div>
+          <div className="block block-1 center">5</div>
+          <div className="block block-1 center">6</div>
+          <div className="block block-2 right">*</div>
+        </div>
+        <div className="line">
+          <div className="block block-1 left">1</div>
+          <div className="block block-1 center">2</div>
+          <div className="block block-1 center">3</div>
+          <div className="block block-2 right">-</div>
+        </div>
+        <div className="line">
+          <div className="block block-1 left">0</div>
+          <div className="block block-1 center">.</div>
+          <div className="block block-1 center">=</div>
+          <div className="block block-2 right">+</div>
+        </div>
+      </div>
+    );
+  }
+}

+ 65 - 0
front/project/www/components/Calculator/index.less

@@ -0,0 +1,65 @@
+@charset "utf-8";
+
+.calculator {
+  background: #006DAA;
+  width: 240px;
+  height: 345px;
+  padding: 15px 15px 0;
+  display: inline-block;
+  overflow: hidden;
+
+  .line {
+    display: flex;
+    margin-bottom: 15px;
+
+    .block {
+      background: #fff;
+      border-radius: 6px;
+      text-align: center;
+      line-height: 38px;
+      height: 38px;
+      cursor: pointer;
+    }
+
+    .block:hover {
+      background: #f4f4f4;
+    }
+
+    .value {
+      height: 50px;
+      line-height: 50px;
+      text-align: left;
+      padding: 0 10px;
+      cursor: text;
+    }
+
+    .value:hover {
+      background: #fff;
+    }
+
+    .block-1 {
+      flex: 1;
+    }
+
+    .block-2 {
+      flex: 2;
+    }
+
+    .block-3 {
+      flex: 3;
+    }
+
+    .left {
+      margin-right: 2.5px;
+    }
+
+    .right {
+      margin-left: 2.5px;
+    }
+
+    .center {
+      margin-right: 2.5px;
+      margin-left: 2.5px;
+    }
+  }
+}

+ 1 - 1
front/project/www/components/ListTable/index.js

@@ -2,7 +2,7 @@ import React from 'react';
 import './index.less';
 import Module from '../Module';
 import Table from '../Table';
-import Radio from '../Radio';
+import Radio from '../RadioButton';
 import Select from '../Select';
 
 function getFilter(filter) {

+ 0 - 3
front/project/www/components/ListTable/index.less

@@ -39,9 +39,6 @@
   }
 
   .table {
-    .th {
-      padding: 0 44px;
-    }
 
     .tr {
       padding: 0 44px;

+ 19 - 0
front/project/www/components/Navigation/index.js

@@ -0,0 +1,19 @@
+import React from 'react';
+import './index.less';
+
+function Navigation(props) {
+  const { list = [], active = 0 } = props;
+  return (
+    <div className="navigation">
+      {list.map((item, index) => {
+        return (
+          <div className={`item ${index === active ? 'active' : ''}`}>
+            <span className="text">{item}</span>
+          </div>
+        );
+      })}
+    </div>
+  );
+}
+Navigation.propTypes = {};
+export default Navigation;

+ 76 - 0
front/project/www/components/Navigation/index.less

@@ -0,0 +1,76 @@
+@import '../../app.less';
+
+.navigation {
+  text-align: center;
+  display: flex;
+  height: 44px;
+  line-height: 44px;
+  color: #fff;
+  overflow: hidden;
+
+  .item {
+    flex: 1;
+    position: relative;
+    background: #006DAA;
+    cursor: pointer;
+    transition: all 0.3s;
+
+    .text {
+      margin-left: 5px;
+    }
+  }
+
+  .item:first-child:before {
+    display: none;
+  }
+
+  .item:before {
+    content: '';
+    position: absolute;
+    height: 0;
+    width: 0;
+    top: -16px;
+    left: 0;
+    right: -34px;
+    border-width: 38px 19px;
+    z-index: 1;
+    border-style: solid;
+    border-color: transparent;
+    border-left-color: #fff;
+    transition: all 0.3s;
+  }
+
+  .item:after {
+    content: '';
+    position: absolute;
+    height: 0;
+    width: 0;
+    right: -22px;
+    border-width: 22px 11px;
+    z-index: 2;
+    border-style: solid;
+    border-color: transparent;
+    border-left-color: #006DAA;
+    transition: all 0.3s;
+  }
+
+  .item.active,
+  .item.active:hover {
+    color: #fff;
+    background: #003366;
+  }
+
+  .item.active:after,
+  .item.active:hover:after {
+    border-left-color: #003366;
+  }
+
+  .item:hover {
+    color: #fff;
+    background: darken(#006DAA, 5);
+  }
+
+  .item:hover:after {
+    border-left-color: darken(#006DAA, 5);
+  }
+}

+ 4 - 4
front/project/www/components/Radio/index.js

@@ -2,10 +2,10 @@ import React from 'react';
 import './index.less';
 import Button from '../Button';
 
-function Radio(props) {
+function RadioButton(props) {
   const { list, value } = props;
   return (
-    <div className="radio">
+    <div className="radio-button">
       {list.map(item => {
         return (
           <Button theme={item.key === value ? 'theme' : 'default'} size="small" radius>
@@ -16,5 +16,5 @@ function Radio(props) {
     </div>
   );
 }
-Radio.propTypes = {};
-export default Radio;
+RadioButton.propTypes = {};
+export default RadioButton;

+ 1 - 1
front/project/www/components/Radio/index.less

@@ -1,6 +1,6 @@
 @import '../../app.less';
 
-.radio {
+.radio-button {
   .button {
     margin-right: 10px;
   }

+ 9 - 0
front/project/www/components/RadioItem/index.js

@@ -0,0 +1,9 @@
+import React from 'react';
+import './index.less';
+
+function RadioItem(props) {
+  const { checked, onClick } = props;
+  return <div className={`radio-item ${checked ? 'checked' : ''}`} onClick={() => !checked && onClick && onClick()} />;
+}
+RadioItem.propTypes = {};
+export default RadioItem;

+ 30 - 0
front/project/www/components/RadioItem/index.less

@@ -0,0 +1,30 @@
+@import '../../app.less';
+
+.radio-item {
+  width: 16px;
+  height: 16px;
+  vertical-align: middle;
+  border-radius: 8px;
+  border: 1px solid #C4C6CF;
+  background: #D8D8D8;
+  display: inline-block;
+  cursor: pointer;
+}
+
+.radio-item.checked {
+  background: #006DAA;
+  border-color: #006DAA;
+  position: relative;
+}
+
+.radio-item.checked:after {
+  content: '';
+  position: absolute;
+  width: 6px;
+  height: 6px;
+  border-radius: 3px;
+  background: #fff;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+}

+ 2 - 2
front/project/www/components/Select/index.js

@@ -22,7 +22,7 @@ export default class Select extends Component {
 
   render() {
     const { selecting } = this.state;
-    const { value, list = [] } = this.props;
+    const { value, list = [], size = 'small', theme = 'theme' } = this.props;
     let index = 0;
     for (let i = 0; i < list.length; i += 1) {
       if (list[i].key === value) {
@@ -35,7 +35,7 @@ export default class Select extends Component {
       <div className="select">
         <div hidden={!selecting} className="mask" onClick={() => this.close()} />
         <div className="select-warp">
-          <Button size="small" radius onClick={() => this.open()}>
+          <Button size={size} theme={theme} radius onClick={() => this.open()}>
             {title}
           </Button>
           <div className={`select-body ${selecting ? 'select' : ''}`}>

+ 2 - 0
front/project/www/components/Select/index.less

@@ -16,6 +16,7 @@
     line-height: 30px;
     display: inline-block;
     position: relative;
+    text-align: center;
   }
 
   .select-body {
@@ -40,6 +41,7 @@
       font-size: 12px;
       cursor: pointer;
       transition: all 0.3s;
+      text-align: left;
     }
 
     .select-option:hover {

+ 2 - 2
front/project/www/components/Table/index.js

@@ -5,10 +5,10 @@ function Table(props) {
   const { columns = [], data = [] } = props;
   return (
     <div className="table">
-      <div className="th">
+      <div className="tr">
         {columns.map(column => {
           return (
-            <div style={{ width: column.width, textAlign: column.align }} className={`td ${column.className}`}>
+            <div style={{ width: column.width, textAlign: column.align }} className={`th ${column.className}`}>
               {column.title}
             </div>
           );

+ 6 - 10
front/project/www/components/Table/index.less

@@ -2,23 +2,19 @@
 
 .table {
 
-  .td {
+  .td,
+  .th {
     display: inline-block;
     vertical-align: middle;
   }
 
-  .th {
-    height: 44px;
-    line-height: 44px;
-    border-bottom: 1px solid @line_color;
-
-    .td {}
-  }
-
   .tr {
     border-bottom: 1px solid @line_color;
 
-    .td {}
+    .th {
+      height: 44px;
+      line-height: 44px;
+    }
   }
 
   .tr:last-child {

+ 2 - 1
front/project/www/routes/page/index.js

@@ -1,6 +1,7 @@
 import home from './home';
 import practise from './practise';
 import report from './report';
+import start from './start';
 import login from './login';
 
-export default [home, practise, report, login];
+export default [home, practise, report, start, login];

+ 10 - 0
front/project/www/routes/page/start/index.js

@@ -0,0 +1,10 @@
+export default {
+  path: '/start',
+  key: 'start',
+  title: '开始考试',
+  needLogin: true,
+  hideHeader: true,
+  component() {
+    return import('./page');
+  },
+};

+ 211 - 0
front/project/www/routes/page/start/index.less

@@ -0,0 +1,211 @@
+@charset "utf-8";
+
+#start {
+  height: 100%;
+  color: #000;
+
+  .start {
+    background: #3A4287;
+    height: 100%;
+    padding: 40px 20px;
+
+    .bg {
+      height: 100%;
+      width: 100%;
+      background: #fff;
+    }
+
+    .fixed-content {
+      position: fixed;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+
+      .title {
+        text-align: center;
+        font-size: 40px;
+        font-weight: 600;
+        margin-bottom: 100px;
+      }
+
+      .desc {
+        text-align: center;
+        margin-bottom: 80px;
+
+        .block {
+          display: inline-block;
+          width: 300px;
+
+          .desc-title {
+            margin-bottom: 20px;
+
+            .assets {
+              margin-right: 10px;
+            }
+          }
+
+          .desc-info {
+            font-size: 40px;
+            font-weight: 600;
+          }
+        }
+      }
+
+      .tip {
+        text-align: center;
+        margin-bottom: 20px;
+      }
+
+      .submit {
+        text-align: center;
+      }
+    }
+  }
+
+  .layout {
+    background: #006DAA;
+    height: 100%;
+    padding: 0 25px;
+    display: flex;
+    flex-direction: column;
+    position: relative;
+
+    .calculator {
+      position: absolute;
+      z-index: 9;
+      top: 60px;
+    }
+
+    .fixed {
+      position: absolute;
+      top: 62px;
+      left: 0;
+      right: 0;
+      height: 30px;
+      line-height: 30px;
+      background: #7EAFE0;
+      color: #fff;
+      padding: 0 25px;
+
+      .calculator-icon {
+        margin-left: 50px;
+        cursor: pointer;
+      }
+
+      .collect-icon {
+        float: right;
+        cursor: pointer;
+        transform: translateY(5px);
+      }
+    }
+
+    .layout-header {
+      height: 60px;
+      color: #fff;
+
+      .title {
+        font-size: 20px;
+        line-height: 60px;
+        display: inline-block;
+      }
+
+      .right {
+        float: right;
+        text-align: right;
+
+        .block {
+          line-height: 30px;
+
+          .assets {
+            margin-right: 10px;
+          }
+        }
+      }
+    }
+
+    .layout-footer {
+      height: 35px;
+      line-height: 35px;
+      color: #fff;
+      margin-right: -25px;
+
+      .help {
+        padding: 0 10px;
+        border-left: 1px solid #fff;
+        border-right: 1px solid #fff;
+        display: inline-block;
+        cursor: pointer;
+
+        .assets {
+          margin-right: 10px;
+        }
+      }
+
+      .help:hover {
+        background: darken(#006DAA, 10);
+      }
+
+      .full {
+        display: inline-block;
+        padding: 0 10px;
+        border-right: 1px solid #fff;
+        cursor: pointer;
+      }
+
+      .full:hover {
+        background: darken(#006DAA, 10);
+      }
+
+      .next {
+        float: right;
+        padding: 0 10px;
+        border-left: 1px solid #fff;
+        border-top: 1px solid #fff;
+        cursor: pointer;
+        box-sizing: border-box;
+        height: 35px;
+
+        .assets {
+          margin-left: 20px;
+        }
+      }
+
+      .next:hover {
+        background: darken(#006DAA, 10);
+      }
+    }
+
+    .layout-body {
+      background: #fff;
+      flex: 1;
+      overflow: hidden;
+      overflow-y: auto;
+
+      .block {
+        padding: 60px 20px 20px;
+      }
+    }
+
+    .layout-body.two {
+      display: flex;
+
+      .block {
+        overflow: hidden;
+        overflow-y: auto;
+        flex: 1;
+      }
+
+      .block-content {
+        border-right: 4px solid #006DAA;
+
+        .navigation {
+          margin-bottom: 80px;
+        }
+      }
+
+      .block-answer {
+        border-left: 4px solid #006DAA;
+      }
+    }
+  }
+}

+ 147 - 0
front/project/www/routes/page/start/page.js

@@ -0,0 +1,147 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.less';
+import Assets from '@src/components/Assets';
+import Page from '@src/containers/Page';
+import Button from '../../../components/Button';
+import Navigation from '../../../components/Navigation';
+import Answer from '../../../components/Answer';
+// import Calculator from '../../../components/Calculator';
+import AnswerSelect from '../../../components/AnswerSelect';
+import AnswerTable from '../../../components/AnswerTable';
+
+export default class extends Page {
+  renderView() {
+    return this.renderDetail();
+  }
+
+  initData() {
+    setTimeout(() => {
+      ReactDOM.render(
+        <AnswerSelect list={[{ title: '123' }, { title: '321' }]} />,
+        document.getElementById('#select#'),
+      );
+      ReactDOM.render(
+        <AnswerTable
+          list={[{ title: '123' }, { title: '321' }]}
+          columns={[{ key: 'one', title: 'one' }, { key: 'two', title: 'two' }]}
+          data={[{ one: '123', two: '321' }]}
+        />,
+        document.getElementById('#table#'),
+      );
+    }, 1);
+  }
+
+  renderCotent() {
+    return (
+      <div className="block block-content">
+        <Navigation list={['Sports Association', 'News Orgnization', 'News Orgnization']} onChange={() => {}} />
+        <div className="text">
+          For each of the following statements, select Both accept if, based on the information provided, it can be
+          inferred that both the sports association and the news organizations would likely accept that the statement is
+          true. If not, select Otherwise.
+          <span id="#table#" />
+          For each of the following statements, select Both accept if, based on the information provided, it can be
+          inferred <span id="#select#" />
+          that both the sports association and the news organizations would likely accept that the statement is true. If
+          not, select Otherwise.
+        </div>
+      </div>
+    );
+  }
+
+  renderAnswer() {
+    return (
+      <div className="block block-answer">
+        <div className="text m-b-2">
+          For each of the following statements, select Both accept if, based on the information provided, it can be
+          inferred that both the sports association and the news organizations would likely accept that the statement is
+          true. If not, select Otherwise.{' '}
+        </div>
+        <Answer
+          list={[
+            'Neuroscientists, having amassed a wealth of knowledge',
+            'the past twenty years about the brain and its development from birth to adulthood',
+            'Neuroscientists, having amassed a wealth of knowledge',
+            'the past twenty years about the brain and its development from birth to adulthood, ) the past twenty years about the brain and its development from birth to adulthood',
+          ]}
+        />
+      </div>
+    );
+  }
+
+  renderDetail() {
+    return (
+      <div className="layout">
+        <div className="fixed">
+          Analytical Writing Assessment
+          <Assets className="calculator-icon" name="calculator_icon" />
+          <Assets className="collect-icon" name="collect_icon" />
+        </div>
+        {/* <Calculator /> */}
+        <div className="layout-header">
+          <div className="title">OG18:1-20</div>
+          <div className="right">
+            <div className="block">
+              <Assets name="timeleft_icon" />
+              Time left 00:02
+            </div>
+            <div className="block">
+              <Assets name="subjectnumber_icon" />1 of 20
+            </div>
+          </div>
+        </div>
+        <div className="layout-body two">
+          {this.renderCotent()}
+          {this.renderAnswer()}
+        </div>
+        <div className="layout-footer">
+          <div className="help">
+            <Assets name="help_icon" />
+            Help
+          </div>
+          <div className="full">
+            <Assets name="fullscreen_icon" />
+          </div>
+          <div className="next">
+            Next
+            <Assets name="next_icon" />
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+  renderStart() {
+    return (
+      <div className="start">
+        <div className="bg" />
+        <div className="fixed-content">
+          <div className="title">「练习」OG18 综合:第1-20题</div>
+          <div className="desc">
+            <div className="block">
+              <div className="desc-title">
+                <Assets name="subject_icon" />
+                题目总数
+              </div>
+              <div className="desc-info">20</div>
+            </div>
+            <div className="block">
+              <div className="desc-title">
+                <Assets name="time_icon" />
+                建议用时
+              </div>
+              <div className="desc-info">20 min</div>
+            </div>
+          </div>
+          <div className="tip">题目选项乱序显示</div>
+          <div className="submit">
+            <Button size="lager" radius>
+              开始练习
+            </Button>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}