Browse Source

More containser vs presentational components to prepare the battle data.

Frederic G. MARAND 8 years ago
parent
commit
4cb04ee970

+ 22 - 0
components/Results.js

@@ -0,0 +1,22 @@
+import React from "react";
+const PropTypes = React.PropTypes;
+
+function puke(obj) {
+  return <pre>{JSON.stringify(obj, null, "  ")}</pre>;
+}
+
+const Results = (props) => {
+  return (
+    <div>
+      Results: {puke(props)}
+    </div>
+  );
+};
+
+Results.propTypes = {
+  isLoading: PropTypes.bool.isRequired,
+  playerInfo: PropTypes.array.isRequired,
+  scores: PropTypes.array.isRequired
+};
+
+export default Results;

+ 0 - 1
components/UserDetails.js

@@ -2,7 +2,6 @@ import React from "react";
 const PropTypes = React.PropTypes;
 
 const UserDetails = (user) => {
-  console.log("Details", user);
   return (
     <div>
       {!user.score && <li className="list-group-item"><h3>Score: {user.score}</h3></li>}

+ 2 - 0
config/routes.js

@@ -4,6 +4,7 @@ import ConfirmBattleContainer from "../containers/ConfirmBattleContainer";
 import Main from "../components/Main";
 import Home from "../components/Home";
 import PromptContainer from "../containers/PromptContainer";
+import ResultsContainer from "../containers/ResultsContainer";
 
 const routes = (
   <Router history={history}>
@@ -12,6 +13,7 @@ const routes = (
       <Route path="playerOne" component={PromptContainer} header="Player One" />
       <Route path="playerTwo/:playerOne" component={PromptContainer} header="Player Two" />
       <Route path="battle" component={ConfirmBattleContainer} />
+      <Route path="results" component={ResultsContainer} />
     </Route>
   </Router>
 );

+ 2 - 2
containers/ConfirmBattleContainer.js

@@ -15,11 +15,11 @@ class ConfirmBattleContainer extends React.Component {
   }
 
   componentWillMount() {
-    console.log("componentWillMount");
+    // console.log("componentWillMount");
   }
 
   componentDidMount() {
-    console.log("componentDidMount");
+    // console.log("componentDidMount");
     const query = this.props.location.query;
     // Fetch info from Github then update state.
     githubHelpers.getPlayersInfo([query.playerOne, query.playerTwo])

+ 2 - 2
containers/PromptContainer.js

@@ -15,7 +15,7 @@ class PromptContainer extends React.Component {
 
   handleSubmitUser(e) {
     e.preventDefault();
-    console.log("oSU", this);
+    // console.log("oSU", this);
     let username = this.state.username;
     this.setState({
       username: ""
@@ -35,7 +35,7 @@ class PromptContainer extends React.Component {
   }
 
   handleUpdateUser(e) {
-    console.log("oUU", this);
+    // console.log("oUU", this);
     this.setState({
       username: e.target.value
     });

+ 41 - 0
containers/ResultsContainer.js

@@ -0,0 +1,41 @@
+import React from "react";
+import Results from "../components/Results";
+import githubHelpers from "../utils/githubHelpers";
+const PropTypes = React.PropTypes;
+
+class ResultsContainer extends React.Component {
+  constructor(props, context, updater) {
+    super(props, context, updater);
+    this.state = {
+      isLoading: true,
+      scores: []
+    };
+  }
+
+  componentDidMount() {
+    githubHelpers.battle(this.props.location.state.playerInfo)
+      .then((scores) => {
+        this.setState({
+          isLoading: false,
+          scores
+        });
+      }).catch((err) => {
+      console.warn("Error in battle", err);
+    });
+  }
+
+  render() {
+    return (
+      <Results
+        isLoading={this.state.isLoading}
+        playerInfo={this.props.location.state.playerInfo}
+        scores={this.state.scores} />
+    );
+  }
+}
+
+ResultsContainer.propTypes = {
+  
+};
+
+export default ResultsContainer;

+ 61 - 0
utils/githubHelpers.js

@@ -8,7 +8,67 @@ function getUserInfo(username) {
   return axios.get(`https://api.github.com/users/${username}${param}`);
 }
 
+/**
+ * Fetch repos for username.
+ *
+ * @param username
+ */
+function getRepos(username) {
+  return axios.get(`https://api.github.com/users/${username}/repos${param}&per_page=100`);
+}
+
+/**
+ * Calculate all the stars that the user has.
+ *
+ * @param repos
+ */
+function getTotalStars(repos) {
+  console.log("getTotalStars, repos", repos);
+  return repos.data.reduce((accu, repo) => {
+    return accu + repo.stargazers_count;
+  }, 0);
+}
+
+/**
+ * Get repos, get total stars, return object with these data.
+ *
+ * @param player
+ */
+function getPlayersData(player) {
+  return getRepos(player.login)
+    .then(getTotalStars)
+    .then((totalStars) => {
+      return {
+        followers: player.followers,
+        totalStars
+      };
+    });
+}
+
+/**
+ * Return an array after doing some fancy calculation to determine a winner.
+ *
+ * @param players
+ */
+function calculateScores(players) {
+  return [
+    players[0].followers * 3 + players[0].totalStars,
+    players[1].followers * 3 + players[1].totalStars
+  ];
+}
+
 const helpers = {
+  battle(players) {
+    const playerOneData = getPlayersData(players[0]);
+    const playerTwoData = getPlayersData(players[1]);
+
+    return axios.all([playerOneData, playerTwoData])
+      .then(calculateScores)
+      .catch((err) => {
+        console.warn("Battle getPlayersData error", err);
+      });
+  },
+
   getPlayersInfo(players) {
     // fetch some data from Github
     return axios.all(players.map((username) => {
@@ -23,4 +83,5 @@ const helpers = {
   }
 };
 
+
 export default helpers;