From b63d889f735852acdf03d2ae8062373adaa77137 Mon Sep 17 00:00:00 2001
From: Joni Laukka <jonilaukka@hotmail.com>
Date: Sun, 14 Jul 2019 17:31:24 +0300
Subject: [PATCH] Game sidebar buttons added to gameview, join game form added,
 playerlist added

---
 src/components/GameSidebar.js       |  14 +---
 src/components/GameView.js          | 102 ++++++++++++++++++++----
 src/components/JoinGameForm.js      | 119 +++++++++++++++++++++++++---
 src/components/NotificationView.js  |   7 ++
 src/components/PlayerlistFaction.js |  44 ++++++++++
 src/components/PlayerlistView.js    |  68 ++++++++++++++++
 6 files changed, 314 insertions(+), 40 deletions(-)
 create mode 100644 src/components/NotificationView.js
 create mode 100644 src/components/PlayerlistFaction.js
 create mode 100644 src/components/PlayerlistView.js

diff --git a/src/components/GameSidebar.js b/src/components/GameSidebar.js
index 0511cdc..0468ddf 100644
--- a/src/components/GameSidebar.js
+++ b/src/components/GameSidebar.js
@@ -14,18 +14,6 @@ export default class GameSidebar extends React.Component {
   };
 
   render() {
-    return (
-      <div className="game-sidebar">
-        <GameList />
-        {this.props.loggedIn && (
-          <button id="newGameButton" onClick={() => this.toggleView("newgame")}>
-            New Game
-          </button>
-        )}
-        {this.state.form === "newgame" && (
-          <NewGameForm view="" toggleView={() => this.toggleView("")} />
-        )}
-      </div>
-    );
+    return false;
   }
 }
diff --git a/src/components/GameView.js b/src/components/GameView.js
index cff3966..184d2a0 100644
--- a/src/components/GameView.js
+++ b/src/components/GameView.js
@@ -2,10 +2,15 @@ import React from "react";
 import UserMap from "./UserMap";
 import TaskListButton from "./TaskListButton";
 import { BrowserRouter as Router, Link } from "react-router-dom";
+import EditGameForm from "./EditGameForm";
+import JoinGameForm from "./JoinGameForm";
+import PlayerlistView from "./PlayerlistView";
+import NotificationView from "./NotificationView";
 
 export default class GameView extends React.Component {
   state = {
-    gameId: null,
+    gameInfo: null,
+    form: "",
     lat: 62.2416479,
     lng: 25.7597186,
     zoom: 13,
@@ -13,32 +18,95 @@ export default class GameView extends React.Component {
   };
 
   componentDidMount() {
-    let id = new URL(window.location.href).searchParams.get("id");
-    this.setState({
-      gameId: id
-    });
+    let gameId = new URL(window.location.href).searchParams.get("id");
+    fetch(`${process.env.REACT_APP_API_URL}/game/${gameId}`)
+      .then(res => res.json())
+      .then(res => {
+        this.setState({
+          gameInfo: res
+        });
+      })
+      .catch(error => console.log(error));
   }
 
   render() {
-    if (this.state.gameId === null) {
-      return false;
-    }
-
     const initialPosition = [this.state.lat, this.state.lng];
 
     return (
       <div>
-        <div>{this.state.gameId}</div>
         <Link to="/">
           <button>Game selection</button>
         </Link>
-        <TaskListButton gameId={this.state.gameId} />
-        <UserMap
-          position={initialPosition}
-          zoom={this.state.zoom}
-          mapUrl={this.state.mapUrl}
-          currentGameId={this.state.currentGameId}
-        />
+        {this.state.gameInfo !== null && (
+          <div>
+            <div>Game Name: {this.state.gameInfo.name}</div>
+            <button
+              id="editGameButton"
+              onClick={() => this.setState({ form: "edit" })}
+            >
+              Edit
+            </button>
+            <button
+              id="joinGameButton"
+              onClick={() => this.setState({ form: "join" })}
+            >
+              Join
+            </button>
+            <button
+              id="showPlayersButton"
+              onClick={() => this.setState({ form: "players" })}
+            >
+              Players
+            </button>
+            <button
+              id="notificationsButton"
+              onClick={() => this.setState({ form: "notifications" })}
+            >
+              Notifications
+            </button>
+            <TaskListButton gameId={this.state.gameInfo.id} />
+            <button
+              id="leaveFactionButton"
+              onClick={() => console.log("WIP: leave faction")}
+            >
+              Leave Faction
+            </button>
+            <UserMap
+              position={initialPosition}
+              zoom={this.state.zoom}
+              mapUrl={this.state.mapUrl}
+              currentGameId={this.state.gameInfo.id}
+            />
+            {this.state.form === "edit" && (
+              <EditGameForm
+                gameId={this.state.gameInfo.id}
+                toggleView={() => this.setState({ form: "" })}
+                onEditSave={() => {
+                  this.getGameInfo();
+                }}
+              />
+            )}
+            {this.state.form === "join" && (
+              <JoinGameForm
+                gameId={this.state.gameInfo.id}
+                toggleView={() => this.setState({ form: "" })}
+                onJoin={() => console.log("joinde")}
+              />
+            )}
+            {this.state.form === "players" && (
+              <PlayerlistView
+                gameId={this.state.gameInfo.id}
+                toggleView={() => this.setState({ form: "" })}
+              />
+            )}
+            {this.state.form === "notifications" && (
+              <NotificationView
+                gameId={this.state.gameInfo.id}
+                toggleView={() => this.setState({ form: "" })}
+              />
+            )}
+          </div>
+        )}
       </div>
     );
   }
diff --git a/src/components/JoinGameForm.js b/src/components/JoinGameForm.js
index 7ea0aaf..f4f89ed 100644
--- a/src/components/JoinGameForm.js
+++ b/src/components/JoinGameForm.js
@@ -1,13 +1,20 @@
 import React from "react";
+import ReactDOM from "react-dom";
+import PropTypes from "prop-types";
 
 export default class JoinGameForm extends React.Component {
   constructor(props) {
     super(props);
     this.state = {
-      gameJSON: undefined
+      gameJSON: undefined,
+      selectedFactionId: "",
+      factionPasswordInput: "", //>= 3 chars
+      errorMessage: ""
     };
   }
 
+  // Get game info
+  //TODO: from props
   componentDidMount() {
     if (this.props.gameId === undefined) {
       alert("game not selected");
@@ -16,26 +23,118 @@ export default class JoinGameForm extends React.Component {
         .then(result => result.json())
         .then(json => {
           this.setState({
-            gameJSON: json
+            gameJSON: json,
+            selectedFactionId:
+              json.factions.length > 0 ? json.factions[0].factionId : ""
           });
         })
         .catch(error => console.log(error));
     }
   }
 
+  handleView = e => {
+    this.props.toggleView(this.props.view);
+  };
+
+  handleGameJoin = e => {
+    e.preventDefault();
+
+    let token = sessionStorage.getItem("token");
+    let error = false;
+
+    fetch(
+      `${process.env.REACT_APP_API_URL}/faction/join-faction/${
+        this.state.gameJSON.id
+      }`,
+      {
+        method: "PUT",
+        headers: {
+          Authorization: "Bearer " + token,
+          Accept: "application/json",
+          "Content-Type": "application/json"
+        },
+        body: JSON.stringify({
+          factionPassword: this.state.factionPasswordInput,
+          factionId: this.state.selectedFactionId,
+          game: this.state.gameJSON.id
+        })
+      }
+    )
+      .then(res => {
+        if (!res.ok) {
+          error = true;
+        }
+        return res.json();
+      })
+      .then(result => {
+        if (!error) {
+          alert("Joined faction " + result.faction.factionName);
+          this.props.onJoin();
+          this.handleView();
+        } else {
+          alert(result.message);
+        }
+      })
+      .catch(error => console.log(error));
+  };
+
   render() {
     if (this.state.gameJSON === undefined) {
       return false;
     }
 
-    return (
-      <div>
-        <form>
-          <label>Join game: {this.state.gameJSON.name}</label>
-          <div>{this.state.gameJSON.desc}</div>
-          <button onClick={() => console.log("clicked")}>Submit</button>
-        </form>
-      </div>
+    let factionItems = this.state.gameJSON.factions.map(faction => (
+      <option key={faction.factionId} value={faction.factionId}>
+        {faction.factionName}
+      </option>
+    ));
+
+    return ReactDOM.createPortal(
+      <div className="fade-main">
+        <div className="sticky">
+          <span
+            id="closeNewGameFormX"
+            className="close"
+            onClick={this.handleView}
+          >
+            ×
+          </span>
+        </div>
+        <div className="">
+          <form onSubmit={this.handleGameJoin}>
+            <h1>Join game: {this.state.gameJSON.name}</h1>
+            <h2>Description: {this.state.gameJSON.desc}</h2>
+            <select
+              onChange={e =>
+                this.setState({ selectedFactionId: e.target.value })
+              }
+            >
+              {factionItems}
+            </select>
+            <input
+              id="factionPasswordInput"
+              value={this.state.factionPasswordInput}
+              onChange={e =>
+                this.setState({ factionPasswordInput: e.target.value })
+              }
+              placeholder="Password"
+              minLength="3"
+              required
+            />
+            <button id="joinGameSubmitButton" type="submit">
+              Submit
+            </button>
+            <h2>{this.state.errorMsg}</h2>
+          </form>
+        </div>
+      </div>,
+      document.getElementById("form")
     );
   }
 }
+
+JoinGameForm.propTypes = {
+  gameId: PropTypes.string,
+  toggleView: PropTypes.func,
+  onJoin: PropTypes.func
+};
diff --git a/src/components/NotificationView.js b/src/components/NotificationView.js
new file mode 100644
index 0000000..5fcf801
--- /dev/null
+++ b/src/components/NotificationView.js
@@ -0,0 +1,7 @@
+import React from "react";
+
+export default class NotificationView extends React.Component {
+  render() {
+    return false;
+  }
+}
diff --git a/src/components/PlayerlistFaction.js b/src/components/PlayerlistFaction.js
new file mode 100644
index 0000000..13638fd
--- /dev/null
+++ b/src/components/PlayerlistFaction.js
@@ -0,0 +1,44 @@
+import React from "react";
+
+export default class PlayerlistFaction extends React.Component {
+  state = {
+    factionMembers: null
+  };
+
+  // get faction members
+  componentDidMount() {
+    fetch(
+      `${process.env.REACT_APP_API_URL}/faction/get-faction-members/${
+        this.props.faction.factionId
+      }`
+    )
+      .then(res => res.json())
+      .then(res => {
+        this.setState({ factionMembers: res });
+      })
+      .catch(error => console.log(error));
+  }
+
+  render() {
+    if (this.state.factionMembers === null) {
+      return false;
+    }
+
+    let members = this.state.factionMembers.map(member => {
+      return (
+        <div key={member.gamepersonId}>
+          {member.person.name} : {member.role}
+        </div>
+      );
+    });
+
+    return (
+      <div>
+        <br />
+        <div>{this.props.faction.factionName}</div>
+        <br />
+        <div>{members}</div>
+      </div>
+    );
+  }
+}
diff --git a/src/components/PlayerlistView.js b/src/components/PlayerlistView.js
new file mode 100644
index 0000000..f14cb74
--- /dev/null
+++ b/src/components/PlayerlistView.js
@@ -0,0 +1,68 @@
+import React from "react";
+import PropTypes from "prop-types";
+import PlayerlistFaction from "./PlayerlistFaction";
+
+export default class PlayerlistView extends React.Component {
+  state = {
+    factions: null,
+    isAdmin: false
+  };
+
+  componentDidMount() {
+    let token = sessionStorage.getItem("token");
+
+    if (this.state.isAdmin) {
+      // get all factions in the game
+      fetch(
+        `${process.env.REACT_APP_API_URL}/game/get-factions/${
+          this.props.gameId
+        }`,
+        {
+          method: "GET",
+          headers: {
+            Authorization: "Bearer " + token
+          }
+        }
+      )
+        .then(res => res.json())
+        .then(res => {
+          this.setState({ factions: res });
+        })
+        .catch(error => console.log(error));
+    } else {
+      // get player's faction
+      fetch(
+        `${process.env.REACT_APP_API_URL}/faction/check-faction/${
+          this.props.gameId
+        }`,
+        {
+          method: "GET",
+          headers: {
+            Authorization: "Bearer " + token
+          }
+        }
+      )
+        .then(res => res.json())
+        .then(res => {
+          this.setState({ factions: [res] });
+        })
+        .catch(error => console.log(error));
+    }
+  }
+
+  render() {
+    if (this.state.factions === null) {
+      return false;
+    }
+
+    let factionlistItems = this.state.factions.map(faction => {
+      return <PlayerlistFaction faction={faction} />;
+    });
+
+    return <div className="fade-main">{factionlistItems}</div>;
+  }
+}
+
+PlayerlistView.propTypes = {
+  gameId: PropTypes.string
+};
-- 
GitLab