diff --git a/.env b/.env index aae0c767..6449f712 100644 --- a/.env +++ b/.env @@ -14,22 +14,22 @@ NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" # BASE_URL=http://localhost -BASE_URL=localhost -REACT_APP_BASE_URL=localhost -REDIRECT_URI=http://localhost/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_USER=postgres -POSTGRES_PASSWORD=pass +POSTGRES_PASSWORD=postgres POSTGRES_DATABASE=postgres MODE=DEV #port API_PORT=3000 # REACT_PORT=3000 (current = 8080) -NGINX_PORT=80 +NGINX_PORT=8080 PONG_PORT=4000 CHAT_PORT=4001 POSTGRES_PORT=5432 diff --git a/containers/react/assets.d.ts b/containers/react/assets.d.ts new file mode 100644 index 00000000..cb5e5ab2 --- /dev/null +++ b/containers/react/assets.d.ts @@ -0,0 +1,2 @@ +declare module '*.jpg'; +declare module 'styled-components' \ No newline at end of file diff --git a/containers/react/interfaces.tsx b/containers/react/interfaces.tsx new file mode 100644 index 00000000..1faa97ec --- /dev/null +++ b/containers/react/interfaces.tsx @@ -0,0 +1,48 @@ +export interface User { + id: number; + otp_enabled: boolean; + otp_verified: boolean; + otp_base32: string; + nickname: string; + username: string; + photo: Buffer; + password: string; + win: number; + loss: number; + rank: number; + status: number; + userId: number; + friendRequest: string[]; + partyInvite: Record[]; + friends: string[]; + blocked: string[]; + } + +export interface Conv { + id: number; + members?: string[]; + name: string + group: boolean + private: boolean + banned?: string[]; + muted?: string[]; + admin?: string[]; + owner?: string; + password?: string; + } + +export interface Message { + id: number; + convId: number; + sender: string; + text: string; + createdAt?: Date; + } + +export interface Matchlog { + id: number; + opponent: string; + myScore: number; + opScore: number; + parent: User; + } \ No newline at end of file diff --git a/containers/react/src/assets/110-1104986_download-medal-hd-png-download.png b/containers/react/src/assets/110-1104986_download-medal-hd-png-download.png new file mode 100644 index 00000000..7fa54245 Binary files /dev/null and b/containers/react/src/assets/110-1104986_download-medal-hd-png-download.png differ diff --git a/containers/react/src/assets/81-810382_gold-medal-olympic-medal-bronze-medal-clip-art.png b/containers/react/src/assets/81-810382_gold-medal-olympic-medal-bronze-medal-clip-art.png new file mode 100644 index 00000000..1617c25d Binary files /dev/null and b/containers/react/src/assets/81-810382_gold-medal-olympic-medal-bronze-medal-clip-art.png differ diff --git a/containers/react/src/assets/Silver-Medal-PNG-Image-0986sd.jpg b/containers/react/src/assets/Silver-Medal-PNG-Image-0986sd.jpg new file mode 100644 index 00000000..6ca1316d Binary files /dev/null and b/containers/react/src/assets/Silver-Medal-PNG-Image-0986sd.jpg differ diff --git a/containers/react/src/assets/silver-medal-gold-medal-png-favpng-WmKbe5M1ptvCs0UCUQiCXiHBA.jpg b/containers/react/src/assets/silver-medal-gold-medal-png-favpng-WmKbe5M1ptvCs0UCUQiCXiHBA.jpg new file mode 100644 index 00000000..7bfd217d Binary files /dev/null and b/containers/react/src/assets/silver-medal-gold-medal-png-favpng-WmKbe5M1ptvCs0UCUQiCXiHBA.jpg differ diff --git a/containers/react/src/components/Messages/GameModal.tsx b/containers/react/src/components/Messages/GameModal.tsx new file mode 100644 index 00000000..00a4a542 --- /dev/null +++ b/containers/react/src/components/Messages/GameModal.tsx @@ -0,0 +1,152 @@ +import { motion } from "framer-motion"; +import Backdrop from "../Sidebar/Backdrop.tsx"; +import '../../styles/Messages.css'; +import { useState, useEffect } from "react"; +import api from "../../script/axiosApi.tsx"; +import React from "react"; +import {User} from "../../../interfaces.tsx" +// import { useNavigate } from "react-router-dom"; + +const dropIn = { + hidden: { y: "-100vh", opacity: 0 }, + visible: { + y: "0", + opacity: 1, + transition: { + duration: 0.3, + type: "spring", + damping: 100, + stiffness: 500, + }, + }, + exit: { y: "100vh", opacity: 0 }, +}; + +interface ModalGame { + handleClose: Function, + // convId: string +} + +const GameModal = ({ handleClose }: ModalGame) => { + const [users, setUsers] = useState([]); +// const [user, setUser] = useState(); + const [selectedUser, setSelectedUser] = useState(''); +// const [convs, setConvs] = useState([]); + const [channel, setChannel] = useState(''); + +// const history = useNavigate(); + + useEffect(() => { + const fetchData = async () => { + try { + const tmpUsers = await api.get("/users"); + // const tmpUser = await api.get("/profile"); + // const tmpConvs = await api.get("/convs"); + setUsers(tmpUsers.data); + // setUser(tmpUser.data); + // setConvs(tmpConvs.data); + } catch (err) { + console.log(err); + } + }; + fetchData(); + }, []); + + const handleUserChange = (event: { target: { value: React.SetStateAction; }; }) => { + setSelectedUser(event.target.value); + }; + +// const joinChannel = async () => { +// try { +// await api.post("/join", { convId: channel }); +// } catch (err) { +// console.log(err); +// } +// }; + +// const handleCheckButtonClick = () => { +// // Perform your check action here +// console.log("Checking user:", selectedUser); +// }; + + const handleButtonClick = async () => { + // let path = `play?`; + let path = `http://` + process.env.REACT_APP_BASE_URL + `/pong/play?`; + + + const superpowerCheckbox = document.querySelector('input[value="superpower"]'); + if (superpowerCheckbox && superpowerCheckbox.checked) { + path += 'superpower=true&'; + } + + const obstacleCheckbox = document.querySelector('input[value="obstacle"]'); + if (obstacleCheckbox && obstacleCheckbox.checked) { + path += 'obstacle=true&'; + } + + const speedCheckbox = document.querySelector('input[value="speed"]'); + if (speedCheckbox && speedCheckbox.checked) { + path += 'speed=true&'; + } + + if (selectedUser.length > 0) + path += 'username=' + selectedUser;//important here + + // Remove the trailing '&' character + // path = path.slice(0, -1); + // console.log(path) + + // await api.post("/partyInvite", {username: selectedUser, gameId}) + + // console.log("path= ", path) + // history(path, { replace: true }); + // window.location.replace(path); + window.history.pushState({}, '', path); + window.location.reload(); + + // history(path); + }; + + return ( + + e.stopPropagation()} + className="modal" + // variant={dropIn} + initial="hidden" + animate="visible" + exit="exit" + > +
+ +
+ +
+ {/* */} +
+

Super Power

+

Obstacle

+

Faster and Faster

+
+ + {/* */} +
+ + {/*
+ +
*/} +
+
+ ); +}; + +export default GameModal; diff --git a/containers/react/src/components/Messages/PartyInvite.tsx b/containers/react/src/components/Messages/PartyInvite.tsx new file mode 100644 index 00000000..791d632b --- /dev/null +++ b/containers/react/src/components/Messages/PartyInvite.tsx @@ -0,0 +1,138 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* PartyInvite.tsx :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: apommier +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/06/19 16:44:29 by apommier #+# #+# */ +/* Updated: 2023/06/20 23:53:01 by apommier ### ########.fr */ +/* */ +/* ************************************************************************** */ + + +import { useEffect, useState } from "react"; +import api from '../../script/axiosApi.tsx'; +import DefaultPicture from '../../assets/profile.jpg' +import styled from "styled-components"; + +import {User} from "../../../interfaces.tsx" +import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx"; +import React from "react"; + +const UserChat = styled.div ` + padding: 5px; + display: flex; + align-items: center; + gap: 5px; + color: white; + cursor: pointer; + + &:hover{ + background-color: #3e3c61; + } +` + +const SideP = styled.p` + font-size: 14px; + color: lightgray; + margin-left: 15px; +` + +interface InviteProps { + username: string, + gameId: string + } + +interface UserProps { + currentInvite: {username: string, gameId: string} + } + +export default function PartyInvite({currentInvite}: UserProps) +{ + const [profilePicture, setProfilePicture] = useState(''); + const [request, setRequest] = useState(); //user who invite + const [clickEvent, setClickEvent] = useState(false); + // const [user, setUser] = useState(null); + + useEffect(() => { + const fetchProfilePicture = async () => { + try { + // const user = await api.get("/profile");\ + // const tmpUser = await api.get("/profile") + const pic = await api.post("/getPicture", {username: currentInvite.username}) + const tmpRequest = await api.post("/user", {username: currentInvite.username}) + // setUser(tmpUser.data); + setRequest(tmpRequest.data); + // console.log(`user naem profile pic222= ${currentInvite.username}`) + // console.log(` profile pic222= ${pic.data}`) + setProfilePicture(pic.data); + } catch (error) { + console.error('Error fetching profile picture:', error); + } + }; + + fetchProfilePicture(); + }, [clickEvent]) + + const handleButtonClick = (user: InviteProps) => { + let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`; + // history(path, { replace: true }); + // window.location.replace(path); + window.history.pushState({}, '', path); + window.location.reload(); + }; + + const Accept = async (request: User) => { + try{ + //call canvas ?? + // await api.post("/friend", {username: request.username}) + await api.post("/deleteInvite", {username: request.username}) + let path = `http://` + process.env.REACT_APP_BASE_URL + `/pong/play?` + path += 'username=' + request.username; + path += '&gameId=' + currentInvite.gameId; + // setClickEvent(true); + window.history.pushState({}, '', path); + window.location.reload(); + } catch(err) { + console.log(err); + } + console.log("accept") + console.log(`request = ${request}`) + } + + const Refuse = async (request: User) => { + try{ + await api.post("/deleteInvite", {username: request.username}) + // await api.post("/refuseInvite", {username: request.username}) + setClickEvent(true); + } catch(err) { + console.log(err); + } + console.log("refuse") + console.log(`request = ${request}`) + } + + // Vérifier si le contenu doit être caché + if (clickEvent) { + console.log("retrun true") + return null; // Rendre null pour ne pas afficher le contenu + } + + return ( + + {profilePicture ? ( + + ) : ( + Default Profile Picture + )} + {request ? ( +
+ handleButtonClick(currentInvite)}>{request.nickname} + Accept(request)} color={'green'}/> + Refuse(request)} color={'red'}/> +
+ ) : ( "" )} +
+ ) +} \ No newline at end of file diff --git a/containers/react/tsconfig.json b/containers/react/tsconfig.json new file mode 100644 index 00000000..bd4507fe --- /dev/null +++ b/containers/react/tsconfig.json @@ -0,0 +1,111 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + "jsx": "react", + "noEmit": true, + "allowImportingTsExtensions": true, + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +}