Merge branch 'Users'

pull/83/head
Baptiste MARCEL 1 year ago
commit b803c82dad

3
.gitignore vendored

@ -43,6 +43,9 @@ psd
thumb thumb
sketch sketch
### modules ###
yarn.lock
package-lock.json
# db # db

@ -10,6 +10,7 @@ import Home from './Pages/Home';
import Login from './Pages/LoginForm'; import Login from './Pages/LoginForm';
import SignUp from './Pages/SignUpForm'; import SignUp from './Pages/SignUpForm';
import Play from './Pages/Play'; import Play from './Pages/Play';
import Profile from './Pages/Profile';
import Lobby from './Pages/Lobby'; import Lobby from './Pages/Lobby';
import InGame from './Pages/InGame'; import InGame from './Pages/InGame';
@ -84,6 +85,7 @@ function App() {
<Route path="/endgame" element={<EndGame/>} /> <Route path="/endgame" element={<EndGame/>} />
<Route path="/game" element={<InGame locale={locale} changeLocale={changeLocale}/>}/> <Route path="/game" element={<InGame locale={locale} changeLocale={changeLocale}/>}/>
<Route path="/info" element={<InfoPage locale={locale} changeLocale={changeLocale}/>} /> <Route path="/info" element={<InfoPage locale={locale} changeLocale={changeLocale}/>} />
<Route path="/profile" element={<Profile/>} />
{/* <Route path="/solo" element={<SoloGame locale={locale} changeLocale={changeLocale} />}/> */} {/* <Route path="/solo" element={<SoloGame locale={locale} changeLocale={changeLocale} />}/> */}
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>

@ -13,7 +13,6 @@ import Bot from "../model/Bot";
import NodePerson from "../model/Graph/NodePerson"; import NodePerson from "../model/Graph/NodePerson";
import { useAuth } from "../Contexts/AuthContext"; import { useAuth } from "../Contexts/AuthContext";
interface MyGraphComponentProps { interface MyGraphComponentProps {
onNodeClick: (shouldShowChoiceBar: boolean) => void; onNodeClick: (shouldShowChoiceBar: boolean) => void;
handleShowTurnBar: (shouldShowTurnBar: boolean) => void handleShowTurnBar: (shouldShowTurnBar: boolean) => void
@ -40,6 +39,7 @@ let lastSocketId= ""
let firstLap = true let firstLap = true
let cptHistory = 0 let cptHistory = 0
let lastNodes: NodePerson[] = [] let lastNodes: NodePerson[] = []
let cptEndgame = 0
let firstEnigme = true let firstEnigme = true
let endgame= false let endgame= false
@ -50,7 +50,7 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
//* Gestion du temps : //* Gestion du temps :
let initMtn = 0 let initMtn = 0
const {user} = useAuth() const {isLoggedIn, user, manager} = useAuth();
const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setTurnPlayerIndexData, setWinnerData, dailyEnigme, setNbCoupData, settempsData} = useGame(); const { indices, indice, person, personNetwork, setNodeIdData, players, askedPersons, setActualPlayerIndexData, room, actualPlayerIndex, turnPlayerIndex, setTurnPlayerIndexData, setWinnerData, dailyEnigme, setNbCoupData, settempsData} = useGame();
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
@ -484,17 +484,49 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
}) })
socket.on("end game", (winnerIndex) =>{ socket.on("end game", (winnerIndex) =>{
if (cptEndgame % 2 == 0){
cptEndgame++;
const currentPlayer = players[actualPlayerIndex];
const winner = players[winnerIndex];
setNodeIdData(-1) setNodeIdData(-1)
setActualPlayerIndexData(-1) setActualPlayerIndexData(-1)
setLastIndex(-1) setLastIndex(-1)
setPlayerTouched(-1) setPlayerTouched(-1)
setWinnerData(players[winnerIndex]) setWinnerData(players[winnerIndex])
setElapsedTime(0) setElapsedTime(0)
first = true first = true
cptHistory = 0 cptHistory = 0
askedWrong=false askedWrong=false
askedWrongBot=false askedWrongBot=false
endgame = true endgame = true
try{
if(isLoggedIn){
if(!solo){
if(user && user.onlineStats){
// console.log("nbGames: " + user.onlineStats.nbGames + " nbWins: " + user.onlineStats.nbWins);
if(winner.id === currentPlayer.id){
// Ajouter une victoire
user.onlineStats.nbWins = null ? user.onlineStats.nbWins = 1 : user.onlineStats.nbWins += 1;
}
// Update les stats
user.onlineStats.nbGames = null ? user.onlineStats.nbGames = 1 : user.onlineStats.nbGames += 1;
user.onlineStats.ratio = user.onlineStats.nbWins / user.onlineStats.nbGames;
manager.userService.updateOnlineStats(user.pseudo, user.onlineStats.nbGames, user.onlineStats.nbWins, user.onlineStats.ratio);
}
else{
console.error("User not found");
}
}
}
}
catch(e){
console.log(e);
}
finally{
socket.off("end game") socket.off("end game")
socket.off("asked all") socket.off("asked all")
socket.off("opacity activated") socket.off("opacity activated")
@ -509,6 +541,8 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
socket.off("put imossible grey") socket.off("put imossible grey")
navigate("/endgame") navigate("/endgame")
}
}
}) })
@ -670,6 +704,22 @@ const MyGraphComponent: React.FC<MyGraphComponentProps> = ({onNodeClick, handleS
setNbCoupData(cptTour) setNbCoupData(cptTour)
setElapsedTime(0) setElapsedTime(0)
endgame = true endgame = true
try{
if(user && user.soloStats){
user.soloStats.nbGames = null ? user.soloStats.nbGames = 1 : user.soloStats.nbGames += 1;
if(cptTour < user.soloStats.bestScore || user.soloStats.bestScore == 0 || user.soloStats.bestScore == null){
user.soloStats.bestScore = cptTour;
}
user.soloStats.avgNbTry = (user.soloStats.avgNbTry * (user.soloStats.nbGames - 1) + cptTour) / user.soloStats.nbGames;
manager.userService.updateSoloStats(user.pseudo, user.soloStats.nbGames, user.soloStats.bestScore, user.soloStats.avgNbTry);
}
}
catch(error){
console.log(error);
}
navigate("/endgame?solo=true&daily=" + isDaily) navigate("/endgame?solo=true&daily=" + isDaily)
} }

@ -23,16 +23,31 @@ import './NavBar.css';
/* Style */ /* Style */
import { useTheme } from '../Style/ThemeContext'; import { useTheme } from '../Style/ThemeContext';
import { useAuth } from '../Contexts/AuthContext'; import { useAuth } from '../Contexts/AuthContext';
import { useNavigate } from 'react-router-dom';
// @ts-ignore // @ts-ignore
function AppNavbar({changeLocale}) { function AppNavbar({changeLocale}) {
const theme = useTheme(); const theme = useTheme();
const {isLoggedIn, logout} = useAuth(); const {user, isLoggedIn, logout} = useAuth();
const navigate = useNavigate();
useEffect(() => {
console.log(user)
}, [user])
function navigateToProfile(){
navigate("/profile")
}
function navigateToHome(){
navigate("/")
}
return ( return (
<Navbar expand="lg" className="custom-navbar" style={{ backgroundColor: theme.colors.primary }}> <Navbar expand="lg" className="custom-navbar" style={{ backgroundColor: theme.colors.primary }}>
<Container> <Container>
<Navbar.Brand href="/"> <Navbar.Brand onClick={navigateToHome}>
<img src={logo} alt="logo" className="logo" /> <img src={logo} alt="logo" className="logo" />
</Navbar.Brand> </Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" /> <Navbar.Toggle aria-controls="basic-navbar-nav" />
@ -54,7 +69,7 @@ function AppNavbar({changeLocale}) {
align="end" align="end"
drop='down-centered' drop='down-centered'
> >
<NavDropdown.Item href="/profile">Profil</NavDropdown.Item> <NavDropdown.Item onClick={navigateToProfile}>Profil</NavDropdown.Item>
<LanguageNavItem <LanguageNavItem
countryCode="FR" countryCode="FR"
languageKey="languageSelector.french" languageKey="languageSelector.french"

@ -31,7 +31,7 @@ const PlayerItemList:React.FC<MyPlayerItemListProps> =({ player, room }) => {
// const isBot = pdp === Bot; // const isBot = pdp === Bot;
let pdp; let pdp;
const isBot = player instanceof Bot; const isBot = player instanceof Bot;
isBot ? pdp = BotPDP : pdp = PersonPDP; isBot ? pdp = BotPDP : pdp = player.profilePicture;
const delBot = () => { const delBot = () => {

@ -0,0 +1,52 @@
import React, { useState } from 'react';
import '../Pages/Profile.css'
import dl from '../res/icon/download.png'
import defaultImg from '../res/img/Person.png'
import { useAuth } from '../Contexts/AuthContext';
//@ts-ignore
const ProfilePDP = () => {
const [selectedFile, setSelectedFile] = useState(null);
const {user} = useAuth()
// @ts-ignores
const handleFileChange = (event) => {
let file = event.target.files[0];
setSelectedFile(file);
if (file) {
const pdpUrl = URL.createObjectURL(file);
if (user!=null){
user.profilePicture = pdpUrl
}
}
};
return (
<div className='mainPDPContainer'>
{selectedFile ? (
<div >
{/* @ts-ignore */}
{/* <p>Selected File: {selectedFile.name}</p> */}
<img src={URL.createObjectURL(selectedFile)} alt="Preview" className='imgContainer' width='100px' height='100px' />
</div>
) : (
<div >
<img src={user?.profilePicture} alt="Preview" className='imgContainer' width='100px' height='100px' />
</div>
)}
<div className="parent">
<div className="file-upload">
<img src={dl} alt="upload" width='25px' height='25px'/>
{/* <h6>Cliquer ici pour ajouter une image</h6> */}
<p>Taille recommandée : 100px</p>
<input type="file" accept="image/*" onChange={handleFileChange}/>
</div>
</div>
{/* <input type="file" accept="image/*" onChange={handleFileChange} /> */}
</div>
);
};
export default ProfilePDP;

@ -1,5 +1,7 @@
// AuthContext.js // AuthContext.js
import React, { createContext, useContext, useState, ReactNode } from 'react'; import React, { createContext, useContext, useState, ReactNode } from 'react';
import DbUserService from '../model/DataManagers/DbUserService';
import Manager from '../model/DataManagers/Manager';
import Player from '../model/Player'; import Player from '../model/Player';
import User from '../model/User'; import User from '../model/User';
import AuthService from '../services/AuthService'; import AuthService from '../services/AuthService';
@ -10,6 +12,7 @@ interface AuthContextProps {
logout: () => void; logout: () => void;
user: User | null user: User | null
setUserData: (newPlayer: User) => void setUserData: (newPlayer: User) => void
manager: Manager
} }
const AuthContext = createContext<AuthContextProps | undefined>(undefined); const AuthContext = createContext<AuthContextProps | undefined>(undefined);
@ -17,19 +20,24 @@ const AuthContext = createContext<AuthContextProps | undefined>(undefined);
const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => { const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false); const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
const [user, setUser] = useState<User| null>(null) const [user, setUser] = useState<User| null>(null)
const [manager] = useState<Manager>(new Manager(new DbUserService()))
const login = () => { const login = async () => {
setIsLoggedIn(true); setIsLoggedIn(true);
const [u, bool] = await manager.userService.fetchUserInformation()
setUser(u)
}; };
const setUserData = (player: User | null) => { const setUserData = (newPlayer: User) => {
setUser(player) setUser(newPlayer)
} }
const logout = async() => { const logout = async() => {
try { try {
await AuthService.logout(); await AuthService.logout();
setIsLoggedIn(false); setIsLoggedIn(false);
const [u, bool] = await manager.userService.fetchUserInformation()
setUser(u)
} }
catch (error) { catch (error) {
console.log(error); console.log(error);
@ -37,7 +45,7 @@ const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
}; };
return ( return (
<AuthContext.Provider value={{ isLoggedIn, login, logout, user, setUserData }}> <AuthContext.Provider value={{ isLoggedIn, login, logout, user, setUserData, manager }}>
{children} {children}
</AuthContext.Provider> </AuthContext.Provider>
); );

@ -11,24 +11,22 @@ import ButtonImgNav from '../Components/ButtonImgNav';
// @ts-ignore // @ts-ignore
function Home() { function Home() {
const theme=useTheme(); const theme=useTheme();
const {isLoggedIn, login} = useAuth(); const {isLoggedIn, login, user, setUserData, manager } = useAuth();
useEffect(() => { useEffect(() => {
// Verifie la connexion
const verifSession = async () => { if (user == null){
try { manager.userService.fetchUserInformation().then(([user, loggedIn]) =>{
const sessionData = await SessionService.getSession(); if (user!=null){
if (sessionData.user) { setUserData(user)
login(); if (loggedIn){
login()
} }
console.log('isLoggedIn : ', isLoggedIn);
} }
catch (error) { })
console.log(error);
};
} }
}, [isLoggedIn]);
verifSession();
}, []);
return ( return (

@ -38,7 +38,7 @@ function Lobby() {
const { indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, setActualPlayerIndexData, setTurnPlayerIndexData, setRoomData } = useGame(); const { indices, setIndicesData, indice, setIndiceData, person, setPersonData, personNetwork, setPersonNetworkData, players, setPlayersData, setActualPlayerIndexData, setTurnPlayerIndexData, setRoomData } = useGame();
const {user, setUserData} = useAuth() const {user, setUserData, manager, login} = useAuth()
let first = true let first = true
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
@ -53,45 +53,15 @@ function Lobby() {
first=false first=false
if (user == null){ if (user == null){
try { manager.userService.fetchUserInformation().then(([u, loggedIn]) => {
const sessionData = SessionService.getSession(); if (u!=null){
sessionData.then((s) => { setUserData(u)
if (s.user) { if (loggedIn){
// Il y a une session on récupère les infos du joueur login()
const updatedPlayer: User = new User(socket.id, s.user.pseudo, s.user.profilePicture, {
nbGames: s.user.soloStats.nbGames,
bestScore: s.user.soloStats.bestScore,
avgNbTry: s.user.soloStats.avgNbTry,
},
{
nbGames: s.user.onlineStats.nbGames,
nbWins: s.user.onlineStats.nbWins,
ratio: s.user.onlineStats.ratio,
})
setUserData(updatedPlayer);
socket.emit("lobby joined", room, updatedPlayer.toJson())
} else {
// Pas de session on génère un guest random
const guestPlayer: User = new User(socket.id, 'Guest_' + Math.floor(Math.random() * 1000000), '',
{
nbGames: 0,
bestScore: 0,
avgNbTry: 0,
},
{
nbGames: 0,
nbWins: 0,
ratio: 0,
})
setUserData(guestPlayer);
socket.emit("lobby joined", room, guestPlayer.toJson())
}
})
} }
catch (error) { socket.emit("lobby joined", room, u.toJson())
console.error(error);
} }
})
} }
else{ else{
socket.emit("lobby joined", room, user.toJson()) socket.emit("lobby joined", room, user.toJson())

@ -30,11 +30,12 @@ const SignIn = () => {
setError(null); setError(null);
const result = await AuthService.signIn(data); const result = await AuthService.signIn(data);
// console.log(result); // console.log(result);
setShowConfirmation(true); setShowConfirmation(true);
setTimeout(() => { setTimeout(async () => {
login(); await login();
navigate('/play'); // 3 secondes avant de rediriger vers la page de connexion navigate('/play'); // 3 secondes avant de rediriger vers la page de connexion
}, 3000); }, 3000);
} }

@ -8,8 +8,7 @@ import './Play.css';
import { useTheme } from '../Style/ThemeContext'; import { useTheme } from '../Style/ThemeContext';
/* Component */ /* Component */
import ButtonImgNav from "../Components/ButtonImgNav" import ButtonImgNav from "../Components/ButtonImgNav";
import SessionService from "../services/SessionService";
/* Img */ /* Img */
import Person from '../res/img/Person.png'; import Person from '../res/img/Person.png';
@ -22,16 +21,15 @@ import { useGame } from '../Contexts/GameContext';
import ScoreBoard from '../Components/ScoreBoard'; import ScoreBoard from '../Components/ScoreBoard';
/* Types */ /* Types */
import { PlayerProps } from '../types/Player';
import Player from '../model/Player';
import Human from '../model/User';
import User from '../model/User'; import User from '../model/User';
import EnigmeDuJourCreator from '../model/EnigmeDuJourCreator'; import EnigmeDuJourCreator from '../model/EnigmeDuJourCreator';
import Stub from '../model/Stub'; import Stub from '../model/Stub';
let first = true import SessionService from '../services/SessionService';
function Play() { function Play() {
let first = true
const theme=useTheme() const theme=useTheme()
const {isLoggedIn, login, user, setUserData } = useAuth(); const {isLoggedIn, login, user, setUserData } = useAuth();
const {setDailyEnigmeData} = useGame() const {setDailyEnigmeData} = useGame()
@ -90,6 +88,10 @@ function Play() {
socket.emit("lobby created") socket.emit("lobby created")
} }
useEffect(() => {
console.log(user)
}, [user])
function launchMastermind(){ function launchMastermind(){
const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(3, 30) const [networkPerson, choosenPerson, choosenIndices] = GameCreator.CreateGame(3, 30)
setPersonData(choosenPerson) setPersonData(choosenPerson)
@ -151,7 +153,7 @@ function Play() {
<h2> <h2>
{user && user.pseudo} {user && user.pseudo}
</h2> </h2>
<img src={Person} <img src={user?.profilePicture}
height='300' height='300'
width='300' width='300'
alt="Person" alt="Person"

@ -0,0 +1,65 @@
.mainContainer{
display: flex;
justify-content: center;
align-items: center;
margin: 50px;
}
.mainPDPContainer{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 2px solid whitesmoke;
border-radius: 15px;
background-color: white;
margin: 10px;
min-height: 250px;
}
.imgContainer{
border: 5px solid black;
border-radius: 50px;
margin: 15px;
}
/*File upload*/
.parent {
/* width: 250px; */
/* margin: auto; */
margin: 2rem;
background: #ffffff;
border-radius: 25px;
/* box-shadow: 7px 20px 20px rgb(210, 227, 244); */
}
.file-upload {
text-align: center;
border: 3px dashed rgb(210, 227, 244);
/* padding: 1.5rem; */
position: relative;
cursor: pointer;
max-width: 100px;
max-height: 50px;
}
.file-upload p {
font-size: 0.5rem;
/* margin-top: 10px; */
color: #bbcada;
}
.file-upload input {
display: block;
height: 100%;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
opacity: 0;
cursor: pointer;
}

@ -0,0 +1,31 @@
import React, { useEffect, useState } from 'react';
import ProfilePDP from '../Components/ProfilePDP';
import './Profile.css'
import SessionService from '../services/SessionService';
import { PlayerProps } from '../types/Player';
import { update } from 'lodash';
import User from '../model/User';
import { socket } from '../SocketConfig';
import { useAuth } from '../Contexts/AuthContext';
//@ts-ignore
const Profile = () => {
//let player;
const {user} = useAuth()
//! useeffect pour l'instant, il faudra voir pour changer la facons de prendre une session
return (
<div className='mainContainer'>
<ProfilePDP/>
<h1> {user?.pseudo} </h1>
</div>
);
};
export default Profile;

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 254 KiB

After

Width:  |  Height:  |  Size: 254 KiB

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

@ -1,7 +1,6 @@
import { io } from "socket.io-client"; import { io } from "socket.io-client";
import { ADRESSE_WEBSERVER } from "./adressConfig"; import { ADRESSE_WEBSERVER } from "./adressConfig";
const socket = io(ADRESSE_WEBSERVER); const socket = io(ADRESSE_WEBSERVER);
export {socket} export {socket}

@ -0,0 +1,74 @@
import SessionService from "../../services/SessionService";
import { socket } from "../../SocketConfig";
import User from "../User";
import IUserService from "./IUserService";
class DbUserService implements IUserService{
async fetchUserInformation(): Promise<[User | null, boolean]> {
try {
const sessionData = await SessionService.getSession();
// Vérifie si il y a une session
if (sessionData.user) {
// Il y a une session on récupère les infos du joueur
const updatedPlayer: User = new User(socket.id, sessionData.user.pseudo, sessionData.user.profilePicture, {
nbGames: sessionData.user.soloStats.nbGames,
bestScore: sessionData.user.soloStats.bestScore,
avgNbTry: sessionData.user.soloStats.avgNbTry,
},
{
nbGames: sessionData.user.onlineStats.nbGames,
nbWins: sessionData.user.onlineStats.nbWins,
ratio: sessionData.user.onlineStats.ratio,
})
return [updatedPlayer, true]
} else {
// Pas de session on génère un guest random
const guestPlayer: User = new User(socket.id, 'Guest_' + Math.floor(Math.random() * 1000000), '',
{
nbGames: 0,
bestScore: 0,
avgNbTry: 0,
},
{
nbGames: 0,
nbWins: 0,
ratio: 0,
})
return [guestPlayer, false]
}
} catch (error) {
console.error(error);
return [null, false]
}
}
async updateSoloStats(pseudo: string, nbGames: number, bestScore: number, avgNbTry: number): Promise<void> {
try {
const result = await SessionService.updateSoloStats(pseudo, nbGames, bestScore, avgNbTry);
if (result) {
console.log("Stats solo updated");
} else {
console.log("Stats solo not updated");
}
} catch (error) {
console.error(error);
}
}
async updateOnlineStats(pseudo: string, nbGames: number, bestScore: number, ratio: number): Promise<void> {
try {
const result = await SessionService.updateOnlineStats(pseudo, nbGames, bestScore, ratio);
if (result) {
console.log("Stats online updated");
} else {
console.log("Stats online not updated");
}
} catch (error) {
console.error(error);
}
}
}
export default DbUserService

@ -0,0 +1,10 @@
import User from "../User";
interface IUserService{
fetchUserInformation(): Promise<[User | null, boolean]>
updateSoloStats(pseudo: string, nbGames: number, bestScore: number, avgNbTry: number): Promise<void>
updateOnlineStats(pseudo: string, nbGames: number, bestScore: number, ratio: number): Promise<void>
}
export default IUserService

@ -0,0 +1,12 @@
import IUserService from "./IUserService";
class Manager{
public userService: IUserService
constructor(userService: IUserService){
this.userService = userService
}
}
export default Manager

@ -1,3 +1,4 @@
abstract class Player{ abstract class Player{
public id: string public id: string
public pseudo: string; public pseudo: string;

@ -1,16 +1,21 @@
import Player from "./Player"; import Player from "./Player";
import defaultpdp from "../res/img/Person.png"
class User extends Player{ class User extends Player{
public soloStats: any public soloStats: any
public onlineStats: any public onlineStats: any
constructor(id: string, name: string, profilePicture: string, soloStats: any, onlineStats: any){ constructor(id: string, pseudo: string, profilePicture: string, soloStats: any, onlineStats: any){
super(id, name, profilePicture) if (profilePicture == ""){
profilePicture = defaultpdp
}
super(id, pseudo, profilePicture)
this.soloStats=soloStats this.soloStats=soloStats
this.onlineStats=onlineStats this.onlineStats=onlineStats
} }
toJson() { toJson() {
return { return {
type: "User", type: "User",

@ -8,6 +8,10 @@ class AuthController {
static async signUp(req, res) { static async signUp(req, res) {
const databaseService = new DatabaseService(); const databaseService = new DatabaseService();
const pseudo = req.body.pseudo; const pseudo = req.body.pseudo;
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try { try {
await databaseService.connect(); await databaseService.connect();
@ -31,11 +35,9 @@ class AuthController {
const soloStats = await databaseService.getSoloStatsByUserId(user.idUser); const soloStats = await databaseService.getSoloStatsByUserId(user.idUser);
const onlineStats = await databaseService.getOnlineStatsByUserId(user.idUser); const onlineStats = await databaseService.getOnlineStatsByUserId(user.idUser);
console.log(soloStats);
console.log(onlineStats);
await databaseService.updateUserIDStats(user.idUser, soloStats.idSoloStats, onlineStats.idOnlineStats); await databaseService.updateUserIDStats(user.idUser, soloStats.idSoloStats, onlineStats.idOnlineStats);
// Envoyer une réponse réussie
console.log("[" + hour + ":" + minutes + "] " + user.pseudo + " have been registered.");
res.status(201).json({ message: 'Inscription réussie', user: insertedUser}); res.status(201).json({ message: 'Inscription réussie', user: insertedUser});
} }
catch (error) { catch (error) {
@ -50,6 +52,9 @@ class AuthController {
static async signIn(req, res) { static async signIn(req, res) {
const databaseService = new DatabaseService(); const databaseService = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{ try{
await databaseService.connect(); await databaseService.connect();
@ -70,12 +75,11 @@ class AuthController {
return; return;
} }
// Stocker l'utilisateur dans la session){ // Stocker l'utilisateur dans la session)
console.log("SESSION")
console.log(req.session);
req.session.user = user; req.session.user = user;
// Envoyer une réponse réussie // Envoyer une réponse réussie
console.log("[" + hour + ":" + minutes + "] " + user.pseudo + " have been connected.");
res.status(200).json({ message: 'Connexion réussie', user: user }); res.status(200).json({ message: 'Connexion réussie', user: user });
} }
catch(error){ catch(error){
@ -89,12 +93,17 @@ class AuthController {
} }
static async logout(req, res) { static async logout(req, res) {
const pseudo = req.session.user.pseudo;
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
// Détruire la session pour déconnecter l'utilisateur // Détruire la session pour déconnecter l'utilisateur
req.session.destroy((err) => { req.session.destroy((err) => {
if (err) { if (err) {
console.error(err); console.error(err);
res.status(500).json({ error: 'Erreur lors de la déconnexion.' }); res.status(500).json({ error: 'Erreur lors de la déconnexion.' });
} else { } else {
console.log("[" + hour + ":" + minutes + "] " + pseudo + " have been disconnected.");
res.status(200).json({ message: 'Déconnexion réussie' }); res.status(200).json({ message: 'Déconnexion réussie' });
} }
}); });

@ -3,6 +3,9 @@ const DatabaseService = require('../services/DatabaseService');
class SessionController { class SessionController {
static async getUserInformation(req, res) { static async getUserInformation(req, res) {
const db = new DatabaseService(); const db = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{ try{
await db.connect(); await db.connect();
@ -15,8 +18,7 @@ class SessionController {
req.session.user.soloStats = await db.getSoloStatsByUserId(req.session.user.idUser); req.session.user.soloStats = await db.getSoloStatsByUserId(req.session.user.idUser);
req.session.user.onlineStats = await db.getOnlineStatsByUserId(req.session.user.idUser); req.session.user.onlineStats = await db.getOnlineStatsByUserId(req.session.user.idUser);
console.log(req.session.user); console.log("[" + hour + ":" + minutes + "] " + req.session.user.pseudo + " have a session.");
res.status(200).json({ user: req.session.user }); res.status(200).json({ user: req.session.user });
} }
catch(error){ catch(error){
@ -27,6 +29,88 @@ class SessionController {
await db.disconnect(); await db.disconnect();
} }
} }
static async updateSoloStats(req, res) {
const db = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
const soloStats = await db.getSoloStatsByUserId(user.idUser);
if (!soloStats) {
res.status(200).json({ error: "true", message: 'Solo stats not found' });
return;
}
await db.updateSoloStats(user.idUser, req.body.nbGames, req.body.bestScore, req.body.avgNbTry);
const newSoloStats = await db.getSoloStatsByUserId(user.idUser);
req.session.user.soloStats = newSoloStats;
console.log("[" + hour + ":" + minutes + "] " + req.session.user.pseudo + "'s solot_stats are updated.");
res.status(200).json({ user: req.session.user });
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la mise à jour des statistiques solo.' });
}
finally{
await db.disconnect();
}
}
static async updateOnlineStats(req, res) {
const db = new DatabaseService();
const date = new Date();
const hour = date.getHours();
const minutes = date.getMinutes();
try{
await db.connect();
const user = await db.getUserByPseudo(req.body.pseudo);
if (!user) {
res.status(200).json({ error: "true", message: 'User not found' });
return;
}
const onlineStats = await db.getOnlineStatsByUserId(user.idUser);
if (!onlineStats) {
res.status(200).json({ error: "true", message: 'Online stats not found' });
return;
}
await db.updateOnlineStats(user.idUser, req.body.nbGames, req.body.nbWins, req.body.ratio);
const newOnlineStats = await db.getOnlineStatsByUserId(user.idUser);
req.session.user.onlineStats = newOnlineStats;
console.log("[" + hour + ":" + minutes + "] " + req.session.user.pseudo + "'s online_stats are updated.");
res.status(200).json({ user: req.session.user });
}
catch(error){
console.error(error);
res.status(500).json({ error: 'Erreur lors de la mise à jour des statistiques en ligne.' });
}
finally{
await db.disconnect();
}
}
} }
module.exports = SessionController; module.exports = SessionController;

@ -10,5 +10,7 @@ router.delete('/auth/logout', AuthController.logout)
// Routes pour les sessions // Routes pour les sessions
router.get('/session', SessionController.getUserInformation); router.get('/session', SessionController.getUserInformation);
router.put('/session/updateSoloStats', SessionController.updateSoloStats);
router.put('/session/updateOnlineStats', SessionController.updateOnlineStats);
module.exports = router; module.exports = router;

@ -50,6 +50,20 @@ class DatabaseService {
}); });
} }
// Récupère l'utilisateur par son id
async getUserByID(id){
return new Promise((resolve, reject) => {
this.client.get('SELECT * FROM users WHERE idUser = ?', id, (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// Récupère stats solo de l'utilisateur // Récupère stats solo de l'utilisateur
async getSoloStatsByUserId(userId){ async getSoloStatsByUserId(userId){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -106,6 +120,33 @@ class DatabaseService {
}); });
} }
// Mettre à jour les stats solo de l'utilisateur
async updateSoloStats(userId, nbGames, bestScore, avgNbTry){
return new Promise((resolve, reject) => {
this.client.run('UPDATE solo_stats SET nbGames = ?, bestScore = ?, avgNbTry = ? WHERE idUser = ?', [nbGames, bestScore, avgNbTry, userId], (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
// Mettre à jour les stats online de l'utilisateur
async updateOnlineStats(userId, nbGames, nbWins, ratio){
return new Promise((resolve, reject) => {
this.client.run('UPDATE online_stats SET nbGames = ?, nbWins = ?, ratio = ? WHERE idUser = ?', [nbGames, nbWins, ratio, userId], (err, result) => {
if(err){
reject(err);
}
else{
resolve(result);
}
});
});
}
async initSoloStats(userId) { async initSoloStats(userId) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

@ -23,6 +23,66 @@ class SessionService {
throw error; throw error;
} }
} }
static async updateSoloStats(pseudo: string, nbGames: number, bestScore: number, avgNbTry: number){
try {
const response = await fetch(ADRESSE_DBSERVER + '/session/updateSoloStats', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
pseudo,
nbGames,
bestScore,
avgNbTry
}),
});
if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResponse = await response.json();
throw new Error(errorResponse.error);
}
} catch (error) {
console.error(error);
throw error;
}
}
static async updateOnlineStats(pseudo: string, nbGames: number, nbWins: number, ratio: number){
try {
console.log("updateOnlineStats : ", pseudo, nbGames, nbWins, ratio);
const response = await fetch(ADRESSE_DBSERVER + '/session/updateOnlineStats', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({
pseudo,
nbGames,
nbWins,
ratio
}),
});
if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResponse = await response.json();
throw new Error(errorResponse.error);
}
} catch (error) {
console.error(error);
throw error;
}
}
} }
export default SessionService; export default SessionService;

File diff suppressed because it is too large Load Diff

@ -1,3 +0,0 @@
\relax
\@writefile{toc}{\contentsline {paragraph}{Première énigme}{2}{}\protected@file@percent }
\gdef \@abspage@last{2}

Binary file not shown.

@ -1,132 +0,0 @@
\documentclass[11pt]{article}
\usepackage{fullpage}
\usepackage{times}
\usepackage{tikz}
\usepackage{paralist}
\usetikzlibrary {shapes.multipart}
\newcommand{\Basketball}{\includegraphics[width=.5cm]{ballon-de-basket.png}}
\newcommand{\Football}{\includegraphics[width=.4cm]{ballon-de-foot.png}}
\newcommand{\Bowling}{\includegraphics[width=.5cm]{bowling.png}}
\newcommand{\Baseball}{\includegraphics[width=.5cm]{baseball.png}}
\newcommand{\Tennis}{\includegraphics[width=.5cm]{tennis.png}}
\begin{document}
\thispagestyle{empty}
Voici le graphe de SocialGraphe
\begin{center}
\begin{tikzpicture}[scale=.9]
\node[draw, circle split] (0) at (0,0) { Alexander \nodepart{lower} \Football{} \Bowling{}};
\node[draw, circle split] (1) at (4,0) { Wyatt \nodepart{lower} \Baseball{} \Tennis{}};
\node[draw, circle split] (2) at (8,0) { Mia \nodepart{lower} \Basketball{}};
\node[draw, circle split] (3) at (12,0) { William \nodepart{lower} \Baseball{} \Football{}};
\node[draw, circle split] (4) at (16,0) { Zoey \nodepart{lower} \Basketball{} \Bowling{} \Tennis{}};
\node[draw, circle split] (5) at (0,4) { Isabella \nodepart{lower} \Tennis{}};
\node[draw, circle split] (6) at (4,4) { Abigail \nodepart{lower} \Baseball{}};
\node[draw, circle split] (7) at (8,4) { Savannah \nodepart{lower} \Bowling{} \Basketball{} \Football{}};
\node[draw, circle split] (8) at (12,4) { Peyton \nodepart{lower} \Football{}};
\node[draw, circle split] (9) at (16,4) { Alice \nodepart{lower} \Tennis{} \Baseball{}};
\node[draw, circle split] (10) at (0,8) { Sophia \nodepart{lower} \Bowling{} \Basketball{} \Bowling{}};
\node[draw, circle split] (11) at (4,8) { Layla \nodepart{lower} \Tennis{} \Baseball{} \Football{}};
\node[draw, circle split] (12) at (8,8) { Ava \nodepart{lower} \Basketball{}};
\node[draw, circle split] (13) at (12,8) { Harper \nodepart{lower} \Bowling{}};
\node[draw, circle split] (14) at (16,8) { Sebastian \nodepart{lower} \Tennis{} \Basketball{} \Baseball{}};
\node[draw, circle split] (15) at (0,12) { Michael \nodepart{lower} \Football{}};
\node[draw, circle split] (16) at (4,12) { Natalie \nodepart{lower} \Bowling{} \Football{} \Baseball{}};
\node[draw, circle split] (17) at (8,12) { Penelope \nodepart{lower} \Basketball{}};
\node[draw, circle split] (18) at (12,12) { Lily \nodepart{lower} \Tennis{} \Tennis{}};
\node[draw, circle split] (19) at (16,12) { Eleanor \nodepart{lower} \Football{}};
\node[draw, circle split] (20) at (0,16) { Henry \nodepart{lower} \Bowling{} \Basketball{}};
\node[draw, circle split] (21) at (4,16) { Claire \nodepart{lower} \Baseball{} \Basketball{}};
\node[draw, circle split] (22) at (8,16) { Caleb \nodepart{lower} \Baseball{}};
\node[draw, circle split] (23) at (12,16) { Charlotte \nodepart{lower} \Bowling{} \Football{} \Tennis{}};
\node[draw, circle split] (24) at (16,16) { Luke \nodepart{lower} \Football{}};
\node[draw, circle split] (25) at (0,20) { Connor \nodepart{lower} \Baseball{} \Tennis{}};
\node[draw, circle split] (26) at (4,20) { Aiden \nodepart{lower} \Basketball{} \Bowling{} \Tennis{}};
\node[draw, circle split] (27) at (8,20) { Aurora \nodepart{lower} \Football{}};
\node[draw, circle split] (28) at (12,20) { Nathan \nodepart{lower} \Bowling{} \Baseball{}};
\node[draw, circle split] (29) at (16,20) { Aurora \nodepart{lower} \Basketball{}};
\draw (0) -- (11);
\draw (0) -- (13);
\draw (0) -- (18);
\draw (1) -- (13);
\draw (1) -- (24);
\draw (2) -- (22);
\draw (2) -- (16);
\draw (2) -- (9);
\draw (2) -- (6);
\draw (3) -- (4);
\draw (3) -- (20);
\draw (4) -- (28);
\draw (4) -- (3);
\draw (5) -- (17);
\draw (5) -- (15);
\draw (5) -- (24);
\draw (6) -- (2);
\draw (7) -- (17);
\draw (7) -- (24);
\draw (7) -- (22);
\draw (7) -- (11);
\draw (8) -- (25);
\draw (8) -- (21);
\draw (8) -- (24);
\draw (8) -- (11);
\draw (9) -- (2);
\draw (10) -- (25);
\draw (10) -- (26);
\draw (10) -- (27);
\draw (11) -- (0);
\draw (11) -- (7);
\draw (11) -- (8);
\draw (12) -- (20);
\draw (12) -- (27);
\draw (13) -- (0);
\draw (13) -- (1);
\draw (14) -- (15);
\draw (15) -- (5);
\draw (15) -- (14);
\draw (15) -- (20);
\draw (15) -- (17);
\draw (16) -- (2);
\draw (16) -- (26);
\draw (17) -- (5);
\draw (17) -- (7);
\draw (17) -- (15);
\draw (17) -- (20);
\draw (18) -- (0);
\draw (19) -- (23);
\draw (20) -- (3);
\draw (20) -- (12);
\draw (20) -- (15);
\draw (20) -- (17);
\draw (21) -- (8);
\draw (22) -- (2);
\draw (22) -- (7);
\draw (22) -- (23);
\draw (23) -- (19);
\draw (23) -- (22);
\draw (24) -- (1);
\draw (24) -- (5);
\draw (24) -- (7);
\draw (24) -- (8);
\draw (25) -- (8);
\draw (25) -- (10);
\draw (26) -- (10);
\draw (26) -- (16);
\draw (26) -- (29);
\draw (27) -- (10);
\draw (27) -- (12);
\draw (28) -- (4);
\draw (29) -- (26);
\end{tikzpicture}
\end{center}
\paragraph{Première énigme}
Trouver qui est le coupable avec les indices suivants.
\begin{compactitem}
\item Indice 1 : Le suspect pratique au moins du Baseball et/ou du Basketball .
\item Indice 2 : Le suspect pratique 2 ou 1 sport(s).
\item Indice 3 : Le suspect a les cheveux Roux ou Blond .
\item Indice 4 : Le suspect a au moins un ami avec les cheveux Roux .
\end{compactitem}
% Solution : Nathan
\end{document}
Loading…
Cancel
Save