edX Hackathon 4/13/2017 Project: Insights Courses Page in Server-side Rendered React

index.js 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import 'isomorphic-fetch';
  2. import Immutable from 'immutable';
  3. import PropTypes from 'prop-types';
  4. import React, { PureComponent } from 'react';
  5. import Head from 'next/head';
  6. import Table from '../components/table.js';
  7. export default class Application extends PureComponent {
  8. constructor (props, context) {
  9. super(props, context);
  10. this.state = {
  11. courses: this.props.courses,
  12. refreshing: false
  13. }
  14. this._onRefreshClick = this._onRefreshClick.bind(this);
  15. }
  16. static async getInitialProps ({ req }) {
  17. console.log('INITIAL PROPS');
  18. const courses = await Application.fetchCourses();
  19. return {'courses': courses};
  20. }
  21. static async fetchCourses () {
  22. let res;
  23. try {
  24. res = await fetch('http://localhost:9001/api/v0/course_summaries/', {
  25. headers: {
  26. 'Authorization': 'Token edx'
  27. }
  28. });
  29. } catch (exception) {
  30. console.error(exception);
  31. }
  32. if (res !== undefined) {
  33. const json = await res.json();
  34. const list = Immutable.List(json);
  35. return list;
  36. } else {
  37. return Immutable.List([]);
  38. }
  39. }
  40. _onRefreshClick (event) {
  41. this.refresh();
  42. return true;
  43. }
  44. async refresh () {
  45. this.setState({refreshing: true});
  46. const courses = await Application.fetchCourses();
  47. this.setState({'courses': courses});
  48. this.setState({refreshing: false});
  49. }
  50. render () {
  51. const courses = this.state.courses ? this.state.courses : this.props.courses;
  52. return (
  53. <div>
  54. <Head>
  55. <title>Insights React Demo</title>
  56. <meta name="viewport" content="initial-scale=1.0, width=device-width" />
  57. <style>{`
  58. html, body {
  59. height: 98%;
  60. margin: 0;
  61. }
  62. html {
  63. font-size: 14px;
  64. }
  65. body {
  66. font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  67. font-size: 1rem;
  68. font-weight: normal;
  69. line-height: 20px;
  70. -webkit-font-smoothing: antialiased;
  71. background-color: whitesmoke;
  72. }
  73. .contents {
  74. margin: 10px;
  75. }
  76. `}</style>
  77. </Head>
  78. <div className="contents">
  79. <h1 style={{
  80. marginBottom: '40px',
  81. fontWeight: '300'
  82. }}>edX Insights</h1>
  83. <button
  84. style={{
  85. float: 'right'
  86. }}
  87. onClick={this._onRefreshClick}
  88. disabled={this.state.refreshing ? 'disabled' : ''}
  89. >
  90. {this.state.refreshing ? '↻' : ''}Refresh
  91. </button>
  92. <Table list={this.props.courses} />
  93. </div>
  94. </div>
  95. );
  96. }
  97. }