From 46aa945c1c1f0377e949257f9a50a9c57aac8f5d Mon Sep 17 00:00:00 2001 From: "pro.boooooo" Date: Sun, 31 Mar 2024 23:45:25 +0200 Subject: [PATCH] $ --- README.md | 14 +- package-lock.json | 120 +- package.json | 3 + pnpm-lock.yaml | 213 +- src/App.jsx | 14 +- src/api/authentication.js | 43 +- src/api/items.js | 1 + src/api/rooms.js | 28 +- src/api/user.js | 29 +- src/assets/styles/{index.css => index.scss} | 16 +- src/assets/styles/vars.scss | 9 + src/components/AddBtn/AddBtn.scss | 6 +- src/components/NavBar/NavBar.jsx | 80 +- src/components/NavBar/NavBar.scss | 22 +- src/components/Stats/Stats.jsx | 3 + src/components/StylizedBtn/StylizedBtn.jsx | 13 + src/components/StylizedBtn/StylizedBtn.scss | 17 + src/contexts/auth-context.jsx | 149 +- src/layout/Layout.css | 5 - src/main.jsx | 16 +- src/pages/authenticated/login.jsx | 68 +- src/pages/authenticated/register.jsx | 83 +- src/pages/home.jsx | 15 - src/pages/home/home.jsx | 184 ++ src/pages/home/home.scss | 84 + src/pages/index.js | 2 +- src/pages/profile/Profile.jsx | 101 +- src/pages/profile/Profile.scss | 16 +- src/pages/room/Room.jsx | 34 +- src/pages/room/Room.scss | 40 +- src/pages/rooms/Rooms.jsx | 34 +- src/pages/rooms/Rooms.scss | 20 +- src/router.jsx | 17 +- src/services/password.js | 31 + test.json | 2355 ------------------- 35 files changed, 1176 insertions(+), 2709 deletions(-) rename src/assets/styles/{index.css => index.scss} (71%) create mode 100644 src/assets/styles/vars.scss create mode 100644 src/components/Stats/Stats.jsx create mode 100644 src/components/StylizedBtn/StylizedBtn.jsx create mode 100644 src/components/StylizedBtn/StylizedBtn.scss delete mode 100644 src/pages/home.jsx create mode 100644 src/pages/home/home.jsx create mode 100644 src/pages/home/home.scss create mode 100644 src/services/password.js delete mode 100644 test.json diff --git a/README.md b/README.md index 3620307..3d1d432 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,25 @@ # Projet BUT 3 -## Run Locally +## Acces en ligne -### Clone the project +(ici)[https://www.google.com] + +## Demarrer en local + +### Cloner le projet git ```bash git clone https://grond.iut-fbleau.fr/boudjeml/2024_DEV_BUT3.git cd 2024_DEV_BUT3 ``` -### Install dependencies +### Installation des dependences ```bash - pnpm i + pnpm install ``` -### Start the front-end +### Demarrer le front-end ```bash pnpm run dev diff --git a/package-lock.json b/package-lock.json index 395b287..cd10364 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "react": "^18.2.0", "react-cookie": "^7.0.2", "react-dom": "^18.2.0", - "react-router-dom": "^6.21.3" + "react-router-dom": "^6.21.3", + "sass": "^1.72.0" }, "devDependencies": { "@playwright/test": "^1.41.1", @@ -1494,6 +1495,18 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1662,6 +1675,17 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1676,7 +1700,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -1762,6 +1785,40 @@ "node": "*" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -2492,7 +2549,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2587,7 +2643,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -2913,6 +2968,11 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -3025,6 +3085,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -3084,7 +3155,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3132,7 +3202,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -3165,7 +3234,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -3761,6 +3829,14 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npm-run-path": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", @@ -4051,7 +4127,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -4326,6 +4401,17 @@ "react-dom": ">=16.8" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -4562,6 +4648,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sass": { + "version": "1.72.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz", + "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -4694,7 +4796,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4947,7 +5048,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, diff --git a/package.json b/package.json index 3010981..3b9de7e 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,11 @@ "dependencies": { "axios": "^1.6.7", "react": "^18.2.0", + "react-apexcharts": "^1.4.1", + "react-chartjs-2": "^5.2.0", "react-cookie": "^7.0.2", "react-dom": "^18.2.0", + "react-loader-spinner": "^6.1.6", "react-router-dom": "^6.21.3", "sass": "^1.72.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1101d4f..5c197e8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,12 +11,21 @@ dependencies: react: specifier: ^18.2.0 version: 18.2.0 + react-apexcharts: + specifier: ^1.4.1 + version: 1.4.1(apexcharts@3.48.0)(react@18.2.0) + react-chartjs-2: + specifier: ^5.2.0 + version: 5.2.0(chart.js@4.4.2)(react@18.2.0) react-cookie: specifier: ^7.0.2 version: 7.1.0(react@18.2.0) react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + react-loader-spinner: + specifier: ^6.1.6 + version: 6.1.6(react-dom@18.2.0)(react@18.2.0) react-router-dom: specifier: ^6.21.3 version: 6.22.3(react-dom@18.2.0)(react@18.2.0) @@ -111,6 +120,20 @@ packages: regenerator-runtime: 0.14.1 dev: true + /@emotion/is-prop-valid@1.2.1: + resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} + dependencies: + '@emotion/memoize': 0.8.1 + dev: false + + /@emotion/memoize@0.8.1: + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + dev: false + + /@emotion/unitless@0.8.0: + resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} + dev: false + /@esbuild/aix-ppc64@0.20.2: resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} engines: {node: '>=12'} @@ -386,6 +409,10 @@ packages: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: true + /@kurkle/color@0.3.2: + resolution: {integrity: sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==} + dev: false + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -725,6 +752,10 @@ packages: /@types/scheduler@0.23.0: resolution: {integrity: sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==} + /@types/stylis@4.2.0: + resolution: {integrity: sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==} + dev: false + /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true @@ -779,6 +810,10 @@ packages: pretty-format: 29.7.0 dev: true + /@yr/monotone-cubic-spline@1.0.3: + resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==} + dev: false + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -853,6 +888,18 @@ packages: normalize-path: 3.0.0 picomatch: 2.3.1 + /apexcharts@3.48.0: + resolution: {integrity: sha512-Lhpj1Ij6lKlrUke8gf+P+SE6uGUn+Pe1TnCJ+zqrY0YMvbqM3LMb1lY+eybbTczUyk0RmMZomlTa2NgX2EUs4Q==} + dependencies: + '@yr/monotone-cubic-spline': 1.0.3 + svg.draggable.js: 2.2.2 + svg.easing.js: 2.0.0 + svg.filter.js: 2.0.2 + svg.pathmorphing.js: 0.1.3 + svg.resize.js: 1.4.3 + svg.select.js: 3.0.1 + dev: false + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true @@ -1015,6 +1062,10 @@ packages: engines: {node: '>=6'} dev: true + /camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + dev: false + /chai@4.4.1: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} engines: {node: '>=4'} @@ -1050,6 +1101,13 @@ packages: engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: true + /chart.js@4.4.2: + resolution: {integrity: sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==} + engines: {pnpm: '>=8'} + dependencies: + '@kurkle/color': 0.3.2 + dev: false + /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: @@ -1140,6 +1198,23 @@ packages: which: 2.0.2 dev: true + /css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + dev: false + + /css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + dev: false + + /csstype@3.1.2: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + dev: false + /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -2324,7 +2399,6 @@ packages: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -2344,7 +2418,6 @@ packages: /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - dev: true /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} @@ -2504,7 +2577,6 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -2545,6 +2617,19 @@ packages: engines: {node: '>= 0.4'} dev: true + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: false + + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: false + /postcss@8.4.38: resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} @@ -2589,7 +2674,6 @@ packages: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - dev: true /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -2604,6 +2688,27 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /react-apexcharts@1.4.1(apexcharts@3.48.0)(react@18.2.0): + resolution: {integrity: sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==} + peerDependencies: + apexcharts: ^3.41.0 + react: '>=0.13' + dependencies: + apexcharts: 3.48.0 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /react-chartjs-2@5.2.0(chart.js@4.4.2)(react@18.2.0): + resolution: {integrity: sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==} + peerDependencies: + chart.js: ^4.1.1 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + chart.js: 4.4.2 + react: 18.2.0 + dev: false + /react-cookie@7.1.0(react@18.2.0): resolution: {integrity: sha512-n2+Gt07/xxuShXary+SImk1sw5l7a1UguQOQEN55YewEW5LoA0opbR4nbeo8sY6OYwR37iCFJtqJ0AGEywqAtg==} peerDependencies: @@ -2633,7 +2738,19 @@ packages: /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true + + /react-loader-spinner@6.1.6(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-x5h1Jcit7Qn03MuKlrWcMG9o12cp9SNDVHVJTNRi9TgtGPKcjKiXkou4NRfLAtXaFB3+Z8yZsVzONmPzhv2ErA==} + engines: {node: '>= 12'} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.2.0 + styled-components: 6.1.8(react-dom@18.2.0)(react@18.2.0) + dev: false /react-router-dom@6.22.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==} @@ -2824,6 +2941,10 @@ packages: has-property-descriptors: 1.0.2 dev: true + /shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + dev: false + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2983,6 +3104,30 @@ packages: js-tokens: 8.0.3 dev: true + /styled-components@6.1.8(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==} + engines: {node: '>= 16'} + peerDependencies: + react: '>= 16.8.0' + react-dom: '>= 16.8.0' + dependencies: + '@emotion/is-prop-valid': 1.2.1 + '@emotion/unitless': 0.8.0 + '@types/stylis': 4.2.0 + css-to-react-native: 3.2.0 + csstype: 3.1.2 + postcss: 8.4.31 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + shallowequal: 1.1.0 + stylis: 4.3.1 + tslib: 2.5.0 + dev: false + + /stylis@4.3.1: + resolution: {integrity: sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==} + dev: false + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -3002,6 +3147,60 @@ packages: engines: {node: '>= 0.4'} dev: true + /svg.draggable.js@2.2.2: + resolution: {integrity: sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.easing.js@2.0.0: + resolution: {integrity: sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.filter.js@2.0.2: + resolution: {integrity: sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.js@2.7.1: + resolution: {integrity: sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==} + dev: false + + /svg.pathmorphing.js@0.1.3: + resolution: {integrity: sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.resize.js@1.4.3: + resolution: {integrity: sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + svg.select.js: 2.1.2 + dev: false + + /svg.select.js@2.1.2: + resolution: {integrity: sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.select.js@3.0.1: + resolution: {integrity: sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -3026,6 +3225,10 @@ packages: dependencies: is-number: 7.0.0 + /tslib@2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + dev: false + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} diff --git a/src/App.jsx b/src/App.jsx index 601b8a4..387524d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,12 +4,12 @@ import { Authenticated } from "./components"; import Layout from "./layout/Layout"; import { Router } from "./router"; -const App = () => ( +export default function App() { + return ( - - - + + + -); - -export default App; + ); +} diff --git a/src/api/authentication.js b/src/api/authentication.js index 3577433..ed86046 100644 --- a/src/api/authentication.js +++ b/src/api/authentication.js @@ -1,34 +1,35 @@ import axios from "axios"; export const isLoggedIn = async () => { - try { - const response = await axios.get("/authenticate"); + try { + const response = await axios.get("/authenticate"); - return response.data; - } catch (error) { - return error.response.data; - } + return response.data; + } catch (error) { + return error.response.data; + } }; export const login = async (username, password) => { - try { - const response = await axios.post("/authenticate", { - username, - password, - }); + try { + const response = await axios.post("/authenticate", { + username, + password, + }); - return response.data; - } catch (error) { - return error.response.data; - } + return response.data; + } catch (error) { + window.location.reload(); + return error.response.data; + } }; export const logout = async () => { - try { - const response = await axios.delete("/authenticate"); + try { + const response = await axios.delete("/authenticate"); - return response.data; - } catch (error) { - return error.response.data; - } + return response.data; + } catch (error) { + return error.response.data; + } }; diff --git a/src/api/items.js b/src/api/items.js index c286d39..242ba61 100644 --- a/src/api/items.js +++ b/src/api/items.js @@ -26,6 +26,7 @@ export const updateItem = async (settings) => { formData.append("brand", settings.brand); formData.append("model", settings.model); formData.append("price", settings.price); + formData.append("description", settings.description); formData.append("purchaseDate", settings.purchaseDate); formData.append("link", settings.link); diff --git a/src/api/rooms.js b/src/api/rooms.js index 1875aef..950d0b1 100644 --- a/src/api/rooms.js +++ b/src/api/rooms.js @@ -1,23 +1,33 @@ import axios from "axios"; export const createRoom = async (name) => { - const response = await axios.post("/room", { - name, - }); + const response = await axios.post("/room", { + name, + }); + return response.data; +}; + +export const getState = async () => { + try { + const response = await axios.get("/room/stats"); return response.data; + } catch (err) { + console.error(err); + return null; + } }; export const deleteRoom = async (id) => { - const response = await axios.delete(`/room/${id}`); - return response.data; + const response = await axios.delete(`/room/${id}`); + return response.data; }; export const getRooms = async () => { - const response = await axios.get(`/room`); - return response.data; + const response = await axios.get(`/room`); + return response.data; }; export const getRoom = async (id) => { - const response = await axios.get(`/room/${id}`); - return response.data; + const response = await axios.get(`/room/${id}`); + return response.data; }; diff --git a/src/api/user.js b/src/api/user.js index 5f2b13d..e0a4c62 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -1,5 +1,15 @@ import axios from "axios"; +export const deleteUser = async (userId) => { + try { + const response = await axios.delete(`/user/${userId}`); + return response.data; + } catch (err) { + console.error(err); + return null; + } +}; + export const createUser = async (username, password, confirmation) => { try { const response = await axios.post("/user", { @@ -13,5 +23,20 @@ export const createUser = async (username, password, confirmation) => { } }; -// TODO: REgarde postman -export const updateUser = 0; +export const updateUser = async (settings) => { + try { + console.log("try"); + const formData = new FormData(); + formData.append("_id", settings._id); + formData.append("username", settings.username); + formData.append("password", settings.password); + formData.append("confirmation", settings.confirmation); + formData.append("old_password", settings.old_password); + + const response = await axios.put(`/user/${settings._id}`, formData); + return response.data; + } catch (err) { + console.error(err); + return null; + } +}; diff --git a/src/assets/styles/index.css b/src/assets/styles/index.scss similarity index 71% rename from src/assets/styles/index.css rename to src/assets/styles/index.scss index 74c6818..92c2b81 100644 --- a/src/assets/styles/index.css +++ b/src/assets/styles/index.scss @@ -1,13 +1,13 @@ -body { - height: 100vh; - font-family: Arial, Helvetica, sans-serif; -} +@import "./vars.scss"; * { - a { - color: rgb(123, 106, 156); - font-weight: bold; - } margin: 0; padding: 0; } +body { + a { + color: $primary; + font-weight: bold; + } + font-family: Arial, Helvetica, sans-serif; +} diff --git a/src/assets/styles/vars.scss b/src/assets/styles/vars.scss new file mode 100644 index 0000000..f9188ea --- /dev/null +++ b/src/assets/styles/vars.scss @@ -0,0 +1,9 @@ +$primary: #7b6a9c; +$good_black: #363636; +$black_text: #252525; +$white: #fff; +$black: #000; +$red: #ce5353; +$orange: #f6a439; +$shadow_box_def: rgba(0, 0, 0, 0.1) 0px 4px 12px; +$my_border_rad: 6px; diff --git a/src/components/AddBtn/AddBtn.scss b/src/components/AddBtn/AddBtn.scss index 54c2517..5abc993 100644 --- a/src/components/AddBtn/AddBtn.scss +++ b/src/components/AddBtn/AddBtn.scss @@ -1,3 +1,5 @@ +@import "../../assets/styles/vars.scss"; + .add-btn-container { display: flex; position: fixed; @@ -11,8 +13,8 @@ height: 100%; border-radius: 50px; border: none; - background: rgb(123, 106, 156); - color: white; + background: $primary; + color: $white; font-weight: bold; font-size: 15px; diff --git a/src/components/NavBar/NavBar.jsx b/src/components/NavBar/NavBar.jsx index 3dee69f..1d03595 100644 --- a/src/components/NavBar/NavBar.jsx +++ b/src/components/NavBar/NavBar.jsx @@ -4,47 +4,51 @@ import { logout } from "../../api"; import { Link } from "react-router-dom/"; export default function NavBar() { - const { user } = useAuth(); - console.log(user); + const { user } = useAuth(); - const onLogout = () => { - logout().then((res) => { - if (res === "Ok") { - window.location.reload(); - } - }); - }; + const onLogout = () => { + logout().then((res) => { + if (res === "Ok") { + alert("etes vous sur de vouloir quitter"); + window.location.reload(); + } + }); + }; - return ( - + ); } diff --git a/src/components/NavBar/NavBar.scss b/src/components/NavBar/NavBar.scss index 3fa6965..f028302 100644 --- a/src/components/NavBar/NavBar.scss +++ b/src/components/NavBar/NavBar.scss @@ -1,14 +1,16 @@ +@import "../../assets/styles/vars.scss"; + #nav-container { - background: rgb(123, 106, 156); + background: $primary; padding: 15px; a { font-weight: bold; - color: white; + color: $white; text-decoration: none; &:hover { - border-bottom: 1.5px solid white; + border-bottom: 1.5px solid $white; } } @@ -17,14 +19,26 @@ display: flex; flex-direction: row; flex-wrap: wrap; - color: white; + color: $white; gap: 50px; align-items: center; justify-content: center; padding: 0; .leaf-into { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 2px; + .leaf-btn { + background: $white; + border: none; + padding: 5px; + &:hover { + cursor: pointer; + } } .leaf { diff --git a/src/components/Stats/Stats.jsx b/src/components/Stats/Stats.jsx new file mode 100644 index 0000000..fa98353 --- /dev/null +++ b/src/components/Stats/Stats.jsx @@ -0,0 +1,3 @@ +export default function Stats({ chart = null, datas }) { + return
{chart ? chart : null}
; +} diff --git a/src/components/StylizedBtn/StylizedBtn.jsx b/src/components/StylizedBtn/StylizedBtn.jsx new file mode 100644 index 0000000..00a55fc --- /dev/null +++ b/src/components/StylizedBtn/StylizedBtn.jsx @@ -0,0 +1,13 @@ +import "./StylizedBtn.scss"; + +export default function StylizedBtn({ text, handle, perso_style = null }) { + return ( + + ); +} diff --git a/src/components/StylizedBtn/StylizedBtn.scss b/src/components/StylizedBtn/StylizedBtn.scss new file mode 100644 index 0000000..563c4fb --- /dev/null +++ b/src/components/StylizedBtn/StylizedBtn.scss @@ -0,0 +1,17 @@ +@import "../../assets/styles/vars.scss"; + +.stylized-btn { + background: $primary; + border: none; + padding: 5px; + width: 50px; + color: $white; + font-weight: bold; + height: 30px; + + &:hover { + cursor: pointer; + transform: scale(1.05); + transition: 0.2s; + } +} diff --git a/src/contexts/auth-context.jsx b/src/contexts/auth-context.jsx index f216f03..d716c6b 100644 --- a/src/contexts/auth-context.jsx +++ b/src/contexts/auth-context.jsx @@ -1,100 +1,99 @@ import React, { useEffect, useState } from "react"; import { - createUser as registerApi, - isLoggedIn, - login as loginApi, - logout as logoutApi, + createUser as registerApi, + isLoggedIn, + login as loginApi, + logout as logoutApi, } from "../api"; import { useQuery } from "../hooks"; import { useLocation, useNavigate } from "react-router-dom"; const initState = { - user: undefined, + user: undefined, }; export const AuthenticationContext = React.createContext({ - ...initState, - login: () => {}, - register: () => {}, - logout: () => {}, + ...initState, + login: () => {}, + register: () => {}, + logout: () => {}, }); export const AuthenticationProvider = ({ children }) => { - const navigate = useNavigate(); - const location = useLocation(); - const query = useQuery(); - const [authState, setAuthState] = useState(initState); - const [isLoading, setIsLoading] = useState(true); + const navigate = useNavigate(); + const location = useLocation(); + const query = useQuery(); + const [authState, setAuthState] = useState(initState); + const [isLoading, setIsLoading] = useState(true); - const redirect = () => { - navigate(query.get("redirect_uri") || "/"); - }; + const redirect = () => { + navigate(query.get("redirect_uri") || "/"); + }; - const login = async (email, password) => { - loginApi(email, password) - .then((user) => { - setAuthState({ user }); - redirect(); - }) - .catch(() => { - setAuthState({ user: undefined }); - }); - }; + const login = async (email, password) => { + loginApi(email, password) + .then((user) => { + setAuthState({ user }); + redirect(); + }) + .catch(() => { + console.error("ici ca catch fort"); + setAuthState({ user: undefined }); + }); + }; - const register = async (username, password, confirmation) => { - registerApi(username, password, confirmation).then((user) => { - setAuthState({ user }); - redirect(); - }); - }; + const register = async (username, password, confirmation) => { + registerApi(username, password, confirmation).then((user) => { + setAuthState({ user }); + redirect(); + }); + }; - const logout = () => { - logoutApi().then(() => { - setAuthState(initState); - navigate(`/login`); - }); - }; + const logout = () => { + logoutApi().then(() => { + setAuthState(initState); + navigate(`/login`); + }); + }; - useEffect(() => { - isLoggedIn() - .then((user) => { - if (user === "Unauthorized") throw new Error("Unauthorized"); - setAuthState({ user }); - if (location.pathname === "/login") { - redirect(); - } - }) - .catch(() => { - setAuthState({ user: undefined }); - - if (!location.pathname.match(/^(\/|\/login|\/register)$/)) { - navigate( - `/login?redirect_uri=${encodeURI(location.pathname)}` - ); - } - }) - .finally(() => { - setIsLoading(false); - }); - }, []); - - useEffect(() => { - if (location.pathname === "/logout") { - logout(); + useEffect(() => { + isLoggedIn() + .then((user) => { + if (user === "Unauthorized") throw new Error("Unauthorized"); + setAuthState({ user }); + if (location.pathname === "/login") { + redirect(); } - }, [location]); + }) + .catch(() => { + setAuthState({ user: undefined }); - if (isLoading) { - return

Loading...

; + if (!location.pathname.match(/^(\/|\/login|\/register)$/)) { + navigate(`/login?redirect_uri=${encodeURI(location.pathname)}`); + } + }) + .finally(() => { + setIsLoading(false); + }); + }, []); + + useEffect(() => { + if (location.pathname === "/logout") { + logout(); } + }, [location]); - return ( - - {children} - - ); + if (isLoading) { + return

Loading...

; + } + + return ( + + {children} + + ); }; diff --git a/src/layout/Layout.css b/src/layout/Layout.css index faa80ba..b15e85e 100644 --- a/src/layout/Layout.css +++ b/src/layout/Layout.css @@ -1,9 +1,4 @@ #layout-container { display: flex; flex-direction: column; - height: 100vh; - - main { - height: 100%; - } } diff --git a/src/main.jsx b/src/main.jsx index 5d0bd19..7494e1e 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,7 +1,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App.jsx"; -import "./assets/styles/index.css"; +import "./assets/styles/index.scss"; import { BrowserRouter } from "react-router-dom"; import { CookiesProvider } from "react-cookie"; import setupAxios from "./setupAxios"; @@ -9,11 +9,11 @@ import setupAxios from "./setupAxios"; setupAxios(); ReactDOM.createRoot(document.getElementById("root")).render( - - - - - - - + + + + + + + , ); diff --git a/src/pages/authenticated/login.jsx b/src/pages/authenticated/login.jsx index b24c727..bca0e78 100644 --- a/src/pages/authenticated/login.jsx +++ b/src/pages/authenticated/login.jsx @@ -3,40 +3,44 @@ import React, { useState } from "react"; import { useAuth } from "../../hooks"; export const Login = () => { - const { login } = useAuth(); + const { login } = useAuth(); - const [username, setUsername] = useState(""); - const [password, setPassword] = useState(""); - const [error, setError] = useState(); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(); - const onSubmit = async (e) => { - e.preventDefault(); - const response = await login(username, password); + const onSubmit = async (e) => { + e.preventDefault(); + const response = await login(username, password); - if (response && !response.success) { - setError(response.error); - } - }; + if (response && !response.success) { + console.log("salut"); + setError(response.error); + } + }; - return ( -
-

Login page

- {error &&

{error}

} -
- setUsername(e.target.value)} - /> - setPassword(e.target.value)} - /> - -
-
- ); + return ( +
+

Login page

+ {error &&

{error}

} + +
+ setUsername(e.target.value)} + /> + setPassword(e.target.value)} + /> + +
+
+ ); }; diff --git a/src/pages/authenticated/register.jsx b/src/pages/authenticated/register.jsx index 0846e4f..6e9e48e 100644 --- a/src/pages/authenticated/register.jsx +++ b/src/pages/authenticated/register.jsx @@ -3,48 +3,51 @@ import React, { useState } from "react"; import { useAuth } from "../../hooks"; export const Register = () => { - const { register } = useAuth(); + const { register } = useAuth(); - const [username, setUsername] = useState(""); - const [password, setPassword] = useState(""); - const [confirmation, setConfirmation] = useState(""); - const [error, setError] = useState(); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [confirmation, setConfirmation] = useState(""); + const [error, setError] = useState(); - const onSubmit = async (e) => { - e.preventDefault(); - const response = await register(username, password, confirmation); - console.log(response); + const onSubmit = async (e) => { + e.preventDefault(); + const response = await register(username, password, confirmation); + console.log(response); - if (response && !response.success) { - setError(response.error); - } - }; + if (response && !response.success) { + setError(response.error); + } + }; - return ( -
-

Register page

- {error &&

{error}

} -
- setUsername(e.target.value)} - /> - setPassword(e.target.value)} - /> - setConfirmation(e.target.value)} - /> - -
-
- ); + return ( +
+

Register page

+ {error &&

{error}

} +
+ setUsername(e.target.value)} + /> + setPassword(e.target.value)} + /> + setConfirmation(e.target.value)} + /> + +
+
+ ); }; diff --git a/src/pages/home.jsx b/src/pages/home.jsx deleted file mode 100644 index 057fa9f..0000000 --- a/src/pages/home.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; - -import { useAuth } from "../hooks"; - -export const Home = () => { - const { user } = useAuth(); - console.log(user); - - return ( -
-

Home page

- {user &&

Hello {user.user.username}

} -
- ); -}; diff --git a/src/pages/home/home.jsx b/src/pages/home/home.jsx new file mode 100644 index 0000000..8fae44e --- /dev/null +++ b/src/pages/home/home.jsx @@ -0,0 +1,184 @@ +import React from "react"; +import { useAuth } from "../../hooks"; +import { useEffect } from "react"; +import { getState } from "../../api"; +import { useState } from "react"; +import Chart from "react-apexcharts"; +import "./home.scss"; +import { Link } from "react-router-dom"; +import { MagnifyingGlass } from "react-loader-spinner"; + +export const Home = () => { + const { user } = useAuth(); + const [dataset, setDataset] = useState(null); + const [generalStat, setGeneralStat] = useState(null); + const [roomsStats, setRoomsState] = useState(null); + const [isLoad, setIsLoad] = useState(true); + + useEffect(() => { + getState().then((res) => { + try { + setIsLoad(false); + console.log(res); + setDataset(res); + setupRoomsStats(res.rooms); + setupGlobalStat({ years: res.years, global: res.global }); + } catch (err) { + console.error(err); + } + }); + }, []); + + const setupRoomsStats = (rooms) => { + setRoomsState( + Object.values(rooms).sort((a, b) => b.room_price - a.room_price), + ); + }; + + const setupGlobalStat = (data) => { + const stats = { + options: { + chart: { + id: "", + }, + xaxis: { + categories: [], + }, + stroke: { + curve: "smooth", + }, + }, + series: [ + { + name: "", + type: "line", + data: [], + color: "#7b6a9c", + }, + ], + }; + + for (let i in data.years) { + if (data.years[i] === 0) { + continue; + } + + stats.options.xaxis.categories.push(i); + stats.series[0].data.push(data.years[i]); + } + + const component = ( + + ); + + setGeneralStat(component); + }; + + return ( +
+ {user && ( +
+

Bonjour {user.user.username} !

+
+ )} + + + + {dataset ? ( +
+
+
+

Statistique general

+
+ + {generalStat ? generalStat : null} + +
+
+
Moyenne de vos depenses
+
+ {dataset.global.average_price}e +
+
+ +
+
Nombre total d'objet
+
+ {dataset.global.items_count}e +
+
+ +
+
Nombre de piece
+
{dataset.global.rooms_count}
+
+ +
+
Prix total
+
+ {dataset.global.total_price}e +
+
+ +
+
Piece la plus cher
+
+ {dataset.global.most_expensive_room.name} ( + {dataset.global.most_expensive_room.count}e) +
+
+ +
+
Piece avec le plus d'objet
+
+ {dataset.global.most_item_room.name} ( + {dataset.global.most_item_room.count}). +
+
+ +
+
Piece avec le plus d'objet
+
+ {dataset.global.most_item_room.name} ( + {dataset.global.most_item_room.count}). +
+
+
+
+ +
+
+

Pieces

+
+ +
+ {roomsStats.length >= 1 + ? roomsStats.map((r, i) => ( +
+ - + {r.name} + + + {" "} + contient {r.items_count} objet(s) pour une valeur + total de {r.room_price}e{" "} + +
+ )) + : null} +
+
+
+ ) : null} +
+ ); +}; diff --git a/src/pages/home/home.scss b/src/pages/home/home.scss new file mode 100644 index 0000000..37aa939 --- /dev/null +++ b/src/pages/home/home.scss @@ -0,0 +1,84 @@ +@import "../../assets/styles/vars.scss"; + +#home-container { + width: 100%; + height: 100%; + + #home-title { + #title { + margin-top: 30px; + text-align: center; + } + } + + #stats-container { + margin-top: 50px; + flex-wrap: wrap; + display: flex; + flex-direction: row; + justify-content: space-around; + width: 100%; + gap: 20px; + + .stats { + display: flex; + flex-direction: column; + align-items: center; + + .header { + .header-title { + text-align: center; + } + } + + #rooms-container { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 20px; + max-height: 500px; + overflow: auto; + + .rooms { + border: 1px dashed $good_black; + padding: 10px; + } + } + + #others-container { + display: flex; + flex-direction: column; + height: 100%; + gap: 10px; + + .others { + display: flex; + flex-direction: row; + justify-content: space-between; + border: 1px dashed $good_black; + padding: 10px; + width: 100%; + + .others-label { + display: flex; + align-items: center; + } + + .others-value { + display: flex; + justify-content: center; + align-items: center; + width: 90px; + height: 30px; + transform: rotate(10deg); + background: $primary; + color: $white; + font-weight: bold; + padding: 5px; + text-align: left; + } + } + } + } + } +} diff --git a/src/pages/index.js b/src/pages/index.js index 16dcd34..e465d9e 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -1,2 +1,2 @@ export * from "./authenticated"; -export * from "./home"; +export * from "./home/home"; diff --git a/src/pages/profile/Profile.jsx b/src/pages/profile/Profile.jsx index f7ab9a4..602d654 100644 --- a/src/pages/profile/Profile.jsx +++ b/src/pages/profile/Profile.jsx @@ -1,45 +1,102 @@ import { useAuth } from "../../hooks"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import "./Profile.scss"; +import { updateUser, deleteUser, logout } from "../../api"; +import StylizedBtn from "../../components/StylizedBtn/StylizedBtn"; +import passwordCheck from "../../services/password"; //Bilouuuuuuu94!@@ export default function Profile() { const { user } = useAuth(); const [username, setUsername] = useState(""); - const [oldPUsername, setOldPUsername] = useState(""); - + const [pUsername, setPUsername] = useState(""); const [oldPPassword, setOldPPassword] = useState(""); const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); + useEffect(() => { + if (!user.user.username) { + console.log("pas de login"); + } + }); + const handleUsername = (e) => { setUsername(e.target.value); }; + const handlePUsername = (e) => { + setPUsername(e.target.value); + }; const handlePassword = (e) => { setPassword(e.target.value); }; const handleConfirmPassword = (e) => { setConfirmPassword(e.target.value); }; - const handleOldPUsername = (e) => { - setOldPUsername(e.target.value); - }; const handleOldPPassword = (e) => { setOldPPassword(e.target.value); }; - // TODO: Faire la paire de fonction - const handleSubmitPassword = () => {}; - const handleSubmitUsername = () => {}; + const handleSubmitPassword = () => { + if (!passwordCheck(password, confirmPassword)) { + alert( + "Verifiez que les mdps sont identiques, contiennent au moins un caractere special, font au moins 8 characteres", + ); + return; + } + + updateUser({ + username: user.user.username, + password: password, + confirmation: confirmPassword, + old_password: oldPPassword, + _id: user.user._id, + }).then((res) => { + logout().then((_) => { + window.location.reload(); + }); + console.log(res); + console.log(oldPPassword, password, confirmPassword); + }); + }; + + const handleSubmitUsername = () => { + updateUser({ + username: username, + password: pUsername, + confirmation: pUsername, + old_password: pUsername, + _id: user.user._id, + }).then((res) => { + console.log(res); + console.log(username, pUsername); + }); + }; + + const handleDeleteUser = () => { + deleteUser(user.user._id).then((_) => { + logout().then((res) => { + window.location.reload(); + }); + }); + }; return (
-

+ Heureux de vous voir {user.user.username} ! -

+ - +
@@ -47,46 +104,42 @@ export default function Profile() { - +
Change ton mot de passe - - - - - +
); diff --git a/src/pages/profile/Profile.scss b/src/pages/profile/Profile.scss index 3feb699..2d265e6 100644 --- a/src/pages/profile/Profile.scss +++ b/src/pages/profile/Profile.scss @@ -1,3 +1,5 @@ +@import "../../assets/styles/vars.scss"; + #profile-container { display: flex; flex-direction: column; @@ -7,12 +9,21 @@ margin-top: 15px; #title-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 20px; + #title { } + + .stylized-btn { + } } .profile-modifier-container { - border: 1px dashed rgb(61, 61, 61); + border: 1px dashed $good_black; width: 450px; display: flex; flex-direction: column; @@ -20,13 +31,14 @@ justify-content: space-between; align-items: center; gap: 10px; + border-radius: $my_border_rad; @media (max-width: 770px) { width: 80%; } .profile-modifier-title { - color: rgb(49, 49, 49); + color: $black_text; font-weight: bold; } diff --git a/src/pages/room/Room.jsx b/src/pages/room/Room.jsx index ab5a6f1..4c59051 100644 --- a/src/pages/room/Room.jsx +++ b/src/pages/room/Room.jsx @@ -4,6 +4,7 @@ import { getRoom } from "../../api"; import "./Room.scss"; import AddBtn from "../../components/AddBtn/AddBtn"; import { createItem, deleteItem, updateItem } from "../../api/"; +import StylizedBtn from "../../components/StylizedBtn/StylizedBtn"; export default function Room() { const { id } = useParams(); @@ -14,11 +15,13 @@ export default function Room() { useEffect(() => { getRoom(id).then((res) => { + console.log(res); setData(res); }); }, []); const handleFormUpdateDataChange = (e, name) => { + console.log(e.target.value); const cpy = { ...formUpdateData }; cpy[name] = name === "purchaseDate" @@ -40,7 +43,6 @@ export default function Room() { delete cpy.user; delete cpy.updatedAt; delete cpy.__v; - delete cpy.description; setFormUpdateData(cpy); } @@ -106,6 +108,8 @@ export default function Room() { ) : null} + {isInForm || isInFormUpdate ?
: null} + {data.items && data.items.length > 0 ? (
{data.items.map((e, i) => ( @@ -159,7 +163,7 @@ export default function Room() {
- Montant ➜ {e.price}$ + Montant ➜ {e.price}e
@@ -239,6 +243,13 @@ export default function Room() { type="text" placeholder={formUpdateData.model} /> + { + handleFormUpdateDataChange(e, "description"); + }} + type="text" + placeholder={formUpdateData.description} + /> { handleFormUpdateDataChange(e, "price"); @@ -251,6 +262,9 @@ export default function Room() { handleFormUpdateDataChange(e, "purchaseDate"); }} type="date" + min="1900-01-01" + max="2100-01-01" + value={`${new Date(formUpdateData.purchaseDate).toISOString().split("T")[0].replace(/-/g, "-")}`} /> { @@ -261,12 +275,16 @@ export default function Room() { />
- - + +
diff --git a/src/pages/room/Room.scss b/src/pages/room/Room.scss index 28e6250..77010ad 100644 --- a/src/pages/room/Room.scss +++ b/src/pages/room/Room.scss @@ -1,8 +1,20 @@ +@import "../../assets/styles/vars.scss"; + #room-container { display: flex; flex-direction: column; width: 100%; - height: 100%; + + #blur { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + filter: blur(30px); + background: $primary; + z-index: 99; + } #items-container { margin-top: 20px; @@ -18,7 +30,7 @@ .item-container { padding: 10px; gap: 10px; - border: 1px dashed rgb(54, 54, 54); + border: 1px dashed $good_black; width: 370px; border-radius: 6px; height: 370px; @@ -41,7 +53,7 @@ border: none; &:hover { - background-color: orange; + background-color: $orange; cursor: pointer; } } @@ -53,8 +65,8 @@ border: none; &:hover { - background: red; - color: white; + background: $red; + color: $white; font-weight: bold; cursor: pointer; } @@ -82,12 +94,12 @@ .item-image { width: 200px; - box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px; + box-shadow: $shadow_box_def; } } .item-no-img { - color: red; + color: $red; } .item-description-container { @@ -96,7 +108,7 @@ width: 100%; .item-description { - color: black; + color: $black; font-weight: bold; } } @@ -125,18 +137,21 @@ #form-container, #form-update-container { - border: 1px solid black; + z-index: 9999; + border: 1px solid $black; width: 300px; height: 400px; display: flex; flex-direction: column; position: fixed; + justify-content: center; gap: 20px; padding: 20px; top: 50%; left: 50%; transform: translate(-50%, -50%); - background: white; + border-radius: $my_border_rad; + background: $white; #form-closure-container { position: absolute; @@ -149,11 +164,12 @@ width: 100%; height: 100%; border: none; + border-top-right-radius: $my_border_rad; &:hover { - background: red; + background: $red; cursor: pointer; - color: white; + color: $white; font-weight: bold; } } diff --git a/src/pages/rooms/Rooms.jsx b/src/pages/rooms/Rooms.jsx index b763b66..9c155ce 100644 --- a/src/pages/rooms/Rooms.jsx +++ b/src/pages/rooms/Rooms.jsx @@ -2,14 +2,18 @@ import "./Rooms.scss"; import { useState, useEffect } from "react"; import { createRoom, getRooms, deleteRoom } from "../../api"; import { Link } from "react-router-dom"; +import { MagnifyingGlass } from "react-loader-spinner"; export default function Rooms() { - const [rooms, setRooms] = useState([]); + const [rooms, setRooms] = useState(null); + const [isLoad, setIsLoad] = useState(true); + const [isErr, setIsErr] = useState(false); const onClickCreate = () => { const name = prompt("Nom de la piece ?"); createRoom(name).then((res) => { + setIsErr(false); const values = [...rooms]; values.push(res); setRooms(values); @@ -22,7 +26,7 @@ export default function Rooms() { "non", ); - if (confirmation.toLocaleLowerCase() !== "oui") return; + if (!confirmation || !confirmation.toLocaleLowerCase() !== "oui") return; deleteRoom(id).then((res) => { const values = rooms.filter((e) => e._id !== id); @@ -32,15 +36,18 @@ export default function Rooms() { useEffect(() => { getRooms().then((res) => { + if (res.length === 0) { + setIsLoad(false); + setIsErr(true); + } + setRooms(res); }); }, []); return (
- {rooms.length === 0 ? ( - Aucune piece enregistree - ) : ( + {rooms ? (
{rooms.map((i, j) => (
@@ -75,8 +82,25 @@ export default function Rooms() {
))}
+ ) : ( +
+ +
)} + {isErr && !isLoad ? ( + Vous n'avez pas de piece pour le moment ! + ) : null} +
Creer une nouvelle piece