diff options
-rw-r--r-- | frontend/src/components/game-browser/GameBrowser.jsx | 7 | ||||
-rw-r--r-- | frontend/src/components/game-browser/GameList.css | 3 | ||||
-rw-r--r-- | frontend/src/components/game-browser/GameList.jsx | 54 | ||||
-rw-r--r-- | frontend/src/components/game-browser/GameStatus.jsx | 17 | ||||
-rw-r--r-- | frontend/src/components/game-browser/PlayerCount.css | 3 | ||||
-rw-r--r-- | frontend/src/components/game-browser/PlayerCount.jsx | 13 | ||||
-rw-r--r-- | frontend/src/models/games.js | 3 |
7 files changed, 82 insertions, 18 deletions
diff --git a/frontend/src/components/game-browser/GameBrowser.jsx b/frontend/src/components/game-browser/GameBrowser.jsx index db0bbb9a..84abd978 100644 --- a/frontend/src/components/game-browser/GameBrowser.jsx +++ b/frontend/src/components/game-browser/GameBrowser.jsx @@ -41,14 +41,11 @@ class GameBrowserPresenter extends Component<GameBrowserProps> { } const CreateGameButton = ({onClick}) => ( - <Button className={Classes.MINIMAL} onClick={onClick} intent={Intent.PRIMARY}>Create Game</Button> + <Button className={Classes.MINIMAL} intent={Intent.PRIMARY} icon='add' onClick={onClick} /> ); -const mapStateToProps = () => ({ -}); - const mapDispatchToProps = { createGame: actions.requestCreateGame, }; -export const GameBrowser = connect(mapStateToProps, mapDispatchToProps)(GameBrowserPresenter); +export const GameBrowser = connect(null, mapDispatchToProps)(GameBrowserPresenter); diff --git a/frontend/src/components/game-browser/GameList.css b/frontend/src/components/game-browser/GameList.css new file mode 100644 index 00000000..6b29741f --- /dev/null +++ b/frontend/src/components/game-browser/GameList.css @@ -0,0 +1,3 @@ +table.pt-html-table td { + vertical-align: middle; +} diff --git a/frontend/src/components/game-browser/GameList.jsx b/frontend/src/components/game-browser/GameList.jsx index e3601d51..5ec2303b 100644 --- a/frontend/src/components/game-browser/GameList.jsx +++ b/frontend/src/components/game-browser/GameList.jsx @@ -1,11 +1,13 @@ // @flow -import { Button, Text } from '@blueprintjs/core'; +import { Button, Icon } from '@blueprintjs/core'; import type { List } from 'immutable'; import React from 'react'; import { connect } from 'react-redux'; -import { Flex } from 'reflexbox'; import type { Game } from '../../models/games'; import { actions, getAllGames } from '../../redux/games'; +import './GameList.css'; +import { GameStatus } from './GameStatus'; +import { PlayerCount } from './PlayerCount'; type GameListProps = { games: List<Game>, @@ -13,18 +15,46 @@ type GameListProps = { }; const GameListPresenter = ({ games, joinGame }: GameListProps) => ( - <div> - {games.map((game: Game, index: number) => { - return ( - <Flex key={game.get('displayName', index)}> - <Text>{game.name}</Text> - <Button onClick={() => joinGame(game.id)}>Join</Button> - </Flex> - ); - })} - </div> + <table className='pt-html-table pt-interactive'> + <thead> + <GameListHeaderRow /> + </thead> + <tbody> + {games.map((game: Game) => <GameListItemRow key={game.id} game={game} joinGame={joinGame}/>)} + </tbody> + </table> ); +const GameListHeaderRow = () => ( + <tr> + <th>Name</th> + <th>Status</th> + <th>Nb Players</th> + <th>Join</th> + </tr> +); + +const GameListItemRow = ({game, joinGame}) => ( + <tr> + <td>{game.name}</td> + <td> + <GameStatus state={game.state} /> + </td> + <td> + <PlayerCount nbPlayers={game.players.size} /> + </td> + <td> + <JoinButton game={game} joinGame={joinGame}/> + </td> + </tr> +); + +const JoinButton = ({game, joinGame}) => { + const disabled = game.state !== 'LOBBY'; + const icon = <Icon icon='arrow-right' title={false} />; + return <Button minimal disabled={disabled} icon={icon} title='Join Game' onClick={() => joinGame(game.id)}/>; +}; + const mapStateToProps = state => ({ games: getAllGames(state.get('games')), }); diff --git a/frontend/src/components/game-browser/GameStatus.jsx b/frontend/src/components/game-browser/GameStatus.jsx new file mode 100644 index 00000000..4168f0a5 --- /dev/null +++ b/frontend/src/components/game-browser/GameStatus.jsx @@ -0,0 +1,17 @@ +//@flow +import { Tag } from '@blueprintjs/core'; +import * as React from 'react'; +import type { GameState } from '../../models/games'; + +export type GameStatusProps = { + state: GameState, +} + +export const GameStatus = ({state}: GameStatusProps) => ( + <Tag minimal intent={statusIntents[state]}>{state}</Tag> +); + +const statusIntents = { + 'LOBBY': 'success', + 'PLAYING': 'warning', +}; diff --git a/frontend/src/components/game-browser/PlayerCount.css b/frontend/src/components/game-browser/PlayerCount.css new file mode 100644 index 00000000..ca1a3723 --- /dev/null +++ b/frontend/src/components/game-browser/PlayerCount.css @@ -0,0 +1,3 @@ +svg.pt-icon, .playerCount { + vertical-align: middle; +} diff --git a/frontend/src/components/game-browser/PlayerCount.jsx b/frontend/src/components/game-browser/PlayerCount.jsx new file mode 100644 index 00000000..ea2161a4 --- /dev/null +++ b/frontend/src/components/game-browser/PlayerCount.jsx @@ -0,0 +1,13 @@ +//@flow +import { Icon } from '@blueprintjs/core'; +import * as React from 'react'; +import './PlayerCount.css'; + +export type PlayerCountProps = { + nbPlayers: number, +} + +export const PlayerCount = ({nbPlayers}: PlayerCountProps) => <div title='Number of players'> + <Icon icon="people" title={false} /> + <span className='playerCount'> {nbPlayers}</span> +</div>; diff --git a/frontend/src/models/games.js b/frontend/src/models/games.js index 6420e06d..dfa0591d 100644 --- a/frontend/src/models/games.js +++ b/frontend/src/models/games.js @@ -34,12 +34,13 @@ const SettingsRecord: SettingsType = Record({ }); export class Settings extends SettingsRecord {} +export type GameState = 'LOBBY' | 'PLAYING'; export type GameShape = { id: number, name: string | void, players: List<string>, settings: SettingsType, - state: "LOBBY" | "TODO" + state: GameState, }; export type GameType = Record<GameShape>; export type GameMapType = Map<string, GameShape>; |