front: Game section sceleton
This commit is contained in:
		
							parent
							
								
									0c24d8c3ac
								
							
						
					
					
						commit
						a2de2331cf
					
				| @ -1,7 +1,7 @@ | |||||||
| import './index.css'; | import './index.css'; | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| import { WhiteStone, BlackStone } from '../Stone'  | import { WhiteStone, BlackStone } from '../Game/Stone'  | ||||||
| 
 | 
 | ||||||
| export default function Board() { | export default function Board() { | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								webapp/src/components/Game/GameHeader.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								webapp/src/components/Game/GameHeader.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | import './GameHeader.css'; | ||||||
|  | import React from 'react'; | ||||||
|  | import { NavLink } from "react-router-dom"; | ||||||
|  | 
 | ||||||
|  | export default function GameHeader() { | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <nav className='game-header'> | ||||||
|  |       <NavLink to="/game/proposal">Proposal</NavLink> | ||||||
|  |       <NavLink to="/game/active">Active</NavLink> | ||||||
|  |       <NavLink to="/game/archive">Archive</NavLink> | ||||||
|  |     </nav> | ||||||
|  |   ) | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								webapp/src/components/Game/GameSelector.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								webapp/src/components/Game/GameSelector.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | import './GameSelector.css'; | ||||||
|  | import React from 'react'; | ||||||
|  | import { useLocation, matchPath } from "react-router"; | ||||||
|  | 
 | ||||||
|  | import { AppData } from "../../context/data" | ||||||
|  | import Proposal from './GameSelector/GameProposal'; | ||||||
|  | 
 | ||||||
|  | export default function Game() { | ||||||
|  |   const [data] = React.useContext(AppData) | ||||||
|  | 
 | ||||||
|  |   const { pathname } = useLocation(); | ||||||
|  |   const isProposalPath = matchPath("/game/proposal/*", pathname); | ||||||
|  |   const isActivelPath = matchPath("/game/active/*", pathname); | ||||||
|  |   const isArchivePath = matchPath("/game/archive/*", pathname); | ||||||
|  | 
 | ||||||
|  |   if (!data.games) | ||||||
|  |     return <div>Loading..</div> | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className='game-selector'> | ||||||
|  |       {isProposalPath && <Proposal games={data.games} />} | ||||||
|  |       {isActivelPath  && <div>TBD #1</div>} | ||||||
|  |       {isArchivePath  && <div>TBD #2</div>} | ||||||
|  |     </div> | ||||||
|  |   ) | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								webapp/src/components/Game/GameSelector/ActiveGames.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								webapp/src/components/Game/GameSelector/ActiveGames.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | import './ProposalSelector.css' | ||||||
|  | import React from 'react'; | ||||||
|  | import Selectable from './Selectable'; | ||||||
|  | 
 | ||||||
|  | export default function ProposalSelector({ games }) { | ||||||
|  | 
 | ||||||
|  |   const waitForYou = games | ||||||
|  |     .filter(game => game.status === Status.WaitForYou) | ||||||
|  |     .map(game => <Selectable game={game} />) | ||||||
|  | 
 | ||||||
|  |   const WaitForOpponent = games | ||||||
|  |     .filter(game => game.status === Status.WaitForOpponent) | ||||||
|  |     .map(game => <Selectable game={game} />) | ||||||
|  | 
 | ||||||
|  |   return <div className="Container"> | ||||||
|  |     <div className="Games"> | ||||||
|  |       {waitForYou} | ||||||
|  |       {WaitForOpponent.length > 0 && | ||||||
|  |         <div className="separator"> | ||||||
|  |           waiting for opponent ({WaitForOpponent.length}) | ||||||
|  |         </div> | ||||||
|  |       } | ||||||
|  |       {WaitForOpponent} | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const Status = { | ||||||
|  |   WaitForOpponent: "GAME_PROPOSAL_WAIT_FOR_OPPONENT", | ||||||
|  |   WaitForYou: "GAME_PROPOSAL_WAIT_FOR_YOU", | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								webapp/src/components/Game/GameSelector/GameArchive.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								webapp/src/components/Game/GameSelector/GameArchive.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | import './ProposalSelector.css' | ||||||
|  | import React from 'react'; | ||||||
|  | import Selectable from './Selectable'; | ||||||
|  | 
 | ||||||
|  | export default function ProposalSelector({ games }) { | ||||||
|  | 
 | ||||||
|  |   const waitForYou = games | ||||||
|  |     .filter(game => game.status === Status.WaitForYou) | ||||||
|  |     .map(game => <Selectable game={game} />) | ||||||
|  | 
 | ||||||
|  |   const WaitForOpponent = games | ||||||
|  |     .filter(game => game.status === Status.WaitForOpponent) | ||||||
|  |     .map(game => <Selectable game={game} />) | ||||||
|  | 
 | ||||||
|  |   return <div className="Container"> | ||||||
|  |     <div className="Games"> | ||||||
|  |       {waitForYou} | ||||||
|  |       {WaitForOpponent.length > 0 && | ||||||
|  |         <div className="separator"> | ||||||
|  |           waiting for opponent ({WaitForOpponent.length}) | ||||||
|  |         </div> | ||||||
|  |       } | ||||||
|  |       {WaitForOpponent} | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const Status = { | ||||||
|  |   WaitForOpponent: "GAME_PROPOSAL_WAIT_FOR_OPPONENT", | ||||||
|  |   WaitForYou: "GAME_PROPOSAL_WAIT_FOR_YOU", | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								webapp/src/components/Game/GameSelector/GameProposal.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								webapp/src/components/Game/GameSelector/GameProposal.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | import React from 'react'; | ||||||
|  | import Selectable from './Selectable'; | ||||||
|  | 
 | ||||||
|  | export default function ProposalSelector({ games }) { | ||||||
|  | 
 | ||||||
|  |   const waitForYou = games | ||||||
|  |     .filter(game => game.status === Status.WaitForYou) | ||||||
|  |     .map(game => <Selectable game={game} />) | ||||||
|  | 
 | ||||||
|  |   const WaitForOpponent = games | ||||||
|  |     .filter(game => game.status === Status.WaitForOpponent) | ||||||
|  |     .map(game => <Selectable game={game} />) | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="Games"> | ||||||
|  |       {waitForYou} | ||||||
|  |       {WaitForOpponent.length > 0 && | ||||||
|  |         <div className="separator"> | ||||||
|  |           waiting for opponent ({WaitForOpponent.length}) | ||||||
|  |         </div> | ||||||
|  |       } | ||||||
|  |       {WaitForOpponent} | ||||||
|  |     </div> | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const Status = { | ||||||
|  |   WaitForOpponent: "GAME_PROPOSAL_WAIT_FOR_OPPONENT", | ||||||
|  |   WaitForYou: "GAME_PROPOSAL_WAIT_FOR_YOU", | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								webapp/src/components/Game/GameSelector/Selectable.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								webapp/src/components/Game/GameSelector/Selectable.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | .selectable { | ||||||
|  |     border: 1px solid black; | ||||||
|  |     margin-bottom: 5px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .selectable q { | ||||||
|  |     color: gray; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .selectable i { | ||||||
|  |     font-size: 70%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* .Games .li button.action { | ||||||
|  |     display: none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .Games .li:hover button.action { | ||||||
|  |     display: initial; | ||||||
|  | } */ | ||||||
|  | 
 | ||||||
|  | .separator { | ||||||
|  |     /* width: 20%;  */ | ||||||
|  |     /* height: 20px;  */ | ||||||
|  |     border-bottom: 1px dotted black;  | ||||||
|  |     text-align: center; | ||||||
|  |     font-size: 50%; | ||||||
|  |     padding-left: 50%; | ||||||
|  |     margin-bottom: 7px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .stone { | ||||||
|  |     vertical-align: -3px;  | ||||||
|  |     margin: 3px 3px; | ||||||
|  | }  | ||||||
							
								
								
									
										19
									
								
								webapp/src/components/Game/GameSelector/Selectable.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								webapp/src/components/Game/GameSelector/Selectable.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | import './Selectable.css' | ||||||
|  | import React from 'react'; | ||||||
|  | import { Stone, oppositeColor } from '../Stone'; | ||||||
|  | 
 | ||||||
|  | export default function Selectable({game}) { | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className='selectable' key={game.uuid}> | ||||||
|  |       <div className='tiltle'> | ||||||
|  |         {Stone(game.myColor)} | ||||||
|  |         <i>vs</i> | ||||||
|  |         {Stone(oppositeColor(game.myColor))} | ||||||
|  |         {game.opponentName} | ||||||
|  |       </div> | ||||||
|  |       <q>{game.message}</q> | ||||||
|  |     </div> | ||||||
|  |   ) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| @ -1,22 +0,0 @@ | |||||||
| import './index.css'; |  | ||||||
| import React from 'react'; |  | ||||||
| // import { NavLink } from "react-router-dom"; |  | ||||||
| // import { AppData } from "../../../context/data" |  | ||||||
| import GameHeader from '../../GameHeader' |  | ||||||
| import GameSelector from '../../GameSelector' |  | ||||||
| import Board from '../../Board'  |  | ||||||
| 
 |  | ||||||
| export default function Proposal() { |  | ||||||
|   // const [data] = React.useContext(AppData) |  | ||||||
| 
 |  | ||||||
|   return <div className="split"> |  | ||||||
|     <div className='split left'> |  | ||||||
|       <GameHeader/> |  | ||||||
|       <button>+ Create</button> |  | ||||||
|       <GameSelector/> |  | ||||||
|     </div> |  | ||||||
| 
 |  | ||||||
|     <div className='split right'></div> |  | ||||||
|       <Board/> |  | ||||||
|     </div> |  | ||||||
| }; |  | ||||||
| @ -1,4 +1,4 @@ | |||||||
| import './index.css'; | import './Stone.css'; | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| export function Stone( color ) { | export function Stone( color ) { | ||||||
| @ -1,7 +1,7 @@ | |||||||
| import './index.css'; | import './index.css'; | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| import GameHeader from '../GameHeader' | import GameHeader from './GameHeader' | ||||||
| import GameSelector from '../GameSelector' | import GameSelector from './GameSelector' | ||||||
| import Board from '../Board' | import Board from '../Board' | ||||||
| 
 | 
 | ||||||
| // import { AppData } from "../../context/data" | // import { AppData } from "../../context/data" | ||||||
| @ -15,8 +15,9 @@ export default function Game() { | |||||||
|       <GameSelector /> |       <GameSelector /> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <div className='split right'></div> |     <div className='split right'> | ||||||
|     <Board /> |       <Board /> | ||||||
|  |     </div> | ||||||
|   </div> |   </div> | ||||||
| 
 | 
 | ||||||
| }; | } | ||||||
|  | |||||||
| @ -1,15 +0,0 @@ | |||||||
| import './index.css'; |  | ||||||
| import React from 'react'; |  | ||||||
| import { NavLink } from "react-router-dom"; |  | ||||||
| // import { AppData } from "../../context/data" |  | ||||||
| 
 |  | ||||||
| export default function GameHeader() { |  | ||||||
|   // const [data] = React.useContext(AppData) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   return <nav className="game-header"> |  | ||||||
|     <NavLink to="/game/proposal">Proposal</NavLink> |  | ||||||
|     <NavLink to="/game/active">Active</NavLink> |  | ||||||
|     <NavLink to="/game/archive">Archive</NavLink> |  | ||||||
|   </nav> |  | ||||||
| }; |  | ||||||
| @ -1,89 +0,0 @@ | |||||||
| import './index.css'; |  | ||||||
| import React from 'react'; |  | ||||||
| import { useLocation, matchPath } from "react-router"; |  | ||||||
| 
 |  | ||||||
| import { AppData } from "../../context/data" |  | ||||||
| 
 |  | ||||||
| export default function Game() { |  | ||||||
|   const [data] = React.useContext(AppData) |  | ||||||
| 
 |  | ||||||
| const { pathname } = useLocation(); |  | ||||||
| const isProposalPath = matchPath("/game/proposal/*", pathname); |  | ||||||
| const isActivelPath = matchPath("/game/active/*", pathname); |  | ||||||
| const isArchivePath = matchPath("/game/archive/*", pathname); |  | ||||||
| 
 |  | ||||||
| console.log("path: Proposal ", isProposalPath != null, "Active", isActivelPath != null, "Archive", isArchivePath != null ) |  | ||||||
| 
 |  | ||||||
|   if (!data?.games) |  | ||||||
|     return <div>Loading..</div> |  | ||||||
| 
 |  | ||||||
|   // for (const [key, value] of Object.entries(data.games)) |  | ||||||
|   //   console.log(key, value); |  | ||||||
|     |  | ||||||
|   const waitForYou = data.games |  | ||||||
|     .filter(game => game.status === Status.WaitForYou) |  | ||||||
|     .map(game => {  |  | ||||||
|       return <div className="li" key={game.uuid}> |  | ||||||
|         <p> |  | ||||||
|           You {Stone(game.myColor)} <i>vs</i> {game.opponentName} {Stone(oppositeColor(game.myColor))} |  | ||||||
|           <br/> |  | ||||||
|           <q>{game.message}</q> |  | ||||||
|           <br/> |  | ||||||
|           {/* <Accept uuid={game.uuid}/> |  | ||||||
|           <Reject uuid={game.uuid}/> */} |  | ||||||
|         </p> |  | ||||||
|         </div> |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|   const WaitForOpponent = data.games |  | ||||||
|     .filter(game => game.status === Status.WaitForOpponent) |  | ||||||
|     .map(game => {  |  | ||||||
|       return <div className="li" key={game.uuid}> |  | ||||||
|         <p>  |  | ||||||
|           You {Stone(game.myColor)} <i>vs</i> {game.opponentName} {Stone(oppositeColor(game.myColor))} |  | ||||||
|           <br/> |  | ||||||
|           <q>{game.message}</q> |  | ||||||
|           <br/> |  | ||||||
|           {/* <Cancel uuid={game.uuid}/> */} |  | ||||||
|         </p> |  | ||||||
|         </div> |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|   return <div className="Container"> |  | ||||||
|     <div className="Games"> |  | ||||||
|       {waitForYou} |  | ||||||
|       {WaitForOpponent.length > 0 &&  |  | ||||||
|         <div className="separator"> |  | ||||||
|           waiting for opponent ({WaitForOpponent.length}) |  | ||||||
|         </div> |  | ||||||
|       } |  | ||||||
|       {WaitForOpponent} |  | ||||||
|     </div> |  | ||||||
|     </div> |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const Status = { |  | ||||||
| 	WaitForOpponent: "GAME_PROPOSAL_WAIT_FOR_OPPONENT", |  | ||||||
| 	WaitForYou:      "GAME_PROPOSAL_WAIT_FOR_YOU", |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function Stone(color) { |  | ||||||
|   if (color === "WHITE") |  | ||||||
|     return <span className="stone">⛀</span> |  | ||||||
| 
 |  | ||||||
|   if (color === "BLACK") |  | ||||||
|     return <span className="stone">⛂</span> |  | ||||||
| 
 |  | ||||||
|   return <span className="stone">{color}</span> |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function oppositeColor(color) { |  | ||||||
|   if (color === "WHITE") |  | ||||||
|     return "BLACK" |  | ||||||
| 
 |  | ||||||
|   if (color === "BLACK") |  | ||||||
|     return "WHITE" |  | ||||||
| 
 |  | ||||||
|   return color |  | ||||||
| } |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user