front: Game section sceleton

This commit is contained in:
djmil 2023-10-25 18:18:56 +02:00
parent 0c24d8c3ac
commit a2de2331cf
17 changed files with 196 additions and 133 deletions

View File

@ -1,7 +1,7 @@
import './index.css';
import React from 'react';
import { WhiteStone, BlackStone } from '../Stone'
import { WhiteStone, BlackStone } from '../Game/Stone'
export default function Board() {

View 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>
)
}

View 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>
)
}

View 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",
}

View 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",
}

View 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",
}

View 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;
}

View 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>
)
};

View File

@ -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>
};

View File

@ -1,4 +1,4 @@
import './index.css';
import './Stone.css';
import React from 'react';
export function Stone( color ) {

View File

@ -1,7 +1,7 @@
import './index.css';
import React from 'react';
import GameHeader from '../GameHeader'
import GameSelector from '../GameSelector'
import GameHeader from './GameHeader'
import GameSelector from './GameSelector'
import Board from '../Board'
// import { AppData } from "../../context/data"
@ -15,8 +15,9 @@ export default function Game() {
<GameSelector />
</div>
<div className='split right'></div>
<div className='split right'>
<Board />
</div>
</div>
};
}

View File

@ -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>
};

View File

@ -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
}