From 93fb07b9497a8ae3bdf8dc615e1e10af193c7f57 Mon Sep 17 00:00:00 2001 From: Stanleyowskiki Date: Fri, 10 May 2024 22:57:57 +0200 Subject: [PATCH] Added matches list view and match view --- src/Match/MatchView.js | 75 +++++++++++++++++++++++++++++++ src/Match/MovesTable.js | 56 +++++++++++++++++++++++ src/Match/MovesTable.scss | 73 ++++++++++++++++++++++++++++++ src/Matches/MatchesFilterPanel.js | 19 ++++++++ src/Matches/MatchesList.css | 39 ++++++++++++++++ src/Matches/MatchesList.js | 31 +++++++++++++ src/Matches/MatchesSearch.css | 4 ++ src/Matches/MatchesSearch.js | 38 ++++++++++++++++ src/index.js | 10 +++++ src/services/MatchesService.js | 73 ++++++++++++++++++++++++++++++ 10 files changed, 418 insertions(+) create mode 100644 src/Match/MatchView.js create mode 100644 src/Match/MovesTable.js create mode 100644 src/Match/MovesTable.scss create mode 100644 src/Matches/MatchesFilterPanel.js create mode 100644 src/Matches/MatchesList.css create mode 100644 src/Matches/MatchesList.js create mode 100644 src/Matches/MatchesSearch.css create mode 100644 src/Matches/MatchesSearch.js create mode 100644 src/services/MatchesService.js diff --git a/src/Match/MatchView.js b/src/Match/MatchView.js new file mode 100644 index 0000000..1e45a9e --- /dev/null +++ b/src/Match/MatchView.js @@ -0,0 +1,75 @@ +import React, { useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import UserButtons from '../User/UserButtons'; +import { MatchesService } from '../services/MatchesService'; +import MovesTable from './MovesTable'; + +function getLog(log) { + let table = log.split('\n').map((x) => x.trim()); + const result = table[table.length - 1]; + table = table.slice(0, -2) + const boardStates = []; + const playerMoves = []; + const playerHands = []; + let currentPlayer = 0; + let round, move; + const output = {"rounds": [], "result": result}; + for (let i = 0; i < table.length; i++) { + switch (i % 3) { + case 0: // player side + currentPlayer = parseInt(table[i]); + output.rounds.push({"player": currentPlayer}); + break; + case 1: // board state and player hand + round = table[i].split('; Table:').map((x) => x.split(';').map((y) => y.trim())); + boardStates.push(round[0]); + round[1] = round[1].slice(0, -1); + playerHands.push(round[1]); + output.rounds[output.rounds.length - 1]["boardState"] = round[1]; + output.rounds[output.rounds.length - 1]["playerHand"] = round[0]; + break; + case 2: // player move + move = table[i].trim(); + if (move === 'fold') { + move = ['fold']; + } else { + console.log(move); + move = move.split(' ').map((x) => parseInt(x)); + move = [playerHands[playerHands.length - 1][move[1]], boardStates[boardStates.length - 1][move[0]]]; + } + playerMoves.push(move); + output.rounds[output.rounds.length - 1]["playerMove"] = move; + break; + } + } + return output; +} + +export default function MatchView() { + const { id } = useParams(); + + const [match, setMatch] = useState({}); + const [log, setLog] = useState({"rounds": [], "result": ""}); + + useEffect(() => { + MatchesService.getMatch(id).then((data) => { + setMatch(data); + }).catch((e) => { + console.log(e); + }); + + MatchesService.getMatchLog(id).then((data) => { + setLog(getLog(data.log)); + console.log(log); + }).catch((e) => { + console.log(e); + }); + }, [id]); + + return ( +
+ + +
+ ); +} \ No newline at end of file diff --git a/src/Match/MovesTable.js b/src/Match/MovesTable.js new file mode 100644 index 0000000..2b0b533 --- /dev/null +++ b/src/Match/MovesTable.js @@ -0,0 +1,56 @@ +import "./MovesTable.scss"; + +function getColor(value) { + if (typeof value !== 'string') return 'def'; + if (value.toUpperCase().includes('RED')) { + return 'red'; + } else if (value.toUpperCase().includes('BLUE')) { + return 'blue'; + } else if (value.toUpperCase().includes('YELLOW')) { + return 'yellow'; + } else if (value.toUpperCase().includes('BROWN')) { + return 'brown'; + } else if (value.toUpperCase().includes('PINK')) { + return 'pink'; + } else if (value.toUpperCase().includes('WHITE')) { + return 'white'; + } else if (value.toUpperCase().includes('GREEN')) { + return 'green'; + } + return 'def'; +} + +export default function MovesTable({log}) { + let boardState, playerMove, playerHand; + return <> +
+
+ + + + + + + + + + + {log.rounds.map((round, index) => { + //console.log(round.boardState); + boardState = round.boardState.map((x) =>

{x}

) + playerMove = round.playerMove.map((x) =>

{x}

) + playerHand = round.playerHand.map((x) =>

{x}

) + return + + + + + + })} + +
RoundBoard StateMovePlayer hand
{index}.{boardState}{playerMove}{playerHand}
+
+
+ +} \ No newline at end of file diff --git a/src/Match/MovesTable.scss b/src/Match/MovesTable.scss new file mode 100644 index 0000000..bbbcb18 --- /dev/null +++ b/src/Match/MovesTable.scss @@ -0,0 +1,73 @@ + +.move-table { + height: 50vh; + width: fit-content; + overflow: hidden; + + .move-table-container { + display: grid; + align-items: center; + justify-content: center; + overflow-y: scroll; + table { + border: 1px solid #000; + + thead { + padding: 10px; + + tr { + th { + font-size: 20px; + } + } + } + tbody { + tr { + td { + font-size: 20px; + } + } + } + } + } +} + +p { + font-size: 16px; +} + +.red { + color: red; +} + +.green { + color: green; +} + +.blue { + color: blue; +} +.yellow { + color: yellow; +} +.brown { + color: brown; +} +.pink { + color: #ff31e0; +} +.white { + color: white; +} + +.move-element-row{ + +} + +.player-0 { + background-color: #313131; +} + +.player-1 { + background-color: #1b1b1b; +} \ No newline at end of file diff --git a/src/Matches/MatchesFilterPanel.js b/src/Matches/MatchesFilterPanel.js new file mode 100644 index 0000000..be8924a --- /dev/null +++ b/src/Matches/MatchesFilterPanel.js @@ -0,0 +1,19 @@ + + +export default function MatchesFilterPanel({setTournamentId, setPlayerName, setMaxDate, setMinDate, setGameType}) { + return ( +
+ + setTournamentId(e.target.value)} /> + + setPlayerName(e.target.value)} /> + + setMaxDate(e.target.value)} /> + + setMinDate(e.target.value)} /> + + setGameType(e.target.value)} /> +
+ ); + +} \ No newline at end of file diff --git a/src/Matches/MatchesList.css b/src/Matches/MatchesList.css new file mode 100644 index 0000000..7120b6b --- /dev/null +++ b/src/Matches/MatchesList.css @@ -0,0 +1,39 @@ +.match-list-element { + justify-content: space-between; + align-items: center; + padding: 10px; + border-bottom: 1px solid #ccc; + + border-radius: 5px; + + transition: all 0.5s ease-in; +} + +.match-list-element:hover { + background-color: #333; + cursor: pointer; +} + +.match-list-element-title { + font-size: 30px; +} + +.match-list-element-container { + display: flex; +} + +.match-list-element-container-info { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +} + +.match-list-element-info{ + font-size: medium; +} + +.match-list-container { + width: 60%; + margin: 0 auto; +} \ No newline at end of file diff --git a/src/Matches/MatchesList.js b/src/Matches/MatchesList.js new file mode 100644 index 0000000..c462842 --- /dev/null +++ b/src/Matches/MatchesList.js @@ -0,0 +1,31 @@ +import "./MatchesList.css"; +import {useNavigate} from 'react-router-dom'; + +export default function MatchesList({matchList}) { + const navigate = useNavigate(); + const handleTournamentClick = (matchId) => { + return () => navigate(`/match/${matchId}`); + }; + + const handleMatchChecked = (matchId) => { + return () => navigate(`/match/${matchId}`); + } + + return <> +
+ {matchList.map((match) => ( +
+
+ +
{match.tournamentName}
+
+
{match.players.join(', ')}
+
{match.gameType}
+
{match.date}
+
+
+
+ ))} +
+ +} \ No newline at end of file diff --git a/src/Matches/MatchesSearch.css b/src/Matches/MatchesSearch.css new file mode 100644 index 0000000..38ee97f --- /dev/null +++ b/src/Matches/MatchesSearch.css @@ -0,0 +1,4 @@ +.matches-list-container { + display: grid; + grid-template-columns: 25% 70%; +} \ No newline at end of file diff --git a/src/Matches/MatchesSearch.js b/src/Matches/MatchesSearch.js new file mode 100644 index 0000000..c66d3e0 --- /dev/null +++ b/src/Matches/MatchesSearch.js @@ -0,0 +1,38 @@ +import { useParams } from 'react-router-dom'; +import UserButtons from '../User/UserButtons'; +import { useEffect, useState } from 'react'; +import { MatchesService } from '../services/MatchesService'; +import MatchesList from './MatchesList'; +import MatchesFilterPanel from './MatchesFilterPanel'; +import './MatchesSearch.css'; + +export default function MatchesSearch() { + const { tournamentid, playername, maxdate, mindate, gametype } = useParams(); + + const [tournamentId, setTournamentId] = useState(parseInt(tournamentid) ? parseInt(tournamentid) : null); + const [playerName, setPlayerName] = useState(playername ? playername : null); + const [maxDate, setMaxDate] = useState(maxdate ? new Date(maxdate) : null); + const [minDate, setMinDate] = useState(mindate ? new Date(mindate) : null); + const [gameType, setGameType] = useState(gametype ? gametype : null); + + const [matches, setMatches] = useState([]); + + useEffect(() => { + MatchesService.getMatches(1, 10, tournamentId, maxDate, minDate, gameType).then((data) => { + setMatches(data); + }).catch((e) => { + console.log(e); + }); + }, [tournamentId, playerName, maxDate, minDate, gameType]); + + return ( +
+ +

Matches

+
+ + +
+
+ ); +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index c9e4144..0f9a8a0 100644 --- a/src/index.js +++ b/src/index.js @@ -28,6 +28,8 @@ import { Provider } from 'react-redux'; import store from './User/store'; import { getListOfTournaments } from './Tournaments/getListOfTournaments'; import UserSettings from './User/Settings/UserSettings'; +import MatchesSearch from './Matches/MatchesSearch'; +import MatchView from './Match/MatchView'; const games = [{name:'Szachy', id:1}, {name:'Warcaby', id:2}, {name:'Scrabble', id:3}, {name:'ChiƄczyk', id:4}, {name:'Go', id:5}] @@ -50,6 +52,14 @@ const router = createBrowserRouter([ path: "/games/add", element: , }, + { + path: "/matches/:tournamentId?/:playerName?/:maxDate?/:minDate?/:gameType?", + element: , + }, + { + path: "/match/:id", + element: , + }, { path: "/tournaments/add", element: , diff --git a/src/services/MatchesService.js b/src/services/MatchesService.js new file mode 100644 index 0000000..0344833 --- /dev/null +++ b/src/services/MatchesService.js @@ -0,0 +1,73 @@ +import { Api } from './Api' + +export const MatchesService = { + getMatches: async (page, pageSize, tournamentId, maxDate, minDate, gameType) => { + // Type Post + // Params: + //// page - integer - int32 + //// pageSize - integer - int32 + // Body: + //// tournamentId - integer - int64 + //// maxDate - string - date-time + //// minDate - string - date-time + //// gameType - string + + return [{"players": ["stanely", "jordan", "stachurski"], "gameType": "chess", "tournamentName": "chess tournament", "date": "2021-10-10", "id": 1}, + {"players": ["stanely", "jordan", "stachurski"], "gameType": "chess", "tournamentName": "chess tournament", "date": "2021-10-10", "id": 2}, + {"players": ["stanely", "jordan", "stachurski"], "gameType": "chess", "tournamentName": "chess tournament", "date": "2021-10-10", "id": 3}, + {"players": ["stanely", "jordan", "stachurski"], "gameType": "chess", "tournamentName": "chess tournament", "date": "2021-10-10", "id": 4}, + {"players": ["stanely", "jordan", "stachurski"], "gameType": "chess", "tournamentName": "chess tournament", "date": "2021-10-10", "id": 5}, + {"players": ["stanely", "jordan", "stachurski"], "gameType": "chess", "tournamentName": "chess tournament", "date": "2021-10-10", "id": 6}] + + const response = await Api.get(`Matches/getAll?page=${page}&pageSize=${pageSize}`, { + tournamentId: tournamentId, + maxDate: maxDate, + minDate: minDate, + gameType: gameType + }); + return response.data; + }, + getMatch: async (matchId) => { + // Type Get + // Params: + //// matchId - integer - int64 + return {"players": ["stanely", "jordan", "stachurski"], "gameType": "chess", "tournamentName": "chess tournament", "date": "2021-10-10", "id": 1} + const response = await Api.get('Matches/get', { + params: { + matchId: matchId + } + }); + return response.data; + }, + getMatchLog: async (matchId) => { + // Type Get + // Params: + //// matchId - integer - int64 + return {log: `0 + 7 of Yellow;6 of Brown;2 of Red;8 of Brown;3 of Pink;7 of Brown;8 of Red;8 of Green;4 of Yellow; Table: 2 of Brown;6 of Yellow;6 of White;7 of White;8 of White; + 1 4 + 1 + 7 of Red;1 of Yellow;7 of Pink;5 of Brown;1 of Blue;4 of Green;5 of Red;7 of Green;8 of Pink; Table: 2 of Brown;6 of Yellow;6 of White;7 of White;6 of Brown; + 8 3 + 0 + 7 of Yellow;8 of White;2 of Red;8 of Brown;3 of Pink;7 of Brown;8 of Red;8 of Green;4 of Yellow; Table: 2 of Brown;6 of Yellow;6 of White;8 of Pink;6 of Brown; + 8 3 + 1 + 7 of Red;1 of Yellow;7 of Pink;5 of Brown;1 of Blue;4 of Green;5 of Red;7 of Green;7 of White; Table: 2 of Brown;6 of Yellow;6 of White;4 of Yellow;6 of Brown; + 5 0 + 0 + 7 of Yellow;8 of White;2 of Red;8 of Brown;3 of Pink;7 of Brown;8 of Red;8 of Green;8 of Pink; Table: 4 of Green;6 of Yellow;6 of White;4 of Yellow;6 of Brown; + fold + 1 + 7 of Red;1 of Yellow;7 of Pink;5 of Brown;1 of Blue;2 of Brown;5 of Red;7 of Green;7 of White; Table: 4 of Green;6 of Yellow;6 of White;4 of Yellow;6 of Brown; + fold + -1 + 0`}; + const response = await Api.get('Matches/getLog', { + params: { + matchId: matchId + } + }); + return response.data; + }, +} \ No newline at end of file