generated from hatchways/express-starter
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
1,897 additions
and
355 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,11 @@ | |
width: 75px; | ||
background-color: limegreen; | ||
} | ||
|
||
.grid-content { | ||
padding: 25px; | ||
} | ||
|
||
.label { | ||
padding-right: 8px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import React, { useState } from "react"; | ||
import Button from "@material-ui/core/Button"; | ||
import Container from "@material-ui/core/Container"; | ||
import Grid from "@material-ui/core/Grid"; | ||
import Typography from "@material-ui/core/Typography"; | ||
|
||
import { copyToClipboard } from "../../utils/utils"; | ||
import Header from "../common/Header"; | ||
import TeamSelect from "./team_select/TeamSelect"; | ||
import "../common/common.css"; | ||
import "./GameLobby.css"; | ||
|
||
const SPYMASTER_INDEX = 0; | ||
const FIELD_AGENT_INDEX = 1; | ||
|
||
function GameLobby() { | ||
const currentUser = { sessionID: 1, firstName: "Tony" }; // dummy data of current user. sessionID will be generated from web socket in backend | ||
const [matchID] = useState("ABCD"); // dummy match ID | ||
const [canStartGame, setCanStartGame] = useState(false); | ||
|
||
const isTeamReady = (team) => { | ||
const spyMaster = team[SPYMASTER_INDEX]; | ||
const fieldAgents = team.slice(FIELD_AGENT_INDEX); | ||
|
||
return spyMaster.player && fieldAgents.some((agent) => agent.player); | ||
}; | ||
|
||
const onTeamSelect = (redTeam, blueTeam) => { | ||
const isRedTeamReady = isTeamReady(redTeam); | ||
const isBlueTeamReady = isTeamReady(blueTeam); | ||
|
||
setCanStartGame(isRedTeamReady && isBlueTeamReady); | ||
}; | ||
|
||
const startGame = () => { | ||
if (canStartGame) { | ||
// send list of players of each team to server and transition to game board | ||
console.log("Game is starting..."); | ||
} | ||
}; | ||
|
||
return ( | ||
<Container> | ||
<Grid container direction="column" justify="center" alignItems="center"> | ||
<Grid item className="header"> | ||
<Header title="New Game" /> | ||
</Grid> | ||
<Grid item> | ||
<Grid | ||
container | ||
direction="column" | ||
justify="center" | ||
alignItems="center" | ||
> | ||
<Grid item> | ||
<TeamSelect currentUser={currentUser} onChange={onTeamSelect} /> | ||
</Grid> | ||
<Grid item> | ||
<Button | ||
onClick={() => startGame()} | ||
disabled={!canStartGame} | ||
variant="contained" | ||
color="primary" | ||
size="large" | ||
> | ||
Start Game | ||
</Button> | ||
</Grid> | ||
<Grid item> | ||
<Grid | ||
className="grid-content" | ||
container | ||
justify="center" | ||
alignItems="center" | ||
> | ||
<Grid className="label" item> | ||
<Typography>Share Match ID:</Typography> | ||
</Grid> | ||
<Grid item> | ||
<Button | ||
onClick={() => { | ||
copyToClipboard(matchID); | ||
}} | ||
variant="outlined" | ||
color="default" | ||
size="small" | ||
> | ||
Copy | ||
</Button> | ||
</Grid> | ||
</Grid> | ||
</Grid> | ||
</Grid> | ||
</Grid> | ||
</Grid> | ||
</Container> | ||
); | ||
} | ||
|
||
export default GameLobby; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
export const TEAM_CODE = { | ||
RED: "RED", | ||
BLUE: "BLUE", | ||
}; | ||
|
||
export const DEFAULT_TEAM_STATE = [ | ||
{ role: "Spymaster", player: null }, | ||
{ role: "Field Agent", player: null }, | ||
{ role: "Field Agent", player: null }, | ||
{ role: "Field Agent", player: null }, | ||
]; | ||
|
||
export const ACTION_TYPE = { | ||
SET_PLAYER: "SET_PLAYER", | ||
REMOVE_PLAYER: "REMOVE_PLAYER", | ||
}; | ||
|
||
export const reducer = (state, action) => { | ||
switch (action.type) { | ||
case ACTION_TYPE.SET_PLAYER: | ||
state[action.payload].player = action.player; | ||
return state; | ||
case ACTION_TYPE.REMOVE_PLAYER: | ||
state[action.payload].player = null; | ||
return state; | ||
default: | ||
return state; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
.team { | ||
padding: 25px; | ||
} | ||
|
||
#red-team { | ||
color: red; | ||
} | ||
|
||
#blue-team { | ||
color: blue; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import React, { useState, useEffect, useReducer } from "react"; | ||
import Grid from "@material-ui/core/Grid"; | ||
import List from "@material-ui/core/List"; | ||
import ListItem from "@material-ui/core/ListItem"; | ||
import ListItemText from "@material-ui/core/ListItemText"; | ||
import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction"; | ||
import Typography from "@material-ui/core/Typography"; | ||
|
||
import { | ||
TEAM_CODE, | ||
ACTION_TYPE, | ||
DEFAULT_TEAM_STATE, | ||
reducer as teamReducer, | ||
} from "./TeamPresets"; | ||
import { JoinRoleAction, LeaveRoleAction } from "./TeamSelectActions"; | ||
import "./TeamSelect.css"; | ||
|
||
const DEFAULT_RED_TEAM_STATE = JSON.parse(JSON.stringify(DEFAULT_TEAM_STATE)); | ||
const DEFAULT_BLUE_TEAM_STATE = JSON.parse(JSON.stringify(DEFAULT_TEAM_STATE)); | ||
|
||
const UNOCCUPIED_SPOT_NAME = "--"; | ||
|
||
function TeamSelect(props) { | ||
const [redTeam, redTeamDispatch] = useReducer( | ||
teamReducer, | ||
DEFAULT_RED_TEAM_STATE | ||
); | ||
const [blueTeam, blueTeamDispatch] = useReducer( | ||
teamReducer, | ||
DEFAULT_BLUE_TEAM_STATE | ||
); | ||
const [isRoleAssigned, setIsRoleAssigned] = useState(false); | ||
|
||
useEffect(() => { | ||
props.onChange(redTeam, blueTeam); | ||
}); | ||
|
||
const joinRole = (teamCode, index) => { | ||
const action = { | ||
type: ACTION_TYPE.SET_PLAYER, | ||
payload: index, | ||
player: props.currentUser, | ||
}; | ||
|
||
teamCode === TEAM_CODE.RED | ||
? redTeamDispatch(action) | ||
: blueTeamDispatch(action); | ||
|
||
setIsRoleAssigned(!isRoleAssigned); | ||
}; | ||
|
||
const leaveRole = (teamCode, index) => { | ||
const action = { | ||
type: ACTION_TYPE.SET_PLAYER, | ||
payload: index, | ||
}; | ||
|
||
teamCode === TEAM_CODE.RED | ||
? redTeamDispatch(action) | ||
: blueTeamDispatch(action); | ||
|
||
setIsRoleAssigned(!isRoleAssigned); | ||
}; | ||
|
||
const generateListItem = (teamCode) => { | ||
const team = teamCode === TEAM_CODE.RED ? redTeam : blueTeam; | ||
const generateActions = (spot, index) => { | ||
return !spot.player ? ( | ||
!isRoleAssigned ? ( | ||
<JoinRoleAction | ||
joinRole={joinRole} | ||
teamCode={teamCode} | ||
index={index} | ||
/> | ||
) : null | ||
) : // show "Leave Role" action only if current user's session ID matches their own | ||
props.currentUser.sessionID === spot.player.sessionID && | ||
isRoleAssigned ? ( | ||
<LeaveRoleAction | ||
leaveRole={leaveRole} | ||
teamCode={teamCode} | ||
index={index} | ||
/> | ||
) : null; | ||
}; | ||
|
||
return team.map((spot, index) => { | ||
const uniquekey = teamCode + "-" + index; | ||
return ( | ||
<ListItem key={uniquekey}> | ||
<ListItemText secondary={spot.role}> | ||
{spot.player ? spot.player.firstName : UNOCCUPIED_SPOT_NAME} | ||
</ListItemText> | ||
<ListItemSecondaryAction> | ||
{generateActions(spot, index)} | ||
</ListItemSecondaryAction> | ||
</ListItem> | ||
); | ||
}); | ||
}; | ||
|
||
return ( | ||
<Grid container justify="center" alignItems="center"> | ||
<Grid item className="team"> | ||
<Grid container direction="column" justify="center" alignItems="center"> | ||
<Grid item> | ||
<Typography id="red-team" variant="h6" gutterBottom> | ||
Red Team | ||
</Typography> | ||
</Grid> | ||
<Grid item> | ||
<List>{generateListItem(TEAM_CODE.RED)}</List> | ||
</Grid> | ||
</Grid> | ||
</Grid> | ||
<Grid item className="team"> | ||
<Grid container direction="column" justify="center" alignItems="center"> | ||
<Grid item> | ||
<Typography id="blue-team" variant="h6" gutterBottom> | ||
Blue Team | ||
</Typography> | ||
</Grid> | ||
<Grid item> | ||
<List>{generateListItem(TEAM_CODE.BLUE)}</List> | ||
</Grid> | ||
</Grid> | ||
</Grid> | ||
</Grid> | ||
); | ||
} | ||
|
||
export default TeamSelect; |
30 changes: 30 additions & 0 deletions
30
client/src/pages/game_lobby/team_select/TeamSelectActions.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from "react"; | ||
import AddCircle from "@material-ui/icons/AddCircle"; | ||
import IconButton from "@material-ui/core/IconButton"; | ||
import RemoveCircle from "@material-ui/icons/RemoveCircle"; | ||
|
||
export const JoinRoleAction = ({ joinRole, teamCode, index }) => { | ||
return ( | ||
<IconButton | ||
onClick={() => { | ||
joinRole(teamCode, index); | ||
}} | ||
edge="end" | ||
> | ||
<AddCircle /> | ||
</IconButton> | ||
); | ||
}; | ||
|
||
export const LeaveRoleAction = ({ leaveRole, teamCode, index }) => { | ||
return ( | ||
<IconButton | ||
onClick={() => { | ||
leaveRole(teamCode, index); | ||
}} | ||
edge="end" | ||
> | ||
<RemoveCircle /> | ||
</IconButton> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export const copyToClipboard = (text) => { | ||
// source: https://stackoverflow.com/questions/33855641/copy-output-of-a-javascript-variable-to-the-clipboard | ||
let dummy = document.createElement("textarea"); | ||
document.body.appendChild(dummy); | ||
dummy.value = text; | ||
dummy.select(); | ||
document.execCommand("copy"); | ||
document.body.removeChild(dummy); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
const mongoose = require('mongoose'); | ||
const mongoose = require("mongoose"); | ||
const url = process.env.MONGOLAB_URI; | ||
|
||
mongoose.connect(url, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true}); | ||
module.exports = { mongoose }; | ||
mongoose.connect(url, { | ||
useNewUrlParser: true, | ||
useCreateIndex: true, | ||
useUnifiedTopology: true, | ||
}); | ||
module.exports = { mongoose }; |
Oops, something went wrong.