Compare commits
1 Commits
new_sadjig
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 82633fb869 |
15
.env
15
.env
@ -12,9 +12,14 @@
|
|||||||
|
|
||||||
#URL
|
#URL
|
||||||
NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf"
|
NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf"
|
||||||
BASE_URL=bess-f2r2s14:8080
|
|
||||||
REACT_APP_BASE_URL=bess-f2r2s14:8080
|
# BASE_URL=http://localhost
|
||||||
REDIRECT_URI=http://bess-f2r2s14:8080/api/auth/login
|
BASE_URL=localhost:8080
|
||||||
|
REACT_APP_BASE_URL=localhost:8080
|
||||||
|
REDIRECT_URI=http://localhost:8080/api/auth/login
|
||||||
|
#postgres var
|
||||||
|
# POSTGRES_HOST=127.0.0.1
|
||||||
|
# DB_TYPE=postgres
|
||||||
POSTGRES_HOST=postgresql
|
POSTGRES_HOST=postgresql
|
||||||
POSTGRES_USER=postgres
|
POSTGRES_USER=postgres
|
||||||
POSTGRES_PASSWORD=postgres
|
POSTGRES_PASSWORD=postgres
|
||||||
@ -37,5 +42,5 @@ REACT_HOST=0.0.0.0
|
|||||||
#auth var
|
#auth var
|
||||||
JWT_SECRET=secrethere
|
JWT_SECRET=secrethere
|
||||||
# REDIRECT_URI=http://localhost:80/api/auth/login
|
# REDIRECT_URI=http://localhost:80/api/auth/login
|
||||||
API_SECRET=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
|
API_SECRET=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
|
||||||
CLIENT_UID=u-s4t2ud-a58c0bac83e6a599129ff519650335526c634890b80bd360bce3a8007db4897e
|
CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
.env
|
#.env
|
||||||
containers/react/.env
|
|
||||||
backend/node_modules/
|
backend/node_modules/
|
||||||
containers/backend/dist/
|
containers/backend/dist/
|
||||||
|
|
||||||
|
|||||||
153
README.md
Normal file
153
README.md
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
# ft_transcendence
|
||||||
|
|
||||||
|
## Description
|
||||||
|
ft_transcendence est le projet final du tronc commun de l'École 42. Il s'agit de créer une application web complète permettant de jouer au Pong en ligne avec des fonctionnalités modernes comme les tournois, le chat en temps réel, et l'authentification.
|
||||||
|
|
||||||
|
## Fonctionnalités principales
|
||||||
|
- 🎮 **Jeu Pong** en temps réel multijoueur
|
||||||
|
- 🏆 **Système de tournois** avec brackets
|
||||||
|
- 💬 **Chat en temps réel** avec channels
|
||||||
|
- 👤 **Profils utilisateurs** et amis
|
||||||
|
- 🔐 **Authentification 2FA** (Google, 42)
|
||||||
|
- 📊 **Statistiques** et historique des parties
|
||||||
|
- 🎨 **Interface moderne** et responsive
|
||||||
|
- 🔒 **Sécurité** web avancée
|
||||||
|
|
||||||
|
## Technologies utilisées
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- **Framework** : React/Vue.js/Angular ou Vanilla JS
|
||||||
|
- **Styling** : CSS3, Bootstrap/Tailwind
|
||||||
|
- **WebSockets** : Pour le temps réel
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- **Framework** : Django/Flask/Node.js
|
||||||
|
- **Base de données** : PostgreSQL
|
||||||
|
- **API** : REST ou GraphQL
|
||||||
|
- **Authentication** : OAuth2, JWT
|
||||||
|
|
||||||
|
### DevOps
|
||||||
|
- **Containerisation** : Docker & Docker Compose
|
||||||
|
- **Reverse Proxy** : Nginx
|
||||||
|
- **SSL/TLS** : Certificats HTTPS
|
||||||
|
- **Base de données** : PostgreSQL en conteneur
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
```
|
||||||
|
ft_transcendence/
|
||||||
|
├── docker-compose.yml # Orchestration des services
|
||||||
|
├── frontend/ # Application client
|
||||||
|
│ ├── src/
|
||||||
|
│ ├── public/
|
||||||
|
│ └── Dockerfile
|
||||||
|
├── backend/ # API serveur
|
||||||
|
│ ├── api/
|
||||||
|
│ ├── models/
|
||||||
|
│ ├── services/
|
||||||
|
│ └── Dockerfile
|
||||||
|
├── database/ # Configuration PostgreSQL
|
||||||
|
├── nginx/ # Configuration reverse proxy
|
||||||
|
└── ssl/ # Certificats SSL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Modules bonus
|
||||||
|
- **Module Web** : Framework moderne (React/Vue/Angular)
|
||||||
|
- **Module User Management** : Authentification avancée
|
||||||
|
- **Module Gaming** : Variantes de Pong ou autres jeux
|
||||||
|
- **Module AI-Algo** : IA pour jouer contre
|
||||||
|
- **Module Cybersecurity** : Sécurité renforcée
|
||||||
|
- **Module DevOps** : Infrastructure monitoring
|
||||||
|
- **Module Graphics** : Interface 3D avancée
|
||||||
|
|
||||||
|
## Installation et déploiement
|
||||||
|
|
||||||
|
### Prérequis
|
||||||
|
- Docker et Docker Compose
|
||||||
|
- Domaine avec certificat SSL
|
||||||
|
- Clés API (42, Google) pour OAuth
|
||||||
|
|
||||||
|
### Lancement
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd ft_transcendence
|
||||||
|
docker-compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
1. Configurer les variables d'environnement
|
||||||
|
2. Générer les certificats SSL
|
||||||
|
3. Configurer OAuth applications
|
||||||
|
4. Initialiser la base de données
|
||||||
|
|
||||||
|
## Gameplay
|
||||||
|
|
||||||
|
### Pong multijoueur
|
||||||
|
- Contrôles clavier fluides
|
||||||
|
- Synchronisation en temps réel
|
||||||
|
- Système de score et timer
|
||||||
|
- Reconnexion automatique
|
||||||
|
|
||||||
|
### Tournois
|
||||||
|
- Création de tournois public/privé
|
||||||
|
- Système d'élimination
|
||||||
|
- Classements et récompenses
|
||||||
|
- Notifications en temps réel
|
||||||
|
|
||||||
|
## Sécurité implémentée
|
||||||
|
- 🔒 **HTTPS** obligatoire
|
||||||
|
- 🛡️ **Protection CSRF/XSS**
|
||||||
|
- 🔑 **Authentification 2FA**
|
||||||
|
- 💾 **Hashage sécurisé** des mots de passe
|
||||||
|
- 🚫 **Protection injection SQL**
|
||||||
|
- 🔐 **Validation** côté serveur
|
||||||
|
- 🍪 **Gestion sécurisée** des sessions
|
||||||
|
|
||||||
|
## Fonctionnalités sociales
|
||||||
|
- **Profils utilisateurs** personnalisables
|
||||||
|
- **Système d'amis** avec invitations
|
||||||
|
- **Chat global** et channels privés
|
||||||
|
- **Statut en ligne** des utilisateurs
|
||||||
|
- **Historique des parties**
|
||||||
|
- **Achievements** et badges
|
||||||
|
|
||||||
|
## Performance et scalabilité
|
||||||
|
- **WebSockets** pour le temps réel
|
||||||
|
- **Cache Redis** pour les sessions
|
||||||
|
- **Optimisation** des requêtes DB
|
||||||
|
- **Load balancing** pour la montée en charge
|
||||||
|
- **Monitoring** des performances
|
||||||
|
|
||||||
|
## Tests et qualité
|
||||||
|
- **Tests unitaires** backend
|
||||||
|
- **Tests d'intégration** API
|
||||||
|
- **Tests end-to-end** Selenium
|
||||||
|
- **Sécurité** avec OWASP ZAP
|
||||||
|
- **Performance** avec JMeter
|
||||||
|
|
||||||
|
## Compétences développées
|
||||||
|
- Architecture d'applications web modernes
|
||||||
|
- Développement full-stack
|
||||||
|
- Sécurité web avancée
|
||||||
|
- DevOps et containerisation
|
||||||
|
- Gestion de projet complexe
|
||||||
|
- Programmation temps réel
|
||||||
|
- UI/UX design
|
||||||
|
|
||||||
|
## Contraintes 42
|
||||||
|
- **Single Page Application** obligatoire
|
||||||
|
- **3 frameworks/langages** différents minimum
|
||||||
|
- **Docker** pour tous les services
|
||||||
|
- **Sécurité** de niveau production
|
||||||
|
- **Code maintenable** et documenté
|
||||||
|
|
||||||
|
## Auteur
|
||||||
|
Alexandre Pommier (apommier) - École 42
|
||||||
|
|
||||||
|
## Équipe (si applicable)
|
||||||
|
- Développeur Frontend
|
||||||
|
- Développeur Backend
|
||||||
|
- DevOps Engineer
|
||||||
|
- Security Specialist
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
Projet académique - École 42
|
||||||
@ -1 +1 @@
|
|||||||
ALTER USER postgres WITH PASSWORD 'postgres';
|
ALTER USER postgres WITH PASSWORD 'pass';
|
||||||
@ -10,7 +10,7 @@ server {
|
|||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_pass http://react_app:8081;
|
proxy_pass http://react_app:8001;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /api {
|
location /api {
|
||||||
@ -21,7 +21,7 @@ server {
|
|||||||
proxy_pass http://api:3000/api;
|
proxy_pass http://api:3000/api;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /socket.io {
|
location /socket {
|
||||||
# Forward requests to socket server running on port 4001
|
# Forward requests to socket server running on port 4001
|
||||||
if ($request_uri ~ ^/socket/4001) {
|
if ($request_uri ~ ^/socket/4001) {
|
||||||
proxy_pass http://chat:4001;
|
proxy_pass http://chat:4001;
|
||||||
|
|||||||
@ -3,10 +3,10 @@
|
|||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* app.controller.ts :+: :+: :+: */
|
/* app.controller.ts :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: sadjigui <sadjigui@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/17 01:00:00 by apommier #+# #+# */
|
/* Created: 2023/06/17 01:00:00 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/24 20:37:12 by sadjigui ### ########.fr */
|
/* Updated: 2023/06/21 01:19:01 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -180,9 +180,6 @@ export class AppController {
|
|||||||
// let user = req.user
|
// let user = req.user
|
||||||
// user.nickname = data.nickname
|
// user.nickname = data.nickname
|
||||||
console.log(`user= ${req.user.username}`)
|
console.log(`user= ${req.user.username}`)
|
||||||
const taken = await this.userService.findNickname(data.nickname)
|
|
||||||
if (taken)
|
|
||||||
return (0);
|
|
||||||
let user = await this.userService.findOne(req.user.username)
|
let user = await this.userService.findOne(req.user.username)
|
||||||
user.nickname = data.nickname;
|
user.nickname = data.nickname;
|
||||||
// return await this.userService.getFriends(req.user.username);
|
// return await this.userService.getFriends(req.user.username);
|
||||||
@ -483,6 +480,8 @@ export class AppController {
|
|||||||
// res.json(messages);
|
// res.json(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Get('/conv')
|
@Get('/conv')
|
||||||
async getConv(@Request() req) {
|
async getConv(@Request() req) {
|
||||||
@ -589,7 +588,7 @@ export class AppController {
|
|||||||
async muteUser(@Body() data: any) {
|
async muteUser(@Body() data: any) {
|
||||||
if (!data.username)
|
if (!data.username)
|
||||||
return ;
|
return ;
|
||||||
return await this.chatService.muteUser(data.convId, data.username, data.time)
|
return await this.chatService.muteUser(data.convId, data.username)
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@ -599,16 +598,11 @@ export class AppController {
|
|||||||
return await this.chatService.isAdmin(data.convId, req.user.username)
|
return await this.chatService.isAdmin(data.convId, req.user.username)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/private')
|
@Post('/private')
|
||||||
async setPrivate(@Body() data: any) {
|
async setPrivate(@Body() data: any) {
|
||||||
return await this.chatService.setPrivate(data.convId, true)
|
return await this.chatService.setPrivate(data.convId)
|
||||||
}
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
|
||||||
@Post('/public')
|
|
||||||
async setPublic(@Body() data: any) {
|
|
||||||
return await this.chatService.setPrivate(data.convId, false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/17 01:00:25 by apommier #+# #+# */
|
/* Created: 2023/06/17 01:00:25 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/24 18:47:59 by apommier ### ########.fr */
|
/* Updated: 2023/06/20 16:47:02 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -119,22 +119,14 @@ async verifyPassword(convId: number, password: string) {
|
|||||||
// conv.password = password
|
// conv.password = password
|
||||||
}
|
}
|
||||||
|
|
||||||
async muteUser(convId: number, username: string, time: string) {
|
async muteUser(convId: number, username: string) {
|
||||||
const conv = await this.findConv(convId);
|
const conv = await this.findConv(convId);
|
||||||
|
|
||||||
console.log("MUTE USER");
|
|
||||||
|
|
||||||
conv.muted = conv.muted || [];
|
conv.muted = conv.muted || [];
|
||||||
if (conv.muted.find(item => item === username))
|
if (conv.muted.find(item => item === username))
|
||||||
return (1);
|
return (1);
|
||||||
conv.muted.push(username);
|
conv.muted.push(username);
|
||||||
this.save(conv);
|
this.save(conv);
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
conv.muted = conv.muted.filter((item) => item !== username)
|
|
||||||
this.save(conv);
|
|
||||||
}, 5000);
|
|
||||||
console.log("END MUTE USER");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async setAdmin(convId: number, username: string) {
|
async setAdmin(convId: number, username: string) {
|
||||||
@ -157,14 +149,12 @@ async isAdmin(convId: number, username: string) {
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setPrivate(convId: number, bool: boolean) {
|
async setPrivate(convId: number) {
|
||||||
const conv = await this.findConv(convId);
|
const conv = await this.findConv(convId);
|
||||||
console.log("bool= ", bool);
|
if (conv.private === true)
|
||||||
conv.private = bool;
|
conv.private = false;
|
||||||
// if (conv.private === true)
|
else
|
||||||
// conv.private = false;
|
conv.private = true;
|
||||||
// else
|
|
||||||
// conv.private = true;
|
|
||||||
this.save(conv);
|
this.save(conv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,10 +3,10 @@
|
|||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* config.service.ts :+: :+: :+: */
|
/* config.service.ts :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: sadjigui <sadjigui@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
|
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/24 15:09:20 by sadjigui ### ########.fr */
|
/* Updated: 2023/06/22 20:42:32 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|||||||
@ -82,7 +82,7 @@ export class User {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity({name: 'MatchLog' })
|
@Entity()
|
||||||
export class MatchLog {
|
export class MatchLog {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id: number;
|
id: number;
|
||||||
|
|||||||
@ -3,10 +3,10 @@
|
|||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* users.service.ts :+: :+: :+: */
|
/* users.service.ts :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: sadjigui <sadjigui@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/17 01:00:07 by apommier #+# #+# */
|
/* Created: 2023/06/17 01:00:07 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/24 19:45:28 by sadjigui ### ########.fr */
|
/* Updated: 2023/06/21 01:31:44 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -18,7 +18,6 @@ import { User } from '../model/user.entity';
|
|||||||
import { MatchLog } from '../model/user.entity';
|
import { MatchLog } from '../model/user.entity';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UsersService {
|
export class UsersService {
|
||||||
constructor(
|
constructor(
|
||||||
@ -38,21 +37,10 @@ export class UsersService {
|
|||||||
return await this.userRepository.find();
|
return await this.userRepository.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
// async findNickname(username: string): Promise<User> {
|
|
||||||
// console.log("nick in find =", username)
|
|
||||||
// const ret= await this.userRepository.findOneBy({nickname: username});
|
|
||||||
// console.log("ret noick=", ret )
|
|
||||||
// return ret;
|
|
||||||
// }
|
|
||||||
|
|
||||||
async findOne(username: string): Promise<User> {
|
async findOne(username: string): Promise<User> {
|
||||||
return await this.userRepository.findOneBy({username: username});
|
return await this.userRepository.findOneBy({username: username});
|
||||||
}
|
}
|
||||||
|
|
||||||
async findNickname(username: string): Promise<User> {
|
|
||||||
return await this.userRepository.findOneBy({nickname: username});
|
|
||||||
}
|
|
||||||
|
|
||||||
async save(user: User): Promise<User> {
|
async save(user: User): Promise<User> {
|
||||||
return await this.userRepository.save(user);
|
return await this.userRepository.save(user);
|
||||||
}
|
}
|
||||||
@ -83,8 +71,6 @@ export class UsersService {
|
|||||||
user.friendRequest = user.friendRequest || [];
|
user.friendRequest = user.friendRequest || [];
|
||||||
if (user.friendRequest.find(item => item === username))
|
if (user.friendRequest.find(item => item === username))
|
||||||
return (1);
|
return (1);
|
||||||
if (user.friends.find(item => item === username))
|
|
||||||
return (1);
|
|
||||||
user.friendRequest.push(username);
|
user.friendRequest.push(username);
|
||||||
this.save(user);
|
this.save(user);
|
||||||
return (1);
|
return (1);
|
||||||
@ -110,24 +96,16 @@ export class UsersService {
|
|||||||
async getHistory(username: string) {
|
async getHistory(username: string) {
|
||||||
const user = await this.findOne(username);
|
const user = await this.findOne(username);
|
||||||
|
|
||||||
if (user)
|
if (user) {
|
||||||
{
|
const children = user.children;
|
||||||
|
console.log(user);
|
||||||
// const ret = await this.matchRepository.query("SELECT * FROM \"MatchLog\" WHERE id = ($1);", [user.id]);
|
console.log(user.children); // or perform any operations with the children
|
||||||
const ret = await this.matchRepository.query("SELECT * FROM \"MatchLog\"");
|
return children;
|
||||||
console.log("all match= ", ret);
|
|
||||||
}
|
}
|
||||||
// const children = user.children;
|
|
||||||
// console.log(user);
|
|
||||||
// console.log(user.children); // or perform any operations with the children
|
|
||||||
// return children;
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async addFriend(user: User, username: string) {
|
async addFriend(user: User, username: string) {
|
||||||
const user2 = await this.findOne(username)
|
if (!(await this.findOne(username)))
|
||||||
if (!user)
|
|
||||||
return (0);
|
return (0);
|
||||||
// user.friendRequest = user.friendRequest || [];
|
// user.friendRequest = user.friendRequest || [];
|
||||||
user.friends = user.friends || [];
|
user.friends = user.friends || [];
|
||||||
@ -139,9 +117,6 @@ export class UsersService {
|
|||||||
}
|
}
|
||||||
user.friends.push(username);
|
user.friends.push(username);
|
||||||
user.friendRequest = user.friendRequest.filter((item) => item !== username);
|
user.friendRequest = user.friendRequest.filter((item) => item !== username);
|
||||||
user2.friends = user2.friends || [];
|
|
||||||
user2.friends.push(user.username);
|
|
||||||
this.save(user2);
|
|
||||||
this.save(user);
|
this.save(user);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,12 +6,10 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/19 15:18:38 by apommier #+# #+# */
|
/* Created: 2023/06/19 15:18:38 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/24 17:20:24 by apommier ### ########.fr */
|
/* Updated: 2023/06/23 15:19:12 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
//0.0001
|
|
||||||
|
|
||||||
import { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
|
import { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
|
||||||
import { Server, Socket } from 'socket.io';
|
import { Server, Socket } from 'socket.io';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
@ -167,9 +165,8 @@ addMatchmaking(client: Socket, payload: any): void {
|
|||||||
player.join(gameId);
|
player.join(gameId);
|
||||||
console.log(`Player ${player.id} joined game ${gameId}`);
|
console.log(`Player ${player.id} joined game ${gameId}`);
|
||||||
});
|
});
|
||||||
payload.gameId = gameId;
|
|
||||||
players.forEach((player) => {
|
players.forEach((player) => {
|
||||||
player.emit('pong:gameId', payload);
|
player.emit('pong:gameId', gameId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,8 +200,8 @@ joinPrivateParty(client: Socket, payload: any): void {
|
|||||||
{
|
{
|
||||||
game.push(client);
|
game.push(client);
|
||||||
const playersIds = game.map(socket => socket.id);
|
const playersIds = game.map(socket => socket.id);
|
||||||
this.clients[playersIds[0]].emit('pong:gameId', payload);
|
this.clients[playersIds[0]].emit('pong:gameId', payload.gameId);
|
||||||
this.clients[playersIds[1]].emit('pong:gameId', payload);
|
this.clients[playersIds[1]].emit('pong:gameId', payload.gameId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -340,24 +337,6 @@ addPrivateParty(client: Socket, payload: any): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeMessage('pong:myPoint')
|
|
||||||
handleMyPoint(client: Socket, payload: any): void
|
|
||||||
{
|
|
||||||
const game = this.games.get(payload.gameId);
|
|
||||||
const playersIds = game.map(socket => socket.id);
|
|
||||||
console.log(`id of 0 mypoint= ${playersIds[0]}`);
|
|
||||||
|
|
||||||
if (playersIds[0] === payload.id)
|
|
||||||
{
|
|
||||||
this.clients[playersIds[1]].emit('pong:hisPoint', payload);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (playersIds[1] === payload.id)
|
|
||||||
{
|
|
||||||
this.clients[playersIds[0]].emit('pong:hisPoint', payload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeMessage('pong:name')
|
@SubscribeMessage('pong:name')
|
||||||
getName(client: Socket, payload: any): void
|
getName(client: Socket, payload: any): void
|
||||||
{
|
{
|
||||||
@ -368,11 +347,11 @@ addPrivateParty(client: Socket, payload: any): void {
|
|||||||
|
|
||||||
if (playersIds[0] === payload.id)
|
if (playersIds[0] === payload.id)
|
||||||
{
|
{
|
||||||
this.clients[playersIds[1]].emit('pong:name', payload);
|
this.clients[playersIds[1]].emit('pong:name', payload.name);
|
||||||
}
|
}
|
||||||
if (playersIds[1] === payload.id)
|
if (playersIds[1] === payload.id)
|
||||||
{
|
{
|
||||||
this.clients[playersIds[0]].emit('pong:name', payload);
|
this.clients[playersIds[0]].emit('pong:name', payload.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
REACT_APP_BASE_URL=bess-f2r2s14:8080
|
REACT_APP_BASE_URL=localhost:8080
|
||||||
REACT_APP_SOCKET_URL=bess-f2r2s14:8080
|
REACT_APP_API_SECRET=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
|
||||||
REACT_APP_API_SECRET=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
|
REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41
|
||||||
REACT_APP_CLIENT_UID=u-s4t2ud-a58c0bac83e6a599129ff519650335526c634890b80bd360bce3a8007db4897e
|
|
||||||
|
|
||||||
# REACT_APP_BASE_URL=92.143.191.152
|
# REACT_APP_BASE_URL=92.143.191.152
|
||||||
# REACT_APP_BASE_URL=192.168.1.19
|
# REACT_APP_BASE_URL=192.168.1.19
|
||||||
@ -22,7 +22,7 @@
|
|||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "HOST=0.0.0.0 PORT=8081 react-scripts start",
|
"start": "HOST=0.0.0.0 PORT=8001 react-scripts start",
|
||||||
"start:dev": "npm run start --watch",
|
"start:dev": "npm run start --watch",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
|
|||||||
@ -40,9 +40,9 @@ function PlayButton() {
|
|||||||
<button onClick={handleButtonClick} className="playButton">Play</button>
|
<button onClick={handleButtonClick} className="playButton">Play</button>
|
||||||
{/* !buttonClicked && <button onClick={handleButtonClick}>Draw on Canvas</button> */}
|
{/* !buttonClicked && <button onClick={handleButtonClick}>Draw on Canvas</button> */}
|
||||||
<div className='checkbox'>
|
<div className='checkbox'>
|
||||||
<p><input className="inside_checkbox" type="checkbox" value="superpower"/> Super Power </p>
|
<p><input type="checkbox" value="superpower"/> Super Power </p>
|
||||||
<p><input className="inside_checkbox" type="checkbox" value="obstacle"/> Obstacle </p>
|
<p><input type="checkbox" value="obstacle"/> Obstacle </p>
|
||||||
<p><input className="inside_checkbox" type="checkbox" value="speed"/> Faster and Faster </p>
|
<p><input type="checkbox" value="speed"/> Faster and Faster </p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/09 08:49:24 by apommier #+# #+# */
|
/* Created: 2023/06/09 08:49:24 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/23 17:16:40 by apommier ### ########.fr */
|
/* Updated: 2023/06/20 13:06:35 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ function Rank({user, index}: RankProps){
|
|||||||
};
|
};
|
||||||
|
|
||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
}, [])
|
})
|
||||||
|
|
||||||
// console.log(index);
|
// console.log(index);
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -21,15 +21,18 @@ function Ranking(){
|
|||||||
// setFriends(tmpFriends.data);
|
// setFriends(tmpFriends.data);
|
||||||
// return tmpUser;
|
// return tmpUser;
|
||||||
// console.log(`user= ${tmpUser.data.username}`);
|
// console.log(`user= ${tmpUser.data.username}`);
|
||||||
setIsLoading(false);
|
setIsLoading(false)
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(err){
|
catch(err){
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getRanking();
|
getRanking();
|
||||||
}, []);
|
|
||||||
console.log(`ranking after= ${ranking}`);
|
}, [])
|
||||||
|
|
||||||
|
console.log(`ranking after= ${ranking}`)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import { ImBlocked } from 'react-icons/im';
|
|||||||
import { MdOutlineGroupAdd } from 'react-icons/md';
|
import { MdOutlineGroupAdd } from 'react-icons/md';
|
||||||
import { GrAdd } from 'react-icons/gr';
|
import { GrAdd } from 'react-icons/gr';
|
||||||
import { RiListSettingsLine } from 'react-icons/ri'
|
import { RiListSettingsLine } from 'react-icons/ri'
|
||||||
// import { HiChatBubbleLeft } from 'react-icons/hi2'
|
|
||||||
|
|
||||||
// import { Rank } from "../../DataBase/DataRank";
|
// import { Rank } from "../../DataBase/DataRank";
|
||||||
import GreenAlert from "../Alert/GreenAlert.tsx";
|
import GreenAlert from "../Alert/GreenAlert.tsx";
|
||||||
@ -28,7 +27,6 @@ import PartyInvite from "./PartyInvite.tsx";
|
|||||||
|
|
||||||
// import {User, Conv, Message} from "../../../interfaces.tsx"
|
// import {User, Conv, Message} from "../../../interfaces.tsx"
|
||||||
import {User, Conv} from "../../../interfaces.tsx"
|
import {User, Conv} from "../../../interfaces.tsx"
|
||||||
import { IoChatbox, IoLogoOctocat } from "react-icons/io5";
|
|
||||||
|
|
||||||
const TouchDiv = styled.div`
|
const TouchDiv = styled.div`
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
@ -121,7 +119,7 @@ function Chats(){
|
|||||||
setUsers(tmpUsers.data);
|
setUsers(tmpUsers.data);
|
||||||
|
|
||||||
// console.log(`connection....`);
|
// console.log(`connection....`);
|
||||||
socket.current = io('http://' + process.env.REACT_APP_SOCKET_URL + ':4001', { transports: ['polling'] });
|
socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001', { transports: ['polling'] });
|
||||||
// console.log(`connection done`);
|
// console.log(`connection done`);
|
||||||
socket.current.emit('connection', {username: tmpUser.data.username})
|
socket.current.emit('connection', {username: tmpUser.data.username})
|
||||||
socket.current.on('message', (data) => { //data should be a message ?)
|
socket.current.on('message', (data) => { //data should be a message ?)
|
||||||
@ -207,12 +205,11 @@ function Chats(){
|
|||||||
getMessage();
|
getMessage();
|
||||||
}, [currentChat]);
|
}, [currentChat]);
|
||||||
|
|
||||||
const handleSubmit = async (e: { key?: any; preventDefault: any; })=>{
|
const handleSubmit = async (e: { preventDefault: () => void; })=>{
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// console.log(`e= ${e.key}`)
|
// console.log(`e= ${e.key}`)
|
||||||
// console.log(`name= ${user.username}`)
|
// console.log(`name= ${user.username}`)
|
||||||
// let message;
|
// let message;
|
||||||
console.log("in handle");
|
|
||||||
if (!user || !currentChat)
|
if (!user || !currentChat)
|
||||||
return ;
|
return ;
|
||||||
const message = {
|
const message = {
|
||||||
@ -245,11 +242,33 @@ function Chats(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleKeyPress = async (e: { key?: any; preventDefault: () => void; })=> {
|
const handleKeyPress = async (e: { key: string; })=> {
|
||||||
// console.log(`e in press= ${e.key}`)
|
// console.log(`e in press= ${e.key}`)
|
||||||
if (e.key !== "Enter")
|
if (e.key !== "Enter")
|
||||||
return ;
|
return ;
|
||||||
handleSubmit(e);
|
// console.log(`name= ${user.username}`)
|
||||||
|
if (!user || !currentChat)
|
||||||
|
return ;
|
||||||
|
const message = {
|
||||||
|
sender: user.username,
|
||||||
|
text: newMessages,
|
||||||
|
convId: currentChat.id,
|
||||||
|
members: null,
|
||||||
|
id: null,
|
||||||
|
};
|
||||||
|
try{
|
||||||
|
const res = await api.post('/message', message);
|
||||||
|
const convMember = await api.post('/member', message);
|
||||||
|
message.members = convMember.data.members;
|
||||||
|
message.id = res.data.id
|
||||||
|
setMessage([...messages, res.data]);
|
||||||
|
setNewMessage("");
|
||||||
|
if (socket.current)
|
||||||
|
socket.current.emit('sendMessage', message);
|
||||||
|
}
|
||||||
|
catch(err){
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -304,7 +323,6 @@ function Chats(){
|
|||||||
|
|
||||||
const handleAddFriend = async () => {
|
const handleAddFriend = async () => {
|
||||||
try{
|
try{
|
||||||
console.log("friend= ", friend);
|
|
||||||
const res = await api.post("/invite", {username: friend})
|
const res = await api.post("/invite", {username: friend})
|
||||||
// if (res.data === 1)
|
// if (res.data === 1)
|
||||||
// console.log("res in friend= ", res)
|
// console.log("res in friend= ", res)
|
||||||
@ -353,7 +371,6 @@ function Chats(){
|
|||||||
|
|
||||||
const handleOptionChange = (selectId: number, selectedOption: string) => {
|
const handleOptionChange = (selectId: number, selectedOption: string) => {
|
||||||
console.log("selected Option=", selectedOption)
|
console.log("selected Option=", selectedOption)
|
||||||
setFriend(selectedOption);
|
|
||||||
setSelectTag((prevTags) =>
|
setSelectTag((prevTags) =>
|
||||||
prevTags.map((tag) =>
|
prevTags.map((tag) =>
|
||||||
tag.id === selectId ? { ...tag, selectedOption } : tag
|
tag.id === selectId ? { ...tag, selectedOption } : tag
|
||||||
@ -372,13 +389,12 @@ function Chats(){
|
|||||||
<div className="chat">
|
<div className="chat">
|
||||||
|
|
||||||
<div className='navbar'>
|
<div className='navbar'>
|
||||||
{/* <img src={DefaultPic} alt="profile" className="pic"/> */}
|
<img src={DefaultPic} alt="profile" className="pic"/>
|
||||||
<IoLogoOctocat className="catchat"/>
|
|
||||||
<span>
|
<span>
|
||||||
{isLoading || !user ? (
|
{isLoading || !user ? (
|
||||||
<h4>Loading...</h4>
|
<h4>Loading...</h4>
|
||||||
) : (
|
) : (
|
||||||
<h2>Chat</h2>
|
<h4>{user.nickname}</h4>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
{/* <div className="end">
|
{/* <div className="end">
|
||||||
@ -447,7 +463,7 @@ function Chats(){
|
|||||||
))}
|
))}
|
||||||
<TouchDiv>
|
<TouchDiv>
|
||||||
<motion.div onClick={handleAddFriend}>
|
<motion.div onClick={handleAddFriend}>
|
||||||
<MdOutlineGroupAdd className="catchat"/>
|
<MdOutlineGroupAdd />
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<AnimatePresence initial={false} onExitComplete={() => null}>
|
<AnimatePresence initial={false} onExitComplete={() => null}>
|
||||||
{showAddFriendAlert && addFriend && (
|
{showAddFriendAlert && addFriend && (
|
||||||
@ -460,7 +476,7 @@ function Chats(){
|
|||||||
</TouchDiv>
|
</TouchDiv>
|
||||||
<TouchDiv>
|
<TouchDiv>
|
||||||
<motion.div onClick={handleBlockFriend}>
|
<motion.div onClick={handleBlockFriend}>
|
||||||
<ImBlocked className="block"/>
|
<ImBlocked />
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<AnimatePresence initial={false} onExitComplete={() => null}>
|
<AnimatePresence initial={false} onExitComplete={() => null}>
|
||||||
{showBlockAlert && block && (
|
{showBlockAlert && block && (
|
||||||
@ -476,7 +492,7 @@ function Chats(){
|
|||||||
<motion.div
|
<motion.div
|
||||||
onClick={() => (setting ? setSetting(false) : setSetting(true))}
|
onClick={() => (setting ? setSetting(false) : setSetting(true))}
|
||||||
>
|
>
|
||||||
<RiListSettingsLine className="inline"/>
|
<RiListSettingsLine/>
|
||||||
<AnimatePresence
|
<AnimatePresence
|
||||||
initial={false}
|
initial={false}
|
||||||
onExitComplete={() => null}
|
onExitComplete={() => null}
|
||||||
@ -527,8 +543,7 @@ function Chats(){
|
|||||||
<div key={index}
|
<div key={index}
|
||||||
onClick={() => setCurrentChat(c)}>
|
onClick={() => setCurrentChat(c)}>
|
||||||
<UserChat>
|
<UserChat>
|
||||||
{/* <img className="pic-user" src={DefaultPic} alt="User" /> */}
|
<img className="pic-user" src={DefaultPic} alt="User" />
|
||||||
{/* <HiChatBubbleLeft className="catchat"/> */}
|
|
||||||
<div className="infoSideBar">
|
<div className="infoSideBar">
|
||||||
<span>{c.name}</span>
|
<span>{c.name}</span>
|
||||||
{/* <SideP>Desc?</SideP> */}
|
{/* <SideP>Desc?</SideP> */}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
|
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/24 16:00:48 by apommier ### ########.fr */
|
/* Updated: 2023/06/20 19:05:10 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -42,16 +42,15 @@ function MessageMe({message, own}: MessageMeProps){
|
|||||||
const [user, setUser] = useState<User>();
|
const [user, setUser] = useState<User>();
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
// console.log("Message eher")
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (scrollRef.current)
|
if (scrollRef.current)
|
||||||
{
|
{
|
||||||
scrollRef.current.scrollIntoView({ behavior: "smooth"});
|
scrollRef.current.scrollIntoView({ behavior: "smooth",})
|
||||||
}})
|
}
|
||||||
useEffect(() => {
|
|
||||||
const fetchProfilePicture = async () => {
|
const fetchProfilePicture = async () => {
|
||||||
try {
|
try {
|
||||||
console.log("useEffect message")
|
|
||||||
// const user = await api.get("/profile");
|
// const user = await api.get("/profile");
|
||||||
const tmpSender = await api.post("/user", {username: message.sender})
|
const tmpSender = await api.post("/user", {username: message.sender})
|
||||||
const tmpConv = await api.post("/convId", {convId: message.convId})
|
const tmpConv = await api.post("/convId", {convId: message.convId})
|
||||||
@ -82,37 +81,23 @@ function MessageMe({message, own}: MessageMeProps){
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
// const isAllowed = async () => {
|
|
||||||
// const ret = await api.post("/allowed", {convId: message.convId});
|
|
||||||
// return ret.data;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (!user || !sender || !conv)
|
if (!user || !sender || !conv)
|
||||||
return (<></>);
|
|
||||||
// console.log("result includes=", conv.banned.includes(user.username))
|
|
||||||
// console.log("result includes=", conv.blocked.includes(user.username))
|
|
||||||
// const conv2: Conv = getConv();
|
|
||||||
// if (!conv)
|
|
||||||
// isAllowed().then((ret: number) => {
|
|
||||||
// if (!ret)
|
|
||||||
// {
|
|
||||||
// console.log("return not allowed");
|
|
||||||
// return ;
|
|
||||||
// }
|
|
||||||
// // Use the resolved currentConv here
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (user.blocked && user.blocked.includes(message.sender))
|
|
||||||
return (<></>);
|
|
||||||
else if (conv.banned && conv.banned.includes(user.username))
|
|
||||||
return (<></>);
|
|
||||||
else if (conv.muted && conv.muted.includes(user.username))
|
|
||||||
{
|
{
|
||||||
// console.log("muted00")
|
// console.log("return")
|
||||||
return (<></>);
|
return (<></>);
|
||||||
}
|
}
|
||||||
|
// console.log("result includes=", conv.banned.includes(user.username))
|
||||||
|
// console.log("result includes=", conv.blocked.includes(user.username))
|
||||||
|
if (user.blocked && user.blocked.includes(message.sender))
|
||||||
|
return (<></>);
|
||||||
|
// else if (conv.banned && conv.banned.includes(user.username))
|
||||||
|
// {
|
||||||
|
// console.log("return2")
|
||||||
|
// return (<></>);
|
||||||
|
// }
|
||||||
|
// console.log("noy return")
|
||||||
// if (user.blocked.includes(message.sender))/
|
// if (user.blocked.includes(message.sender))/
|
||||||
console.log("no return message good");
|
|
||||||
return (
|
return (
|
||||||
<div className={own ? "meMessage" : "youMessage"} ref={scrollRef}>
|
<div className={own ? "meMessage" : "youMessage"} ref={scrollRef}>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { GrAdd } from "react-icons/gr";
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import api from "../../script/axiosApi.tsx";
|
import api from "../../script/axiosApi.tsx";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {User, Conv} from "../../../interfaces.tsx"
|
|
||||||
|
|
||||||
const dropIn = {
|
const dropIn = {
|
||||||
hidden:{y:"-100vh",
|
hidden:{y:"-100vh",
|
||||||
@ -22,19 +21,16 @@ const dropIn = {
|
|||||||
}},
|
}},
|
||||||
exit:{y: "100vh",
|
exit:{y: "100vh",
|
||||||
opacity: 0,},
|
opacity: 0,},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ModalProps {
|
const Modal = ({handleClose}) => {
|
||||||
handleClose: Function,
|
|
||||||
}
|
|
||||||
|
|
||||||
const Modal = ({handleClose}: ModalProps) => {
|
|
||||||
// const [multi, setMulti] = useState(false);
|
// const [multi, setMulti] = useState(false);
|
||||||
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
|
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
|
||||||
const [selectedOptionArray, setSelectedOptionArray] = useState<string[]>([]);
|
const [selectedOptionArray, setSelectedOptionArray] = useState([]);
|
||||||
const [users, setUsers] = useState<User[]>([]);
|
const [users, setUsers] = useState([]);
|
||||||
const [user, setUser] = useState<User>();
|
const [user, setUser] = useState();
|
||||||
const [convs, setConvs] = useState<Conv[]>([]);
|
const [convs, setConvs] = useState([]);
|
||||||
|
|
||||||
const [channel, setChannel] = useState('');
|
const [channel, setChannel] = useState('');
|
||||||
|
|
||||||
@ -57,7 +53,7 @@ const Modal = ({handleClose}: ModalProps) => {
|
|||||||
getConv();
|
getConv();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleOptionChange = (selectId: number, selectedOption: string) => {
|
const handleOptionChange = (selectId, selectedOption) => {
|
||||||
console.log("selected Option=", selectedOption)
|
console.log("selected Option=", selectedOption)
|
||||||
setSelectTag((prevTags) =>
|
setSelectTag((prevTags) =>
|
||||||
prevTags.map((tag) =>
|
prevTags.map((tag) =>
|
||||||
@ -107,15 +103,12 @@ const Modal = ({handleClose}: ModalProps) => {
|
|||||||
<Backdrop onClick={handleClose}>
|
<Backdrop onClick={handleClose}>
|
||||||
<motion.div
|
<motion.div
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
className="modalSetting"
|
className="modal"
|
||||||
// variant={dropIn}
|
// variant={dropIn}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit"
|
exit="exit"
|
||||||
>
|
>
|
||||||
{/* <p>New Conversation</p> */}
|
|
||||||
<div className="settingFirstPart2">
|
|
||||||
|
|
||||||
{selectTags.map((selectTag) => (
|
{selectTags.map((selectTag) => (
|
||||||
<div key={selectTag.id}>
|
<div key={selectTag.id}>
|
||||||
<select
|
<select
|
||||||
@ -125,9 +118,9 @@ const Modal = ({handleClose}: ModalProps) => {
|
|||||||
<option value="">{
|
<option value="">{
|
||||||
selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
|
selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
|
||||||
}</option>
|
}</option>
|
||||||
{users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.nickname)).map((item, index) => (
|
{users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.name)).map((item, index) => (
|
||||||
<option key={index} value={item.username}>
|
<option key={index} value={item.username}>
|
||||||
{item.nickname}
|
{item.username}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
@ -139,12 +132,10 @@ const Modal = ({handleClose}: ModalProps) => {
|
|||||||
<div className="div_submit">
|
<div className="div_submit">
|
||||||
<Link to='#' className="submit" onClick={ saveSelectedOptions}>Submit</Link>
|
<Link to='#' className="submit" onClick={ saveSelectedOptions}>Submit</Link>
|
||||||
|
|
||||||
<Link to="#" className="submit" onClick={() => handleClose}>Cancel</Link>
|
<Link to="#" className="submit" onClick={handleClose}>Cancel</Link>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="settingSecondPart">
|
|
||||||
|
|
||||||
{convs.length > 0 && (
|
{convs.length > 0 && (
|
||||||
<select
|
<select
|
||||||
@ -154,7 +145,7 @@ const Modal = ({handleClose}: ModalProps) => {
|
|||||||
>
|
>
|
||||||
<option value="">Select an option</option>
|
<option value="">Select an option</option>
|
||||||
{convs.map((conv) => (
|
{convs.map((conv) => (
|
||||||
!(!conv.group || conv.private || (conv.banned && user && conv.banned.includes(user.username)) || (conv.members && user && conv.members.includes(user.username))) && (
|
!(!conv.group || conv.private || (conv.banned && conv.banned.includes(user.username)) || (conv.members && conv.members.includes(user.username))) && (
|
||||||
<option key={conv.id} value={conv.id}>
|
<option key={conv.id} value={conv.id}>
|
||||||
{conv.name}
|
{conv.name}
|
||||||
</option>
|
</option>
|
||||||
@ -162,9 +153,9 @@ const Modal = ({handleClose}: ModalProps) => {
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
)}
|
)}
|
||||||
{/* {channel.private ? (
|
{channel.private ? (
|
||||||
<input className="mdp" placeholder="passdddddword" type="text" />
|
<input className="mdp" placeholder="password" type="text" />
|
||||||
):("")} */}
|
):("")}
|
||||||
|
|
||||||
|
|
||||||
<div className="div_submit">
|
<div className="div_submit">
|
||||||
@ -173,7 +164,6 @@ const Modal = ({handleClose}: ModalProps) => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</Backdrop>
|
</Backdrop>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -39,10 +39,8 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
|
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
|
||||||
const [selectedUser, setSelectedUser] = useState("");
|
const [selectedUser, setSelectedUser] = useState("");
|
||||||
const [newName, setNewName] = useState("");
|
const [newName, setNewName] = useState("");
|
||||||
const [time, setTime] = useState("");
|
|
||||||
const [newPassword, setNewPassword] = useState("");
|
const [newPassword, setNewPassword] = useState("");
|
||||||
const [privateConv, setPrivateConv] = useState<Boolean>();
|
const [privateConv, setPrivateConv] = useState(false);
|
||||||
const [loading, setLoading] = useState<Boolean>(true);
|
|
||||||
const dark = () => setPrivateConv(true);
|
const dark = () => setPrivateConv(true);
|
||||||
const light = () => setPrivateConv(false);
|
const light = () => setPrivateConv(false);
|
||||||
const [mute, setMute] = useState(false);
|
const [mute, setMute] = useState(false);
|
||||||
@ -55,15 +53,9 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
console.log("convid =", convId)
|
console.log("convid =", convId)
|
||||||
const getUsers = async ()=>{
|
const getUsers = async ()=>{
|
||||||
try {
|
try {
|
||||||
const currentConv = await api.post("/convId", {convId: convId});
|
|
||||||
|
|
||||||
// console.log("conv private =================== ", )
|
|
||||||
if (currentConv.data.private)
|
|
||||||
setPrivateConv(true);
|
|
||||||
const tmpUsers = await api.get("/users");
|
const tmpUsers = await api.get("/users");
|
||||||
console.log("users=", tmpUsers.data);
|
console.log("users=", tmpUsers.data);
|
||||||
setUsers(tmpUsers.data);
|
setUsers(tmpUsers.data);
|
||||||
setLoading(false);
|
|
||||||
} catch(err){
|
} catch(err){
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
@ -71,31 +63,6 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
getUsers();
|
getUsers();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Function to run when myVariable changes
|
|
||||||
const handleVariableChange = () => {
|
|
||||||
console.log('Variable changed:', privateConv);
|
|
||||||
if (privateConv === undefined)
|
|
||||||
{
|
|
||||||
console.log("return")
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (privateConv)
|
|
||||||
api.post("/private", {convId: convId})
|
|
||||||
else
|
|
||||||
api.post("/public", {convId: convId})
|
|
||||||
} catch (err){
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!loading)
|
|
||||||
handleVariableChange();
|
|
||||||
// return () => {
|
|
||||||
// handleVariableChange();
|
|
||||||
// };
|
|
||||||
}, [privateConv]);
|
|
||||||
|
|
||||||
// const [multi, setMulti] = useState(false);
|
// const [multi, setMulti] = useState(false);
|
||||||
// const [selectedOptionArray, setSelectedOptionArray] = useState([]);
|
// const [selectedOptionArray, setSelectedOptionArray] = useState([]);
|
||||||
|
|
||||||
@ -113,30 +80,30 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
|
|
||||||
const handleCheckPass = (e: { target: { checked: boolean | ((prevState: boolean) => boolean); }; }) => {
|
const handleCheckPass = (e: { target: { checked: boolean | ((prevState: boolean) => boolean); }; }) => {
|
||||||
setPassword(e.target.checked);
|
setPassword(e.target.checked);
|
||||||
console.log("password??", e.target.checked);
|
console.log("password??", e.target.checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
// const handleCheckPriv = (e: { target: { checked: any; }; }) => {
|
const handleCheckPriv = (e: { target: { checked: any; }; }) => {
|
||||||
// // setPassword(e.target.checked);
|
// setPassword(e.target.checked);
|
||||||
// if (e.target.checked)
|
if (e.target.checked)
|
||||||
// {
|
{
|
||||||
// console.log("chack true", e.target.checked)
|
console.log("chack true", e.target.checked)
|
||||||
// try{
|
try{
|
||||||
// api.post("/private", {convId: convId})
|
api.post("/private", {convId: convId})
|
||||||
// } catch(err) {
|
} catch(err) {
|
||||||
// console.log(err);
|
console.log(err);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// {
|
{
|
||||||
// console.log("chack false", e.target.checked)
|
console.log("chack false", e.target.checked)
|
||||||
// try{
|
try{
|
||||||
// api.post("/private", {convId: convId})
|
api.post("/private", {convId: convId})
|
||||||
// } catch(err) {
|
} catch(err) {
|
||||||
// console.log(err);
|
console.log(err);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
const handleName = async (e: { key: string; })=>{
|
const handleName = async (e: { key: string; })=>{
|
||||||
if (e.key !== "Enter")
|
if (e.key !== "Enter")
|
||||||
@ -190,15 +157,11 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMute = async (e: { key: string; }) => {
|
const handleMute = async () => {
|
||||||
console.log(`e in press= ${e.key}`)
|
if (!selectedUser.length)
|
||||||
if (e.key != "Enter")
|
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// console.log("value mute = ", e.target.value);
|
|
||||||
console.log("value mute = ", time);
|
|
||||||
try{
|
try{
|
||||||
await api.post("/mute", {convId: convId, username: selectedUser, time: time})
|
await api.post("/mute", {convId: convId, username: selectedUser})
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
@ -214,17 +177,6 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKeyPress = async (e: { key: string; })=> {
|
|
||||||
if (e.key !== "Enter")
|
|
||||||
return ;
|
|
||||||
try{
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(err){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Backdrop onClick={handleClose}>
|
<Backdrop onClick={handleClose}>
|
||||||
<motion.div
|
<motion.div
|
||||||
@ -246,7 +198,7 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
<p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p>
|
<p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p>
|
||||||
|
|
||||||
|
|
||||||
{password ? (
|
{password || privateConv ? (
|
||||||
<input
|
<input
|
||||||
onChange={(e) => setNewPassword(e.target.value)}
|
onChange={(e) => setNewPassword(e.target.value)}
|
||||||
onKeyDown={handlePassword}
|
onKeyDown={handlePassword}
|
||||||
@ -256,6 +208,7 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
):
|
):
|
||||||
("")}
|
("")}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className="forName">
|
<div className="forName">
|
||||||
<input
|
<input
|
||||||
@ -301,14 +254,7 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
{mute ? (
|
{mute ? (
|
||||||
<input
|
<input type="text" className="in_howLong" placeholder="How long ?" />
|
||||||
onKeyDown={handleMute}
|
|
||||||
type="number"
|
|
||||||
className="in_howLong"
|
|
||||||
placeholder="How long ?"
|
|
||||||
value={time}
|
|
||||||
onChange={(e) => setTime(e.target.value)}
|
|
||||||
/>
|
|
||||||
):("")}
|
):("")}
|
||||||
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import { AnimatePresence, motion } from "framer-motion"
|
import {motion} from "framer-motion"
|
||||||
// import Backdrop from "../Sidebar/Backdrop"
|
// import Backdrop from "../Sidebar/Backdrop"
|
||||||
import { Link } from 'react-router-dom';
|
import {Link} from 'react-router-dom';
|
||||||
// import { UserProfile } from "../../DataBase/DataUserProfile";
|
import { UserProfile } from "../../DataBase/DataUserProfile";
|
||||||
import { useState } from 'react';
|
import {useState} from 'react';
|
||||||
import "../../styles/Profile.css"
|
import "../../styles/Profile.css"
|
||||||
|
|
||||||
import api from '../../script/axiosApi.tsx';
|
import api from '../../script/axiosApi.tsx';
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import RedAlert from "../Alert/RedAlert.tsx";
|
|
||||||
|
|
||||||
const dropIn = {
|
const dropIn = {
|
||||||
hidden: {
|
hidden: {
|
||||||
@ -27,55 +26,37 @@ const dropIn = {
|
|||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const ModalEdit = (handleClose) => {
|
const ModalEdit = ( handleClose ) => {
|
||||||
// let new_name = "";
|
// let new_name = "";
|
||||||
const [nickname, setNickname] = useState("");
|
const [nickname, setNickname] = useState("");
|
||||||
const [errTaken, setErrTaken] = useState(false);
|
|
||||||
const closeTaken = () => setErrTaken(false);
|
|
||||||
const [errTooShort, setErrTooShort] = useState(false);
|
|
||||||
const closeTooShort = () => setErrTooShort(false);
|
|
||||||
|
|
||||||
const handler = e => {
|
const handler = e =>
|
||||||
|
{
|
||||||
setNickname(e.target.value);
|
setNickname(e.target.value);
|
||||||
console.log("testeeeee")
|
console.log("testeeeee")
|
||||||
const postNickname = async () => {
|
const postNickname = async ()=>{
|
||||||
// try{
|
try{
|
||||||
// await api.post("/nickname", {nickname: nickname})
|
await api.post("/nickname", {nickname: nickname})
|
||||||
// // setUser(tmpUser.data);
|
// setUser(tmpUser.data);
|
||||||
// // setIsLoading(false)
|
// setIsLoading(false)
|
||||||
// }
|
}
|
||||||
// catch(err){
|
catch(err){
|
||||||
// console.log(err);
|
console.log(err);
|
||||||
// }
|
}
|
||||||
};
|
};
|
||||||
postNickname();
|
postNickname();
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePostNickname = async () => {
|
const handlePostNickname = async () =>
|
||||||
console.log("nickname=", nickname)
|
{
|
||||||
try {
|
console.log("nickname=" ,nickname)
|
||||||
const ret = await api.post("/nickname", { nickname: nickname });
|
try{
|
||||||
// console.log("cest ici = ",ret);
|
await api.post("/nickname", {nickname: nickname})
|
||||||
// if (!ret)
|
|
||||||
console.log("test ret =", ret.data);
|
|
||||||
if (nickname.length < 3) {
|
|
||||||
setErrTooShort(true);
|
|
||||||
}
|
|
||||||
else if (ret.data) {
|
|
||||||
console.log("ici error = ", ret.data);
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log("nickname already set = ", ret.data);
|
|
||||||
|
|
||||||
setErrTaken(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// setUser(tmpUser.data);
|
// setUser(tmpUser.data);
|
||||||
// setIsLoading(false)
|
// setIsLoading(false)
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch(err){
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,27 +73,16 @@ const ModalEdit = (handleClose) => {
|
|||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit">
|
exit="exit">
|
||||||
<h2>Type your new name</h2>
|
<h2>Type your new name</h2>
|
||||||
<input className="text" minLength={2} maxLength={10} type="text" value={nickname} onChange={handler} />
|
<input className="text" maxLength="10" type="text" value={nickname} onChange={handler} handleClose/>
|
||||||
<div>
|
<div>
|
||||||
<div className="button" onClick={handlePostNickname}>
|
<div className="button" onClick={ () => handlePostNickname()}>
|
||||||
change
|
change
|
||||||
{/* <Link className="button" to={""}>change</Link> */}
|
{/* <Link className="button" to={""}>change</Link> */}
|
||||||
</div>
|
</div>
|
||||||
<AnimatePresence initial={false} onExitComplete={() => null}>
|
|
||||||
{
|
|
||||||
errTaken ? (
|
|
||||||
<RedAlert handleClose={closeTaken} text="Error: Nickname already taken" />
|
|
||||||
) : ("")
|
|
||||||
}
|
|
||||||
{
|
|
||||||
errTooShort ? (
|
|
||||||
<RedAlert handleClose={closeTooShort} text="Error: Nickname it too short" />
|
|
||||||
) : ("")
|
|
||||||
}
|
|
||||||
|
|
||||||
</AnimatePresence>
|
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,7 @@ function WinLoss() {
|
|||||||
// <span>Loading...</span>
|
// <span>Loading...</span>
|
||||||
) : (
|
) : (
|
||||||
<div className='scroll'>
|
<div className='scroll'>
|
||||||
<h2 className='title'>Match history {user.win}/{user.loss}</h2>
|
<h2 className='title'>Match history Win/Loss</h2>
|
||||||
{history.map((c: Matchlog, index) => {
|
{history.map((c: Matchlog, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={index} className='elements'>
|
<div key={index} className='elements'>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/09 08:18:58 by apommier #+# #+# */
|
/* Created: 2023/06/09 08:18:58 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/23 17:12:07 by apommier ### ########.fr */
|
/* Updated: 2023/06/20 13:41:44 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -59,8 +59,9 @@ export default function Friend({currentUser}: UserProps)
|
|||||||
console.error('Error fetching profile picture:', error);
|
console.error('Error fetching profile picture:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
}, []);
|
})
|
||||||
|
|
||||||
function getStatus(friend: User)
|
function getStatus(friend: User)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,10 +3,10 @@
|
|||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* Home.tsx :+: :+: :+: */
|
/* Home.tsx :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: sadjigui <sadjigui@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/09 08:19:04 by apommier #+# #+# */
|
/* Created: 2023/06/09 08:19:04 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/24 20:16:28 by sadjigui ### ########.fr */
|
/* Updated: 2023/06/23 15:58:14 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ import { motion, AnimatePresence } from 'framer-motion'
|
|||||||
// import { GrClose } from 'react-icons/gr'
|
// import { GrClose } from 'react-icons/gr'
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import ModalEdit from "../components/Profile/EditName.tsx";
|
import ModalEdit from "../components/Profile/EditName.tsx";
|
||||||
import {AiOutlineCloseCircle, AiOutlineHistory} from 'react-icons/ai'
|
import {AiOutlineHistory} from 'react-icons/ai'
|
||||||
import { MdQrCodeScanner, MdOutlinePhotoLibrary } from 'react-icons/md';
|
import { MdQrCodeScanner, MdOutlinePhotoLibrary } from 'react-icons/md';
|
||||||
import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi';
|
import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi';
|
||||||
|
|
||||||
@ -82,13 +82,43 @@ function Profile () {
|
|||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// const handleUpload = async () => {
|
||||||
|
// const formData = new FormData();
|
||||||
|
// formData.append('photo', selectedPhoto);
|
||||||
|
// try {
|
||||||
|
// await api.post('/picture', formData);
|
||||||
|
// console.log('File uploaded successfully');
|
||||||
|
// window.location.reload();
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Error uploading file:', error);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleUpload = async (event: React.FormEvent) => {
|
||||||
|
// event.preventDefault()
|
||||||
|
// console.log("up photo")
|
||||||
|
// if (selectedPhoto) {
|
||||||
|
// console.log("selected photo")
|
||||||
|
// const formData = new FormData();
|
||||||
|
// formData.append('photo', selectedPhoto);
|
||||||
|
// try {
|
||||||
|
// await api.post('/picture', formData);
|
||||||
|
// console.log('File uploaded successfully');
|
||||||
|
// window.location.reload();
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Error uploading file:', error);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// console.log('No file selected');
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
const getUser = async ()=>{
|
const getUser = async ()=>{
|
||||||
console.log(`username= ${username}`)
|
console.log(`username= ${username}`)
|
||||||
// const pic
|
// const pic
|
||||||
let pic;
|
let pic
|
||||||
try{
|
try{
|
||||||
console.log("before request")
|
|
||||||
const me = await api.get("/profile")
|
const me = await api.get("/profile")
|
||||||
if (!username)
|
if (!username)
|
||||||
{
|
{
|
||||||
@ -130,7 +160,7 @@ function Profile () {
|
|||||||
{isLoading || !user ? (
|
{isLoading || !user ? (
|
||||||
<h1>Loading...</h1>
|
<h1>Loading...</h1>
|
||||||
) : (
|
) : (
|
||||||
<h1 className='user_name'>{user.nickname}</h1>
|
<h1>{user.nickname}</h1>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@ -172,7 +202,7 @@ function Profile () {
|
|||||||
|
|
||||||
function Home () {
|
function Home () {
|
||||||
const [move, setmove ] = useState(false);
|
const [move, setmove ] = useState(false);
|
||||||
const [user, setUser] = useState<User>();
|
const [user, setUser] = useState([]);
|
||||||
|
|
||||||
const [successQr, setSuccessQr] = useState(false);
|
const [successQr, setSuccessQr] = useState(false);
|
||||||
const [successSword, setSuccessSword] = useState(false);
|
const [successSword, setSuccessSword] = useState(false);
|
||||||
@ -181,31 +211,20 @@ function Home () {
|
|||||||
const closeSword = () => setSuccessSword(false);
|
const closeSword = () => setSuccessSword(false);
|
||||||
const closeCrown = () => setSuccessCrown(false);
|
const closeCrown = () => setSuccessCrown(false);
|
||||||
|
|
||||||
const { username } = useParams();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchSuccess = async () => {
|
const fetchSuccess = async () => {
|
||||||
try {
|
try {
|
||||||
if (!username)
|
|
||||||
{
|
|
||||||
const tmpUser = await api.get("/profile");
|
const tmpUser = await api.get("/profile");
|
||||||
setUser(tmpUser.data);
|
setUser(tmpUser.data);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
const tmpUser = await api.post("/user", {username: username});
|
|
||||||
setUser(tmpUser.data);
|
|
||||||
}
|
|
||||||
// const tmpUser = await api.get("/profile");
|
|
||||||
// setUser(tmpUser.data);
|
|
||||||
}
|
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fetchSuccess();
|
fetchSuccess();
|
||||||
}, []);
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.div className="page"
|
<motion.div className="page"
|
||||||
@ -213,20 +232,20 @@ function Home () {
|
|||||||
animate={{opacity: 1}}
|
animate={{opacity: 1}}
|
||||||
exit={{opacity: -1}}>
|
exit={{opacity: -1}}>
|
||||||
<div>
|
<div>
|
||||||
{user && user.otp_verified ? (
|
{user.otp_verified ? (
|
||||||
<MdQrCodeScanner className='success' onClick={() => setSuccessQr(true)}/>
|
<MdQrCodeScanner className='success' onClick={() => setSuccessQr(true)}/>
|
||||||
):("")}
|
):("")}
|
||||||
{user && user.win >= 2 ? (
|
{user.win >= 2 ? (
|
||||||
<GiWingedSword className="success" onClick={() => setSuccessSword(true)}/>
|
<GiWingedSword className="success" onClick={() => setSuccessSword(true)}/>
|
||||||
):("")}
|
):("")}
|
||||||
{user && user.win >= 5 ? (
|
|
||||||
|
{user.win >= 5 ? (
|
||||||
<GiCrownedSkull className="success" onClick={() => setSuccessCrown(true)}/>
|
<GiCrownedSkull className="success" onClick={() => setSuccessCrown(true)}/>
|
||||||
):("")}
|
):("")}
|
||||||
</div>
|
</div>
|
||||||
<div className="home">
|
<div className="home">
|
||||||
<motion.div animate={{x: move ? -200: 120}}
|
<motion.div animate={{x: move ? -200: 120}}
|
||||||
transition={{type: "tween", duration: 0.5, position: "fixed",}}
|
transition={{type: "tween", duration: 0.5}}>
|
||||||
>
|
|
||||||
<Profile/>
|
<Profile/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<motion.div animate={{opacity: !move ? -1 : 1}}>
|
<motion.div animate={{opacity: !move ? -1 : 1}}>
|
||||||
@ -237,7 +256,7 @@ function Home () {
|
|||||||
className="div_history"
|
className="div_history"
|
||||||
// className="history"
|
// className="history"
|
||||||
onClick={ () => setmove(!move)}>
|
onClick={ () => setmove(!move)}>
|
||||||
<Link to="#" className="history"> {move ? (<AiOutlineCloseCircle/>):(<AiOutlineHistory/>)} Match History</Link>
|
<Link to="#" className="history"><AiOutlineHistory/> Match History</Link>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<AnimatePresence initial={false} onExitComplete={() => null}>
|
<AnimatePresence initial={false} onExitComplete={() => null}>
|
||||||
{successQr ? (
|
{successQr ? (
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import "../styles/App.css";
|
|||||||
import api from '../script/axiosApi.tsx';
|
import api from '../script/axiosApi.tsx';
|
||||||
|
|
||||||
import QRCodeStyling from "qr-code-styling";
|
import QRCodeStyling from "qr-code-styling";
|
||||||
import { motion , AnimatePresence} from 'framer-motion'
|
import { motion } from 'framer-motion'
|
||||||
import RedAlert from "../components/Alert/RedAlert.tsx";
|
|
||||||
|
|
||||||
|
|
||||||
const qrCode = new QRCodeStyling({
|
const qrCode = new QRCodeStyling({
|
||||||
@ -25,9 +25,9 @@ const qrCode = new QRCodeStyling({
|
|||||||
crossOrigin: "anonymous",
|
crossOrigin: "anonymous",
|
||||||
margin: 20
|
margin: 20
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function QrCode() {
|
function QrCode () {
|
||||||
// const url = "https://www.youtube.com";
|
// const url = "https://www.youtube.com";
|
||||||
// const ref = useRef(null);
|
// const ref = useRef(null);
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
@ -42,13 +42,14 @@ function QrCode() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ref.current)
|
if (ref.current)
|
||||||
qrCode.append(ref.current);
|
qrCode.append(ref.current);
|
||||||
const getUser = async () => {
|
const getUser = async ()=>{
|
||||||
try {
|
try{
|
||||||
const tmpUser = await api.get("/profile");
|
const tmpUser = await api.get("/profile");
|
||||||
setUser(tmpUser.data);
|
setUser(tmpUser.data);
|
||||||
if (tmpUser.data.otp_verified) {
|
if (tmpUser.data.otp_verified)
|
||||||
|
{
|
||||||
setActivated(true);
|
setActivated(true);
|
||||||
return;
|
return ;
|
||||||
}
|
}
|
||||||
const otpData = await api.post("/otp");
|
const otpData = await api.post("/otp");
|
||||||
setUrl(otpData.data.otpauth_url);
|
setUrl(otpData.data.otpauth_url);
|
||||||
@ -57,7 +58,7 @@ function QrCode() {
|
|||||||
// console.log("test")
|
// console.log("test")
|
||||||
// console.table(convs);
|
// console.table(convs);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch(err){
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -66,24 +67,21 @@ function QrCode() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
qrCode.update({ data: url });
|
qrCode.update({data: url});
|
||||||
}, [url]);
|
}, [url]);
|
||||||
|
|
||||||
const [errCode, setErrCode] = useState(false);
|
|
||||||
const closeErr = () => setErrCode(false);
|
const handleKeyPress = async (e: { key: string; })=>{
|
||||||
const handleKeyPress = async (e: { key: string; }) => {
|
|
||||||
// console.log(`e in press= ${e.key}`)
|
// console.log(`e in press= ${e.key}`)
|
||||||
if (e.key !== "Enter")
|
if (e.key !== "Enter")
|
||||||
return;
|
return ;
|
||||||
try {
|
try{
|
||||||
console.log("code= ", code)
|
console.log("code= ", code)
|
||||||
const res = await api.post("/verifyOtp", { token: code })
|
const res = await api.post("/verifyOtp", {token: code})
|
||||||
if (!res.data) {
|
|
||||||
setErrCode(true);
|
|
||||||
}
|
|
||||||
console.log("res= ", res.data)
|
console.log("res= ", res.data)
|
||||||
console.log("res= ", res)
|
console.log("res= ", res)
|
||||||
if (res.data === 1) {
|
if (res.data === 1)
|
||||||
|
{
|
||||||
console.log("registered")
|
console.log("registered")
|
||||||
// history.push('/login')
|
// history.push('/login')
|
||||||
|
|
||||||
@ -92,13 +90,14 @@ function QrCode() {
|
|||||||
window.location.reload();
|
window.location.reload();
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
console.log("bad code")
|
console.log("bad code")
|
||||||
//alert ?? retry
|
//alert ?? retry
|
||||||
}
|
}
|
||||||
// redirect('/test')
|
// redirect('/test')
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch(err){
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +108,7 @@ function QrCode() {
|
|||||||
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
||||||
// window.history.pushState({}, '', path);
|
// window.history.pushState({}, '', path);
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
} catch (err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -143,13 +142,13 @@ function QrCode() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<>
|
<>
|
||||||
{!activated && localStorage.getItem('token') ? (
|
{!activated && localStorage.getItem('token') ? (
|
||||||
<>
|
<>
|
||||||
<h1>Double Auth Validation</h1>
|
<h1>Double Auth Validation</h1>
|
||||||
<input
|
<input
|
||||||
onKeyDown={handleKeyPress}
|
onKeyDown={handleKeyPress}
|
||||||
type="number"
|
type="text"
|
||||||
className="qr"
|
className="qr"
|
||||||
placeholder="6 Digits Code"
|
placeholder="6 Digits Code"
|
||||||
value={code}
|
value={code}
|
||||||
@ -159,13 +158,6 @@ function QrCode() {
|
|||||||
) : (
|
) : (
|
||||||
<button onClick={handleDesactivate}>Desactivate 2FA</button>
|
<button onClick={handleDesactivate}>Desactivate 2FA</button>
|
||||||
)}
|
)}
|
||||||
<AnimatePresence initial={false} onExitComplete={() => null}>
|
|
||||||
{
|
|
||||||
errCode ? (
|
|
||||||
<RedAlert handleClose={closeErr} text="Error: Incorrect Code" />
|
|
||||||
) : ("")
|
|
||||||
}
|
|
||||||
</AnimatePresence>
|
|
||||||
</>
|
</>
|
||||||
|
|
||||||
{/* {!localStorage.getItem('token') && (
|
{/* {!localStorage.getItem('token') && (
|
||||||
|
|||||||
@ -61,7 +61,7 @@ function DrawCanvas(option: number, gameParam: GameProps) {
|
|||||||
if(!ctx)
|
if(!ctx)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
const socket = io('http://' + process.env.REACT_APP_SOCKET_URL + ':4000', { transports: ['polling'] });
|
const socket = io('http://localhost:4000', { transports: ['polling'] });
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// console.log("useeffect?????????????????")
|
// console.log("useeffect?????????????????")
|
||||||
// return () => {
|
// return () => {
|
||||||
@ -170,9 +170,7 @@ socket.on('pong:privateId', async (data) => {
|
|||||||
|
|
||||||
socket.on('pong:gameId', async (data) => {
|
socket.on('pong:gameId', async (data) => {
|
||||||
console.log("gameId received");
|
console.log("gameId received");
|
||||||
gameId = data.gameId;
|
gameId = data;
|
||||||
console.log("gameid = ", gameId);
|
|
||||||
console.log("data gameid = ", data);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let response = await api.get('/profile');
|
let response = await api.get('/profile');
|
||||||
@ -192,16 +190,6 @@ socket.on('pong:gameId', async (data) => {
|
|||||||
|
|
||||||
console.log("emit to name");
|
console.log("emit to name");
|
||||||
socket.emit('pong:name', info);
|
socket.emit('pong:name', info);
|
||||||
if (data.id === myId)
|
|
||||||
{
|
|
||||||
console.log("myId= true")
|
|
||||||
vX = 0.0001;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
console.log("myId= false")
|
|
||||||
vX = -0.0001;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
// Handle error here
|
// Handle error here
|
||||||
@ -210,11 +198,7 @@ socket.on('pong:gameId', async (data) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
socket.on('pong:name', (data) => {
|
socket.on('pong:name', (data) => {
|
||||||
opName = data.name;
|
opName = data;
|
||||||
// if (data.myId === myId)
|
|
||||||
// vX = 0.0001;
|
|
||||||
// else
|
|
||||||
// vX = -0.0001;
|
|
||||||
console.log(`opponent Name= ${opName}`)
|
console.log(`opponent Name= ${opName}`)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -238,6 +222,7 @@ socket.on('pong:info', (data) => {
|
|||||||
vY = data.vY;
|
vY = data.vY;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
socket.on('pong:paddle', (data) => {
|
socket.on('pong:paddle', (data) => {
|
||||||
console.log("paddle info receive")
|
console.log("paddle info receive")
|
||||||
oPaddleY = (data.paddleY / data.height) * canvas.height
|
oPaddleY = (data.paddleY / data.height) * canvas.height
|
||||||
@ -266,27 +251,12 @@ socket.on('pong:point', (data) => {
|
|||||||
// console.log("up point");
|
// console.log("up point");
|
||||||
myScore = data.point;
|
myScore = data.point;
|
||||||
// }
|
// }
|
||||||
vX = -0.0001;
|
vX = 0;
|
||||||
vY = 0;
|
vY = 0;
|
||||||
ballX = canvas.width / 2;
|
ballX = canvas.width / 2;
|
||||||
ballY = canvas.height / 2;
|
ballY = canvas.height / 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('pong:hisPoint', (data) => {
|
|
||||||
// hisScore += 1;
|
|
||||||
console.log("myPointawdawdawdawd point");
|
|
||||||
// if (vX != 0)
|
|
||||||
// {
|
|
||||||
// console.log("up point");
|
|
||||||
hisScore = data.point;
|
|
||||||
// }
|
|
||||||
vX = -0.0001;
|
|
||||||
vY = 0;
|
|
||||||
ballX = canvas.width / 2;
|
|
||||||
ballY = canvas.height / 2;
|
|
||||||
// send_forced_info();
|
|
||||||
});
|
|
||||||
|
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
// Socket EMIT
|
// Socket EMIT
|
||||||
@ -353,26 +323,6 @@ socket.on('pong:hisPoint', (data) => {
|
|||||||
point: hisScore,
|
point: hisScore,
|
||||||
}
|
}
|
||||||
socket.emit('pong:point', info);
|
socket.emit('pong:point', info);
|
||||||
vX = 0.0001;
|
|
||||||
}
|
|
||||||
|
|
||||||
function send_my_point()
|
|
||||||
{
|
|
||||||
if (!gameId || !canvas)
|
|
||||||
return ;
|
|
||||||
// console.log("send point");
|
|
||||||
const info = {
|
|
||||||
id: myId,
|
|
||||||
gameId: gameId,
|
|
||||||
point: myScore,
|
|
||||||
}
|
|
||||||
socket.emit('pong:myPoint', info);
|
|
||||||
myScore++;
|
|
||||||
vX = 0.0001;
|
|
||||||
vY = 0;
|
|
||||||
ballX = canvas.width / 2;
|
|
||||||
ballY = canvas.height / 2;
|
|
||||||
send_forced_info();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_paddle_info()
|
function send_paddle_info()
|
||||||
@ -509,10 +459,7 @@ async function draw(timestamp: number)
|
|||||||
{
|
{
|
||||||
console.log("turning, running= ", running);
|
console.log("turning, running= ", running);
|
||||||
if (!running)
|
if (!running)
|
||||||
{
|
|
||||||
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong")
|
|
||||||
return ;
|
return ;
|
||||||
}
|
|
||||||
if (!gameId || !canvas )
|
if (!gameId || !canvas )
|
||||||
{
|
{
|
||||||
// console.log("nogameid score= ", myScore);
|
// console.log("nogameid score= ", myScore);
|
||||||
@ -646,17 +593,16 @@ async function draw(timestamp: number)
|
|||||||
}
|
}
|
||||||
ballX = canvas.width / 2;
|
ballX = canvas.width / 2;
|
||||||
ballY = canvas.height / 2;
|
ballY = canvas.height / 2;
|
||||||
vX = 0.0001;
|
vX = 0;
|
||||||
vY = 0;
|
vY = 0;
|
||||||
hisScore += 1;
|
hisScore += 1;
|
||||||
send_point();
|
send_point();
|
||||||
// send_forced_info();
|
// send_forced_info();
|
||||||
}
|
}
|
||||||
if (ballX > (canvas.width * 1.2) && ballX - vX > canvas.width)
|
if (ballX > canvas.width)
|
||||||
{
|
{
|
||||||
console.log("ball out win point pls")
|
|
||||||
send_my_point();
|
|
||||||
// if (ballX > canvas.width * 2)
|
// if (ballX > canvas.width * 2)
|
||||||
|
// socket.emit
|
||||||
// console.log("win point")
|
// console.log("win point")
|
||||||
// if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
|
// if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
|
||||||
// {
|
// {
|
||||||
@ -756,8 +702,9 @@ async function draw(timestamp: number)
|
|||||||
vX -= 0.0001;
|
vX -= 0.0001;
|
||||||
}
|
}
|
||||||
send_forced_info();
|
send_forced_info();
|
||||||
|
// console.log(`vx = ${vX}`);
|
||||||
}
|
}
|
||||||
else if (event.code === "KeyW")
|
else if (event.code === "KeyR")
|
||||||
{
|
{
|
||||||
if (!superpowerModifier)
|
if (!superpowerModifier)
|
||||||
return ;
|
return ;
|
||||||
@ -770,13 +717,6 @@ async function draw(timestamp: number)
|
|||||||
paddleY = canvas.height / 2 - paddleHeight / 2;
|
paddleY = canvas.height / 2 - paddleHeight / 2;
|
||||||
console.log('Cinq secondes se sont écoulées.');
|
console.log('Cinq secondes se sont écoulées.');
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
// setTimeout(() => {
|
|
||||||
// // code à exécuter après 5 secondes
|
|
||||||
// paddleHeight = canvas.height * 0.25;
|
|
||||||
// paddleY = canvas.height / 2 - paddleHeight / 2;
|
|
||||||
// console.log('Cinq secondes se sont écoulées.');
|
|
||||||
// }, 5000);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -3,15 +3,12 @@ import { useState, useEffect } from 'react'
|
|||||||
import queryString from 'query-string';
|
import queryString from 'query-string';
|
||||||
import api from "./axiosApi.tsx";
|
import api from "./axiosApi.tsx";
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import {Matchlog, User} from "../../interfaces.tsx"
|
|
||||||
|
|
||||||
function SuccessToken() {
|
function SuccessToken() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { data } = queryString.parse(location.search);
|
const { data } = queryString.parse(location.search);
|
||||||
const [code, setCode] = useState('');
|
const [code, setCode] = useState('');
|
||||||
const [user, setUser] = useState<User>();
|
const [user, setUser] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
@ -40,7 +37,7 @@ function SuccessToken() {
|
|||||||
getUser();
|
getUser();
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
const handleKeyPress = async (e: { key: string; })=>{
|
const handleKeyPress = async (e)=>{
|
||||||
// console.log(`e in press= ${e.key}`)
|
// console.log(`e in press= ${e.key}`)
|
||||||
if (e.key !== "Enter")
|
if (e.key !== "Enter")
|
||||||
return ;
|
return ;
|
||||||
@ -93,8 +90,7 @@ function SuccessToken() {
|
|||||||
// Render a loading indicator or return null while user is being fetched
|
// Render a loading indicator or return null while user is being fetched
|
||||||
return <h1>Loading...</h1>;
|
return <h1>Loading...</h1>;
|
||||||
}
|
}
|
||||||
if (!data)
|
|
||||||
return ;
|
|
||||||
const cleanData = data.slice(1, -1); // Declare cleanData here as well
|
const cleanData = data.slice(1, -1); // Declare cleanData here as well
|
||||||
|
|
||||||
if (!user.otp_verified) {
|
if (!user.otp_verified) {
|
||||||
|
|||||||
@ -5,13 +5,9 @@
|
|||||||
background-color: black;
|
background-color: black;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
input.qr::-webkit-outer-spin-button,
|
|
||||||
input.qr::-webkit-inner-spin-button {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
input.qr{
|
input.qr{
|
||||||
width: auto;
|
width: 20%;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: rgb(0, 0, 0);
|
background-color: rgb(0, 0, 0);
|
||||||
margin : 1%;
|
margin : 1%;
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
margin: 50px;
|
margin: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.rank_elements {
|
.rank_elements {
|
||||||
border-width:1px;
|
border-width:1px;
|
||||||
border-style:solid;
|
border-style:solid;
|
||||||
@ -19,23 +18,11 @@
|
|||||||
/* background-color: #5843e4; */
|
/* background-color: #5843e4; */
|
||||||
/* border-color: white; */
|
/* border-color: white; */
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
height: 68vh;
|
height: 70vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profilePic{
|
.profilePic{
|
||||||
margin-left: 10px;
|
|
||||||
/* margin-top: 10px; */
|
|
||||||
height: 30px;
|
height: 30px;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 755px){
|
|
||||||
.game{
|
|
||||||
display: grid;
|
|
||||||
height: 20vh;
|
|
||||||
}
|
|
||||||
.scroll{
|
|
||||||
height: 20vh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
.home{
|
.home{
|
||||||
background-color: rgb(0, 0, 0);
|
background-color: rgb(0, 0, 0);
|
||||||
height: 70vh;
|
height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -19,8 +19,7 @@ select{
|
|||||||
border: 0!important;
|
border: 0!important;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
padding: 5px;
|
border-radius: 6px;
|
||||||
border-radius: 1000px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal{
|
.modal{
|
||||||
@ -55,7 +54,6 @@ select{
|
|||||||
height: 74vh;
|
height: 74vh;
|
||||||
width: 30%;
|
width: 30%;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
border-radius: 0px 0px 0px 10px;
|
|
||||||
/* width: 2rem; */
|
/* width: 2rem; */
|
||||||
/* height: 4rem; */
|
/* height: 4rem; */
|
||||||
}
|
}
|
||||||
@ -133,17 +131,16 @@ select{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.messages{
|
.messages{
|
||||||
/* background-color: rgb(26, 26, 26); */
|
background-color: rgb(26, 26, 26);
|
||||||
/* height: calc(100% - 118px); */
|
/* height: calc(100% - 118px); */
|
||||||
width: 70%;
|
width: 70%;
|
||||||
/* height: 300px; */
|
/* height: 300px; */
|
||||||
border-radius: 0px 0px 10px 0px;
|
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input{
|
.input{
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 6vh;
|
height: 50px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color:#060b26;
|
color:#060b26;
|
||||||
border: none;
|
border: none;
|
||||||
@ -205,7 +202,6 @@ p {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight:lighter;
|
font-weight:lighter;
|
||||||
margin: 1%;
|
margin: 1%;
|
||||||
height: 25px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.darkSubmit{
|
.darkSubmit{
|
||||||
@ -233,8 +229,8 @@ p {
|
|||||||
background-color: rgba(0, 0, 0, 0.3);
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
width: 11rem;
|
width: 11rem;
|
||||||
height: 2rem;
|
height: 1.5rem;
|
||||||
margin-top: 1.3rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.greenAlert{
|
.greenAlert{
|
||||||
@ -311,17 +307,11 @@ p {
|
|||||||
/* flex-direction: column; */
|
/* flex-direction: column; */
|
||||||
/* align-items: center; */
|
/* align-items: center; */
|
||||||
background-color: #3e3c61;
|
background-color: #3e3c61;
|
||||||
overflow: scroll;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingFirstPart{
|
.settingFirstPart{
|
||||||
margin-top: 10%;
|
margin-top: 10%;
|
||||||
margin-left: 20%;
|
margin-left: 15%;
|
||||||
}
|
|
||||||
|
|
||||||
.settingFirstPart2{
|
|
||||||
margin-top: 10%;
|
|
||||||
margin-left: 30%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingSecondPart{
|
.settingSecondPart{
|
||||||
@ -334,7 +324,6 @@ p {
|
|||||||
.checkbox{
|
.checkbox{
|
||||||
display:flex;
|
display:flex;
|
||||||
flex-direction:row;
|
flex-direction:row;
|
||||||
margin-left: 60px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input.in{
|
input.in{
|
||||||
@ -342,25 +331,17 @@ input.in{
|
|||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 4px;
|
border-radius: 12px;
|
||||||
width: 70%;
|
width: 70%;
|
||||||
height: 100%;
|
|
||||||
font-weight:100;
|
|
||||||
font-size: 20px;
|
|
||||||
padding: 7px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input.in_howLong{
|
input.in_howLong{
|
||||||
margin-top: 13%;
|
margin-top: 14.5%;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 4px;
|
border-radius: 12px;
|
||||||
width: 10%;
|
width: 15%;
|
||||||
height: 10%;
|
|
||||||
font-weight:100;
|
|
||||||
font-size: 20px;
|
|
||||||
padding: 7px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mdp{
|
.mdp{
|
||||||
@ -370,25 +351,3 @@ input.in_howLong{
|
|||||||
width: 20%;
|
width: 20%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.case{
|
|
||||||
height: auto;
|
|
||||||
width: auto;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.catchat{
|
|
||||||
font-size: 30px;
|
|
||||||
margin-left: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.block{
|
|
||||||
font-size: 23px;
|
|
||||||
margin-left: 12px;
|
|
||||||
margin-top: 0.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inline{
|
|
||||||
|
|
||||||
font-size: 25px;
|
|
||||||
margin-left: 12px;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -62,7 +62,6 @@
|
|||||||
.page {
|
.page {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
/* height: 80vh; */
|
|
||||||
/* height: 50vh; */
|
/* height: 50vh; */
|
||||||
/* width: 50vh; */
|
/* width: 50vh; */
|
||||||
/* background-color: black; */
|
/* background-color: black; */
|
||||||
@ -81,9 +80,9 @@
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: thick;
|
border: thick;
|
||||||
border-color: red;
|
border-color: red;
|
||||||
margin-left: 20px;
|
|
||||||
/* border-image: linear-gradient(90deg, #5843e4, #5a0760); */
|
/* border-image: linear-gradient(90deg, #5843e4, #5a0760); */
|
||||||
|
|
||||||
|
/* margin-top: 20px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.home{
|
.home{
|
||||||
@ -97,11 +96,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.history{
|
.history{
|
||||||
display:inline-block;
|
display: inline-block;
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #5843e4;
|
background-color: #5843e4;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
padding: 1.3% 30%;
|
padding: 14px;
|
||||||
font-size: 1.7rem;
|
font-size: 1.7rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -154,13 +153,6 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user_name{
|
|
||||||
/* background-image: linear-gradient(90deg, #5843e4, #5a0760); */
|
|
||||||
background: -webkit-linear-gradient(60deg, #5843e4, #5a0760);
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
-webkit-text-fill-color: transparent;
|
|
||||||
}
|
|
||||||
/* canvas {
|
/* canvas {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
border: solid 0px #ccc;
|
border: solid 0px #ccc;
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
.playButton {
|
.playButton {
|
||||||
background-image: linear-gradient(90deg, #5843e4, #5a0760);
|
background-image: linear-gradient(90deg, #5843e4, #5a0760);
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
overflow: hidden;
|
||||||
border-radius: 5vh;
|
border-radius: 5vh;
|
||||||
color: white;
|
color: white;
|
||||||
display: block;
|
/* display: block; */
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: 30vh;
|
margin-top: 30vh;
|
||||||
padding: 2vh 5vw;
|
padding: 2vh 4vw;
|
||||||
height: 10vh;
|
height: 10vh;
|
||||||
width: 20vw;
|
width: 20vw;
|
||||||
font-size: 300%;
|
font-size: 250%;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inside_checkbox{
|
|
||||||
height : 70%;
|
|
||||||
width: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
background-color: rgb(249, 249, 249);
|
background-color: rgb(249, 249, 249);
|
||||||
@ -69,18 +69,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.responsive{
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @media screen and (max-width: 350px){
|
|
||||||
.responsive{
|
|
||||||
display:list-item;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
#myCanvas {
|
#myCanvas {
|
||||||
background-color: rgb(124, 47, 47);
|
background-color: rgb(124, 47, 47);
|
||||||
/* position: absolute; */
|
/* position: absolute; */
|
||||||
|
|||||||
@ -14,9 +14,19 @@ services:
|
|||||||
- 8080:8080
|
- 8080:8080
|
||||||
volumes:
|
volumes:
|
||||||
- ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
|
- ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
# volumes:
|
||||||
|
# - "./conf:/etc/nginx/templates/"
|
||||||
|
# ports:
|
||||||
|
# - 80:80
|
||||||
|
# volumes:
|
||||||
|
# - ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
# command: sh -c "envsubst < /etc/nginx/conf.d/default.conf > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
|
||||||
|
# - ./containers/frontend:/var/www/html
|
||||||
networks:
|
networks:
|
||||||
- pongNetwork
|
- pongNetwork
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
react_app:
|
react_app:
|
||||||
image: node:latest
|
image: node:latest
|
||||||
container_name: react_app
|
container_name: react_app
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user