PollScreen.jsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import { h, render, Component } from 'preact'; // eslint-disable-line no-unused-vars
  2. import HeaderLightItem from './partials/HeaderLightItem.jsx';
  3. import TextItem from './partials/TextItem.jsx';
  4. import AnimItem from './partials/AnimItem.jsx';
  5. // module04: Poll Screen
  6. // wrapper which contains text and animation (side-by-side)
  7. export default class PollScreen extends Component {
  8. // construct properties and initialize functions
  9. constructor (props) {
  10. super(props);
  11. this.state = {
  12. counter: 0,
  13. point: 1,
  14. pollindex: 0,
  15. fillup: false,
  16. scores: [ 0, 0, 0, 0, 0 ],
  17. diffperc: [ 0, 0, 0, 0, 0 ],
  18. shouldUpdate: false,
  19. continue: false
  20. };
  21. this.btns = [];
  22. // context binding
  23. this.setData = this.setData.bind(this);
  24. this.doPoll = this.doPoll.bind(this);
  25. this.handleNext = this.handleNext.bind(this);
  26. }
  27. // set data is triggered from d3js module
  28. setData (data) {
  29. if (data.continue) this.setState({ continue: true });
  30. // all polls completed
  31. if (this.props.iteration === 14) {
  32. this.props.toNext();
  33. } else {
  34. // iteration equals 7, 10 or 11
  35. this.setState(Object.assign(data, { shouldUpdate: false, fillup: false }));
  36. if (data.counter === 10 || data.counter === 100 || data.counter === 1000) {
  37. this.props.toNext();
  38. }
  39. }
  40. }
  41. // execute poll
  42. doPoll (point = 1, fillup = false) {
  43. this.setState({ shouldUpdate: true, point, fillup });
  44. }
  45. // handle next iteration
  46. handleNext (point = 1) {
  47. if (this.state.continue) {
  48. const map = { q7: 10, q10: 100, q11: 1000 };
  49. const isQ0 = this.props.iteration === 0;
  50. const isQ4 = this.props.iteration === 4;
  51. const isQ13 = this.props.iteration === 13;
  52. const isQ14 = this.props.iteration === 14;
  53. const condQ7 = this.props.iteration === 7 && this.state.counter < map.q7;
  54. const condQ10 = this.props.iteration === 10 && this.state.counter < map.q10;
  55. const condQ11 = this.props.iteration === 11 && this.state.counter < map.q11;
  56. const condHideBtn = !isQ0 && !isQ4 && !isQ13 && !isQ14;
  57. if (condHideBtn) this.setState({ continue: false });
  58. // do poll
  59. if (condQ7 || condQ10 || condQ11) {
  60. this.doPoll(point, point === map[`q${this.props.iteration}`]);
  61. } else if (isQ14) {
  62. // generate poll
  63. this.setState({ pollindex: this.state.pollindex + 1, continue: this.state.pollindex < 3 });
  64. } else {
  65. // go to next screen
  66. this.props.toNext();
  67. }
  68. }
  69. }
  70. // LIFECYCLE methods
  71. // handle continue button visibility
  72. componentDidUpdate () {
  73. // handle question screen
  74. const isQuestion = (this.props.iteration === 9 || this.props.iteration === 13) && this.props.currentAnswerIndex === null;
  75. if (this.btns.length && !isQuestion) {
  76. this.btns.forEach(btn => {
  77. if (btn) {
  78. if (this.state.continue) {
  79. btn.classList.add('isvisible');
  80. } else {
  81. btn.classList.remove('isvisible');
  82. }
  83. }
  84. });
  85. }
  86. if (!isQuestion) {
  87. const contentNode = document.querySelector('.fakenews__content');
  88. if (this.state.continue) {
  89. contentNode.classList.add('isvisible');
  90. } else {
  91. contentNode.classList.remove('isvisible');
  92. }
  93. }
  94. }
  95. // RENDER
  96. render () {
  97. const numberOfBtns = this.props.next.length;
  98. const multipleBtn = numberOfBtns > 1 && this.state.counter >= 1;
  99. const pointMap = [ 1, 10, 100, 1000 ];
  100. const classMap = [
  101. multipleBtn ? ' button--wide--first' : '', // first button
  102. numberOfBtns === 2 ? ' button--wide--last' : ' button--wide--between', // second button
  103. numberOfBtns >= 3 ? ' button--wide--last' : ' button--wide--between', // third button
  104. ' button--wide--last' // last btn
  105. ];
  106. return (
  107. <section className="wrapper">
  108. <HeaderLightItem { ...this.props } />
  109. <main className="wrapper__main wrapper--centered">
  110. <div class="wrapper__fakenews">
  111. <TextItem {...this.props} setData={this.setData} />
  112. <AnimItem {...this.props} {...this.state} setData={this.setData} />
  113. </div>
  114. </main>
  115. <footer className="footer footer--flex">
  116. {this.props.next.map((btn, i) => (
  117. <a href="#" title={btn} className={`button--wide button--wide--cond ${classMap[i]}`} key={`key-${i}`}
  118. onClick={() => this.handleNext(pointMap[i]) } ref={elem => (this.btns[i] = elem)}>
  119. {btn}
  120. </a>
  121. ))}
  122. </footer>
  123. </section>
  124. );
  125. }
  126. }