index.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { Component } from "react";
  2. import { Link } from "react-router-dom";
  3. import { Button } from "react-bootstrap";
  4. import { Typography } from "@material-ui/core";
  5. import { Loading } from "..";
  6. import axios from "axios";
  7. import Leaderboard from "./Leaderboard";
  8. import Round from "./Round";
  9. const baseUrl = `https://joystreamstats.live/static`;
  10. class KPI extends Component {
  11. constructor(props: { tokenomics: Tokenomics }) {
  12. super(props);
  13. this.state = { round: null, rounds: [], leaderboard: [], grading: [] };
  14. this.fetchKpi = this.fetchKpi.bind(this);
  15. this.fetchLeaderboard = this.fetchLeaderboard.bind(this);
  16. this.toggleShowLeaderboard = this.toggleShowLeaderboard.bind(this);
  17. }
  18. componentDidMount() {
  19. this.loadData();
  20. }
  21. loadData() {
  22. this.fetchKpi();
  23. this.fetchLeaderboard();
  24. }
  25. fetchKpi() {
  26. axios
  27. .get(`${baseUrl}/kpi.json`)
  28. .then(({ data }) => {
  29. const rounds = data.rounds;
  30. console.debug(`Received KPI for ${rounds.length} round(s).`);
  31. const round = rounds.reduce(
  32. (r, max) => (r.round > max.round ? r : max),
  33. rounds[0]
  34. );
  35. this.setState({ rounds, round });
  36. })
  37. .catch((e) => console.error(`Failed to fetch KPI data.`, e));
  38. }
  39. fetchLeaderboard() {
  40. axios
  41. .get(`${baseUrl}/kpi-grading.json`)
  42. .then(({ data }) => this.setState({ grading: data }))
  43. .catch((e) => console.error(`Failed to fetch KPI grading data.`, e));
  44. axios
  45. .get(`${baseUrl}/leaderboard.json`)
  46. .then(({ data }) => this.setState({ leaderboard: data }))
  47. .catch((e) => console.error(`Failed to fetch Leadboard data.`, e));
  48. }
  49. selectRound(selectedRound: number) {
  50. this.setState({ selectedRound, showLeaderboard: false });
  51. }
  52. toggleShowLeaderboard() {
  53. this.setState({ showLeaderboard: !this.state.showLeaderboard });
  54. }
  55. focus(id) {
  56. document.getElementById(id)?.scrollIntoView();
  57. }
  58. render() {
  59. const { round, rounds, grading, leaderboard, showLeaderboard } = this.state;
  60. if (!round) return <Loading target="KPI" />;
  61. return (
  62. <div className="m-3 p-2 text-light">
  63. <div className="d-flex flex-row">
  64. <Button
  65. variant={showLeaderboard ? "light" : "outline-secondary"}
  66. className="p-1 btn-sm"
  67. onClick={this.toggleShowLeaderboard}
  68. >
  69. Leaderboard
  70. </Button>
  71. <Link
  72. to={`/bounties`}
  73. className="mx-2 p-1 btn btn-sm btn-outline-secondary"
  74. >
  75. Bounties
  76. </Link>
  77. <Link to={`/issues`} className="p-1 btn btn-sm btn-outline-secondary">
  78. Operations Tasks
  79. </Link>
  80. </div>
  81. <Typography variant="h2" className="mt-3">
  82. KPI
  83. </Typography>
  84. <div className="d-flex flex-wrap">
  85. {rounds.map((r) => (
  86. <Button
  87. key={r.round}
  88. variant={r.round === round.round ? "light" : "outline-light"}
  89. className="ml-1 p-1 flex-grow-0"
  90. onClick={() => this.selectRound(round)}
  91. >
  92. {r.round}
  93. </Button>
  94. ))}
  95. </div>
  96. {showLeaderboard ? (
  97. <Leaderboard
  98. kpi={grading}
  99. leaderboard={leaderboard}
  100. tokenomics={this.props.tokenomics}
  101. />
  102. ) : (
  103. <Round
  104. round={round}
  105. fetchKpi={this.fetchKpi}
  106. focus={this.focus}
  107. toggleEditKpi={this.props.toggleEditKpi}
  108. />
  109. )}
  110. </div>
  111. );
  112. }
  113. }
  114. export default KPI;