From eb9712242ea79e17f8e092ed25ead6ab94e19814 Mon Sep 17 00:00:00 2001 From: Stanleyowskiki Date: Tue, 14 May 2024 07:42:31 +0200 Subject: [PATCH] User profile page --- package-lock.json | 26 ++- package.json | 1 + src/User/ProfileView/ProfileGameList.js | 57 +++++ src/User/ProfileView/ProfileGameList.scss | 40 ++++ src/User/ProfileView/ProfileInfoTable.js | 111 +++------- .../ProfileInfoTableAchievements.css | 80 +++++++ .../ProfileInfoTableAchievements.js | 64 +++++- .../ProfileView/ProfileInfoTableButtons.js | 9 +- src/User/ProfileView/ProfileView.css | 53 ++++- src/User/ProfileView/ProfileView.js | 155 ++++++++++---- src/User/ProfileView/ProfileView.scss | 156 ++++++++++++++ .../ProfileView/TournamentsPlayedTable.js | 56 +++++ .../ProfileView/TournamentsPlayedTable.scss | 56 +++++ src/User/Settings/SettingPopup.js | 2 +- src/forms/LoginForm.js | 15 +- src/index.js | 2 +- src/index.scss | 8 +- src/resources/ban.svg | 8 + src/resources/cross.svg | 7 + src/resources/icon1.svg | 2 + src/resources/icon2.svg | 18 ++ src/resources/icon3.svg | 2 + src/resources/skull.svg | 47 ++++ src/resources/tour1.svg | 200 +++++++++++++++++ src/resources/tour3.svg | 202 ++++++++++++++++++ src/resources/tour5.svg | 200 +++++++++++++++++ src/services/AchivmentService.js | 41 ++++ src/services/PointsService.js | 2 +- src/services/ServiceUtils.js | 26 +++ src/services/TournamentService.js | 9 +- src/services/UserService.js | 7 +- 31 files changed, 1487 insertions(+), 175 deletions(-) create mode 100644 src/User/ProfileView/ProfileGameList.js create mode 100644 src/User/ProfileView/ProfileGameList.scss create mode 100644 src/User/ProfileView/ProfileInfoTableAchievements.css create mode 100644 src/User/ProfileView/ProfileView.scss create mode 100644 src/User/ProfileView/TournamentsPlayedTable.js create mode 100644 src/User/ProfileView/TournamentsPlayedTable.scss create mode 100644 src/resources/ban.svg create mode 100644 src/resources/cross.svg create mode 100644 src/resources/icon1.svg create mode 100644 src/resources/icon2.svg create mode 100644 src/resources/icon3.svg create mode 100644 src/resources/skull.svg create mode 100644 src/resources/tour1.svg create mode 100644 src/resources/tour3.svg create mode 100644 src/resources/tour5.svg create mode 100644 src/services/AchivmentService.js create mode 100644 src/services/ServiceUtils.js diff --git a/package-lock.json b/package-lock.json index 2b943ee..f6087fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.6.5", + "buffer": "^6.0.3", "date-fns": "^3.6.0", "jwt-decode": "^4.0.0", "react": "^18.2.0", @@ -6445,7 +6446,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -6652,6 +6652,29 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -10993,7 +11016,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", diff --git a/package.json b/package.json index 224eea4..2153329 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@testing-library/user-event": "^13.5.0", "axios": "^1.6.5", "date-fns": "^3.6.0", + "buffer": "^6.0.3", "jwt-decode": "^4.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/User/ProfileView/ProfileGameList.js b/src/User/ProfileView/ProfileGameList.js new file mode 100644 index 0000000..7a544d6 --- /dev/null +++ b/src/User/ProfileView/ProfileGameList.js @@ -0,0 +1,57 @@ +import React, { useEffect, useState } from 'react'; +import {UserService } from '../../services/UserService'; +import {useNavigate} from 'react-router-dom'; + +import './ProfileGameList.scss'; + +import notAvailableIcon from '../../resources/cross.svg'; + +export default function ProfileGameList({ user }) { + const navigate = useNavigate(); + const [games, setGames] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + UserService.getGamesForPlayer(user.id).then((response) => { + console.log(response); + setGames(response.data.data); + console.log(games); + setLoading(false); + }).catch((error) => { + console.log(error); + }); + }, [user.id]); + + const handleGameElementClick = (gameId) => { + return () => navigate(`/games/details/${gameId}`); + }; + + return ( +
+
+ {loading ? ( +

Loading...

+ ) : ( + <> + {games.map((game, index) => ( +
+

+ {game.gameFileName} +

+

+ {game.lastModificatiosn} +

+
+ {game.isAvailableForPlay || ( + Not available + )} +
+
+ ))} + )} +
+
+ ); +} diff --git a/src/User/ProfileView/ProfileGameList.scss b/src/User/ProfileView/ProfileGameList.scss new file mode 100644 index 0000000..e71ade6 --- /dev/null +++ b/src/User/ProfileView/ProfileGameList.scss @@ -0,0 +1,40 @@ +.user-info-table { + height: 100%; + .user-info-table-content { + overflow-y: scroll; + .game-list-element-container { + display: grid; + grid-template-columns: max-content auto 15px; + padding: 2px 5px; + + .game-list-element-availability { + overflow: hidden; + display: flex; + .not-available-icon { + top: 0; + width: 100%; + aspect-ratio: 1; + } + } + + p { + font-size: 20px; + transition: all 0.3s ease; + } + + p:hover { + cursor: pointer; + text-shadow: #309e00 0px 0px 5px; + color: #79ec48; + } + } + + .light { + background-color: #222222; + } + + .dark { + background-color: #080808; + } + } +} \ No newline at end of file diff --git a/src/User/ProfileView/ProfileInfoTable.js b/src/User/ProfileView/ProfileInfoTable.js index a9cacb3..ea543ca 100644 --- a/src/User/ProfileView/ProfileInfoTable.js +++ b/src/User/ProfileView/ProfileInfoTable.js @@ -1,42 +1,34 @@ import { useEffect, useState } from "react"; import {PointsService} from "../../services/PointsService"; -import {XAxis, YAxis, CartesianGrid, Tooltip, LineChart, Line } from 'recharts'; +import {XAxis, YAxis, CartesianGrid, ResponsiveContainer, Tooltip, LineChart, Line } from 'recharts'; +import ProfileGameList from './ProfileGameList'; +import TournamentsPlayedTable from './TournamentsPlayedTable'; -function StatsTable(props) { - return ( - - - - - - - - - - - -
WinsLossesDraws
{props.wins}{props.losses}{props.draws}
- ); -} - -function RatingTable(props) { +function RatingTable({user}) { const [history, setHistory] = useState([{id: 0, logDate: "", points: 0, playerId: 0}]); useEffect(() => { - setHistory(PointsService.getPointsHistoryForPlayer(props.playerid)["data"]); - }, [props.playerid]); + console.log(user); + PointsService.getPointsHistoryForPlayer(user.id) + .then((data) => { + setHistory(data.data.data); + console.log(history); + }).catch((error) => { + console.log(error); + }); + }, [user.id]); + var ticksize = 20; const chart = - - - - - - - ; - - console.log(history); - + + + + + + + + + return ( <> {chart} @@ -44,68 +36,23 @@ function RatingTable(props) { ); } -function BotsTable(props) { - return ( - - - - - - - -
Bots
{props.bots}
- ); -} - -function GamesAddedTable(props) { - return ( - - - - - - - -
Games Added
{props.games}
- ); -} - -function TournamentsPlayedTable(props) { - return ( - - - - - - - -
Tournaments Played
{props.tournaments}
- ); -} - -function changeState(newState) { +function changeState(newState, user) { switch (newState) { - case "stats": - return ; case "rating": - return ; - case "bots": - return ; + return ; case "games": - return ; + return ; case "tournaments": - return ; + return ; default: return null; } } -function ProfileInfoTable(props) { - const { state } = props; +function ProfileInfoTable({ state, user }) { const [content, setContent] = useState(null); useEffect(() => { - const con = changeState(state); - setContent(con); + setContent(changeState(state, user)); }, [state]); return (<> diff --git a/src/User/ProfileView/ProfileInfoTableAchievements.css b/src/User/ProfileView/ProfileInfoTableAchievements.css new file mode 100644 index 0000000..028e35b --- /dev/null +++ b/src/User/ProfileView/ProfileInfoTableAchievements.css @@ -0,0 +1,80 @@ +.user-achivments-container { + position: relative; + margin-bottom: 10px; + vertical-align: middle; +} + +.user-achivments-container-content { + position: relative; + z-index: 100; + height: 100%; + padding: 10px; +} + +.user-achivments-background { + color:#222222; + background-color: #111111; + position: absolute; + z-index: 10; + width: 100%; + top: 0; + left: 0; + padding: 10px; +} + +.user-achivments-background-text { + text-shadow: 0px 0px 10px #000000; + float: right; + user-select: none; +} + +.user-achivments-scroll { + overflow-x: scroll; + overflow-y: hidden; + height: 100%; + user-select: none; + display: flex; + flex-wrap: nowrap; + justify-content: flex-start; + flex-shrink: 0; +} + + +.user-achivments-container-content > ::-webkit-scrollbar { + background: #222222; + height: 5px; +} + +.user-achivments-container-content > ::-webkit-scrollbar-track { + background: #090909; +} + +.user-achivments-container-content > ::-webkit-scrollbar-thumb { + background: #002200; + border-radius: 5px; +} + +.user-achivments-container-content > ::-webkit-scrollbar-thumb:hover { + background: #006000; +} + +.user-achivments-icon { + height: 30px; + width: auto; + + min-width: 30px; +} + +.user-achivments-icon-container { + margin: 5px; + padding: 0px 10px 0px 10px; + width: fit-content; + border-radius: 50%; + display: inline-block; + transition: all 0.3s ease; +} + +.user-achivments-icon-container:hover { + cursor: pointer; + background: rgb(170, 170, 170, 0.5); +} \ No newline at end of file diff --git a/src/User/ProfileView/ProfileInfoTableAchievements.js b/src/User/ProfileView/ProfileInfoTableAchievements.js index a57f5e9..69e507f 100644 --- a/src/User/ProfileView/ProfileInfoTableAchievements.js +++ b/src/User/ProfileView/ProfileInfoTableAchievements.js @@ -1,17 +1,63 @@ +import { useEffect, useState } from 'react'; +import { Tooltip } from '@mui/material'; +import {AchivmentService} from '../../services/AchivmentService'; + +import './ProfileInfoTableAchievements.css' function ProfileInfoTableAchievements(props) { - const {playerId} = props; + const {userId} = props; + const [achievements, setAchievements] = useState([]); + + useEffect(() => { + console.log(userId); + AchivmentService.getAchivmentsForPlayer(userId) + .then((data) => { + setAchievements(data.data.data); + }).catch((error) => { + console.log(error); + }); + }, [userId]); + let content = achievements.map((achiv) => { + let tooltipcontent = <> +

{achiv.achiv}

+

{achiv.description}

+

Current value: {achiv.value}

+ + return ( + +
+ +
+
+ ); + }); + return ( - - - - - - - -
achievements
{playerId}
+ <> +
+
+
+ {content} +
+
+
+

Achievements

+
+
+ ); } diff --git a/src/User/ProfileView/ProfileInfoTableButtons.js b/src/User/ProfileView/ProfileInfoTableButtons.js index a001db9..641e6f6 100644 --- a/src/User/ProfileView/ProfileInfoTableButtons.js +++ b/src/User/ProfileView/ProfileInfoTableButtons.js @@ -1,15 +1,14 @@ -import "./ProfileView.css"; +import "./ProfileView.scss"; + function ProfileInfoTableButtons(props) { const { setState } = props; return (
- - - - + +
); } diff --git a/src/User/ProfileView/ProfileView.css b/src/User/ProfileView/ProfileView.css index cda01b0..fbfec9d 100644 --- a/src/User/ProfileView/ProfileView.css +++ b/src/User/ProfileView/ProfileView.css @@ -6,7 +6,7 @@ justify-items: stretch; align-content: stretch; - height: 100%; + height: 100hw; } .user-photo { @@ -18,6 +18,11 @@ .profile-image { border: 3px solid black; border-radius: 1px; + + width: 100%; + aspect-ratio: 1/1; + + object-fit: cover; } .change-photo { @@ -27,12 +32,16 @@ } .user-info { - font-size: 20px; + font-size: 30%; border: 3px solid black; padding: 10px; height: 100%; } +.user-info .user-info-text { + color: aqua; +} + .user-info-table-container { border: 3px solid black; padding: 20px; @@ -52,10 +61,38 @@ } .user-info-table-buttons-container { - display: flex; + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; justify-content:space-evenly; } +@media (max-aspect-ratio: 1){ + .user-info-table-buttons-container { + grid-template-columns: 1fr 1fr; + } +} + +@media (max-aspect-ratio: 5/6) { + /*Handling collapse*/ + .main-container { + grid-template-columns: 0% 100%; + } + + .notcollapse { + background-color: red; + visibility: collapse; + width: 0; + } + + .collapse { + visibility: visible; + } +} + +.collapse { + visibility: collapse; +} + .user-overview { height: 100%; } @@ -73,8 +110,6 @@ .settings-button { width: 100%; align-self: flex-end; - - bottom: 0; } .cell { @@ -102,4 +137,10 @@ p { button { width: 100%; padding: 10px; -} \ No newline at end of file +} + +.user-ban-icon { + position: absolute; + width: 50px; + padding: 10px; +} diff --git a/src/User/ProfileView/ProfileView.js b/src/User/ProfileView/ProfileView.js index 049680d..4867e01 100644 --- a/src/User/ProfileView/ProfileView.js +++ b/src/User/ProfileView/ProfileView.js @@ -1,68 +1,133 @@ -import { useParams } from 'react-router-dom'; -import React, { useState, useEffect } from 'react'; +import {Link, useParams} from 'react-router-dom'; +import React, {useState, useEffect, useLayoutEffect} from 'react'; +import { Buffer } from 'buffer'; +import { Tooltip } from '@mui/material'; + import { UserService } from '../../services/UserService' +import PhotoPicker from '../../utils/photo-picker/PhotoPicker'; import ProfileInfoTable from './ProfileInfoTable'; import ProfileInfoTableAchievements from './ProfileInfoTableAchievements'; - -import './ProfileView.css'; import ProfileInfoTableButtons from './ProfileInfoTableButtons'; +import './ProfileView.scss'; + +import defIcon from "../../resources/user.svg"; +import banIcon from "../../resources/ban.svg"; +import deletedIcon from "../../resources/skull.svg"; +import store from "../store"; function ProfileView() { - const { id } = useParams(); + const { name } = useParams(); const [user, setUser] = useState({}); - const [state, setState] = useState("stats"); - const myID = 1; + const [state, setState] = useState("games"); + const [image, setImage] = useState(""); + const [userLoading, setUserLoading] = useState(true); + const myID = store.getState().user.id; + useLayoutEffect(() => { + UserService.getPlayerInfo(name).then((data) => { + setUser(data.data.data); + console.log(user) + setUserLoading(false) + }).catch((error) => { + console.log(error); + }); + }, [name]); useEffect(() => { - setUser(UserService.getPlayerInfo(id)); - }, [id]); + UserService.getImageForPlayer(user.id).then((data) => { + setImage(Buffer.from(data.data.data, "base64").toString()); + }).catch((error) => { + console.log(error); + }); + }, [user.id]); + const updateImage = () => { + UserService.changeMyImage(image) + .then((data) => { + console.log(data); + }).catch((error) => { + console.log(error); + });} return (<>
-
-
- user +
+
+
+ {image === "" ? + user + : + + } +
-
-
-
-
-

{user.login}

-

{user.rating}

+
+
+ {user.isBanned && <> +
+ + banned-account + +
} + {user.isDeleted && <> +
+ + deleted-account + +
} +
+

{user.login}

+

{user.point}

+
+
+
+
-
- +
+ {user.id === myID ? + Change photo} + onSelect={(p) => { + setImage(p); + updateImage(); + console.log(p)}}/> + : + <> + }
-
-
- {id === myID ? - Change photo - : - <> - } -
-
-
- -
-
-
-
-

Member since: {user.joined}

-

Last seen: {user.lastseen}

-

Bots added: #TODO#

-

Tournaments created: #TODO#

+
+
+ +
-
- +
+
+

Member since: {user.memberSince}

+

Last seen: {user.lastSeen}

+

Bots added: {user.botsNumber}

+

Tournaments created: {user.tournamentNumber}

+
+
+ + + +
-
-
-
- +
+
+ {userLoading ? <> : } +
diff --git a/src/User/ProfileView/ProfileView.scss b/src/User/ProfileView/ProfileView.scss new file mode 100644 index 0000000..fccdcfd --- /dev/null +++ b/src/User/ProfileView/ProfileView.scss @@ -0,0 +1,156 @@ +.main-container { + height: 95vh; + .main-container-grid { + height: auto; + display: grid; + grid-template-columns: 20% 80%; + grid-template-rows: min-content min-content 1fr; + align-items: start; + + justify-items: stretch; + align-content: stretch; + + + .profile-image { + border: 3px solid black; + border-radius: 1px; + + width: 100%; + aspect-ratio: 1/1; + + object-fit: cover; + background-color: #0b0b0b; + } + + .change-photo { + font-size: 15px; + margin-left: auto; + margin-right: auto; + } + + .user-info { + background-color: #1b1b1b; + font-size: 30%; + padding: 10px; + height: 100%; + } + + .user-info .user-info-text { + color: aqua; + } + + .user-info-table-container { + padding: 20px; + margin: 20px; + height: 100%; + + background-color: #1b1b1b; + } + + .user-info-table-button { + width: 100%; + display: inline; + } + + .user-info-table-buttons-container { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + justify-content:space-evenly; + } + + @media (max-aspect-ratio: 1){ + .user-info-table-buttons-container { + grid-template-columns: 1fr 1fr; + } + } + + @media (max-aspect-ratio: 5/6) { + /*Handling collapse*/ + .main-container { + grid-template-columns: 0% 100%; + } + + .notcollapse { + background-color: red; + visibility: collapse; + width: 0; + } + + .collapse { + visibility: visible; + } + } + + .collapse { + visibility: collapse; + } + + .user-overview { + height: 100%; + } + + .user-overview-container { + width: fit-content; + position: relative; + margin-left: auto; + } + + .widget { + margin: 10px; + } + + .settings-button { + width: 100%; + align-self: flex-end; + } + + .cell { + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + } + + .user-achievements { + bottom: 0; + padding: 10px; + border: 3px solid black; + } + + img { + max-width:100%; + bottom: 0; + } + + p { + margin: 0; + } + + button { + width: 100%; + padding: 10px; + border: 0; + } + + .user-ban-icon { + position: absolute; + width: 60px; + height: 60px; + padding: 10px; + + background-color: #686868; + border-radius: 5px; + } + + .user-deleted-icon{ + position: absolute; + width: 60px; + height: 60px; + padding: 10px; + top: 80px; + + background-color: #686868; + border-radius: 5px; + } + } +} \ No newline at end of file diff --git a/src/User/ProfileView/TournamentsPlayedTable.js b/src/User/ProfileView/TournamentsPlayedTable.js new file mode 100644 index 0000000..cd4ffaa --- /dev/null +++ b/src/User/ProfileView/TournamentsPlayedTable.js @@ -0,0 +1,56 @@ +import { useEffect, useState } from 'react'; +import {TournamentService} from '../../services/TournamentService'; +import './TournamentsPlayedTable.scss'; + +export default function TournamentsPlayedTable({username}){ + const [tournaments, setTournaments] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + TournamentService.getFilteredTournaments(1, 10,{userParticipation: username}) + .then((data) => { + setTournaments(data.data.data.page); + setLoading(false); + }).catch((error) => { + console.log(error); + }); + }, [username]); + + const getColor = function(status){ + switch(status){ + case "SCHEDULED": + return "dark-blue"; + case "CANCELLED": + return "red"; + case "PLAYED": + return "yellow"; + case "DONE": + return "green"; + default: + return "red"; + } + } + + return ( + <> +
+
+ {loading ? ( +

Loading...

+ ) : ( + <>{tournaments.map((tournament, index) => ( +
+

+ {tournament.tournamentTitle} +

+

+ {tournament.status} +

+
+ ))})} +
+
+ + ); +} \ No newline at end of file diff --git a/src/User/ProfileView/TournamentsPlayedTable.scss b/src/User/ProfileView/TournamentsPlayedTable.scss new file mode 100644 index 0000000..4da4f26 --- /dev/null +++ b/src/User/ProfileView/TournamentsPlayedTable.scss @@ -0,0 +1,56 @@ +.user-info-table { + height: 100%; + .user-info-table-content { + overflow-y: scroll; + .tournament-list-element-container { + display: grid; + grid-template-columns: 70% auto; + padding: 2px 5px; + + p { + font-size: 20px; + transition: all 0.3s ease; + } + + .tournament-list-element-status { + text-align: right; + } + + .tournament-list-element-title { + &:hover { + cursor: pointer; + text-shadow: #309e00 0px 0px 5px; + color: #79ec48; + } + } + + .yellow { + color: #fff826; + } + + .dark-blue { + color: #12287a; + } + + .orange { + color: #e89d26; + } + + .green { + color: #257802; + } + + .red { + color: #ff0000; + } + } + + .light { + background-color: #222222; + } + + .dark { + background-color: #080808; + } + } +} \ No newline at end of file diff --git a/src/User/Settings/SettingPopup.js b/src/User/Settings/SettingPopup.js index 3bc4e2f..624ef0d 100644 --- a/src/User/Settings/SettingPopup.js +++ b/src/User/Settings/SettingPopup.js @@ -36,7 +36,7 @@ export default function SettingPopup(props) { return null; } - var but = + const but = return (<> {close => diff --git a/src/forms/LoginForm.js b/src/forms/LoginForm.js index 8c8fe21..715153b 100644 --- a/src/forms/LoginForm.js +++ b/src/forms/LoginForm.js @@ -5,8 +5,7 @@ import {UserService} from "../services/UserService"; import { connect } from 'react-redux'; import { login, logout } from '../User/store'; -function LoginForm({isAuthenticated, user, login, logout}) { - +function RegisterForm() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [message, setMessage] = useState(true); @@ -18,7 +17,7 @@ function LoginForm({isAuthenticated, user, login, logout}) { await UserService.loginUser(email, password) setMessage('Login succesful.') } catch (e) { - setMessage('There was a problem with login.') + setMessage('There was a problem with the registration.') } }; @@ -65,12 +64,4 @@ function LoginForm({isAuthenticated, user, login, logout}) { ) } -const mapStateToProps = (state) => ({ - isAuthenticated: state.isAuthenticated, - user: state.user, - }); - -const mapDispatchToProps = {login,logout,}; - -export default connect(mapStateToProps, mapDispatchToProps)(LoginForm); - +export default RegisterForm diff --git a/src/index.js b/src/index.js index 16b9b21..c2be328 100644 --- a/src/index.js +++ b/src/index.js @@ -41,7 +41,7 @@ const router = createBrowserRouter([ element: , }, { - path: "/player/:id", + path: "/player/:name", element: , }, { diff --git a/src/index.scss b/src/index.scss index 63bd81a..436190f 100644 --- a/src/index.scss +++ b/src/index.scss @@ -64,10 +64,16 @@ button { display: inline-block; font-size: 20px; cursor: pointer; + + transition: all 0.5s ease-out; +} + +button:hover { + text-shadow: #079200 0 0 15px; } div { - text-shadow: 1px 1px 0.1cm #fff; + color: #6d6d6d; font-size: 45px; } diff --git a/src/resources/ban.svg b/src/resources/ban.svg new file mode 100644 index 0000000..023ae92 --- /dev/null +++ b/src/resources/ban.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/resources/cross.svg b/src/resources/cross.svg new file mode 100644 index 0000000..df57890 --- /dev/null +++ b/src/resources/cross.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/resources/icon1.svg b/src/resources/icon1.svg new file mode 100644 index 0000000..16971c5 --- /dev/null +++ b/src/resources/icon1.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/resources/icon2.svg b/src/resources/icon2.svg new file mode 100644 index 0000000..ea57344 --- /dev/null +++ b/src/resources/icon2.svg @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/resources/icon3.svg b/src/resources/icon3.svg new file mode 100644 index 0000000..8e86823 --- /dev/null +++ b/src/resources/icon3.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/resources/skull.svg b/src/resources/skull.svg new file mode 100644 index 0000000..649fe01 --- /dev/null +++ b/src/resources/skull.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/resources/tour1.svg b/src/resources/tour1.svg new file mode 100644 index 0000000..78dc738 --- /dev/null +++ b/src/resources/tour1.svg @@ -0,0 +1,200 @@ + + + +I diff --git a/src/resources/tour3.svg b/src/resources/tour3.svg new file mode 100644 index 0000000..4b3f3b6 --- /dev/null +++ b/src/resources/tour3.svg @@ -0,0 +1,202 @@ + + + +III diff --git a/src/resources/tour5.svg b/src/resources/tour5.svg new file mode 100644 index 0000000..919b651 --- /dev/null +++ b/src/resources/tour5.svg @@ -0,0 +1,200 @@ + + + +V diff --git a/src/services/AchivmentService.js b/src/services/AchivmentService.js new file mode 100644 index 0000000..b8bd090 --- /dev/null +++ b/src/services/AchivmentService.js @@ -0,0 +1,41 @@ +import {Api} from './Api' + +import icon1 from '../resources/icon1.svg'; +import icon2 from '../resources/icon2.svg'; +import icon3 from '../resources/icon3.svg'; +import icon4 from '../resources/icon1.svg'; +import icon5 from '../resources/icon2.svg'; +import icon6 from '../resources/icon3.svg'; +import icon7 from '../resources/skull.svg'; + +const getIcon = function (typeOfAchivment) { + switch (typeOfAchivment) { + case 1: + return icon1; + case 2: + return icon2; + case 3: + return icon3; + case 4: + return icon4; + case 5: + return icon5; + case 6: + return icon6; + case 7: + return icon7; + default: + return icon1; + } +} + +export const AchivmentService = { + getAchivmentsForPlayer: async function (id) { + return await Api.req(() => {return Api.get(`Achievement/getAchievementsForPlayer?playerId=${id}`)}); + }, + getAchivmentsTypes: async function () { + return await Api.req(() => {return Api.get(`Achievement/getAchievementTypes`)}); + }, + getIcon, + +} \ No newline at end of file diff --git a/src/services/PointsService.js b/src/services/PointsService.js index 415054d..1748adf 100644 --- a/src/services/PointsService.js +++ b/src/services/PointsService.js @@ -9,6 +9,6 @@ export const PointsService = { return await Api.req(() => {return Api.get(`Points/getPointsForPlayer?id=${id}`)}) }, getPointsHistoryForPlayer: async function (id) { - return await Api.req(() => {return Api.get(`Points/getPointsHistoryForPlayer?id=${id}`)}) + return await Api.req(() => {return Api.get(`Points/getPointsHistoryForPlayer?playerId=${id}`)}) }, } \ No newline at end of file diff --git a/src/services/ServiceUtils.js b/src/services/ServiceUtils.js new file mode 100644 index 0000000..28dca6b --- /dev/null +++ b/src/services/ServiceUtils.js @@ -0,0 +1,26 @@ + + +function dateToRequest(date){ + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + const milliseconds = String(date.getMilliseconds()).padStart(3, '0'); + return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}Z`; +} + +// 2024-04-26T11:13:01.8196733 +// YYYY-MM-DDTHH:MM:SS.MMMZ +function dateToResponse(date){ + const dateObj = new Date(Date.parse(date)); + return `${dateObj.getFullYear()}-${dateObj.getMonth()}-${dateObj.getDate()}`; +} + +function getCurrentTimeRequest(){ + const now = new Date(); + return dateToRequest(now); +} + +export { dateToRequest, dateToResponse, getCurrentTimeRequest } \ No newline at end of file diff --git a/src/services/TournamentService.js b/src/services/TournamentService.js index 6d1d999..65c5944 100644 --- a/src/services/TournamentService.js +++ b/src/services/TournamentService.js @@ -1,13 +1,8 @@ import {Api} from './Api' export const TournamentService = { - getFilteredTournaments: async function (page, pageSize, {tournamentTitle, minPlayOutDate, maxPlayOutDate, creator, userParticipation}) { - const body = {}; - if (tournamentTitle) body["tournamentTitle"] = tournamentTitle; - if (minPlayOutDate) body["minPlayOutDate"] = minPlayOutDate; - if (maxPlayOutDate) body.maxPlayOutDate = maxPlayOutDate; - if (creator) body.creator = creator; - if (userParticipation) body.userParticipation = userParticipation; + 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)}) }, getListOfTournaments: async function (page, pageSize) { diff --git a/src/services/UserService.js b/src/services/UserService.js index 157a3d0..7f96533 100644 --- a/src/services/UserService.js +++ b/src/services/UserService.js @@ -29,7 +29,8 @@ export const UserService = { store.dispatch(login({ email: email, token: token, - role: jwtData['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'] + role: jwtData['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'], + id: jwtData['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'] })) }, getPlayerInfo: async function (idOrName) { @@ -52,10 +53,10 @@ export const UserService = { })}) }, getGamesForPlayer: async function (id) { - return await Api.req(() => {return Api.get(`Player/getGamesForPlayer?id=${id}`)}) + return await Api.req(() => {return Api.get(`Player/getGamesForPlayer?playerId=${id}`)}) }, getImageForPlayer: async function (id) { - return await Api.req(() => {return Api.get(`Player/getImageForPlayer?id=${id}`)}) + return await Api.req(() => {return Api.get(`Player/getImageForPlayer?playerId=${id}`)}) }, changeMyImage: async function (image) { return await Api.req(() => {return Api.post('Player/changeMyImage', {