From 15871986a5f6c573489cb39ca9b3115020aa50df Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Tue, 19 Dec 2023 13:34:39 +0100
Subject: [PATCH 01/13] modification de la table party
---
backend/database/schema.sql | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/backend/database/schema.sql b/backend/database/schema.sql
index 8e2bb5e..5ddb256 100644
--- a/backend/database/schema.sql
+++ b/backend/database/schema.sql
@@ -20,8 +20,8 @@ CREATE TABLE
bio VARCHAR(350),
avatar VARCHAR(255),
alt VARCHAR(100),
- player_id_ref INT NOT NULL,
- FOREIGN KEY (player_id_ref) REFERENCES player(id)
+ player_id INT NOT NULL,
+ FOREIGN KEY (player_id) REFERENCES player(id)
);
CREATE TABLE
@@ -41,8 +41,6 @@ CREATE TABLE
start_time TIMESTAMP,
end_time TIMESTAMP,
is_won BOOLEAN,
- player_id_ref INT NOT NULL,
- game_id_ref INT NOT NULL,
- FOREIGN KEY (player_id_ref) REFERENCES player(id),
- FOREIGN KEY (game_id_ref) REFERENCES game(id)
+ FOREIGN KEY (player_id) REFERENCES player(id),
+ FOREIGN KEY (game_id) REFERENCES game(id)
);
\ No newline at end of file
From 42195c7dbd52aea9b8a2c867c3f69a18222c14b8 Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Tue, 19 Dec 2023 13:35:45 +0100
Subject: [PATCH 02/13] ajout de fake data dans toutes les tables
---
backend/seed.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/backend/seed.js b/backend/seed.js
index 97312dd..99fb0ed 100644
--- a/backend/seed.js
+++ b/backend/seed.js
@@ -32,7 +32,7 @@ const seed = async () => {
);
}
- for (let i = 0; i < 5; i += 1) {
+ for (let i = 0; i <= 15; i += 1) {
queries.push(
database.query(
"insert into player(role_id,username, email, password) values (?,?,?,?)",
@@ -45,6 +45,73 @@ const seed = async () => {
)
);
}
+ for (let i = 0; i < 1; i += 1) {
+ queries.push(
+ database.query(
+ "insert into game(name,alt,description,image) values (?,?,?,?)",
+ [
+ "tic-tac-toe",
+ "tic-tac-toe",
+ "Deux joueurs posent tour à tour un rond, pour l'un, une croix, pour l'autre, dans une grille de 3 cases par 3. Le but du jeu est d'obtenir un alignement (en ligne, colonne ou diagonale) de ses trois signes.",
+ faker.image.urlLoremFlickr(),
+ ]
+ )
+ );
+ }
+ for (let i = 0; i < 1; i += 1) {
+ queries.push(
+ database.query(
+ "insert into game(name,alt,description,image) values (?,?,?,?)",
+ [
+ "memory",
+ "memory",
+ "Tout d'abord, il faut mélanger les cartes. Puis, les étaler face contre table afin qu'aucun des joueurs ne puissent les identifier. Une fois cela fait, le premier joueur retourne 2 cartes de son choix. Si les cartes sont identiques, le joueur les conserve à côté de lui et rejoue.",
+ faker.image.urlLoremFlickr(),
+ ]
+ )
+ );
+ }
+ for (let i = 0; i < 1; i += 1) {
+ queries.push(
+ database.query(
+ "insert into game(name,alt,description,image) values (?,?,?,?)",
+
+ [
+ "typeracer",
+ "typeracer",
+ "TypeRacer est un jeu qui vous aide à améliorer vos compétences en matière de dactylographie. Il vous met en concurrence avec d'autres dactylos dans une course. Mais au lieu de manœuvrer une voiture ou un avatar sur une piste ou dans un labyrinthe, vous devrez taper des mots pour amener votre voiture du point A au point B. Ainsi, non seulement vous vous entraînerez à taper rapidement et avec précision, mais vous aurez aussi le plaisir de le faire.",
+ faker.image.urlLoremFlickr(),
+ ]
+ )
+ );
+ }
+
+ for (let i = 0; i <= 10; i += 1) {
+ const startDate = faker.date.past({ years: 1 });
+ const d = new Date(startDate);
+ queries.push(
+ database.query(
+ "insert into party(player_id,game_id,start_time,end_time,is_won) values (?,?,?,?,?)",
+ [
+ Math.ceil(Math.random() * 16),
+ Math.ceil(Math.random() * 3),
+ startDate,
+ new Date(d.getTime() + Math.ceil(Math.random() * 45 * 60000)),
+ Math.floor(Math.random() * 2),
+ ]
+ )
+ );
+ }
+ for (let i = 0; i <= 10; i += 1) {
+ const userId = i + 1;
+ const test = `${faker.lorem.words(1)} profilwe avatar`;
+ queries.push(
+ database.query(
+ "insert into profile(bio,avatar,alt,player_id) values (?,?,?,?)",
+ [faker.lorem.paragraph(), faker.image.avatar(), test, userId]
+ )
+ );
+ }
// requete
// "insert into player(role_id,username, email, password) values (?,?,?,?)",
From 8fea4ff5431c54d15d997b80cd027aab7cd69d9c Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Wed, 20 Dec 2023 15:15:19 +0100
Subject: [PATCH 03/13] ajout du back pour la table id
---
backend/src/controllers/partyControllers.js | 18 ++++++++++++++++++
backend/src/models/PartyManager.js | 17 +++++++++++++++++
backend/src/router.js | 4 ++++
backend/src/tables.js | 2 ++
4 files changed, 41 insertions(+)
create mode 100644 backend/src/controllers/partyControllers.js
create mode 100644 backend/src/models/PartyManager.js
diff --git a/backend/src/controllers/partyControllers.js b/backend/src/controllers/partyControllers.js
new file mode 100644
index 0000000..a230537
--- /dev/null
+++ b/backend/src/controllers/partyControllers.js
@@ -0,0 +1,18 @@
+// Import access to database tables
+const tables = require("../tables");
+
+// The B of BREAD - Browse (Read All) operation
+const browse = async (req, res, next) => {
+ try {
+ // Fetch all items from the database
+ const party = await tables.party.readAll();
+ // Respond with the items in JSON format
+ res.json(party);
+ } catch (err) {
+ // Pass any errors to the error-handling middleware
+ next(err);
+ }
+};
+module.exports = {
+ browse,
+};
diff --git a/backend/src/models/PartyManager.js b/backend/src/models/PartyManager.js
new file mode 100644
index 0000000..000603f
--- /dev/null
+++ b/backend/src/models/PartyManager.js
@@ -0,0 +1,17 @@
+const AbstractManager = require("./AbstractManager");
+
+class PartyManager extends AbstractManager {
+ constructor() {
+ super({ table: "party" });
+ }
+
+ async readAll() {
+ // Execute the SQL SELECT query to retrieve all partys from the "party" table
+ const [rows] = await this.database.query(`select * from ${this.table}`);
+
+ // Return the array of partys
+ return rows;
+ }
+}
+
+module.exports = PartyManager;
diff --git a/backend/src/router.js b/backend/src/router.js
index 76ef994..faef332 100644
--- a/backend/src/router.js
+++ b/backend/src/router.js
@@ -2,4 +2,8 @@ const express = require("express");
const router = express.Router();
+const partyControllers = require("./controllers/partyControllers");
+
+router.get("/admin", partyControllers.browse);
+
module.exports = router;
diff --git a/backend/src/tables.js b/backend/src/tables.js
index 66d032c..9ba4940 100644
--- a/backend/src/tables.js
+++ b/backend/src/tables.js
@@ -4,9 +4,11 @@
// Import the manager modules responsible for handling data operations on the tables
const ItemManager = require("./models/ItemManager");
+const PartyManager = require("./models/PartyManager");
const managers = [
ItemManager,
+ PartyManager,
// Add other managers here
];
From 7e951e91f04436dc6ec7379ac12ad736a598840c Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Wed, 20 Dec 2023 15:16:26 +0100
Subject: [PATCH 04/13] ajout du front avec rechart
---
frontend/components/charts/AreaContainer.jsx | 44 ++
frontend/components/charts/CamenbertChat.jsx | 24 +
frontend/package-lock.json | 556 ++++++++++++++++++-
frontend/package.json | 1 +
frontend/src/main.jsx | 7 +
frontend/src/pages/AdminGame.jsx | 37 +-
6 files changed, 662 insertions(+), 7 deletions(-)
create mode 100644 frontend/components/charts/AreaContainer.jsx
create mode 100644 frontend/components/charts/CamenbertChat.jsx
diff --git a/frontend/components/charts/AreaContainer.jsx b/frontend/components/charts/AreaContainer.jsx
new file mode 100644
index 0000000..d7b3601
--- /dev/null
+++ b/frontend/components/charts/AreaContainer.jsx
@@ -0,0 +1,44 @@
+import PropTypes from "prop-types";
+import {
+ AreaChart,
+ Area,
+ XAxis,
+ YAxis,
+ CartesianGrid,
+ Tooltip,
+ ResponsiveContainer,
+} from "recharts";
+
+function AreaContainer({ data }) {
+ return (
+
+ );
+}
+
+AreaContainer.propTypes = {
+ data: PropTypes.arrayOf(
+ PropTypes.shape({
+ value: PropTypes.number.isRequired,
+ })
+ ).isRequired,
+};
+
+export default AreaContainer;
diff --git a/frontend/components/charts/CamenbertChat.jsx b/frontend/components/charts/CamenbertChat.jsx
new file mode 100644
index 0000000..be0c379
--- /dev/null
+++ b/frontend/components/charts/CamenbertChat.jsx
@@ -0,0 +1,24 @@
+import { ResponsiveContainer, PieChart, Pie } from "recharts";
+import PropTypes from "prop-types";
+
+function CamenbertChart({ data }) {
+ return (
+
+ );
+}
+
+CamenbertChart.propTypes = {
+ data: PropTypes.arrayOf(
+ PropTypes.shape({
+ value: PropTypes.number.isRequired,
+ })
+ ).isRequired,
+};
+
+export default CamenbertChart;
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index fa87a31..b7af2f3 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -11,6 +11,7 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.2",
"react-toastify": "^9.1.3",
+ "recharts": "^2.10.3",
"sass": "^1.69.5"
},
"devDependencies": {
@@ -331,7 +332,6 @@
"version": "7.23.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz",
"integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==",
- "dev": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -996,6 +996,60 @@
"@babel/types": "^7.20.7"
}
},
+ "node_modules/@types/d3-array": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
+ "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="
+ },
+ "node_modules/@types/d3-color": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
+ "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="
+ },
+ "node_modules/@types/d3-ease": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
+ "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="
+ },
+ "node_modules/@types/d3-interpolate": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
+ "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+ "dependencies": {
+ "@types/d3-color": "*"
+ }
+ },
+ "node_modules/@types/d3-path": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.2.tgz",
+ "integrity": "sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA=="
+ },
+ "node_modules/@types/d3-scale": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
+ "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
+ "dependencies": {
+ "@types/d3-time": "*"
+ }
+ },
+ "node_modules/@types/d3-shape": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz",
+ "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==",
+ "dependencies": {
+ "@types/d3-path": "*"
+ }
+ },
+ "node_modules/@types/d3-time": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz",
+ "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw=="
+ },
+ "node_modules/@types/d3-timer": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
+ "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="
+ },
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -1556,6 +1610,116 @@
"node": ">= 8"
}
},
+ "node_modules/d3-array": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+ "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+ "dependencies": {
+ "internmap": "1 - 2"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-color": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+ "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-ease": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+ "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-format": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+ "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-interpolate": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+ "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+ "dependencies": {
+ "d3-color": "1 - 3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-path": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+ "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-scale": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+ "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+ "dependencies": {
+ "d3-array": "2.10.0 - 3",
+ "d3-format": "1 - 3",
+ "d3-interpolate": "1.2.0 - 3",
+ "d3-time": "2.1.1 - 3",
+ "d3-time-format": "2 - 4"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-shape": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+ "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+ "dependencies": {
+ "d3-path": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-time": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+ "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+ "dependencies": {
+ "d3-array": "2 - 3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-time-format": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+ "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+ "dependencies": {
+ "d3-time": "1 - 3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-timer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+ "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/damerau-levenshtein": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -1579,6 +1743,11 @@
}
}
},
+ "node_modules/decimal.js-light": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
+ "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="
+ },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -1691,6 +1860,14 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dom-helpers": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
+ "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
+ "dependencies": {
+ "@babel/runtime": "^7.1.2"
+ }
+ },
"node_modules/electron-to-chromium": {
"version": "1.4.597",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.597.tgz",
@@ -2392,6 +2569,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
+ },
"node_modules/execa": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz",
@@ -2427,6 +2609,14 @@
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true
},
+ "node_modules/fast-equals": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz",
+ "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
@@ -2916,6 +3106,14 @@
"node": ">= 0.4"
}
},
+ "node_modules/internmap": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+ "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/is-array-buffer": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
@@ -3464,6 +3662,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -4045,6 +4248,11 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/react-lifecycles-compat": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
+ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
+ },
"node_modules/react-refresh": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
@@ -4084,6 +4292,20 @@
"react-dom": ">=16.8"
}
},
+ "node_modules/react-smooth": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.5.tgz",
+ "integrity": "sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA==",
+ "dependencies": {
+ "fast-equals": "^5.0.0",
+ "react-transition-group": "2.9.0"
+ },
+ "peerDependencies": {
+ "prop-types": "^15.6.0",
+ "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-toastify": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz",
@@ -4096,6 +4318,21 @@
"react-dom": ">=16"
}
},
+ "node_modules/react-transition-group": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
+ "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
+ "dependencies": {
+ "dom-helpers": "^3.4.0",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2",
+ "react-lifecycles-compat": "^3.0.4"
+ },
+ "peerDependencies": {
+ "react": ">=15.0.0",
+ "react-dom": ">=15.0.0"
+ }
+ },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -4107,6 +4344,45 @@
"node": ">=8.10.0"
}
},
+ "node_modules/recharts": {
+ "version": "2.10.3",
+ "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.10.3.tgz",
+ "integrity": "sha512-G4J96fKTZdfFQd6aQnZjo2nVNdXhp+uuLb00+cBTGLo85pChvm1+E67K3wBOHDE/77spcYb2Cy9gYWVqiZvQCg==",
+ "dependencies": {
+ "clsx": "^2.0.0",
+ "eventemitter3": "^4.0.1",
+ "lodash": "^4.17.19",
+ "react-is": "^16.10.2",
+ "react-smooth": "^2.0.5",
+ "recharts-scale": "^0.4.4",
+ "tiny-invariant": "^1.3.1",
+ "victory-vendor": "^36.6.8"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "prop-types": "^15.6.0",
+ "react": "^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/recharts-scale": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz",
+ "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==",
+ "dependencies": {
+ "decimal.js-light": "^2.4.1"
+ }
+ },
+ "node_modules/recharts/node_modules/clsx": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
+ "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
@@ -4130,8 +4406,7 @@
"node_modules/regenerator-runtime": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
- "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==",
- "dev": true
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.1",
@@ -4643,6 +4918,11 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
+ "node_modules/tiny-invariant": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
+ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="
+ },
"node_modules/titleize": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
@@ -4857,6 +5137,27 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/victory-vendor": {
+ "version": "36.7.0",
+ "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.7.0.tgz",
+ "integrity": "sha512-nqYuTkLSdTTeACyXcCLbL7rl0y6jpzLPtTNGOtSnajdR+xxMxBdjMxDjfNJNlhR+ZU8vbXz+QejntcbY7h9/ZA==",
+ "dependencies": {
+ "@types/d3-array": "^3.0.3",
+ "@types/d3-ease": "^3.0.0",
+ "@types/d3-interpolate": "^3.0.1",
+ "@types/d3-scale": "^4.0.2",
+ "@types/d3-shape": "^3.1.0",
+ "@types/d3-time": "^3.0.0",
+ "@types/d3-timer": "^3.0.0",
+ "d3-array": "^3.1.6",
+ "d3-ease": "^3.0.1",
+ "d3-interpolate": "^3.0.1",
+ "d3-scale": "^4.0.2",
+ "d3-shape": "^3.1.0",
+ "d3-time": "^3.0.0",
+ "d3-timer": "^3.0.1"
+ }
+ },
"node_modules/vite": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
@@ -5248,7 +5549,6 @@
"version": "7.23.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz",
"integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==",
- "dev": true,
"requires": {
"regenerator-runtime": "^0.14.0"
}
@@ -5644,6 +5944,60 @@
"@babel/types": "^7.20.7"
}
},
+ "@types/d3-array": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
+ "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="
+ },
+ "@types/d3-color": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
+ "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="
+ },
+ "@types/d3-ease": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
+ "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="
+ },
+ "@types/d3-interpolate": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
+ "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+ "requires": {
+ "@types/d3-color": "*"
+ }
+ },
+ "@types/d3-path": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.2.tgz",
+ "integrity": "sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA=="
+ },
+ "@types/d3-scale": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
+ "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
+ "requires": {
+ "@types/d3-time": "*"
+ }
+ },
+ "@types/d3-shape": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz",
+ "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==",
+ "requires": {
+ "@types/d3-path": "*"
+ }
+ },
+ "@types/d3-time": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz",
+ "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw=="
+ },
+ "@types/d3-timer": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
+ "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="
+ },
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -6053,6 +6407,83 @@
"which": "^2.0.1"
}
},
+ "d3-array": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+ "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+ "requires": {
+ "internmap": "1 - 2"
+ }
+ },
+ "d3-color": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+ "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="
+ },
+ "d3-ease": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+ "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="
+ },
+ "d3-format": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+ "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="
+ },
+ "d3-interpolate": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+ "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+ "requires": {
+ "d3-color": "1 - 3"
+ }
+ },
+ "d3-path": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+ "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="
+ },
+ "d3-scale": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+ "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+ "requires": {
+ "d3-array": "2.10.0 - 3",
+ "d3-format": "1 - 3",
+ "d3-interpolate": "1.2.0 - 3",
+ "d3-time": "2.1.1 - 3",
+ "d3-time-format": "2 - 4"
+ }
+ },
+ "d3-shape": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+ "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+ "requires": {
+ "d3-path": "^3.1.0"
+ }
+ },
+ "d3-time": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+ "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+ "requires": {
+ "d3-array": "2 - 3"
+ }
+ },
+ "d3-time-format": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+ "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+ "requires": {
+ "d3-time": "1 - 3"
+ }
+ },
+ "d3-timer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+ "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="
+ },
"damerau-levenshtein": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -6068,6 +6499,11 @@
"ms": "2.1.2"
}
},
+ "decimal.js-light": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
+ "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="
+ },
"deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -6144,6 +6580,14 @@
"esutils": "^2.0.2"
}
},
+ "dom-helpers": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
+ "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
+ "requires": {
+ "@babel/runtime": "^7.1.2"
+ }
+ },
"electron-to-chromium": {
"version": "1.4.597",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.597.tgz",
@@ -6671,6 +7115,11 @@
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
+ "eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
+ },
"execa": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz",
@@ -6700,6 +7149,11 @@
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true
},
+ "fast-equals": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz",
+ "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ=="
+ },
"fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
@@ -7047,6 +7501,11 @@
"side-channel": "^1.0.4"
}
},
+ "internmap": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+ "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="
+ },
"is-array-buffer": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
@@ -7420,6 +7879,11 @@
"p-locate": "^5.0.0"
}
},
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -7816,6 +8280,11 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "react-lifecycles-compat": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
+ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
+ },
"react-refresh": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
@@ -7839,6 +8308,15 @@
"react-router": "6.20.0"
}
},
+ "react-smooth": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.5.tgz",
+ "integrity": "sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA==",
+ "requires": {
+ "fast-equals": "^5.0.0",
+ "react-transition-group": "2.9.0"
+ }
+ },
"react-toastify": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz",
@@ -7847,6 +8325,17 @@
"clsx": "^1.1.1"
}
},
+ "react-transition-group": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
+ "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
+ "requires": {
+ "dom-helpers": "^3.4.0",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2",
+ "react-lifecycles-compat": "^3.0.4"
+ }
+ },
"readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -7855,6 +8344,36 @@
"picomatch": "^2.2.1"
}
},
+ "recharts": {
+ "version": "2.10.3",
+ "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.10.3.tgz",
+ "integrity": "sha512-G4J96fKTZdfFQd6aQnZjo2nVNdXhp+uuLb00+cBTGLo85pChvm1+E67K3wBOHDE/77spcYb2Cy9gYWVqiZvQCg==",
+ "requires": {
+ "clsx": "^2.0.0",
+ "eventemitter3": "^4.0.1",
+ "lodash": "^4.17.19",
+ "react-is": "^16.10.2",
+ "react-smooth": "^2.0.5",
+ "recharts-scale": "^0.4.4",
+ "tiny-invariant": "^1.3.1",
+ "victory-vendor": "^36.6.8"
+ },
+ "dependencies": {
+ "clsx": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
+ "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="
+ }
+ }
+ },
+ "recharts-scale": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz",
+ "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==",
+ "requires": {
+ "decimal.js-light": "^2.4.1"
+ }
+ },
"reflect.getprototypeof": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
@@ -7872,8 +8391,7 @@
"regenerator-runtime": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
- "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==",
- "dev": true
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
},
"regexp.prototype.flags": {
"version": "1.5.1",
@@ -8221,6 +8739,11 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
+ "tiny-invariant": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
+ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="
+ },
"titleize": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
@@ -8369,6 +8892,27 @@
"punycode": "^2.1.0"
}
},
+ "victory-vendor": {
+ "version": "36.7.0",
+ "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.7.0.tgz",
+ "integrity": "sha512-nqYuTkLSdTTeACyXcCLbL7rl0y6jpzLPtTNGOtSnajdR+xxMxBdjMxDjfNJNlhR+ZU8vbXz+QejntcbY7h9/ZA==",
+ "requires": {
+ "@types/d3-array": "^3.0.3",
+ "@types/d3-ease": "^3.0.0",
+ "@types/d3-interpolate": "^3.0.1",
+ "@types/d3-scale": "^4.0.2",
+ "@types/d3-shape": "^3.1.0",
+ "@types/d3-time": "^3.0.0",
+ "@types/d3-timer": "^3.0.0",
+ "d3-array": "^3.1.6",
+ "d3-ease": "^3.0.1",
+ "d3-interpolate": "^3.0.1",
+ "d3-scale": "^4.0.2",
+ "d3-shape": "^3.1.0",
+ "d3-time": "^3.0.0",
+ "d3-timer": "^3.0.1"
+ }
+ },
"vite": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 9e0bb9a..12d7ff0 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -11,6 +11,7 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.2",
"react-toastify": "^9.1.3",
+ "recharts": "^2.10.3",
"sass": "^1.69.5"
},
"devDependencies": {
diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx
index 94a3eda..d3dbf3d 100644
--- a/frontend/src/main.jsx
+++ b/frontend/src/main.jsx
@@ -8,6 +8,7 @@ import App from "./App";
import Home from "./pages/Home";
import AdminPage from "./pages/AdminPage";
import AdminGame from "./pages/AdminGame";
+import connexion from "../connexion";
const router = createBrowserRouter([
{
@@ -27,6 +28,12 @@ const router = createBrowserRouter([
{
path: "game",
element: ,
+ loader: () => {
+ return connexion
+ .get("/admin")
+ .then((res) => res.data)
+ .catch((err) => console.error(err));
+ },
},
],
},
diff --git a/frontend/src/pages/AdminGame.jsx b/frontend/src/pages/AdminGame.jsx
index e872298..b2728f9 100644
--- a/frontend/src/pages/AdminGame.jsx
+++ b/frontend/src/pages/AdminGame.jsx
@@ -1,5 +1,40 @@
+import { useLoaderData } from "react-router-dom";
+import CamenbertChart from "../../components/charts/CamenbertChat";
+
function AdminGame() {
- return AdminGame
;
+ const data = useLoaderData();
+
+ const filter = (datas) => {
+ let firstGame = 0;
+ let secondGame = 0;
+ let thirdGame = 0;
+
+ for (let i = 0; i < datas.length; i += 1) {
+ if (datas[i].game_id === 1) {
+ firstGame += 1;
+ } else if (datas[i].game_id === 2) {
+ secondGame += 1;
+ } else if (datas[i].game_id === 3) {
+ thirdGame += 1;
+ }
+ }
+
+ const finalArray = [
+ { game_id: 1, value: firstGame },
+ { game_id: 2, value: secondGame },
+ { game_id: 3, value: thirdGame },
+ ];
+ return finalArray;
+ };
+
+ const state = filter(data);
+
+ return (
+
+
adminGame
+
+
+ );
}
export default AdminGame;
From 423331b44e1a98bfdced7e170fc0aed99f724d10 Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Thu, 21 Dec 2023 17:05:56 +0100
Subject: [PATCH 05/13] ajout de la route party + models query
---
backend/src/controllers/partyControllers.js | 15 +++++++++------
backend/src/models/PartyManager.js | 17 +++++++++++++++++
backend/src/router.js | 2 +-
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/backend/src/controllers/partyControllers.js b/backend/src/controllers/partyControllers.js
index a230537..e9de36c 100644
--- a/backend/src/controllers/partyControllers.js
+++ b/backend/src/controllers/partyControllers.js
@@ -1,15 +1,18 @@
// Import access to database tables
const tables = require("../tables");
-// The B of BREAD - Browse (Read All) operation
const browse = async (req, res, next) => {
try {
- // Fetch all items from the database
- const party = await tables.party.readAll();
- // Respond with the items in JSON format
- res.json(party);
+ let party = [];
+ if (req.query.stat === "played") {
+ party = await tables.party.statByParty();
+ } else if (req.query.stat === "is_won") {
+ party = await tables.party.statByGame();
+ } else {
+ party = await tables.party.readAll();
+ }
+ res.status(200).json(party);
} catch (err) {
- // Pass any errors to the error-handling middleware
next(err);
}
};
diff --git a/backend/src/models/PartyManager.js b/backend/src/models/PartyManager.js
index 000603f..8c93f78 100644
--- a/backend/src/models/PartyManager.js
+++ b/backend/src/models/PartyManager.js
@@ -12,6 +12,23 @@ class PartyManager extends AbstractManager {
// Return the array of partys
return rows;
}
+
+ async statByParty() {
+ const [rows] = await this.database.query(
+ `select count(party.game_id) as value , g.name from ${this.table} inner join game as g on g.id = ${this.table}.game_id group by g.name`
+ );
+ return rows;
+ }
+
+ async statByGame() {
+ const [rows] = await this.database.query(`
+ select
+ sum(case when is_won = 1 then 1 else 0 end) as victory,
+ sum(case when is_won = 0 then 1 else 0 end) as defeat
+ from ${this.table}
+ `);
+ return rows;
+ }
}
module.exports = PartyManager;
diff --git a/backend/src/router.js b/backend/src/router.js
index faef332..28a1e07 100644
--- a/backend/src/router.js
+++ b/backend/src/router.js
@@ -4,6 +4,6 @@ const router = express.Router();
const partyControllers = require("./controllers/partyControllers");
-router.get("/admin", partyControllers.browse);
+router.get("/party", partyControllers.browse);
module.exports = router;
From 2a7ae7ccd747efc51bc9fff2d8385069506e8d87 Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Thu, 21 Dec 2023 17:17:14 +0100
Subject: [PATCH 06/13] ajout du frontent avec 2 chart partie admin
---
frontend/components/charts/CamenbertChat.jsx | 12 ++++-
frontend/src/main.jsx | 2 +-
frontend/src/pages/AdminGame.jsx | 50 ++++++++++----------
3 files changed, 36 insertions(+), 28 deletions(-)
diff --git a/frontend/components/charts/CamenbertChat.jsx b/frontend/components/charts/CamenbertChat.jsx
index be0c379..1f48b8f 100644
--- a/frontend/components/charts/CamenbertChat.jsx
+++ b/frontend/components/charts/CamenbertChat.jsx
@@ -1,12 +1,18 @@
import { ResponsiveContainer, PieChart, Pie } from "recharts";
import PropTypes from "prop-types";
-function CamenbertChart({ data }) {
+function CamenbertChart({ data, dataKey, name }) {
return (
@@ -19,6 +25,8 @@ CamenbertChart.propTypes = {
value: PropTypes.number.isRequired,
})
).isRequired,
+ dataKey: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
};
export default CamenbertChart;
diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx
index d3dbf3d..a1cccea 100644
--- a/frontend/src/main.jsx
+++ b/frontend/src/main.jsx
@@ -30,7 +30,7 @@ const router = createBrowserRouter([
element: ,
loader: () => {
return connexion
- .get("/admin")
+ .get("/party")
.then((res) => res.data)
.catch((err) => console.error(err));
},
diff --git a/frontend/src/pages/AdminGame.jsx b/frontend/src/pages/AdminGame.jsx
index b2728f9..a001621 100644
--- a/frontend/src/pages/AdminGame.jsx
+++ b/frontend/src/pages/AdminGame.jsx
@@ -1,38 +1,38 @@
-import { useLoaderData } from "react-router-dom";
+import { useEffect, useState } from "react";
+import connexion from "../../connexion";
import CamenbertChart from "../../components/charts/CamenbertChat";
function AdminGame() {
- const data = useLoaderData();
+ const [isWon, setIsWon] = useState([]);
+ const [played, setPlayed] = useState([]);
- const filter = (datas) => {
- let firstGame = 0;
- let secondGame = 0;
- let thirdGame = 0;
+ let transformedData = [];
+ if (Array.isArray(isWon) && isWon.length > 0) {
+ transformedData = Object.keys(isWon[0]).map((key) => ({
+ name: key,
+ value: parseInt(isWon[0][key], 10),
+ }));
+ }
- for (let i = 0; i < datas.length; i += 1) {
- if (datas[i].game_id === 1) {
- firstGame += 1;
- } else if (datas[i].game_id === 2) {
- secondGame += 1;
- } else if (datas[i].game_id === 3) {
- thirdGame += 1;
- }
- }
+ useEffect(() => {
+ connexion
+ .get("/party?stat=is_won")
+ .then((res) => setIsWon(res.data))
+ .catch((err) => console.error(err));
+ }, []);
- const finalArray = [
- { game_id: 1, value: firstGame },
- { game_id: 2, value: secondGame },
- { game_id: 3, value: thirdGame },
- ];
- return finalArray;
- };
-
- const state = filter(data);
+ useEffect(() => {
+ connexion
+ .get("/party?stat=played")
+ .then((res) => setPlayed(res.data))
+ .catch((err) => console.error(err));
+ }, []);
return (
adminGame
-
+
+
);
}
From 5d273f8bc3314900d966d73504be65dbe9ba3633 Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Fri, 22 Dec 2023 12:21:02 +0100
Subject: [PATCH 07/13] ajout des chart + route
---
backend/src/controllers/partyControllers.js | 8 +++-
backend/src/models/PartyManager.js | 9 ++++
frontend/components/charts/CamenbertChat.jsx | 32 ---------------
frontend/src/main.jsx | 7 ----
frontend/src/pages/AdminGame.jsx | 43 ++++++--------------
frontend/{ => src/services}/connexion.js | 0
6 files changed, 29 insertions(+), 70 deletions(-)
delete mode 100644 frontend/components/charts/CamenbertChat.jsx
rename frontend/{ => src/services}/connexion.js (100%)
diff --git a/backend/src/controllers/partyControllers.js b/backend/src/controllers/partyControllers.js
index e9de36c..845fc35 100644
--- a/backend/src/controllers/partyControllers.js
+++ b/backend/src/controllers/partyControllers.js
@@ -7,7 +7,13 @@ const browse = async (req, res, next) => {
if (req.query.stat === "played") {
party = await tables.party.statByParty();
} else if (req.query.stat === "is_won") {
- party = await tables.party.statByGame();
+ const stat = await tables.party.statByGame();
+ party.push(
+ { name: "won", value: +stat[0].victory },
+ { name: "lost", value: +stat[0].defeat }
+ );
+ } else if (req.query.stat === "timeperplayer") {
+ party = await tables.party.timeperplayer();
} else {
party = await tables.party.readAll();
}
diff --git a/backend/src/models/PartyManager.js b/backend/src/models/PartyManager.js
index 8c93f78..98910e2 100644
--- a/backend/src/models/PartyManager.js
+++ b/backend/src/models/PartyManager.js
@@ -29,6 +29,15 @@ class PartyManager extends AbstractManager {
`);
return rows;
}
+
+ async timeperplayer() {
+ const [rows] = await this.database.query(`
+ select player_id, sec_to_time(sum(time_to_sec(diff))) as
+ timePerPlayer from(select player_id, timediff(end_time, start_time) as diff from ${this.table})
+ as subquery group by player_id order by time_to_sec(timePerPlayer) desc
+ `);
+ return rows;
+ }
}
module.exports = PartyManager;
diff --git a/frontend/components/charts/CamenbertChat.jsx b/frontend/components/charts/CamenbertChat.jsx
deleted file mode 100644
index 1f48b8f..0000000
--- a/frontend/components/charts/CamenbertChat.jsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import { ResponsiveContainer, PieChart, Pie } from "recharts";
-import PropTypes from "prop-types";
-
-function CamenbertChart({ data, dataKey, name }) {
- return (
-
- );
-}
-
-CamenbertChart.propTypes = {
- data: PropTypes.arrayOf(
- PropTypes.shape({
- value: PropTypes.number.isRequired,
- })
- ).isRequired,
- dataKey: PropTypes.string.isRequired,
- name: PropTypes.string.isRequired,
-};
-
-export default CamenbertChart;
diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx
index a1cccea..94a3eda 100644
--- a/frontend/src/main.jsx
+++ b/frontend/src/main.jsx
@@ -8,7 +8,6 @@ import App from "./App";
import Home from "./pages/Home";
import AdminPage from "./pages/AdminPage";
import AdminGame from "./pages/AdminGame";
-import connexion from "../connexion";
const router = createBrowserRouter([
{
@@ -28,12 +27,6 @@ const router = createBrowserRouter([
{
path: "game",
element: ,
- loader: () => {
- return connexion
- .get("/party")
- .then((res) => res.data)
- .catch((err) => console.error(err));
- },
},
],
},
diff --git a/frontend/src/pages/AdminGame.jsx b/frontend/src/pages/AdminGame.jsx
index a001621..b2fedee 100644
--- a/frontend/src/pages/AdminGame.jsx
+++ b/frontend/src/pages/AdminGame.jsx
@@ -1,38 +1,21 @@
-import { useEffect, useState } from "react";
-import connexion from "../../connexion";
-import CamenbertChart from "../../components/charts/CamenbertChat";
+import CamenbertChart from "../components/charts/CamenbertChat";
function AdminGame() {
- const [isWon, setIsWon] = useState([]);
- const [played, setPlayed] = useState([]);
-
- let transformedData = [];
- if (Array.isArray(isWon) && isWon.length > 0) {
- transformedData = Object.keys(isWon[0]).map((key) => ({
- name: key,
- value: parseInt(isWon[0][key], 10),
- }));
- }
-
- useEffect(() => {
- connexion
- .get("/party?stat=is_won")
- .then((res) => setIsWon(res.data))
- .catch((err) => console.error(err));
- }, []);
-
- useEffect(() => {
- connexion
- .get("/party?stat=played")
- .then((res) => setPlayed(res.data))
- .catch((err) => console.error(err));
- }, []);
-
return (
adminGame
-
-
+
+
);
}
diff --git a/frontend/connexion.js b/frontend/src/services/connexion.js
similarity index 100%
rename from frontend/connexion.js
rename to frontend/src/services/connexion.js
From 1ab6f9e1dbff3d8b00e6eb49a79189b67efd817c Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Thu, 4 Jan 2024 14:43:22 +0100
Subject: [PATCH 08/13] changement backend
---
backend/src/controllers/partyControllers.js | 7 ++-
backend/src/models/ItemManager.js | 26 ----------
backend/src/models/PartyManager.js | 7 +--
backend/src/services/time.js | 9 ++++
frontend/components/charts/AreaContainer.jsx | 44 ----------------
frontend/src/components/charts/BarChart.jsx | 40 +++++++++++++++
.../src/components/charts/CamenbertChart.jsx | 51 +++++++++++++++++++
frontend/src/pages/AdminGame.jsx | 41 +++++++++------
.../src/style/components/camenbertGame.scss | 14 +++++
frontend/src/style/index.scss | 1 +
10 files changed, 149 insertions(+), 91 deletions(-)
create mode 100644 backend/src/services/time.js
delete mode 100644 frontend/components/charts/AreaContainer.jsx
create mode 100644 frontend/src/components/charts/BarChart.jsx
create mode 100644 frontend/src/components/charts/CamenbertChart.jsx
create mode 100644 frontend/src/style/components/camenbertGame.scss
diff --git a/backend/src/controllers/partyControllers.js b/backend/src/controllers/partyControllers.js
index 845fc35..4e4bfad 100644
--- a/backend/src/controllers/partyControllers.js
+++ b/backend/src/controllers/partyControllers.js
@@ -1,5 +1,6 @@
// Import access to database tables
const tables = require("../tables");
+const { transformTimeToMinute } = require("../services/time");
const browse = async (req, res, next) => {
try {
@@ -13,7 +14,11 @@ const browse = async (req, res, next) => {
{ name: "lost", value: +stat[0].defeat }
);
} else if (req.query.stat === "timeperplayer") {
- party = await tables.party.timeperplayer();
+ const stat = await tables.party.timeperplayer();
+ party = stat.map((el) => ({
+ name: el.player_id,
+ value: transformTimeToMinute(el.time),
+ }));
} else {
party = await tables.party.readAll();
}
diff --git a/backend/src/models/ItemManager.js b/backend/src/models/ItemManager.js
index eeeae9f..4e0a8a6 100644
--- a/backend/src/models/ItemManager.js
+++ b/backend/src/models/ItemManager.js
@@ -2,58 +2,32 @@ const AbstractManager = require("./AbstractManager");
class ItemManager extends AbstractManager {
constructor() {
- // Call the constructor of the parent class (AbstractManager)
- // and pass the table name "item" as configuration
super({ table: "item" });
}
- // The C of CRUD - Create operation
-
async create(item) {
- // Execute the SQL INSERT query to add a new item to the "item" table
const [result] = await this.database.query(
`insert into ${this.table} (title) values (?)`,
[item.title]
);
- // Return the ID of the newly inserted item
return result.insertId;
}
- // The Rs of CRUD - Read operations
-
async read(id) {
- // Execute the SQL SELECT query to retrieve a specific item by its ID
const [rows] = await this.database.query(
`select * from ${this.table} where id = ?`,
[id]
);
- // Return the first row of the result, which represents the item
return rows[0];
}
async readAll() {
- // Execute the SQL SELECT query to retrieve all items from the "item" table
const [rows] = await this.database.query(`select * from ${this.table}`);
- // Return the array of items
return rows;
}
-
- // The U of CRUD - Update operation
- // TODO: Implement the update operation to modify an existing item
-
- // async update(item) {
- // ...
- // }
-
- // The D of CRUD - Delete operation
- // TODO: Implement the delete operation to remove an item by its ID
-
- // async delete(id) {
- // ...
- // }
}
module.exports = ItemManager;
diff --git a/backend/src/models/PartyManager.js b/backend/src/models/PartyManager.js
index 98910e2..af622a9 100644
--- a/backend/src/models/PartyManager.js
+++ b/backend/src/models/PartyManager.js
@@ -6,10 +6,7 @@ class PartyManager extends AbstractManager {
}
async readAll() {
- // Execute the SQL SELECT query to retrieve all partys from the "party" table
const [rows] = await this.database.query(`select * from ${this.table}`);
-
- // Return the array of partys
return rows;
}
@@ -33,8 +30,8 @@ class PartyManager extends AbstractManager {
async timeperplayer() {
const [rows] = await this.database.query(`
select player_id, sec_to_time(sum(time_to_sec(diff))) as
- timePerPlayer from(select player_id, timediff(end_time, start_time) as diff from ${this.table})
- as subquery group by player_id order by time_to_sec(timePerPlayer) desc
+ time from(select player_id, timediff(end_time, start_time) as diff from ${this.table})
+ as subquery group by player_id order by time_to_sec(time) desc
`);
return rows;
}
diff --git a/backend/src/services/time.js b/backend/src/services/time.js
new file mode 100644
index 0000000..2426e62
--- /dev/null
+++ b/backend/src/services/time.js
@@ -0,0 +1,9 @@
+const transformTimeToMinute = (time) => {
+ const arr = time.split(":");
+
+ return +arr[0] * 60 + +arr[1];
+};
+
+module.exports = {
+ transformTimeToMinute,
+};
diff --git a/frontend/components/charts/AreaContainer.jsx b/frontend/components/charts/AreaContainer.jsx
deleted file mode 100644
index d7b3601..0000000
--- a/frontend/components/charts/AreaContainer.jsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import PropTypes from "prop-types";
-import {
- AreaChart,
- Area,
- XAxis,
- YAxis,
- CartesianGrid,
- Tooltip,
- ResponsiveContainer,
-} from "recharts";
-
-function AreaContainer({ data }) {
- return (
-
- );
-}
-
-AreaContainer.propTypes = {
- data: PropTypes.arrayOf(
- PropTypes.shape({
- value: PropTypes.number.isRequired,
- })
- ).isRequired,
-};
-
-export default AreaContainer;
diff --git a/frontend/src/components/charts/BarChart.jsx b/frontend/src/components/charts/BarChart.jsx
new file mode 100644
index 0000000..0396bf8
--- /dev/null
+++ b/frontend/src/components/charts/BarChart.jsx
@@ -0,0 +1,40 @@
+import { BarChart, Bar, ResponsiveContainer } from "recharts";
+import { useEffect, useState } from "react";
+import PropTypes from "prop-types";
+import connexion from "../../services/connexion";
+
+function BarContainer({ url, title, dataKey }) {
+ const [stat, setStat] = useState([]);
+
+ const getStat = async () => {
+ try {
+ const res = await connexion.get(url);
+ setStat(res.data);
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ useEffect(() => {
+ getStat();
+ }, []);
+
+ return (
+
+
{title}
+
+
+
+
+
+
+ );
+}
+
+BarContainer.propTypes = {
+ title: PropTypes.string.isRequired,
+ url: PropTypes.string.isRequired,
+ dataKey: PropTypes.string.isRequired,
+};
+
+export default BarContainer;
diff --git a/frontend/src/components/charts/CamenbertChart.jsx b/frontend/src/components/charts/CamenbertChart.jsx
new file mode 100644
index 0000000..0917528
--- /dev/null
+++ b/frontend/src/components/charts/CamenbertChart.jsx
@@ -0,0 +1,51 @@
+import { useState, useEffect } from "react";
+import { ResponsiveContainer, PieChart, Pie, Cell } from "recharts";
+import PropTypes from "prop-types";
+import connexion from "../../services/connexion";
+
+function CamembertChart({ title, url, dataKey, name }) {
+ const [stat, setStat] = useState();
+ const COLORS = ["#5865f2", "#3095B4", "#e59834"];
+
+ const getStats = async () => {
+ try {
+ const res = await connexion.get(url);
+ setStat(res.data);
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ useEffect(() => {
+ getStats();
+ }, []);
+
+ return (
+
+
{title}
+
+
+
+ {stat &&
+ stat.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+ );
+}
+
+CamembertChart.propTypes = {
+ title: PropTypes.string.isRequired,
+ url: PropTypes.string.isRequired,
+ dataKey: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+};
+
+export default CamembertChart;
diff --git a/frontend/src/pages/AdminGame.jsx b/frontend/src/pages/AdminGame.jsx
index b2fedee..ff66bd7 100644
--- a/frontend/src/pages/AdminGame.jsx
+++ b/frontend/src/pages/AdminGame.jsx
@@ -1,21 +1,32 @@
-import CamenbertChart from "../components/charts/CamenbertChat";
+import CamenbertChart from "../components/charts/CamenbertChart";
+import BarContainer from "../components/charts/BarChart";
function AdminGame() {
return (
-
-
adminGame
-
-
+
+
AdminGame
+
+
+
+
+
+
+
);
}
diff --git a/frontend/src/style/components/camenbertGame.scss b/frontend/src/style/components/camenbertGame.scss
new file mode 100644
index 0000000..a71590e
--- /dev/null
+++ b/frontend/src/style/components/camenbertGame.scss
@@ -0,0 +1,14 @@
+.adminContainer {
+ h1 {
+ padding-left: 200px;
+ margin-top: 2rem;
+ }
+ .camenbertContainer {
+ display: flex;
+ text-align: center;
+ margin-top: 6rem;
+ }
+ .barContainer {
+ margin: 75px 15%;
+ }
+}
diff --git a/frontend/src/style/index.scss b/frontend/src/style/index.scss
index 5fcb4de..4583c40 100644
--- a/frontend/src/style/index.scss
+++ b/frontend/src/style/index.scss
@@ -1 +1,2 @@
@import "./settings.scss";
+@import "./components/camenbertGame.scss";
From 850a46891175c941ea99945a7ab620bd1c05dd24 Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Thu, 4 Jan 2024 16:12:30 +0100
Subject: [PATCH 09/13] modif des charts
---
frontend/src/components/charts/BarChart.jsx | 13 ++++++++++++-
frontend/src/components/charts/CamenbertChart.jsx | 3 ++-
frontend/src/pages/AdminGame.jsx | 14 +++++++++++---
frontend/src/style/components/camenbertGame.scss | 3 ++-
frontend/src/style/index.scss | 2 ++
5 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/frontend/src/components/charts/BarChart.jsx b/frontend/src/components/charts/BarChart.jsx
index 0396bf8..1974716 100644
--- a/frontend/src/components/charts/BarChart.jsx
+++ b/frontend/src/components/charts/BarChart.jsx
@@ -1,4 +1,4 @@
-import { BarChart, Bar, ResponsiveContainer } from "recharts";
+import { BarChart, Bar, ResponsiveContainer, Legend } from "recharts";
import { useEffect, useState } from "react";
import PropTypes from "prop-types";
import connexion from "../../services/connexion";
@@ -25,8 +25,19 @@ function BarContainer({ url, title, dataKey }) {
+
+
+ {stat.map((el) => (
+
+
+ - Name: {el.name}
+ - Value: {el.value}
+
+
+ ))}
+
);
}
diff --git a/frontend/src/components/charts/CamenbertChart.jsx b/frontend/src/components/charts/CamenbertChart.jsx
index 0917528..c88aad5 100644
--- a/frontend/src/components/charts/CamenbertChart.jsx
+++ b/frontend/src/components/charts/CamenbertChart.jsx
@@ -1,5 +1,5 @@
import { useState, useEffect } from "react";
-import { ResponsiveContainer, PieChart, Pie, Cell } from "recharts";
+import { ResponsiveContainer, PieChart, Pie, Cell, Legend } from "recharts";
import PropTypes from "prop-types";
import connexion from "../../services/connexion";
@@ -35,6 +35,7 @@ function CamembertChart({ title, url, dataKey, name }) {
/>
))}
+
diff --git a/frontend/src/pages/AdminGame.jsx b/frontend/src/pages/AdminGame.jsx
index ff66bd7..bb7a66a 100644
--- a/frontend/src/pages/AdminGame.jsx
+++ b/frontend/src/pages/AdminGame.jsx
@@ -2,21 +2,29 @@ import CamenbertChart from "../components/charts/CamenbertChart";
import BarContainer from "../components/charts/BarChart";
function AdminGame() {
+ // const array = [
+ // {
+ // name: "won",
+ // },
+ // ];
+
+ const arr = "value";
+
return (
AdminGame
diff --git a/frontend/src/style/components/camenbertGame.scss b/frontend/src/style/components/camenbertGame.scss
index a71590e..db7fdff 100644
--- a/frontend/src/style/components/camenbertGame.scss
+++ b/frontend/src/style/components/camenbertGame.scss
@@ -1,7 +1,8 @@
.adminContainer {
h1 {
- padding-left: 200px;
margin-top: 2rem;
+ position: static;
+ margin-left: 7rem;
}
.camenbertContainer {
display: flex;
diff --git a/frontend/src/style/index.scss b/frontend/src/style/index.scss
index 5fcb4de..0b182c4 100644
--- a/frontend/src/style/index.scss
+++ b/frontend/src/style/index.scss
@@ -1 +1,3 @@
@import "./settings.scss";
+@import "./components/camenbertGame.scss";
+@import "./components/TicTacToe.scss";
From 4139285aa8ddde7898487e1cf50fc0a23dd74e35 Mon Sep 17 00:00:00 2001
From: jean519 <129189905+jean519@users.noreply.github.com>
Date: Fri, 5 Jan 2024 10:07:05 +0100
Subject: [PATCH 10/13] ajout des stats dans les graphiques
---
frontend/src/components/charts/BarChart.jsx | 13 ++++++-------
frontend/src/pages/AdminGame.jsx | 14 +++-----------
frontend/src/style/components/camenbertGame.scss | 4 ++--
frontend/src/style/pages/AdminUsersPage.scss | 16 ++++++++++++++++
frontend/src/style/settings.scss | 4 ++++
5 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/frontend/src/components/charts/BarChart.jsx b/frontend/src/components/charts/BarChart.jsx
index 1974716..8ab57da 100644
--- a/frontend/src/components/charts/BarChart.jsx
+++ b/frontend/src/components/charts/BarChart.jsx
@@ -1,4 +1,4 @@
-import { BarChart, Bar, ResponsiveContainer, Legend } from "recharts";
+import { BarChart, Bar, ResponsiveContainer } from "recharts";
import { useEffect, useState } from "react";
import PropTypes from "prop-types";
import connexion from "../../services/connexion";
@@ -25,15 +25,14 @@ function BarContainer({ url, title, dataKey }) {
-
-