diff --git a/.gitignore b/.gitignore index 1489c98..4e156f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ .idea/ .build/ +build/ diff --git a/src/App.js b/src/App.js index d138b12..e878576 100644 --- a/src/App.js +++ b/src/App.js @@ -4,17 +4,10 @@ import Home from './Home'; import { useState } from 'react'; function App() { - const [isAuthenticated, setIsAuthenticated] = useState(false); - const [isCollapsed, setIsCollapsed] = useState(false); - - - const toggleUserBar = () => { - setIsCollapsed(!isCollapsed); - }; + const [isAuthenticated] = useState(false); return (
- {/* tutaj przesyla uzytkownika */} diff --git a/src/Home.js b/src/Home.js index fe447c1..1f1201d 100644 --- a/src/Home.js +++ b/src/Home.js @@ -54,7 +54,7 @@ function Home({ isAuthenticated }) {
-

Language Bot support

+

Bot Language support

Python Logo diff --git a/src/Tournaments/TournamentNav.scss b/src/Tournaments/TournamentNav.scss index d1a9827..1d174d5 100644 --- a/src/Tournaments/TournamentNav.scss +++ b/src/Tournaments/TournamentNav.scss @@ -39,7 +39,7 @@ .tournament-nav { width: 100%; display: flex; - justify-content: left; + justify-content: center; margin: 10px 0.5em; padding: 10px; font-size: 1.5em; diff --git a/src/User/ProfileView/ProfileGameList.js b/src/User/ProfileView/ProfileGameList.js index 7a544d6..2688b59 100644 --- a/src/User/ProfileView/ProfileGameList.js +++ b/src/User/ProfileView/ProfileGameList.js @@ -20,7 +20,7 @@ export default function ProfileGameList({ user }) { }).catch((error) => { console.log(error); }); - }, [user.id]); + }, [user.id, games]); const handleGameElementClick = (gameId) => { return () => navigate(`/games/details/${gameId}`); diff --git a/src/User/ProfileView/ProfileInfoTable.js b/src/User/ProfileView/ProfileInfoTable.js index ea543ca..5c28061 100644 --- a/src/User/ProfileView/ProfileInfoTable.js +++ b/src/User/ProfileView/ProfileInfoTable.js @@ -16,7 +16,7 @@ function RatingTable({user}) { }).catch((error) => { console.log(error); }); - }, [user.id]); + }, [user, user.id, history]); var ticksize = 20; const chart = @@ -53,7 +53,7 @@ function ProfileInfoTable({ state, user }) { const [content, setContent] = useState(null); useEffect(() => { setContent(changeState(state, user)); - }, [state]); + }, [state, user]); return (<>
diff --git a/src/User/ProfileView/ProfileView.js b/src/User/ProfileView/ProfileView.js index 4867e01..df45d64 100644 --- a/src/User/ProfileView/ProfileView.js +++ b/src/User/ProfileView/ProfileView.js @@ -31,7 +31,7 @@ function ProfileView() { }).catch((error) => { console.log(error); }); - }, [name]); + }, [name, user]); useEffect(() => { UserService.getImageForPlayer(user.id).then((data) => { diff --git a/src/about.js b/src/about.js index 7d365d6..7f90ca5 100644 --- a/src/about.js +++ b/src/about.js @@ -128,8 +128,8 @@ function About() {
Scrum Master -

Scam Master

-

Stanisław Maliński, our Scam Master, facilitates our agile processes, ensures effective communication, and removes any obstacles that may hinder the team's progress.

+

Scum Master

+

Stanisław Maliński, our Scum Master, facilitates our agile processes, ensures effective communication, and removes any obstacles that may hinder the team's progress.

diff --git a/src/elements/Paginator/Paginator.js b/src/elements/Paginator/Paginator.js index 13c3de8..a951f0b 100644 --- a/src/elements/Paginator/Paginator.js +++ b/src/elements/Paginator/Paginator.js @@ -1,7 +1,7 @@ import ReactPaginate from 'react-paginate'; import "./Paginator.scss"; -export default function Paginator({ pageCount, handlePageClick }) { +export default function Paginator({ pageCount, currentPage, handlePageClick }) { return ( { + if (e) { + e.preventDefault() + } + const body = constructObject(); + TournamentService.getFilteredTournaments(currentPage, tournamentsPerPage, body) + .then((response) => { + setPageCount(response.data.data.amountOfPages); + setFilteredTournaments(response.data.data.page); + if (response.data.data.amountOfPages < currentPage) { + setCurrentPage(0); + } + }).catch((error) => { + setMessage('Error loading tournaments'); + }); + } + + useEffect(() => { + filterTournaments(); + }, [currentPage]); + + useImperativeHandle(ref, () => ({ + filterTournaments + })); + + const constructObject = () => { + const data = { + tournamentTitle, + minPlayOutDate, + maxPlayOutDate, + creator, + userParticipation + }; + + Object.keys(data).forEach(key => { + if (data[key] === undefined) { + data[key] = ''; + } + }); + + return data; + } + + const handleClearClick = (selectedObject) => { + setUserParticipation(''); + setCreator(''); + setMaxPlayOutDate(new Date(new Date(new Date().setFullYear(new Date().getFullYear() + 10)))); + setMinPlayOutDate(new Date(0)); + setTournamentTitle(''); + }; + + return ( +
+
+

Filter tournaments

+
+
+ + setTournamentTitle(e.target.value)} + placeholder="Enter tournament title" + maxLength="30" + /> +
+
+ + setMinPlayOutDate(e.target.value)} + placeholder="Enter from date" + maxLength="30" + /> +
+
+ + setMaxPlayOutDate(e.target.value)} + placeholder="Enter to date" + maxLength="30" + /> +
+
+ + setCreator(e.target.value)} + placeholder="Enter creator username" + maxLength="30" + /> +
+
+ + setUserParticipation(e.target.value)} + placeholder="Enter username of partcipating user" + maxLength="30" + /> +
+
+ + +
+
+
+
+ ) +}) + +export default TournamentFilterForm \ No newline at end of file diff --git a/src/forms/TournamentFilterForm.scss b/src/forms/TournamentFilterForm.scss new file mode 100644 index 0000000..5b60b80 --- /dev/null +++ b/src/forms/TournamentFilterForm.scss @@ -0,0 +1,38 @@ +.tournaments-form-container { + margin-top: 25px; + h2 { + margin: 20px 0; + text-align: center; + overflow-wrap: break-word; + } + .tournaments-form { + display: flex; + flex-wrap: wrap; + flex-direction: row; + .tournaments-form-wrapper { + max-width: 100%; + } + .tournaments-form-button-container { + display: flex; + flex-grow: 1; + margin-top: 10px; + justify-content: space-evenly; + } + div { + padding: 0 20px; + label { + margin-right: 20px; + overflow-wrap: break-word; + } + } + } + border: 2px solid #393a39; + margin-bottom: 20px; + padding: 10px; + font-family: Arial, Helvetica, sans-serif; + + @media (max-width: 768px) { + font-size: 0.8rem; + width: 100%; + } +} diff --git a/src/index.scss b/src/index.scss index 7030444..872bf52 100644 --- a/src/index.scss +++ b/src/index.scss @@ -62,6 +62,8 @@ button { display: inline-block; font-size: 20px; cursor: pointer; + padding: 5px; + width: 40%; transition: all 0.5s ease-out; } @@ -82,3 +84,12 @@ div { z-index: -1; } +.btn { + a { + color: rgb(57 185 31); + text-decoration: none; + text-align: center; + margin: 8px; + } +} + diff --git a/src/lists/DeleteTournamentButton.js b/src/lists/DeleteTournamentButton.js index f3d1fe8..7b9364e 100644 --- a/src/lists/DeleteTournamentButton.js +++ b/src/lists/DeleteTournamentButton.js @@ -2,21 +2,19 @@ import React from 'react'; import {TournamentService} from "../services/TournamentService"; -class DeleteTournamentButton extends React.Component { - handleClick = async (tournamentId) => { +function DeleteTournamentButton({tournamentId,onDeleteSuccess}) { + const handleClick = async (event, tournamentId) => { + event.stopPropagation(); try { - console.log('usuwamy gre o id: ' + tournamentId) - const response = await TournamentService.deleteTournament(tournamentId); - console.log(response) + await TournamentService.deleteTournament(tournamentId); + onDeleteSuccess(); } catch (e) { console.log(e); } }; + return ( +
handleClick(e, tournamentId)}>Delete
); - render() { - return ( -
this.handleClick(this.props.tournamentId)}>Delete
); - } } export default DeleteTournamentButton; \ No newline at end of file diff --git a/src/lists/TournamentList.scss b/src/lists/TournamentList.scss index 10cc43e..93ad0a5 100644 --- a/src/lists/TournamentList.scss +++ b/src/lists/TournamentList.scss @@ -26,7 +26,7 @@ background-color: #242424; h1 { - text-align: left; + text-align: center; margin: 0.5em 0.25em; padding-top: 0.7em; font-size: 0.8em; @@ -41,7 +41,6 @@ border-bottom: 2px solid #393a39; font-family: Arial, Helvetica, sans-serif; } - .header-detail { flex: 1; text-align: center; @@ -63,7 +62,6 @@ margin-right: 0px; } } - .tournaments-content { border: 2px solid #393a39; margin-bottom: 20px; @@ -116,5 +114,11 @@ @media (max-width: 768px) { font-size: 0.8rem; width: 100%; + .tournament-wrapper{ + overflow-x: scroll; + .tournaments-content{ + width:700px; + } + } } } \ No newline at end of file diff --git a/src/lists/TournamentsList.js b/src/lists/TournamentsList.js index b9f9873..4c7f6ef 100644 --- a/src/lists/TournamentsList.js +++ b/src/lists/TournamentsList.js @@ -2,94 +2,95 @@ import './TournamentList.scss'; import DeleteTournamentButton from './DeleteTournamentButton'; import TournamentNav from '../Tournaments/TournamentNav'; import {Link, useNavigate} from 'react-router-dom'; -import { connect } from 'react-redux'; -import { TournamentService } from "../services/TournamentService"; -import React, { useState, useEffect, useMemo } from "react"; +import {connect} from 'react-redux'; +import React, {useState} from "react"; +import Paginator from "../elements/Paginator/Paginator" +import TournamentFilterForm from '../forms/TournamentFilterForm'; -function TournamentsList({ tournaments, isAuthenticated }) { - const navigate = useNavigate(); - const currentDate = new Date(); - const [upcomingTournaments, setUpcomingTournaments] = useState([]); - const [pastTournaments, setPastTournaments] = useState([]); - const [message, setMessage] = useState(''); - - useEffect(() => { - TournamentService.getFilteredTournaments(0, 10, {minPlayOutDate: currentDate.toISOString()}) - .then((response) => { - setUpcomingTournaments(response.data.data.page); - }).catch((error) => { - setMessage('Error loading tournaments'); - }); - TournamentService.getFilteredTournaments(0, 10, {maxPlayOutDate: currentDate.toISOString()}) - .then((response) => { - setPastTournaments(response.data.data.page); - }).catch((error) => { - setMessage('Error loading tournaments'); - }); - }, [currentDate]); +function TournamentsList({tournaments, isAuthenticated, user}) { + const tournamentsPerPage = 8; + const navigate = useNavigate(); + const [filteredTournaments, setFilteredTournaments] = useState([]); + const [message, setMessage] = useState(''); + const [pageCount, setPageCount] = useState(''); + const [currentPage, setCurrentPage] = useState(0); + const tournamentFilterFormRef = React.useRef(); - const handleTournamentClick = (tournamentId) => { - navigate(`/tournaments/details/${tournamentId}`); - }; + const handleTournamentClick = (tournamentId) => { + navigate(`/tournaments/details/${tournamentId}`); + }; - const TournamentItem = ({ tournament }) => ( -
handleTournamentClick(tournament.id)}> -
{tournament.tournamentTitle}
-
{tournament.author}
-
{tournament.tournamentsDate}
-
{tournament.playersLimit}
-
- ); + const handlePageClick = (selectedObject) => { + setCurrentPage(selectedObject.selected); + }; - return ( -
- -
-

Upcoming Tournaments

- {isAuthenticated && ( - - - - )} -
- Name - Author - Date - Action -
-
- {isAuthenticated ? - upcomingTournaments.map(tournament => ( -
- - -
- )) - : - upcomingTournaments.map(tournament => ( - - ))} -
-

Past Tournaments

-
- Name - Author - Date - Action -
-
- {pastTournaments.map(tournament => ( - - ))} + const handleDeleteSuccess = () => { + tournamentFilterFormRef.current.filterTournaments(); + }; + + const TournamentItem = ({tournament}) => ( +
handleTournamentClick(tournament.id)}> +
{tournament.tournamentTitle}
+
{tournament.creatorName}
+
{tournament.tournamentsDate}
+
{tournament.status}
+ {isAuthenticated && user.role === "Admin" ? + + : <>} +
+ ); + + return ( +
+ + +
+ {isAuthenticated && ( + + )} + {filteredTournaments.length > 0 ? +
+

Tournaments

+
+ Name + Author + Date + Status + {isAuthenticated && user.role === "Admin" ? + Delete + : <>} +
+
+ {filteredTournaments.map(tournament => ( +
+
+ ))}
-

{message}

-
- ); +
+ : <>There are no tournaments for given filters} + +
+

{message}

+
+ ); } const mapStateToProps = (state) => ({ - isAuthenticated: state.isAuthenticated, + isAuthenticated: state.isAuthenticated, + user: state.user, }); -export default connect(mapStateToProps)(TournamentsList); +export default connect(mapStateToProps)(TournamentsList); \ No newline at end of file diff --git a/src/services/TournamentService.js b/src/services/TournamentService.js index 65c5944..c7970f5 100644 --- a/src/services/TournamentService.js +++ b/src/services/TournamentService.js @@ -3,10 +3,10 @@ import {Api} from './Api' export const TournamentService = { getFilteredTournaments: async function (page, pageSize, body) { const {tournamentTitle, minPlayOutDate, maxPlayOutDate, creator, userParticipation} = body; - return await Api.req(() => {return Api.post(`Tournament/getFiltered?page=${page}&pageSize=${pageSize}`, body)}) + return await Api.req(() => {return Api.post(`Tournament/getFiltered?PageNumber=${page}&PageSize=${pageSize}`, body)}) }, getListOfTournaments: async function (page, pageSize) { - return await Api.req(() => {return Api.post(`Tournament/getFiltered?page=${page}&pageSize=${pageSize}`, {})}) + return await Api.req(() => {return Api.post(`Tournament/getFiltered?PageNumber=${page}&PageSize=${pageSize}`, {})}) }, deleteTournament: async function (id) { return await Api.req(() => {return Api.delete(`Tournament/delete?id=${id}`)})