From 1f751581a82c6145a592fd12dd7b561a2a877e83 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 15 Nov 2024 16:32:17 +0100
Subject: [PATCH 001/283] refactor: ajout du dossier Home

---
 routes/StackNavigator.tsx   | 2 +-
 screens/{ => Home}/Home.tsx | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)
 rename screens/{ => Home}/Home.tsx (95%)

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index e6d9420..28b5292 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -1,6 +1,6 @@
 import {createNativeStackNavigator} from "@react-navigation/native-stack";
 import {NavigationContainer} from "@react-navigation/native";
-import Home from "../screens/Home";
+import Home from "../screens/Home/Home";
 import Question from "../screens/Question/Question";
 import CreationQuiz from "../screens/CreationQuiz/CreationQuiz";
 import FinQuiz from "../screens/FinQuiz/FinQuiz";
diff --git a/screens/Home.tsx b/screens/Home/Home.tsx
similarity index 95%
rename from screens/Home.tsx
rename to screens/Home/Home.tsx
index e682b25..83ff7a9 100644
--- a/screens/Home.tsx
+++ b/screens/Home/Home.tsx
@@ -1,9 +1,9 @@
 import {StyleSheet, View, Text, Modal, TextInput, Image} from "react-native";
-import DefaultButton from "../components/DefaultButton";
-import {TextsStyles} from "../styles/TextsStyles";
+import DefaultButton from "../../components/DefaultButton";
+import {TextsStyles} from "../../styles/TextsStyles";
 import {useTranslation} from "react-i18next";
 import { useState } from "react";
-import { ButtonsStyles } from "../styles/ButtonsStyles";
+import { ButtonsStyles } from "../../styles/ButtonsStyles";
 
 interface Props {
     navigation: any;
-- 
GitLab


From 40eae390fc26c5add850c41ca3fa26e9473c75ca Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 15 Nov 2024 16:38:53 +0100
Subject: [PATCH 002/283] trad: ajout de la traduction de la page Home

---
 screens/Home/Home.tsx         | 4 ++--
 translation/languages/en.json | 4 +++-
 translation/languages/fr.json | 4 +++-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/screens/Home/Home.tsx b/screens/Home/Home.tsx
index 83ff7a9..a4ac3f2 100644
--- a/screens/Home/Home.tsx
+++ b/screens/Home/Home.tsx
@@ -46,8 +46,8 @@ export default function Home({navigation}: Props) {
                 }}>
                     <View style={styles.centeredView}>
                         <View style={styles.modalView}>
-                            <Text style={TextsStyles.subtitleText}>Rejoindre Quiz</Text>
-                            <TextInput placeholder="code de la partie" style={styles.codeTextInput} keyboardType="numeric"/>
+                            <Text style={TextsStyles.subtitleText}>{t.("app.screens.home.joinQuiz")}</Text>
+                            <TextInput placeholder={t("app.screens.home.codeQuiz")} style={styles.codeTextInput} keyboardType="numeric"/>
                             <DefaultButton text="V" handleButtonPressed={handleButtonValidatePressed} buttonStyle={styles.button}></DefaultButton>
                         </View>    
                     </View>
diff --git a/translation/languages/en.json b/translation/languages/en.json
index cd0578e..eb76cb0 100644
--- a/translation/languages/en.json
+++ b/translation/languages/en.json
@@ -4,7 +4,9 @@
       "home": {
         "welcome": "Welcome to Vili",
         "play": "Play",
-        "createQuiz": "Create a Quiz"
+        "createQuiz": "Create a Quiz",
+        "joinQuiz": "Join a Quiz",
+        "codeQuiz": "Quiz Code"
       }
     }
   }
diff --git a/translation/languages/fr.json b/translation/languages/fr.json
index 3cd4cfe..8a93a2f 100644
--- a/translation/languages/fr.json
+++ b/translation/languages/fr.json
@@ -4,7 +4,9 @@
       "home": {
         "welcome": "Bienvenue sur Vili",
         "play": "Jouer",
-        "createQuiz": "Créer un Quizz"
+        "createQuiz": "Créer un Quizz",
+        "joinQuiz": "Rejoindre un Quizz",
+        "codeQuiz": "Code de la partie"
       }
     }
   }
-- 
GitLab


From db0ceb187848d6dd61ea3aaac15645e50aec374c Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 19 Nov 2024 21:28:29 +0100
Subject: [PATCH 003/283] feat: mise a jour expo

---
 app.json          |    1 +
 package-lock.json | 5957 ++++++++++++---------------------------------
 package.json      |   16 +-
 3 files changed, 1619 insertions(+), 4355 deletions(-)

diff --git a/app.json b/app.json
index 74d20a7..0363479 100644
--- a/app.json
+++ b/app.json
@@ -3,6 +3,7 @@
     "name": "vili",
     "slug": "vili",
     "version": "1.0.0",
+    "newArchEnabled": true,
     "orientation": "portrait",
     "icon": "./assets/icon.png",
     "userInterfaceStyle": "light",
diff --git a/package-lock.json b/package-lock.json
index 02eb398..393cf26 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,27 +8,41 @@
       "name": "vili",
       "version": "1.0.0",
       "dependencies": {
-        "@react-native-picker/picker": "2.7.5",
+        "@react-native-picker/picker": "^2.9.0",
         "@react-navigation/native": "^6.1.18",
         "@react-navigation/native-stack": "^6.11.0",
-        "expo": "~51.0.39",
-        "expo-status-bar": "~1.12.1",
+        "expo": "^52.0.8",
+        "expo-status-bar": "~2.0.0",
         "he": "^1.2.0",
         "i18n-js": "^4.5.0",
         "i18next": "^23.16.5",
-        "react": "18.2.0",
+        "react": "^18.3.1",
         "react-i18next": "^15.1.1",
-        "react-native": "0.74.5",
-        "react-native-safe-area-context": "4.10.5",
-        "react-native-screens": "3.31.1"
+        "react-native": "^0.76.2",
+        "react-native-safe-area-context": "^4.12.0",
+        "react-native-screens": "~4.1.0"
       },
       "devDependencies": {
         "@babel/core": "^7.20.0",
         "@types/he": "^1.2.3",
-        "@types/react": "~18.2.45",
+        "@types/react": "~18.3.12",
         "typescript": "~5.3.3"
       }
     },
+    "node_modules/@0no-co/graphql.web": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.11.tgz",
+      "integrity": "sha512-xuSJ9WXwTmtngWkbdEoopMo6F8NLtjy84UNAMsAr5C3/2SgAL/dEU10TMqTIsipqPQ8HA/7WzeqQ9DEQxSvPPA==",
+      "license": "MIT",
+      "peerDependencies": {
+        "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
+      },
+      "peerDependenciesMeta": {
+        "graphql": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@ampproject/remapping": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -207,18 +221,6 @@
         "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
       }
     },
-    "node_modules/@babel/helper-environment-visitor": {
-      "version": "7.24.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
-      "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/types": "^7.24.7"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
     "node_modules/@babel/helper-member-expression-to-functions": {
       "version": "7.25.9",
       "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
@@ -582,25 +584,6 @@
         "@babel/core": "^7.0.0"
       }
     },
-    "node_modules/@babel/plugin-proposal-async-generator-functions": {
-      "version": "7.20.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz",
-      "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==",
-      "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-environment-visitor": "^7.18.9",
-        "@babel/helper-plugin-utils": "^7.20.2",
-        "@babel/helper-remap-async-to-generator": "^7.18.9",
-        "@babel/plugin-syntax-async-generators": "^7.8.4"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
     "node_modules/@babel/plugin-proposal-class-properties": {
       "version": "7.18.6",
       "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
@@ -650,23 +633,6 @@
         "@babel/core": "^7.0.0-0"
       }
     },
-    "node_modules/@babel/plugin-proposal-logical-assignment-operators": {
-      "version": "7.20.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz",
-      "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==",
-      "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/helper-plugin-utils": "^7.20.2",
-        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      },
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
-      }
-    },
     "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": {
       "version": "7.18.6",
       "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz",
@@ -684,15 +650,16 @@
         "@babel/core": "^7.0.0-0"
       }
     },
-    "node_modules/@babel/plugin-proposal-numeric-separator": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz",
-      "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==",
-      "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.",
+    "node_modules/@babel/plugin-proposal-optional-chaining": {
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz",
+      "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==",
+      "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.18.6",
-        "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+        "@babel/helper-plugin-utils": "^7.20.2",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.3"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -701,19 +668,12 @@
         "@babel/core": "^7.0.0-0"
       }
     },
-    "node_modules/@babel/plugin-proposal-object-rest-spread": {
-      "version": "7.20.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz",
-      "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==",
-      "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.",
+    "node_modules/@babel/plugin-proposal-private-property-in-object": {
+      "version": "7.21.0-placeholder-for-preset-env.2",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+      "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
       "license": "MIT",
-      "dependencies": {
-        "@babel/compat-data": "^7.20.5",
-        "@babel/helper-compilation-targets": "^7.20.7",
-        "@babel/helper-plugin-utils": "^7.20.2",
-        "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
-        "@babel/plugin-transform-parameters": "^7.20.7"
-      },
+      "peer": true,
       "engines": {
         "node": ">=6.9.0"
       },
@@ -721,61 +681,52 @@
         "@babel/core": "^7.0.0-0"
       }
     },
-    "node_modules/@babel/plugin-proposal-optional-catch-binding": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz",
-      "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==",
-      "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.",
+    "node_modules/@babel/plugin-syntax-async-generators": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+      "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.18.6",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
-      },
-      "engines": {
-        "node": ">=6.9.0"
+        "@babel/helper-plugin-utils": "^7.8.0"
       },
       "peerDependencies": {
         "@babel/core": "^7.0.0-0"
       }
     },
-    "node_modules/@babel/plugin-proposal-optional-chaining": {
-      "version": "7.21.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz",
-      "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==",
-      "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.",
+    "node_modules/@babel/plugin-syntax-bigint": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+      "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.20.2",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
-        "@babel/plugin-syntax-optional-chaining": "^7.8.3"
-      },
-      "engines": {
-        "node": ">=6.9.0"
+        "@babel/helper-plugin-utils": "^7.8.0"
       },
       "peerDependencies": {
         "@babel/core": "^7.0.0-0"
       }
     },
-    "node_modules/@babel/plugin-proposal-private-property-in-object": {
-      "version": "7.21.0-placeholder-for-preset-env.2",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
-      "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+    "node_modules/@babel/plugin-syntax-class-properties": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+      "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
       "license": "MIT",
-      "peer": true,
-      "engines": {
-        "node": ">=6.9.0"
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.12.13"
       },
       "peerDependencies": {
         "@babel/core": "^7.0.0-0"
       }
     },
-    "node_modules/@babel/plugin-syntax-async-generators": {
-      "version": "7.8.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
-      "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+    "node_modules/@babel/plugin-syntax-class-static-block": {
+      "version": "7.14.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+      "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.8.0"
+        "@babel/helper-plugin-utils": "^7.14.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       },
       "peerDependencies": {
         "@babel/core": "^7.0.0-0"
@@ -859,7 +810,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
       "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9"
       },
@@ -870,6 +820,30 @@
         "@babel/core": "^7.0.0-0"
       }
     },
+    "node_modules/@babel/plugin-syntax-import-meta": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+      "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-json-strings": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+      "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
     "node_modules/@babel/plugin-syntax-jsx": {
       "version": "7.25.9",
       "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz",
@@ -957,6 +931,36 @@
         "@babel/core": "^7.0.0-0"
       }
     },
+    "node_modules/@babel/plugin-syntax-private-property-in-object": {
+      "version": "7.14.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+      "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.14.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-top-level-await": {
+      "version": "7.14.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+      "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.14.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
     "node_modules/@babel/plugin-syntax-typescript": {
       "version": "7.25.9",
       "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz",
@@ -1009,7 +1013,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz",
       "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9",
         "@babel/helper-remap-async-to-generator": "^7.25.9",
@@ -1075,7 +1078,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
       "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-create-class-features-plugin": "^7.25.9",
         "@babel/helper-plugin-utils": "^7.25.9"
@@ -1274,7 +1276,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz",
       "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9",
         "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
@@ -1339,7 +1340,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
       "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9"
       },
@@ -1473,7 +1473,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz",
       "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9"
       },
@@ -1489,7 +1488,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
       "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9"
       },
@@ -1539,7 +1537,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
       "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9"
       },
@@ -1555,7 +1552,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
       "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9",
         "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
@@ -1731,7 +1727,6 @@
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
       "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9",
         "regenerator-transform": "^0.15.2"
@@ -2177,6 +2172,25 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/traverse--for-generate-function-map": {
+      "name": "@babel/traverse",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
+      "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.25.9",
+        "@babel/generator": "^7.25.9",
+        "@babel/parser": "^7.25.9",
+        "@babel/template": "^7.25.9",
+        "@babel/types": "^7.25.9",
+        "debug": "^4.3.1",
+        "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/types": {
       "version": "7.26.0",
       "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
@@ -2203,67 +2217,61 @@
       }
     },
     "node_modules/@expo/cli": {
-      "version": "0.18.31",
-      "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.18.31.tgz",
-      "integrity": "sha512-v9llw9fT3Uv+TCM6Xllo54t672CuYtinEQZ2LPJ2EJsCwuTc4Cd2gXQaouuIVD21VoeGQnr5JtJuWbF97sBKzQ==",
+      "version": "0.21.6",
+      "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.21.6.tgz",
+      "integrity": "sha512-xGeQUK/IX5Wzg2ngXV89wL2s1tWaMJR+sxF8HgGwJqFshC0ikQSV0TRCtz4SCdDjfM7dTPkf4UvOSA45zUMXmA==",
       "license": "MIT",
       "dependencies": {
+        "@0no-co/graphql.web": "^1.0.8",
         "@babel/runtime": "^7.20.0",
-        "@expo/code-signing-certificates": "0.0.5",
-        "@expo/config": "~9.0.0-beta.0",
-        "@expo/config-plugins": "~8.0.8",
-        "@expo/devcert": "^1.0.0",
-        "@expo/env": "~0.3.0",
-        "@expo/image-utils": "^0.5.0",
-        "@expo/json-file": "^8.3.0",
-        "@expo/metro-config": "0.18.11",
+        "@expo/code-signing-certificates": "^0.0.5",
+        "@expo/config": "~10.0.4",
+        "@expo/config-plugins": "~9.0.3",
+        "@expo/devcert": "^1.1.2",
+        "@expo/env": "~0.4.0",
+        "@expo/image-utils": "^0.6.0",
+        "@expo/json-file": "^9.0.0",
+        "@expo/metro-config": "~0.19.0",
         "@expo/osascript": "^2.0.31",
         "@expo/package-manager": "^1.5.0",
-        "@expo/plist": "^0.1.0",
-        "@expo/prebuild-config": "7.0.9",
-        "@expo/rudder-sdk-node": "1.1.1",
+        "@expo/plist": "^0.2.0",
+        "@expo/prebuild-config": "^8.0.16",
+        "@expo/rudder-sdk-node": "^1.1.1",
         "@expo/spawn-async": "^1.7.2",
         "@expo/xcpretty": "^4.3.0",
-        "@react-native/dev-middleware": "0.74.85",
-        "@urql/core": "2.3.6",
-        "@urql/exchange-retry": "0.3.0",
+        "@react-native/dev-middleware": "0.76.2",
+        "@urql/core": "^5.0.6",
+        "@urql/exchange-retry": "^1.3.0",
         "accepts": "^1.3.8",
-        "arg": "5.0.2",
+        "arg": "^5.0.2",
         "better-opn": "~3.0.2",
         "bplist-creator": "0.0.7",
         "bplist-parser": "^0.3.1",
         "cacache": "^18.0.2",
         "chalk": "^4.0.0",
         "ci-info": "^3.3.0",
+        "compression": "^1.7.4",
         "connect": "^3.7.0",
         "debug": "^4.3.4",
         "env-editor": "^0.4.1",
         "fast-glob": "^3.3.2",
-        "find-yarn-workspace-root": "~2.0.0",
         "form-data": "^3.0.1",
-        "freeport-async": "2.0.0",
+        "freeport-async": "^2.0.0",
         "fs-extra": "~8.1.0",
         "getenv": "^1.0.0",
-        "glob": "^7.1.7",
-        "graphql": "15.8.0",
-        "graphql-tag": "^2.10.1",
-        "https-proxy-agent": "^5.0.1",
-        "internal-ip": "4.3.0",
+        "glob": "^10.4.2",
+        "internal-ip": "^4.3.0",
         "is-docker": "^2.0.0",
         "is-wsl": "^2.1.1",
-        "js-yaml": "^3.13.1",
-        "json-schema-deref-sync": "^0.13.0",
         "lodash.debounce": "^4.0.8",
-        "md5hex": "^1.0.0",
         "minimatch": "^3.0.4",
-        "node-fetch": "^2.6.7",
         "node-forge": "^1.3.1",
-        "npm-package-arg": "^7.0.0",
-        "open": "^8.3.0",
-        "ora": "3.4.0",
+        "npm-package-arg": "^11.0.0",
+        "ora": "^3.4.0",
         "picomatch": "^3.0.1",
-        "pretty-bytes": "5.6.0",
-        "progress": "2.0.3",
+        "pretty-bytes": "^5.6.0",
+        "pretty-format": "^29.7.0",
+        "progress": "^2.0.3",
         "prompts": "^2.3.2",
         "qrcode-terminal": "0.11.0",
         "require-from-string": "^2.0.2",
@@ -2272,17 +2280,17 @@
         "resolve-from": "^5.0.0",
         "resolve.exports": "^2.0.2",
         "semver": "^7.6.0",
-        "send": "^0.18.0",
+        "send": "^0.19.0",
         "slugify": "^1.3.4",
         "source-map-support": "~0.5.21",
         "stacktrace-parser": "^0.1.10",
         "structured-headers": "^0.4.1",
-        "tar": "^6.0.5",
+        "tar": "^6.2.1",
         "temp-dir": "^2.0.0",
         "tempy": "^0.7.1",
         "terminal-link": "^2.1.1",
-        "text-table": "^0.2.0",
-        "url-join": "4.0.0",
+        "undici": "^6.18.2",
+        "unique-string": "~2.0.0",
         "wrap-ansi": "^7.0.0",
         "ws": "^8.12.1"
       },
@@ -2290,6 +2298,50 @@
         "expo-internal": "build/bin/cli"
       }
     },
+    "node_modules/@expo/cli/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/@expo/cli/node_modules/glob": {
+      "version": "10.4.5",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+      "license": "ISC",
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@expo/cli/node_modules/glob/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/@expo/cli/node_modules/semver": {
       "version": "7.6.3",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@@ -2313,39 +2365,40 @@
       }
     },
     "node_modules/@expo/config": {
-      "version": "9.0.4",
-      "resolved": "https://registry.npmjs.org/@expo/config/-/config-9.0.4.tgz",
-      "integrity": "sha512-g5ns5u1JSKudHYhjo1zaSfkJ/iZIcWmUmIQptMJZ6ag1C0ShL2sj8qdfU8MmAMuKLOgcIfSaiWlQnm4X3VJVkg==",
+      "version": "10.0.4",
+      "resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.4.tgz",
+      "integrity": "sha512-pkvdPqKTaP6+Qvc8aTmDLQ9Dfwp98P1GO37MFKwsF5XormfN/9/eN8HfIRoM6d3uSIVKCcWW3X2yAEbNmOyfXw==",
       "license": "MIT",
       "dependencies": {
         "@babel/code-frame": "~7.10.4",
-        "@expo/config-plugins": "~8.0.8",
-        "@expo/config-types": "^51.0.3",
-        "@expo/json-file": "^8.3.0",
+        "@expo/config-plugins": "~9.0.0",
+        "@expo/config-types": "^52.0.0",
+        "@expo/json-file": "^9.0.0",
+        "deepmerge": "^4.3.1",
         "getenv": "^1.0.0",
-        "glob": "7.1.6",
+        "glob": "^10.4.2",
         "require-from-string": "^2.0.2",
         "resolve-from": "^5.0.0",
+        "resolve-workspace-root": "^2.0.0",
         "semver": "^7.6.0",
         "slugify": "^1.3.4",
-        "sucrase": "3.34.0"
+        "sucrase": "3.35.0"
       }
     },
     "node_modules/@expo/config-plugins": {
-      "version": "8.0.11",
-      "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-8.0.11.tgz",
-      "integrity": "sha512-oALE1HwnLFthrobAcC9ocnR9KXLzfWEjgIe4CPe+rDsfC6GDs8dGYCXfRFoCEzoLN4TGYs9RdZ8r0KoCcNrm2A==",
+      "version": "9.0.9",
+      "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-9.0.9.tgz",
+      "integrity": "sha512-pbgbY3SwCMwkijhfe163J05BrTx4MqzeaV+nVgUMs7vRcjHY1tfM57Pdv6SPtgeDvZ8fvdXFXXzkJva+a7C9Bw==",
       "license": "MIT",
       "dependencies": {
-        "@expo/config-types": "^51.0.3",
-        "@expo/json-file": "~8.3.0",
-        "@expo/plist": "^0.1.0",
+        "@expo/config-types": "^52.0.0",
+        "@expo/json-file": "~9.0.0",
+        "@expo/plist": "^0.2.0",
         "@expo/sdk-runtime-versions": "^1.0.0",
         "chalk": "^4.1.2",
-        "debug": "^4.3.1",
-        "find-up": "~5.0.0",
+        "debug": "^4.3.5",
         "getenv": "^1.0.0",
-        "glob": "7.1.6",
+        "glob": "^10.4.2",
         "resolve-from": "^5.0.0",
         "semver": "^7.5.4",
         "slash": "^3.0.0",
@@ -2354,22 +2407,45 @@
         "xml2js": "0.6.0"
       }
     },
+    "node_modules/@expo/config-plugins/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
     "node_modules/@expo/config-plugins/node_modules/glob": {
-      "version": "7.1.6",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
-      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
-      "deprecated": "Glob versions prior to v9 are no longer supported",
+      "version": "10.4.5",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
       "license": "ISC",
       "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@expo/config-plugins/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
-        "node": "*"
+        "node": ">=16 || 14 >=14.17"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
@@ -2388,9 +2464,9 @@
       }
     },
     "node_modules/@expo/config-types": {
-      "version": "51.0.3",
-      "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-51.0.3.tgz",
-      "integrity": "sha512-hMfuq++b8VySb+m9uNNrlpbvGxYc8OcFCUX9yTmi9tlx6A4k8SDabWFBgmnr4ao3wEArvWrtUQIfQCVtPRdpKA==",
+      "version": "52.0.1",
+      "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-52.0.1.tgz",
+      "integrity": "sha512-vD8ZetyKV7U29lR6+NJohYeoLYTH+eNYXJeNiSOrWCz0witJYY11meMmEnpEaVbN89EfC6uauSUOa6wihtbyPQ==",
       "license": "MIT"
     },
     "node_modules/@expo/config/node_modules/@babel/code-frame": {
@@ -2402,22 +2478,45 @@
         "@babel/highlight": "^7.10.4"
       }
     },
-    "node_modules/@expo/config/node_modules/glob": {
-      "version": "7.1.6",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
-      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
-      "deprecated": "Glob versions prior to v9 are no longer supported",
-      "license": "ISC",
+    "node_modules/@expo/config/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "license": "MIT",
       "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/@expo/config/node_modules/glob": {
+      "version": "10.4.5",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+      "license": "ISC",
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@expo/config/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
-        "node": "*"
+        "node": ">=16 || 14 >=14.17"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
@@ -2509,9 +2608,9 @@
       }
     },
     "node_modules/@expo/env": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/@expo/env/-/env-0.3.0.tgz",
-      "integrity": "sha512-OtB9XVHWaXidLbHvrVDeeXa09yvTl3+IQN884sO6PhIi2/StXfgSH/9zC7IvzrDB8kW3EBJ1PPLuCUJ2hxAT7Q==",
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/@expo/env/-/env-0.4.0.tgz",
+      "integrity": "sha512-g2JYFqck3xKIwJyK+8LxZ2ENZPWtRgjFWpeht9abnKgzXVXBeSNECFBkg+WQjQocSIdxXhEWM6hz4ZAe7Tc4ng==",
       "license": "MIT",
       "dependencies": {
         "chalk": "^4.0.0",
@@ -2521,10 +2620,43 @@
         "getenv": "^1.0.0"
       }
     },
+    "node_modules/@expo/fingerprint": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.11.2.tgz",
+      "integrity": "sha512-WPibADqymGSKkNNnrGfw4dRipz7F8DwMSv7zb6T9oTGtdRiObrUpGmtBXmvo6z9MqWkNRprEJNxPjvkkvMvwhQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@expo/spawn-async": "^1.7.2",
+        "arg": "^5.0.2",
+        "chalk": "^4.1.2",
+        "debug": "^4.3.4",
+        "find-up": "^5.0.0",
+        "getenv": "^1.0.0",
+        "minimatch": "^3.0.4",
+        "p-limit": "^3.1.0",
+        "resolve-from": "^5.0.0",
+        "semver": "^7.6.0"
+      },
+      "bin": {
+        "fingerprint": "bin/cli.js"
+      }
+    },
+    "node_modules/@expo/fingerprint/node_modules/semver": {
+      "version": "7.6.3",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/@expo/image-utils": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.5.1.tgz",
-      "integrity": "sha512-U/GsFfFox88lXULmFJ9Shfl2aQGcwoKPF7fawSCLixIKtMCpsI+1r0h+5i0nQnmt9tHuzXZDL8+Dg1z6OhkI9A==",
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.6.3.tgz",
+      "integrity": "sha512-v/JbCKBrHeudxn1gN1TgfPE/pWJSlLPrl29uXJBgrJFQVkViQvUHQNDhaS+UEa9wYI5HHh7XYmtzAehyG4L+GA==",
       "license": "MIT",
       "dependencies": {
         "@expo/spawn-async": "^1.7.2",
@@ -2532,20 +2664,11 @@
         "fs-extra": "9.0.0",
         "getenv": "^1.0.0",
         "jimp-compact": "0.16.1",
-        "node-fetch": "^2.6.0",
         "parse-png": "^2.1.0",
         "resolve-from": "^5.0.0",
         "semver": "^7.6.0",
-        "tempy": "0.3.0"
-      }
-    },
-    "node_modules/@expo/image-utils/node_modules/crypto-random-string": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
-      "integrity": "sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
+        "temp-dir": "~2.0.0",
+        "unique-string": "~2.0.0"
       }
     },
     "node_modules/@expo/image-utils/node_modules/fs-extra": {
@@ -2596,50 +2719,6 @@
         "node": ">=10"
       }
     },
-    "node_modules/@expo/image-utils/node_modules/temp-dir": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
-      "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/@expo/image-utils/node_modules/tempy": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz",
-      "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==",
-      "license": "MIT",
-      "dependencies": {
-        "temp-dir": "^1.0.0",
-        "type-fest": "^0.3.1",
-        "unique-string": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@expo/image-utils/node_modules/type-fest": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz",
-      "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==",
-      "license": "(MIT OR CC0-1.0)",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@expo/image-utils/node_modules/unique-string": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
-      "integrity": "sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==",
-      "license": "MIT",
-      "dependencies": {
-        "crypto-random-string": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/@expo/image-utils/node_modules/universalify": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
@@ -2650,13 +2729,13 @@
       }
     },
     "node_modules/@expo/json-file": {
-      "version": "8.3.3",
-      "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-8.3.3.tgz",
-      "integrity": "sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A==",
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-9.0.0.tgz",
+      "integrity": "sha512-M+55xFVrFzDcgMDf+52lPDLjKB5xwRfStWlv/b/Vu2OLgxGZLWpxoPYjlRoHqxjPbCQIi2ZCbobK+0KuNhsELg==",
       "license": "MIT",
       "dependencies": {
         "@babel/code-frame": "~7.10.4",
-        "json5": "^2.2.2",
+        "json5": "^2.2.3",
         "write-file-atomic": "^2.3.0"
       }
     },
@@ -2670,31 +2749,40 @@
       }
     },
     "node_modules/@expo/metro-config": {
-      "version": "0.18.11",
-      "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.18.11.tgz",
-      "integrity": "sha512-/uOq55VbSf9yMbUO1BudkUM2SsGW1c5hr9BnhIqYqcsFv0Jp5D3DtJ4rljDKaUeNLbwr6m7pqIrkSMq5NrYf4Q==",
+      "version": "0.19.4",
+      "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.4.tgz",
+      "integrity": "sha512-2SWwYN8MZvMIRawWEr+1RBYncitPwu2VMACRYig+wBycJ9fsPb6BMVmBYi+3MHDUlJHNy/Bqfw++jn1eqBFETQ==",
       "license": "MIT",
       "dependencies": {
         "@babel/core": "^7.20.0",
         "@babel/generator": "^7.20.5",
         "@babel/parser": "^7.20.0",
         "@babel/types": "^7.20.0",
-        "@expo/config": "~9.0.0-beta.0",
-        "@expo/env": "~0.3.0",
-        "@expo/json-file": "~8.3.0",
+        "@expo/config": "~10.0.4",
+        "@expo/env": "~0.4.0",
+        "@expo/json-file": "~9.0.0",
         "@expo/spawn-async": "^1.7.2",
         "chalk": "^4.1.0",
         "debug": "^4.3.2",
-        "find-yarn-workspace-root": "~2.0.0",
         "fs-extra": "^9.1.0",
         "getenv": "^1.0.0",
-        "glob": "^7.2.3",
+        "glob": "^10.4.2",
         "jsc-safe-url": "^0.2.4",
-        "lightningcss": "~1.19.0",
+        "lightningcss": "~1.27.0",
+        "minimatch": "^3.0.4",
         "postcss": "~8.4.32",
         "resolve-from": "^5.0.0"
       }
     },
+    "node_modules/@expo/metro-config/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
     "node_modules/@expo/metro-config/node_modules/fs-extra": {
       "version": "9.1.0",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
@@ -2710,6 +2798,41 @@
         "node": ">=10"
       }
     },
+    "node_modules/@expo/metro-config/node_modules/glob": {
+      "version": "10.4.5",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+      "license": "ISC",
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@expo/metro-config/node_modules/glob/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/@expo/metro-config/node_modules/jsonfile": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -2732,9 +2855,9 @@
       }
     },
     "node_modules/@expo/osascript": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.1.3.tgz",
-      "integrity": "sha512-aOEkhPzDsaAfolSswObGiYW0Pf0ROfR9J2NBRLQACdQ6uJlyAMiPF45DVEVknAU9juKh0y8ZyvC9LXqLEJYohA==",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.1.4.tgz",
+      "integrity": "sha512-LcPjxJ5FOFpqPORm+5MRLV0CuYWMthJYV6eerF+lQVXKlvgSn3EOqaHC3Vf3H+vmB0f6G4kdvvFtg40vG4bIhA==",
       "license": "MIT",
       "dependencies": {
         "@expo/spawn-async": "^1.7.2",
@@ -2745,21 +2868,21 @@
       }
     },
     "node_modules/@expo/package-manager": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.5.2.tgz",
-      "integrity": "sha512-IuA9XtGBilce0q8cyxtWINqbzMB1Fia0Yrug/O53HNuRSwQguV/iqjV68bsa4z8mYerePhcFgtvISWLAlNEbUA==",
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.6.1.tgz",
+      "integrity": "sha512-4rT46wP/94Ll+CWXtFKok1Lbo9XncSUtErFOo/9/3FVughGbIfdG4SKZOAWIpr9wxwEfkyhHfAP9q71ONlWODw==",
       "license": "MIT",
       "dependencies": {
-        "@expo/json-file": "^8.3.0",
+        "@expo/json-file": "^9.0.0",
         "@expo/spawn-async": "^1.7.2",
         "ansi-regex": "^5.0.0",
         "chalk": "^4.0.0",
         "find-up": "^5.0.0",
-        "find-yarn-workspace-root": "~2.0.0",
         "js-yaml": "^3.13.1",
-        "micromatch": "^4.0.2",
-        "npm-package-arg": "^7.0.0",
+        "micromatch": "^4.0.8",
+        "npm-package-arg": "^11.0.0",
         "ora": "^3.4.0",
+        "resolve-workspace-root": "^2.0.0",
         "split": "^1.0.1",
         "sudo-prompt": "9.1.1"
       }
@@ -2771,9 +2894,9 @@
       "license": "MIT"
     },
     "node_modules/@expo/plist": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.1.3.tgz",
-      "integrity": "sha512-GW/7hVlAylYg1tUrEASclw1MMk9FP4ZwyFAY/SUTJIhPDQHtfOlXREyWV3hhrHdX/K+pS73GNgdfT6E/e+kBbg==",
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.2.0.tgz",
+      "integrity": "sha512-F/IZJQaf8OIVnVA6XWUeMPC3OH6MV00Wxf0WC0JhTQht2QgjyHUa3U5Gs3vRtDq8tXNsZneOQRDVwpaOnd4zTQ==",
       "license": "MIT",
       "dependencies": {
         "@xmldom/xmldom": "~0.7.7",
@@ -2782,25 +2905,22 @@
       }
     },
     "node_modules/@expo/prebuild-config": {
-      "version": "7.0.9",
-      "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-7.0.9.tgz",
-      "integrity": "sha512-9i6Cg7jInpnGEHN0jxnW0P+0BexnePiBzmbUvzSbRXpdXihYUX2AKMu73jgzxn5P1hXOSkzNS7umaY+BZ+aBag==",
+      "version": "8.0.17",
+      "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.0.17.tgz",
+      "integrity": "sha512-HM+XpDox3fAZuXZXvy55VRcBbsZSDijGf8jI8i/pexgWvtsnt1ouelPXRuE1pXDicMX+lZO83QV+XkyLmBEXYQ==",
       "license": "MIT",
       "dependencies": {
-        "@expo/config": "~9.0.0-beta.0",
-        "@expo/config-plugins": "~8.0.8",
-        "@expo/config-types": "^51.0.3",
-        "@expo/image-utils": "^0.5.0",
-        "@expo/json-file": "^8.3.0",
-        "@react-native/normalize-colors": "0.74.85",
+        "@expo/config": "~10.0.4",
+        "@expo/config-plugins": "~9.0.0",
+        "@expo/config-types": "^52.0.0",
+        "@expo/image-utils": "^0.6.0",
+        "@expo/json-file": "^9.0.0",
+        "@react-native/normalize-colors": "0.76.2",
         "debug": "^4.3.1",
         "fs-extra": "^9.0.0",
         "resolve-from": "^5.0.0",
         "semver": "^7.6.0",
         "xml2js": "0.6.0"
-      },
-      "peerDependencies": {
-        "expo-modules-autolinking": ">=0.8.1"
       }
     },
     "node_modules/@expo/prebuild-config/node_modules/fs-extra": {
@@ -2938,30 +3058,6 @@
         "js-yaml": "bin/js-yaml.js"
       }
     },
-    "node_modules/@graphql-typed-document-node/core": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz",
-      "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==",
-      "license": "MIT",
-      "peerDependencies": {
-        "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
-      }
-    },
-    "node_modules/@hapi/hoek": {
-      "version": "9.3.0",
-      "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
-      "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@hapi/topo": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
-      "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "@hapi/hoek": "^9.0.0"
-      }
-    },
     "node_modules/@isaacs/cliui": {
       "version": "8.0.2",
       "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -3067,51 +3163,93 @@
         "node": ">=12"
       }
     },
-    "node_modules/@jest/create-cache-key-function": {
-      "version": "29.7.0",
-      "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
-      "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
+    "node_modules/@istanbuljs/load-nyc-config": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+      "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+      "license": "ISC",
+      "dependencies": {
+        "camelcase": "^5.3.1",
+        "find-up": "^4.1.0",
+        "get-package-type": "^0.1.0",
+        "js-yaml": "^3.13.1",
+        "resolve-from": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
       "license": "MIT",
       "dependencies": {
-        "@jest/types": "^29.6.3"
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
       },
       "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+        "node": ">=8"
       }
     },
-    "node_modules/@jest/create-cache-key-function/node_modules/@jest/types": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
-      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
       "license": "MIT",
       "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^17.0.8",
-        "chalk": "^4.0.0"
+        "p-locate": "^4.1.0"
       },
       "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+        "node": ">=8"
       }
     },
-    "node_modules/@jest/create-cache-key-function/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
       "license": "MIT",
       "dependencies": {
-        "@types/istanbul-lib-report": "*"
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@jest/create-cache-key-function/node_modules/@types/yargs": {
-      "version": "17.0.33",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
-      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
       "license": "MIT",
       "dependencies": {
-        "@types/yargs-parser": "*"
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@istanbuljs/schema": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@jest/create-cache-key-function": {
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
+      "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
+      "license": "MIT",
+      "dependencies": {
+        "@jest/types": "^29.6.3"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
     "node_modules/@jest/environment": {
@@ -3129,59 +3267,75 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/@jest/environment/node_modules/@jest/types": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
-      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+    "node_modules/@jest/fake-timers": {
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
+      "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
       "license": "MIT",
       "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
+        "@jest/types": "^29.6.3",
+        "@sinonjs/fake-timers": "^10.0.2",
         "@types/node": "*",
-        "@types/yargs": "^17.0.8",
-        "chalk": "^4.0.0"
+        "jest-message-util": "^29.7.0",
+        "jest-mock": "^29.7.0",
+        "jest-util": "^29.7.0"
       },
       "engines": {
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/@jest/environment/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/@jest/environment/node_modules/@types/yargs": {
-      "version": "17.0.33",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
-      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+    "node_modules/@jest/schemas": {
+      "version": "29.6.3",
+      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+      "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
       "license": "MIT",
       "dependencies": {
-        "@types/yargs-parser": "*"
+        "@sinclair/typebox": "^0.27.8"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/@jest/fake-timers": {
+    "node_modules/@jest/transform": {
       "version": "29.7.0",
-      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
-      "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
+      "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
+      "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
       "license": "MIT",
       "dependencies": {
+        "@babel/core": "^7.11.6",
         "@jest/types": "^29.6.3",
-        "@sinonjs/fake-timers": "^10.0.2",
-        "@types/node": "*",
-        "jest-message-util": "^29.7.0",
-        "jest-mock": "^29.7.0",
-        "jest-util": "^29.7.0"
+        "@jridgewell/trace-mapping": "^0.3.18",
+        "babel-plugin-istanbul": "^6.1.1",
+        "chalk": "^4.0.0",
+        "convert-source-map": "^2.0.0",
+        "fast-json-stable-stringify": "^2.1.0",
+        "graceful-fs": "^4.2.9",
+        "jest-haste-map": "^29.7.0",
+        "jest-regex-util": "^29.6.3",
+        "jest-util": "^29.7.0",
+        "micromatch": "^4.0.4",
+        "pirates": "^4.0.4",
+        "slash": "^3.0.0",
+        "write-file-atomic": "^4.0.2"
       },
       "engines": {
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/@jest/fake-timers/node_modules/@jest/types": {
+    "node_modules/@jest/transform/node_modules/write-file-atomic": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+      "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+      "license": "ISC",
+      "dependencies": {
+        "imurmurhash": "^0.1.4",
+        "signal-exit": "^3.0.7"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+      }
+    },
+    "node_modules/@jest/types": {
       "version": "29.6.3",
       "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
       "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
@@ -3198,50 +3352,6 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/@jest/fake-timers/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/@jest/fake-timers/node_modules/@types/yargs": {
-      "version": "17.0.33",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
-      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/@jest/schemas": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
-      "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
-      "license": "MIT",
-      "dependencies": {
-        "@sinclair/typebox": "^0.27.8"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@jest/types": {
-      "version": "24.9.0",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz",
-      "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^1.1.1",
-        "@types/yargs": "^13.0.0"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/@jridgewell/gen-mapping": {
       "version": "0.3.5",
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
@@ -3369,50 +3479,149 @@
         "node": ">=14"
       }
     },
-    "node_modules/@react-native-community/cli": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-13.6.9.tgz",
-      "integrity": "sha512-hFJL4cgLPxncJJd/epQ4dHnMg5Jy/7Q56jFvA3MHViuKpzzfTCJCB+pGY54maZbtym53UJON9WTGpM3S81UfjQ==",
+    "node_modules/@react-native-picker/picker": {
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.9.0.tgz",
+      "integrity": "sha512-khEhIW/uhfMqq/+tvg4rEAiPGT8GX+Y6QydlP2TSMSmRHoSJK+ShXvXZXSr4Sii4imkj4BwvLunGywwtQDODqg==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": "*",
+        "react-native": "*"
+      }
+    },
+    "node_modules/@react-native/assets-registry": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.2.tgz",
+      "integrity": "sha512-0CTWv/FqJzU1vsyx2JpCkyLSUOePU7DdKgFvtHdwOxFpOw3aBecszqZDGJADYV9WSZQlq6RV0HmIaWycGYCOMA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@react-native/babel-plugin-codegen": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.2.tgz",
+      "integrity": "sha512-a1IfRho/ZUVbvzSu3JWkxsvqyEI7IXApPQikhGWw4e24QYsIYHdlIULs3rb0840lqpO1dbbuudfO7lmkpkbkMg==",
       "license": "MIT",
       "dependencies": {
-        "@react-native-community/cli-clean": "13.6.9",
-        "@react-native-community/cli-config": "13.6.9",
-        "@react-native-community/cli-debugger-ui": "13.6.9",
-        "@react-native-community/cli-doctor": "13.6.9",
-        "@react-native-community/cli-hermes": "13.6.9",
-        "@react-native-community/cli-server-api": "13.6.9",
-        "@react-native-community/cli-tools": "13.6.9",
-        "@react-native-community/cli-types": "13.6.9",
-        "chalk": "^4.1.2",
-        "commander": "^9.4.1",
-        "deepmerge": "^4.3.0",
-        "execa": "^5.0.0",
-        "find-up": "^4.1.0",
-        "fs-extra": "^8.1.0",
-        "graceful-fs": "^4.1.3",
-        "prompts": "^2.4.2",
-        "semver": "^7.5.2"
+        "@react-native/codegen": "0.76.2"
       },
-      "bin": {
-        "rnc-cli": "build/bin.js"
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@react-native/babel-preset": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.2.tgz",
+      "integrity": "sha512-/kbxZqy70mGONv23uZg7lm7ZCE4dO5dgMzVPz6QsveXIRHQBRLsSC+9w2iZEnYWpLayoWFmTbq8ZG+4W32D3bA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "^7.25.2",
+        "@babel/plugin-proposal-export-default-from": "^7.24.7",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+        "@babel/plugin-syntax-export-default-from": "^7.24.7",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+        "@babel/plugin-transform-arrow-functions": "^7.24.7",
+        "@babel/plugin-transform-async-generator-functions": "^7.25.4",
+        "@babel/plugin-transform-async-to-generator": "^7.24.7",
+        "@babel/plugin-transform-block-scoping": "^7.25.0",
+        "@babel/plugin-transform-class-properties": "^7.25.4",
+        "@babel/plugin-transform-classes": "^7.25.4",
+        "@babel/plugin-transform-computed-properties": "^7.24.7",
+        "@babel/plugin-transform-destructuring": "^7.24.8",
+        "@babel/plugin-transform-flow-strip-types": "^7.25.2",
+        "@babel/plugin-transform-for-of": "^7.24.7",
+        "@babel/plugin-transform-function-name": "^7.25.1",
+        "@babel/plugin-transform-literals": "^7.25.2",
+        "@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
+        "@babel/plugin-transform-modules-commonjs": "^7.24.8",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
+        "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
+        "@babel/plugin-transform-numeric-separator": "^7.24.7",
+        "@babel/plugin-transform-object-rest-spread": "^7.24.7",
+        "@babel/plugin-transform-optional-catch-binding": "^7.24.7",
+        "@babel/plugin-transform-optional-chaining": "^7.24.8",
+        "@babel/plugin-transform-parameters": "^7.24.7",
+        "@babel/plugin-transform-private-methods": "^7.24.7",
+        "@babel/plugin-transform-private-property-in-object": "^7.24.7",
+        "@babel/plugin-transform-react-display-name": "^7.24.7",
+        "@babel/plugin-transform-react-jsx": "^7.25.2",
+        "@babel/plugin-transform-react-jsx-self": "^7.24.7",
+        "@babel/plugin-transform-react-jsx-source": "^7.24.7",
+        "@babel/plugin-transform-regenerator": "^7.24.7",
+        "@babel/plugin-transform-runtime": "^7.24.7",
+        "@babel/plugin-transform-shorthand-properties": "^7.24.7",
+        "@babel/plugin-transform-spread": "^7.24.7",
+        "@babel/plugin-transform-sticky-regex": "^7.24.7",
+        "@babel/plugin-transform-typescript": "^7.25.2",
+        "@babel/plugin-transform-unicode-regex": "^7.24.7",
+        "@babel/template": "^7.25.0",
+        "@react-native/babel-plugin-codegen": "0.76.2",
+        "babel-plugin-syntax-hermes-parser": "^0.25.1",
+        "babel-plugin-transform-flow-enums": "^0.0.2",
+        "react-refresh": "^0.14.0"
       },
       "engines": {
         "node": ">=18"
+      },
+      "peerDependencies": {
+        "@babel/core": "*"
       }
     },
-    "node_modules/@react-native-community/cli-clean": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-13.6.9.tgz",
-      "integrity": "sha512-7Dj5+4p9JggxuVNOjPbduZBAP1SUgNhLKVw5noBUzT/3ZpUZkDM+RCSwyoyg8xKWoE4OrdUAXwAFlMcFDPKykA==",
+    "node_modules/@react-native/codegen": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.2.tgz",
+      "integrity": "sha512-rIgdI5mHHnNTzAeDYH+ivKMIcv6vr04Ol+TmX77n1HjJkzMhQqSHWcX+Pq9oiu7l2zKkymadrw6OPD8VPgre8g==",
       "license": "MIT",
       "dependencies": {
-        "@react-native-community/cli-tools": "13.6.9",
-        "chalk": "^4.1.2",
-        "execa": "^5.0.0",
-        "fast-glob": "^3.3.2"
+        "@babel/parser": "^7.25.3",
+        "glob": "^7.1.1",
+        "hermes-parser": "0.23.1",
+        "invariant": "^2.2.4",
+        "jscodeshift": "^0.14.0",
+        "mkdirp": "^0.5.1",
+        "nullthrows": "^1.1.1",
+        "yargs": "^17.6.2"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@babel/preset-env": "^7.1.6"
+      }
+    },
+    "node_modules/@react-native/community-cli-plugin": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.2.tgz",
+      "integrity": "sha512-ZRL8oTGSMwXqTsVkRL9AVW8C/AZRnxCcFfhestsx//SrQt3J/hbtDOHTIGkkt5AEA0zEvb/UAAyIAN/wuN4llw==",
+      "license": "MIT",
+      "dependencies": {
+        "@react-native/dev-middleware": "0.76.2",
+        "@react-native/metro-babel-transformer": "0.76.2",
+        "chalk": "^4.0.0",
+        "execa": "^5.1.1",
+        "invariant": "^2.2.4",
+        "metro": "^0.81.0",
+        "metro-config": "^0.81.0",
+        "metro-core": "^0.81.0",
+        "node-fetch": "^2.2.0",
+        "readline": "^1.3.0",
+        "semver": "^7.1.3"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@react-native-community/cli-server-api": "*"
+      },
+      "peerDependenciesMeta": {
+        "@react-native-community/cli-server-api": {
+          "optional": true
+        }
       }
     },
-    "node_modules/@react-native-community/cli-clean/node_modules/execa": {
+    "node_modules/@react-native/community-cli-plugin/node_modules/execa": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
       "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
@@ -3435,7 +3644,7 @@
         "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
-    "node_modules/@react-native-community/cli-clean/node_modules/get-stream": {
+    "node_modules/@react-native/community-cli-plugin/node_modules/get-stream": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
       "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
@@ -3447,7 +3656,7 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@react-native-community/cli-clean/node_modules/is-stream": {
+    "node_modules/@react-native/community-cli-plugin/node_modules/is-stream": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
       "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
@@ -3459,7 +3668,7 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@react-native-community/cli-clean/node_modules/mimic-fn": {
+    "node_modules/@react-native/community-cli-plugin/node_modules/mimic-fn": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
       "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
@@ -3468,7 +3677,7 @@
         "node": ">=6"
       }
     },
-    "node_modules/@react-native-community/cli-clean/node_modules/npm-run-path": {
+    "node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
       "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
@@ -3480,7 +3689,7 @@
         "node": ">=8"
       }
     },
-    "node_modules/@react-native-community/cli-clean/node_modules/onetime": {
+    "node_modules/@react-native/community-cli-plugin/node_modules/onetime": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
       "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
@@ -3495,1386 +3704,119 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/@react-native-community/cli-config": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-13.6.9.tgz",
-      "integrity": "sha512-rFfVBcNojcMm+KKHE/xqpqXg8HoKl4EC7bFHUrahMJ+y/tZll55+oX/PGG37rzB8QzP2UbMQ19DYQKC1G7kXeg==",
-      "license": "MIT",
-      "dependencies": {
-        "@react-native-community/cli-tools": "13.6.9",
-        "chalk": "^4.1.2",
-        "cosmiconfig": "^5.1.0",
-        "deepmerge": "^4.3.0",
-        "fast-glob": "^3.3.2",
-        "joi": "^17.2.1"
+    "node_modules/@react-native/community-cli-plugin/node_modules/semver": {
+      "version": "7.6.3",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "node_modules/@react-native-community/cli-debugger-ui": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-13.6.9.tgz",
-      "integrity": "sha512-TkN7IdFmGPPvTpAo3nCAH9uwGCPxWBEAwpqEZDrq0NWllI7Tdie8vDpGdrcuCcKalmhq6OYnkXzeBah7O1Ztpw==",
-      "license": "MIT",
-      "dependencies": {
-        "serve-static": "^1.13.1"
+    "node_modules/@react-native/debugger-frontend": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.2.tgz",
+      "integrity": "sha512-FIcz24Oya2wIO7rZD3dxVyK8t5ZD6Fojl9o7lrjnTWqMedcevRTtdSOIAf4ypksYH/x7HypovE2Zp8U65Xv0Mw==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/@react-native-community/cli-doctor": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-13.6.9.tgz",
-      "integrity": "sha512-5quFaLdWFQB+677GXh5dGU9I5eg2z6Vg4jOX9vKnc9IffwyIFAyJfCZHrxLSRPDGNXD7biDQUdoezXYGwb6P/A==",
+    "node_modules/@react-native/dev-middleware": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.2.tgz",
+      "integrity": "sha512-qiowXpxofLk0lpIZps7fyyp9NiKlqBwh0R0yVub5l4EJcqjLonjsznYAHbusnPW9kb9MQSdovGPNv5b8RadJww==",
       "license": "MIT",
       "dependencies": {
-        "@react-native-community/cli-config": "13.6.9",
-        "@react-native-community/cli-platform-android": "13.6.9",
-        "@react-native-community/cli-platform-apple": "13.6.9",
-        "@react-native-community/cli-platform-ios": "13.6.9",
-        "@react-native-community/cli-tools": "13.6.9",
-        "chalk": "^4.1.2",
-        "command-exists": "^1.2.8",
-        "deepmerge": "^4.3.0",
-        "envinfo": "^7.10.0",
-        "execa": "^5.0.0",
-        "hermes-profile-transformer": "^0.0.6",
-        "node-stream-zip": "^1.9.1",
-        "ora": "^5.4.1",
-        "semver": "^7.5.2",
-        "strip-ansi": "^5.2.0",
-        "wcwidth": "^1.0.1",
-        "yaml": "^2.2.1"
+        "@isaacs/ttlcache": "^1.4.1",
+        "@react-native/debugger-frontend": "0.76.2",
+        "chrome-launcher": "^0.15.2",
+        "chromium-edge-launcher": "^0.2.0",
+        "connect": "^3.6.5",
+        "debug": "^2.2.0",
+        "nullthrows": "^1.1.1",
+        "open": "^7.0.3",
+        "selfsigned": "^2.4.1",
+        "serve-static": "^1.13.1",
+        "ws": "^6.2.3"
+      },
+      "engines": {
+        "node": ">=18"
       }
     },
-    "node_modules/@react-native-community/cli-doctor/node_modules/cli-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
-      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+    "node_modules/@react-native/dev-middleware/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
       "license": "MIT",
       "dependencies": {
-        "restore-cursor": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=8"
+        "ms": "2.0.0"
       }
     },
-    "node_modules/@react-native-community/cli-doctor/node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+    "node_modules/@react-native/dev-middleware/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "license": "MIT"
+    },
+    "node_modules/@react-native/dev-middleware/node_modules/ws": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
+      "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
       "license": "MIT",
       "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
+        "async-limiter": "~1.0.0"
       }
     },
-    "node_modules/@react-native-community/cli-doctor/node_modules/get-stream": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
-      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+    "node_modules/@react-native/gradle-plugin": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.2.tgz",
+      "integrity": "sha512-KC5/uAeLoeD1dOjymx6gnNFHGGLB22xNYjrjrJNK5r0bw2O2KXp4rpB5VCT/2H5B48cVC0xPB7RIKOFrDHr5bQ==",
       "license": "MIT",
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=18"
       }
     },
-    "node_modules/@react-native-community/cli-doctor/node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+    "node_modules/@react-native/js-polyfills": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.2.tgz",
+      "integrity": "sha512-OXunyNn33fa7gQ6iU5rQcYZQsO7OkJIAr/TgVdoHxpOB4i+ZGsfv6df3JKriBVT1ZZm6ZTlKyIa4QpLq3p0dmw==",
       "license": "MIT",
       "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=18"
       }
     },
-    "node_modules/@react-native-community/cli-doctor/node_modules/log-symbols": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+    "node_modules/@react-native/metro-babel-transformer": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.2.tgz",
+      "integrity": "sha512-OIYhmWfN+HDyQLzoEg+2P0h7OopYk4djggg0M+k5e1a+g2dFNJILO/BsDobM8uLA8hAzClAJyJLZbPo5jeqdMA==",
       "license": "MIT",
       "dependencies": {
-        "chalk": "^4.1.0",
-        "is-unicode-supported": "^0.1.0"
+        "@babel/core": "^7.25.2",
+        "@react-native/babel-preset": "0.76.2",
+        "hermes-parser": "0.23.1",
+        "nullthrows": "^1.1.1"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=18"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "peerDependencies": {
+        "@babel/core": "*"
       }
     },
-    "node_modules/@react-native-community/cli-doctor/node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@react-native-community/cli-doctor/node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-doctor/node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "license": "MIT",
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-doctor/node_modules/ora": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
-      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
-      "license": "MIT",
-      "dependencies": {
-        "bl": "^4.1.0",
-        "chalk": "^4.1.0",
-        "cli-cursor": "^3.1.0",
-        "cli-spinners": "^2.5.0",
-        "is-interactive": "^1.0.0",
-        "is-unicode-supported": "^0.1.0",
-        "log-symbols": "^4.1.0",
-        "strip-ansi": "^6.0.0",
-        "wcwidth": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-doctor/node_modules/ora/node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-doctor/node_modules/restore-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
-      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
-      "license": "MIT",
-      "dependencies": {
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-doctor/node_modules/semver": {
-      "version": "7.6.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
-      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@react-native-community/cli-hermes": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-13.6.9.tgz",
-      "integrity": "sha512-GvwiwgvFw4Ws+krg2+gYj8sR3g05evmNjAHkKIKMkDTJjZ8EdyxbkifRUs1ZCq3TMZy2oeblZBXCJVOH4W7ZbA==",
-      "license": "MIT",
-      "dependencies": {
-        "@react-native-community/cli-platform-android": "13.6.9",
-        "@react-native-community/cli-tools": "13.6.9",
-        "chalk": "^4.1.2",
-        "hermes-profile-transformer": "^0.0.6"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-android": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-13.6.9.tgz",
-      "integrity": "sha512-9KsYGdr08QhdvT3Ht7e8phQB3gDX9Fs427NJe0xnoBh+PDPTI2BD5ks5ttsH8CzEw8/P6H8tJCHq6hf2nxd9cw==",
-      "license": "MIT",
-      "dependencies": {
-        "@react-native-community/cli-tools": "13.6.9",
-        "chalk": "^4.1.2",
-        "execa": "^5.0.0",
-        "fast-glob": "^3.3.2",
-        "fast-xml-parser": "^4.2.4",
-        "logkitty": "^0.7.1"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-android/node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
-      "license": "MIT",
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-android/node_modules/get-stream": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
-      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-android/node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-android/node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-android/node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-android/node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "license": "MIT",
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-apple/-/cli-platform-apple-13.6.9.tgz",
-      "integrity": "sha512-KoeIHfhxMhKXZPXmhQdl6EE+jGKWwoO9jUVWgBvibpVmsNjo7woaG/tfJMEWfWF3najX1EkQAoJWpCDBMYWtlA==",
-      "license": "MIT",
-      "dependencies": {
-        "@react-native-community/cli-tools": "13.6.9",
-        "chalk": "^4.1.2",
-        "execa": "^5.0.0",
-        "fast-glob": "^3.3.2",
-        "fast-xml-parser": "^4.0.12",
-        "ora": "^5.4.1"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/cli-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
-      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
-      "license": "MIT",
-      "dependencies": {
-        "restore-cursor": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
-      "license": "MIT",
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/get-stream": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
-      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/log-symbols": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-      "license": "MIT",
-      "dependencies": {
-        "chalk": "^4.1.0",
-        "is-unicode-supported": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "license": "MIT",
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/ora": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
-      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
-      "license": "MIT",
-      "dependencies": {
-        "bl": "^4.1.0",
-        "chalk": "^4.1.0",
-        "cli-cursor": "^3.1.0",
-        "cli-spinners": "^2.5.0",
-        "is-interactive": "^1.0.0",
-        "is-unicode-supported": "^0.1.0",
-        "log-symbols": "^4.1.0",
-        "strip-ansi": "^6.0.0",
-        "wcwidth": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/restore-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
-      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
-      "license": "MIT",
-      "dependencies": {
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-apple/node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-platform-ios": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-13.6.9.tgz",
-      "integrity": "sha512-CiUcHlGs8vE0CAB4oi1f+dzniqfGuhWPNrDvae2nm8dewlahTBwIcK5CawyGezjcJoeQhjBflh9vloska+nlnw==",
-      "license": "MIT",
-      "dependencies": {
-        "@react-native-community/cli-platform-apple": "13.6.9"
-      }
-    },
-    "node_modules/@react-native-community/cli-server-api": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-13.6.9.tgz",
-      "integrity": "sha512-W8FSlCPWymO+tlQfM3E0JmM8Oei5HZsIk5S0COOl0MRi8h0NmHI4WSTF2GCfbFZkcr2VI/fRsocoN8Au4EZAug==",
-      "license": "MIT",
-      "dependencies": {
-        "@react-native-community/cli-debugger-ui": "13.6.9",
-        "@react-native-community/cli-tools": "13.6.9",
-        "compression": "^1.7.1",
-        "connect": "^3.6.5",
-        "errorhandler": "^1.5.1",
-        "nocache": "^3.0.1",
-        "pretty-format": "^26.6.2",
-        "serve-static": "^1.13.1",
-        "ws": "^6.2.2"
-      }
-    },
-    "node_modules/@react-native-community/cli-server-api/node_modules/@jest/types": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
-      "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^15.0.0",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": ">= 10.14.2"
-      }
-    },
-    "node_modules/@react-native-community/cli-server-api/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/@react-native-community/cli-server-api/node_modules/@types/yargs": {
-      "version": "15.0.19",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz",
-      "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/@react-native-community/cli-server-api/node_modules/pretty-format": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
-      "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
-      "license": "MIT",
-      "dependencies": {
-        "@jest/types": "^26.6.2",
-        "ansi-regex": "^5.0.0",
-        "ansi-styles": "^4.0.0",
-        "react-is": "^17.0.1"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@react-native-community/cli-server-api/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "license": "MIT"
-    },
-    "node_modules/@react-native-community/cli-server-api/node_modules/ws": {
-      "version": "6.2.3",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
-      "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
-      "license": "MIT",
-      "dependencies": {
-        "async-limiter": "~1.0.0"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-13.6.9.tgz",
-      "integrity": "sha512-OXaSjoN0mZVw3nrAwcY1PC0uMfyTd9fz7Cy06dh+EJc+h0wikABsVRzV8cIOPrVV+PPEEXE0DBrH20T2puZzgQ==",
-      "license": "MIT",
-      "dependencies": {
-        "appdirsjs": "^1.2.4",
-        "chalk": "^4.1.2",
-        "execa": "^5.0.0",
-        "find-up": "^5.0.0",
-        "mime": "^2.4.1",
-        "node-fetch": "^2.6.0",
-        "open": "^6.2.0",
-        "ora": "^5.4.1",
-        "semver": "^7.5.2",
-        "shell-quote": "^1.7.3",
-        "sudo-prompt": "^9.0.0"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/cli-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
-      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
-      "license": "MIT",
-      "dependencies": {
-        "restore-cursor": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
-      "license": "MIT",
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/get-stream": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
-      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/is-wsl": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
-      "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/log-symbols": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-      "license": "MIT",
-      "dependencies": {
-        "chalk": "^4.1.0",
-        "is-unicode-supported": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "license": "MIT",
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/open": {
-      "version": "6.4.0",
-      "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz",
-      "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==",
-      "license": "MIT",
-      "dependencies": {
-        "is-wsl": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/ora": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
-      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
-      "license": "MIT",
-      "dependencies": {
-        "bl": "^4.1.0",
-        "chalk": "^4.1.0",
-        "cli-cursor": "^3.1.0",
-        "cli-spinners": "^2.5.0",
-        "is-interactive": "^1.0.0",
-        "is-unicode-supported": "^0.1.0",
-        "log-symbols": "^4.1.0",
-        "strip-ansi": "^6.0.0",
-        "wcwidth": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/restore-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
-      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
-      "license": "MIT",
-      "dependencies": {
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/semver": {
-      "version": "7.6.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
-      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli-tools/node_modules/sudo-prompt": {
-      "version": "9.2.1",
-      "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz",
-      "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==",
-      "license": "MIT"
-    },
-    "node_modules/@react-native-community/cli-types": {
-      "version": "13.6.9",
-      "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-13.6.9.tgz",
-      "integrity": "sha512-RLxDppvRxXfs3hxceW/mShi+6o5yS+kFPnPqZTaMKKR5aSg7LwDpLQW4K2D22irEG8e6RKDkZUeH9aL3vO2O0w==",
-      "license": "MIT",
-      "dependencies": {
-        "joi": "^17.2.1"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/commander": {
-      "version": "9.5.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
-      "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
-      "license": "MIT",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
-      "license": "MIT",
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-      "license": "MIT",
-      "dependencies": {
-        "locate-path": "^5.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/get-stream": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
-      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-      "license": "MIT",
-      "dependencies": {
-        "p-locate": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "license": "MIT",
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "license": "MIT",
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-      "license": "MIT",
-      "dependencies": {
-        "p-limit": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native-community/cli/node_modules/semver": {
-      "version": "7.6.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
-      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@react-native-picker/picker": {
-      "version": "2.7.5",
-      "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.7.5.tgz",
-      "integrity": "sha512-vhMaOLkXSUb+YKVbukMJToU4g+89VMhBG2U9+cLYF8X8HtFRidrHjohGqT8/OyesDuKIXeLIP+UFYI9Q9CRA9Q==",
-      "license": "MIT",
-      "peerDependencies": {
-        "react": "*",
-        "react-native": "*"
-      }
-    },
-    "node_modules/@react-native/assets-registry": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.74.87.tgz",
-      "integrity": "sha512-1XmRhqQchN+pXPKEKYdpJlwESxVomJOxtEnIkbo7GAlaN2sym84fHEGDXAjLilih5GVPpcpSmFzTy8jx3LtaFg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/babel-plugin-codegen": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.87.tgz",
-      "integrity": "sha512-+vJYpMnENFrwtgvDfUj+CtVJRJuUnzAUYT0/Pb68Sq9RfcZ5xdcCuUgyf7JO+akW2VTBoJY427wkcxU30qrWWw==",
-      "license": "MIT",
-      "dependencies": {
-        "@react-native/codegen": "0.74.87"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/babel-preset": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.74.87.tgz",
-      "integrity": "sha512-hyKpfqzN2nxZmYYJ0tQIHG99FQO0OWXp/gVggAfEUgiT+yNKas1C60LuofUsK7cd+2o9jrpqgqW4WzEDZoBlTg==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/core": "^7.20.0",
-        "@babel/plugin-proposal-async-generator-functions": "^7.0.0",
-        "@babel/plugin-proposal-class-properties": "^7.18.0",
-        "@babel/plugin-proposal-export-default-from": "^7.0.0",
-        "@babel/plugin-proposal-logical-assignment-operators": "^7.18.0",
-        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.0",
-        "@babel/plugin-proposal-numeric-separator": "^7.0.0",
-        "@babel/plugin-proposal-object-rest-spread": "^7.20.0",
-        "@babel/plugin-proposal-optional-catch-binding": "^7.0.0",
-        "@babel/plugin-proposal-optional-chaining": "^7.20.0",
-        "@babel/plugin-syntax-dynamic-import": "^7.8.0",
-        "@babel/plugin-syntax-export-default-from": "^7.0.0",
-        "@babel/plugin-syntax-flow": "^7.18.0",
-        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
-        "@babel/plugin-syntax-optional-chaining": "^7.0.0",
-        "@babel/plugin-transform-arrow-functions": "^7.0.0",
-        "@babel/plugin-transform-async-to-generator": "^7.20.0",
-        "@babel/plugin-transform-block-scoping": "^7.0.0",
-        "@babel/plugin-transform-classes": "^7.0.0",
-        "@babel/plugin-transform-computed-properties": "^7.0.0",
-        "@babel/plugin-transform-destructuring": "^7.20.0",
-        "@babel/plugin-transform-flow-strip-types": "^7.20.0",
-        "@babel/plugin-transform-function-name": "^7.0.0",
-        "@babel/plugin-transform-literals": "^7.0.0",
-        "@babel/plugin-transform-modules-commonjs": "^7.0.0",
-        "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0",
-        "@babel/plugin-transform-parameters": "^7.0.0",
-        "@babel/plugin-transform-private-methods": "^7.22.5",
-        "@babel/plugin-transform-private-property-in-object": "^7.22.11",
-        "@babel/plugin-transform-react-display-name": "^7.0.0",
-        "@babel/plugin-transform-react-jsx": "^7.0.0",
-        "@babel/plugin-transform-react-jsx-self": "^7.0.0",
-        "@babel/plugin-transform-react-jsx-source": "^7.0.0",
-        "@babel/plugin-transform-runtime": "^7.0.0",
-        "@babel/plugin-transform-shorthand-properties": "^7.0.0",
-        "@babel/plugin-transform-spread": "^7.0.0",
-        "@babel/plugin-transform-sticky-regex": "^7.0.0",
-        "@babel/plugin-transform-typescript": "^7.5.0",
-        "@babel/plugin-transform-unicode-regex": "^7.0.0",
-        "@babel/template": "^7.0.0",
-        "@react-native/babel-plugin-codegen": "0.74.87",
-        "babel-plugin-transform-flow-enums": "^0.0.2",
-        "react-refresh": "^0.14.0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "@babel/core": "*"
-      }
-    },
-    "node_modules/@react-native/codegen": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.74.87.tgz",
-      "integrity": "sha512-GMSYDiD+86zLKgMMgz9z0k6FxmRn+z6cimYZKkucW4soGbxWsbjUAZoZ56sJwt2FJ3XVRgXCrnOCgXoH/Bkhcg==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/parser": "^7.20.0",
-        "glob": "^7.1.1",
-        "hermes-parser": "0.19.1",
-        "invariant": "^2.2.4",
-        "jscodeshift": "^0.14.0",
-        "mkdirp": "^0.5.1",
-        "nullthrows": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "@babel/preset-env": "^7.1.6"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.87.tgz",
-      "integrity": "sha512-EgJG9lSr8x3X67dHQKQvU6EkO+3ksVlJHYIVv6U/AmW9dN80BEFxgYbSJ7icXS4wri7m4kHdgeq2PQ7/3vvrTQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@react-native-community/cli-server-api": "13.6.9",
-        "@react-native-community/cli-tools": "13.6.9",
-        "@react-native/dev-middleware": "0.74.87",
-        "@react-native/metro-babel-transformer": "0.74.87",
-        "chalk": "^4.0.0",
-        "execa": "^5.1.1",
-        "metro": "^0.80.3",
-        "metro-config": "^0.80.3",
-        "metro-core": "^0.80.3",
-        "node-fetch": "^2.2.0",
-        "querystring": "^0.2.1",
-        "readline": "^1.3.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/@react-native/debugger-frontend": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.74.87.tgz",
-      "integrity": "sha512-MN95DJLYTv4EqJc+9JajA3AJZSBYJz2QEJ3uWlHrOky2vKrbbRVaW1ityTmaZa2OXIvNc6CZwSRSE7xCoHbXhQ==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/@react-native/dev-middleware": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.74.87.tgz",
-      "integrity": "sha512-7TmZ3hTHwooYgIHqc/z87BMe1ryrIqAUi+AF7vsD+EHCGxHFdMjSpf1BZ2SUPXuLnF2cTiTfV2RwhbPzx0tYIA==",
-      "license": "MIT",
-      "dependencies": {
-        "@isaacs/ttlcache": "^1.4.1",
-        "@react-native/debugger-frontend": "0.74.87",
-        "@rnx-kit/chromium-edge-launcher": "^1.0.0",
-        "chrome-launcher": "^0.15.2",
-        "connect": "^3.6.5",
-        "debug": "^2.2.0",
-        "node-fetch": "^2.2.0",
-        "nullthrows": "^1.1.1",
-        "open": "^7.0.3",
-        "selfsigned": "^2.4.1",
-        "serve-static": "^1.13.1",
-        "temp-dir": "^2.0.0",
-        "ws": "^6.2.2"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
-      "license": "MIT",
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/get-stream": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
-      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
-      "license": "MIT"
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
-      "license": "MIT",
-      "dependencies": {
-        "path-key": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "license": "MIT",
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/open": {
-      "version": "7.4.2",
-      "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
-      "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
-      "license": "MIT",
-      "dependencies": {
-        "is-docker": "^2.0.0",
-        "is-wsl": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native/community-cli-plugin/node_modules/ws": {
-      "version": "6.2.3",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
-      "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
-      "license": "MIT",
-      "dependencies": {
-        "async-limiter": "~1.0.0"
-      }
-    },
-    "node_modules/@react-native/debugger-frontend": {
-      "version": "0.74.85",
-      "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.74.85.tgz",
-      "integrity": "sha512-gUIhhpsYLUTYWlWw4vGztyHaX/kNlgVspSvKe2XaPA7o3jYKUoNLc3Ov7u70u/MBWfKdcEffWq44eSe3j3s5JQ==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/dev-middleware": {
-      "version": "0.74.85",
-      "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.74.85.tgz",
-      "integrity": "sha512-BRmgCK5vnMmHaKRO+h8PKJmHHH3E6JFuerrcfE3wG2eZ1bcSr+QTu8DAlpxsDWvJvHpCi8tRJGauxd+Ssj/c7w==",
-      "license": "MIT",
-      "dependencies": {
-        "@isaacs/ttlcache": "^1.4.1",
-        "@react-native/debugger-frontend": "0.74.85",
-        "@rnx-kit/chromium-edge-launcher": "^1.0.0",
-        "chrome-launcher": "^0.15.2",
-        "connect": "^3.6.5",
-        "debug": "^2.2.0",
-        "node-fetch": "^2.2.0",
-        "nullthrows": "^1.1.1",
-        "open": "^7.0.3",
-        "selfsigned": "^2.4.1",
-        "serve-static": "^1.13.1",
-        "temp-dir": "^2.0.0",
-        "ws": "^6.2.2"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/dev-middleware/node_modules/debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/@react-native/dev-middleware/node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
-      "license": "MIT"
-    },
-    "node_modules/@react-native/dev-middleware/node_modules/open": {
-      "version": "7.4.2",
-      "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
-      "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
-      "license": "MIT",
-      "dependencies": {
-        "is-docker": "^2.0.0",
-        "is-wsl": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@react-native/dev-middleware/node_modules/ws": {
-      "version": "6.2.3",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
-      "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
-      "license": "MIT",
-      "dependencies": {
-        "async-limiter": "~1.0.0"
-      }
-    },
-    "node_modules/@react-native/gradle-plugin": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.74.87.tgz",
-      "integrity": "sha512-T+VX0N1qP+U9V4oAtn7FTX7pfsoVkd1ocyw9swYXgJqU2fK7hC9famW7b3s3ZiufPGPr1VPJe2TVGtSopBjL6A==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/js-polyfills": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.74.87.tgz",
-      "integrity": "sha512-M5Evdn76CuVEF0GsaXiGi95CBZ4IWubHqwXxV9vG9CC9kq0PSkoM2Pn7Lx7dgyp4vT7ccJ8a3IwHbe+5KJRnpw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/@react-native/metro-babel-transformer": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.87.tgz",
-      "integrity": "sha512-UsJCO24sNax2NSPBmV1zLEVVNkS88kcgAiYrZHtYSwSjpl4WZ656tIeedBfiySdJ94Hr3kQmBYLipV5zk0NI1A==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/core": "^7.20.0",
-        "@react-native/babel-preset": "0.74.87",
-        "hermes-parser": "0.19.1",
-        "nullthrows": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "peerDependencies": {
-        "@babel/core": "*"
-      }
-    },
-    "node_modules/@react-native/normalize-colors": {
-      "version": "0.74.85",
-      "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz",
-      "integrity": "sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw==",
-      "license": "MIT"
+    "node_modules/@react-native/normalize-colors": {
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.2.tgz",
+      "integrity": "sha512-ICoOpaTLPsFQjNLSM00NgQr6wal300cZZonHVSDXKntX+BfkLeuCHRtr/Mn+klTtW+/1v2/2FRm9dXjvyGf9Dw==",
+      "license": "MIT"
     },
     "node_modules/@react-native/virtualized-lists": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.74.87.tgz",
-      "integrity": "sha512-lsGxoFMb0lyK/MiplNKJpD+A1EoEUumkLrCjH4Ht+ZlG8S0BfCxmskLZ6qXn3BiDSkLjfjI/qyZ3pnxNBvkXpQ==",
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.2.tgz",
+      "integrity": "sha512-FzXvkHgKvJGf0pSuLy6878cxJ6mxWKgZsH9s2kO4LWJocI8Bi3ViDx7IGAWYuvN+Fnue5TKaqGPhfD+4XrKtYQ==",
       "license": "MIT",
       "dependencies": {
         "invariant": "^2.2.4",
@@ -4965,35 +3907,6 @@
         "nanoid": "^3.1.23"
       }
     },
-    "node_modules/@rnx-kit/chromium-edge-launcher": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@rnx-kit/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz",
-      "integrity": "sha512-lzD84av1ZQhYUS+jsGqJiCMaJO2dn9u+RTT9n9q6D3SaKVwWqv+7AoRKqBu19bkwyE+iFRl1ymr40QS90jVFYg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@types/node": "^18.0.0",
-        "escape-string-regexp": "^4.0.0",
-        "is-wsl": "^2.2.0",
-        "lighthouse-logger": "^1.0.0",
-        "mkdirp": "^1.0.4",
-        "rimraf": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=14.15"
-      }
-    },
-    "node_modules/@rnx-kit/chromium-edge-launcher/node_modules/mkdirp": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
-      "license": "MIT",
-      "bin": {
-        "mkdirp": "bin/cmd.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/@segment/loosely-validate-event": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz",
@@ -5003,27 +3916,6 @@
         "join-component": "^1.1.0"
       }
     },
-    "node_modules/@sideway/address": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
-      "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "@hapi/hoek": "^9.0.0"
-      }
-    },
-    "node_modules/@sideway/formula": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
-      "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@sideway/pinpoint": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
-      "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
-      "license": "BSD-3-Clause"
-    },
     "node_modules/@sinclair/typebox": {
       "version": "0.27.8",
       "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@@ -5048,6 +3940,56 @@
         "@sinonjs/commons": "^3.0.0"
       }
     },
+    "node_modules/@types/babel__core": {
+      "version": "7.20.5",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+      "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
+    },
+    "node_modules/@types/babel__generator": {
+      "version": "7.6.8",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+      "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "node_modules/@types/babel__template": {
+      "version": "7.4.4",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+      "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "node_modules/@types/babel__traverse": {
+      "version": "7.20.6",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+      "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.20.7"
+      }
+    },
+    "node_modules/@types/graceful-fs": {
+      "version": "4.1.9",
+      "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
+      "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/he": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/@types/he/-/he-1.2.3.tgz",
@@ -5071,12 +4013,11 @@
       }
     },
     "node_modules/@types/istanbul-reports": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
-      "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==",
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
       "license": "MIT",
       "dependencies": {
-        "@types/istanbul-lib-coverage": "*",
         "@types/istanbul-lib-report": "*"
       }
     },
@@ -5106,9 +4047,9 @@
       "license": "MIT"
     },
     "node_modules/@types/react": {
-      "version": "18.2.79",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz",
-      "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==",
+      "version": "18.3.12",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz",
+      "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==",
       "devOptional": true,
       "license": "MIT",
       "dependencies": {
@@ -5123,9 +4064,9 @@
       "license": "MIT"
     },
     "node_modules/@types/yargs": {
-      "version": "13.0.12",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz",
-      "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==",
+      "version": "17.0.33",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
       "license": "MIT",
       "dependencies": {
         "@types/yargs-parser": "*"
@@ -5138,29 +4079,26 @@
       "license": "MIT"
     },
     "node_modules/@urql/core": {
-      "version": "2.3.6",
-      "resolved": "https://registry.npmjs.org/@urql/core/-/core-2.3.6.tgz",
-      "integrity": "sha512-PUxhtBh7/8167HJK6WqBv6Z0piuiaZHQGYbhwpNL9aIQmLROPEdaUYkY4wh45wPQXcTpnd11l0q3Pw+TI11pdw==",
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.0.8.tgz",
+      "integrity": "sha512-1GOnUw7/a9bzkcM0+U8U5MmxW2A7FE5YquuEmcJzTtW5tIs2EoS4F2ITpuKBjRBbyRjZgO860nWFPo1m4JImGA==",
       "license": "MIT",
       "dependencies": {
-        "@graphql-typed-document-node/core": "^3.1.0",
-        "wonka": "^4.0.14"
-      },
-      "peerDependencies": {
-        "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
+        "@0no-co/graphql.web": "^1.0.5",
+        "wonka": "^6.3.2"
       }
     },
     "node_modules/@urql/exchange-retry": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-0.3.0.tgz",
-      "integrity": "sha512-hHqer2mcdVC0eYnVNbWyi28AlGOPb2vjH3lP3/Bc8Lc8BjhMsDwFMm7WhoP5C1+cfbr/QJ6Er3H/L08wznXxfg==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-1.3.0.tgz",
+      "integrity": "sha512-FLt+d81gP4oiHah4hWFDApimc+/xABWMU1AMYsZ1PVB0L0YPtrMCjbOp9WMM7hBzy4gbTDrG24sio0dCfSh/HQ==",
       "license": "MIT",
       "dependencies": {
-        "@urql/core": ">=2.3.1",
-        "wonka": "^4.0.14"
+        "@urql/core": "^5.0.0",
+        "wonka": "^6.3.2"
       },
       "peerDependencies": {
-        "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
+        "@urql/core": "^5.0.0"
       }
     },
     "node_modules/@xmldom/xmldom": {
@@ -5210,18 +4148,6 @@
         "node": ">=0.4.0"
       }
     },
-    "node_modules/agent-base": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-      "license": "MIT",
-      "dependencies": {
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6.0.0"
-      }
-    },
     "node_modules/aggregate-error": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
@@ -5256,17 +4182,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/ansi-fragments": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz",
-      "integrity": "sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==",
-      "license": "MIT",
-      "dependencies": {
-        "colorette": "^1.0.7",
-        "slice-ansi": "^2.0.0",
-        "strip-ansi": "^5.0.0"
-      }
-    },
     "node_modules/ansi-regex": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -5322,12 +4237,6 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
-    "node_modules/appdirsjs": {
-      "version": "1.2.7",
-      "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.7.tgz",
-      "integrity": "sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==",
-      "license": "MIT"
-    },
     "node_modules/application-config-path": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/application-config-path/-/application-config-path-0.1.1.tgz",
@@ -5342,27 +4251,11 @@
     },
     "node_modules/argparse": {
       "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "license": "MIT",
-      "dependencies": {
-        "sprintf-js": "~1.0.2"
-      }
-    },
-    "node_modules/array-buffer-byte-length": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
-      "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
       "license": "MIT",
       "dependencies": {
-        "call-bind": "^1.0.5",
-        "is-array-buffer": "^3.0.4"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+        "sprintf-js": "~1.0.2"
       }
     },
     "node_modules/array-union": {
@@ -5374,28 +4267,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/arraybuffer.prototype.slice": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
-      "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
-      "license": "MIT",
-      "dependencies": {
-        "array-buffer-byte-length": "^1.0.1",
-        "call-bind": "^1.0.5",
-        "define-properties": "^1.2.1",
-        "es-abstract": "^1.22.3",
-        "es-errors": "^1.2.1",
-        "get-intrinsic": "^1.2.3",
-        "is-array-buffer": "^3.0.4",
-        "is-shared-array-buffer": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/asap": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@@ -5414,15 +4285,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/astral-regex": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
-      "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/async-limiter": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
@@ -5444,28 +4306,65 @@
         "node": ">= 4.0.0"
       }
     },
-    "node_modules/available-typed-arrays": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
-      "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+    "node_modules/babel-core": {
+      "version": "7.0.0-bridge.0",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
+      "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
+      "license": "MIT",
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/babel-jest": {
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
+      "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
       "license": "MIT",
       "dependencies": {
-        "possible-typed-array-names": "^1.0.0"
+        "@jest/transform": "^29.7.0",
+        "@types/babel__core": "^7.1.14",
+        "babel-plugin-istanbul": "^6.1.1",
+        "babel-preset-jest": "^29.6.3",
+        "chalk": "^4.0.0",
+        "graceful-fs": "^4.2.9",
+        "slash": "^3.0.0"
       },
       "engines": {
-        "node": ">= 0.4"
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+      "peerDependencies": {
+        "@babel/core": "^7.8.0"
       }
     },
-    "node_modules/babel-core": {
-      "version": "7.0.0-bridge.0",
-      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
-      "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
+    "node_modules/babel-plugin-istanbul": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+      "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@istanbuljs/load-nyc-config": "^1.0.0",
+        "@istanbuljs/schema": "^0.1.2",
+        "istanbul-lib-instrument": "^5.0.4",
+        "test-exclude": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/babel-plugin-jest-hoist": {
+      "version": "29.6.3",
+      "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
+      "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
       "license": "MIT",
-      "peerDependencies": {
-        "@babel/core": "^7.0.0-0"
+      "dependencies": {
+        "@babel/template": "^7.3.3",
+        "@babel/types": "^7.3.3",
+        "@types/babel__core": "^7.1.14",
+        "@types/babel__traverse": "^7.0.6"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
     "node_modules/babel-plugin-polyfill-corejs2": {
@@ -5507,61 +4406,36 @@
         "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
       }
     },
-    "node_modules/babel-plugin-react-compiler": {
-      "version": "0.0.0-experimental-592953e-20240517",
-      "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-0.0.0-experimental-592953e-20240517.tgz",
-      "integrity": "sha512-OjG1SVaeQZaJrqkMFJatg8W/MTow8Ak5rx2SI0ETQBO1XvOk/XZGMbltNCPdFJLKghBYoBjC+Y3Ap/Xr7B01mA==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/generator": "7.2.0",
-        "@babel/types": "^7.19.0",
-        "chalk": "4",
-        "invariant": "^2.2.4",
-        "pretty-format": "^24",
-        "zod": "^3.22.4",
-        "zod-validation-error": "^2.1.0"
-      }
+    "node_modules/babel-plugin-react-native-web": {
+      "version": "0.19.13",
+      "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.13.tgz",
+      "integrity": "sha512-4hHoto6xaN23LCyZgL9LJZc3olmAxd7b6jDzlZnKXAh4rRAbZRKNBJoOOdp46OBqgy+K0t0guTj5/mhA8inymQ==",
+      "license": "MIT"
     },
-    "node_modules/babel-plugin-react-compiler/node_modules/@babel/generator": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.0.tgz",
-      "integrity": "sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg==",
+    "node_modules/babel-plugin-syntax-hermes-parser": {
+      "version": "0.25.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.25.1.tgz",
+      "integrity": "sha512-IVNpGzboFLfXZUAwkLFcI/bnqVbwky0jP3eBno4HKtqvQJAHBLdgxiG6lQ4to0+Q/YCN3PO0od5NZwIKyY4REQ==",
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.2.0",
-        "jsesc": "^2.5.1",
-        "lodash": "^4.17.10",
-        "source-map": "^0.5.0",
-        "trim-right": "^1.0.1"
+        "hermes-parser": "0.25.1"
       }
     },
-    "node_modules/babel-plugin-react-compiler/node_modules/jsesc": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
-      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
-      "license": "MIT",
-      "bin": {
-        "jsesc": "bin/jsesc"
-      },
-      "engines": {
-        "node": ">=4"
-      }
+    "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-estree": {
+      "version": "0.25.1",
+      "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
+      "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
+      "license": "MIT"
     },
-    "node_modules/babel-plugin-react-compiler/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
+    "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-parser": {
+      "version": "0.25.1",
+      "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
+      "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
+      "license": "MIT",
+      "dependencies": {
+        "hermes-estree": "0.25.1"
       }
     },
-    "node_modules/babel-plugin-react-native-web": {
-      "version": "0.19.13",
-      "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.13.tgz",
-      "integrity": "sha512-4hHoto6xaN23LCyZgL9LJZc3olmAxd7b6jDzlZnKXAh4rRAbZRKNBJoOOdp46OBqgy+K0t0guTj5/mhA8inymQ==",
-      "license": "MIT"
-    },
     "node_modules/babel-plugin-transform-flow-enums": {
       "version": "0.0.2",
       "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz",
@@ -5571,10 +4445,36 @@
         "@babel/plugin-syntax-flow": "^7.12.1"
       }
     },
+    "node_modules/babel-preset-current-node-syntax": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
+      "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/plugin-syntax-async-generators": "^7.8.4",
+        "@babel/plugin-syntax-bigint": "^7.8.3",
+        "@babel/plugin-syntax-class-properties": "^7.12.13",
+        "@babel/plugin-syntax-class-static-block": "^7.14.5",
+        "@babel/plugin-syntax-import-attributes": "^7.24.7",
+        "@babel/plugin-syntax-import-meta": "^7.10.4",
+        "@babel/plugin-syntax-json-strings": "^7.8.3",
+        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+        "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+        "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+        "@babel/plugin-syntax-top-level-await": "^7.14.5"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
     "node_modules/babel-preset-expo": {
-      "version": "11.0.15",
-      "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-11.0.15.tgz",
-      "integrity": "sha512-rgiMTYwqIPULaO7iZdqyL7aAff9QLOX6OWUtLZBlOrOTreGY1yHah/5+l8MvI6NVc/8Zj5LY4Y5uMSnJIuzTLw==",
+      "version": "12.0.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-12.0.1.tgz",
+      "integrity": "sha512-9T2o+aeKnHOtQhk/undQbibJv02bdCgfs68ZwgAdueljDBcs2oVfq41qG9XThYwa6Dn7CdfnoEUsIyFqBwjcVw==",
       "license": "MIT",
       "dependencies": {
         "@babel/plugin-proposal-decorators": "^7.12.9",
@@ -5583,10 +4483,37 @@
         "@babel/plugin-transform-parameters": "^7.22.15",
         "@babel/preset-react": "^7.22.15",
         "@babel/preset-typescript": "^7.23.0",
-        "@react-native/babel-preset": "0.74.87",
-        "babel-plugin-react-compiler": "0.0.0-experimental-592953e-20240517",
-        "babel-plugin-react-native-web": "~0.19.10",
+        "@react-native/babel-preset": "0.76.2",
+        "babel-plugin-react-native-web": "~0.19.13",
         "react-refresh": "^0.14.2"
+      },
+      "peerDependencies": {
+        "babel-plugin-react-compiler": "^19.0.0-beta-9ee70a1-20241017",
+        "react-compiler-runtime": "^19.0.0-beta-8a03594-20241020"
+      },
+      "peerDependenciesMeta": {
+        "babel-plugin-react-compiler": {
+          "optional": true
+        },
+        "react-compiler-runtime": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/babel-preset-jest": {
+      "version": "29.6.3",
+      "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
+      "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
+      "license": "MIT",
+      "dependencies": {
+        "babel-plugin-jest-hoist": "^29.6.3",
+        "babel-preset-current-node-syntax": "^1.0.0"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
       }
     },
     "node_modules/balanced-match": {
@@ -5627,6 +4554,23 @@
         "node": ">=12.0.0"
       }
     },
+    "node_modules/better-opn/node_modules/open": {
+      "version": "8.4.2",
+      "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+      "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+      "license": "MIT",
+      "dependencies": {
+        "define-lazy-prop": "^2.0.0",
+        "is-docker": "^2.1.1",
+        "is-wsl": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/big-integer": {
       "version": "1.6.52",
       "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
@@ -5645,31 +4589,6 @@
         "node": "*"
       }
     },
-    "node_modules/bl": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
-      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
-      "license": "MIT",
-      "dependencies": {
-        "buffer": "^5.5.0",
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.4.0"
-      }
-    },
-    "node_modules/bl/node_modules/readable-stream": {
-      "version": "3.6.2",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
-      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
-      "license": "MIT",
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/bplist-creator": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz",
@@ -5806,12 +4725,6 @@
       "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
       "license": "MIT"
     },
-    "node_modules/builtins": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
-      "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==",
-      "license": "MIT"
-    },
     "node_modules/bytes": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -5894,25 +4807,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/call-bind": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
-      "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
-      "license": "MIT",
-      "dependencies": {
-        "es-define-property": "^1.0.0",
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2",
-        "get-intrinsic": "^1.2.4",
-        "set-function-length": "^1.2.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/caller-callsite": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
@@ -5947,15 +4841,12 @@
       }
     },
     "node_modules/camelcase": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
       "license": "MIT",
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=6"
       }
     },
     "node_modules/caniuse-lite": {
@@ -6030,6 +4921,32 @@
         "node": ">=12.13.0"
       }
     },
+    "node_modules/chromium-edge-launcher": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz",
+      "integrity": "sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@types/node": "*",
+        "escape-string-regexp": "^4.0.0",
+        "is-wsl": "^2.2.0",
+        "lighthouse-logger": "^1.0.0",
+        "mkdirp": "^1.0.4",
+        "rimraf": "^3.0.2"
+      }
+    },
+    "node_modules/chromium-edge-launcher/node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "license": "MIT",
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/ci-info": {
       "version": "3.9.0",
       "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
@@ -6104,15 +5021,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/clone": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
-      "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
     "node_modules/clone-deep": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -6145,12 +5053,6 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "license": "MIT"
     },
-    "node_modules/colorette": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
-      "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==",
-      "license": "MIT"
-    },
     "node_modules/combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -6333,9 +5235,9 @@
       }
     },
     "node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+      "version": "7.0.6",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
       "license": "MIT",
       "dependencies": {
         "path-key": "^3.1.0",
@@ -6371,69 +5273,6 @@
       "devOptional": true,
       "license": "MIT"
     },
-    "node_modules/dag-map": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/dag-map/-/dag-map-1.0.2.tgz",
-      "integrity": "sha512-+LSAiGFwQ9dRnRdOeaj7g47ZFJcOUPukAP8J3A3fuZ1g9Y44BG+P1sgApjLXTQPOzC4+7S9Wr8kXsfpINM4jpw==",
-      "license": "MIT"
-    },
-    "node_modules/data-view-buffer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
-      "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.6",
-        "es-errors": "^1.3.0",
-        "is-data-view": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/data-view-byte-length": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
-      "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "es-errors": "^1.3.0",
-        "is-data-view": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/data-view-byte-offset": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
-      "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.6",
-        "es-errors": "^1.3.0",
-        "is-data-view": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/dayjs": {
-      "version": "1.11.13",
-      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
-      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
-      "license": "MIT"
-    },
     "node_modules/debug": {
       "version": "4.3.7",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
@@ -6445,19 +5284,10 @@
       "engines": {
         "node": ">=6.0"
       },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/decamelize": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
       }
     },
     "node_modules/decode-uri-component": {
@@ -6521,23 +5351,6 @@
         "node": ">=0.8"
       }
     },
-    "node_modules/define-data-property": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
-      "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
-      "license": "MIT",
-      "dependencies": {
-        "es-define-property": "^1.0.0",
-        "es-errors": "^1.3.0",
-        "gopd": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/define-lazy-prop": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
@@ -6547,23 +5360,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/define-properties": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
-      "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
-      "license": "MIT",
-      "dependencies": {
-        "define-data-property": "^1.0.1",
-        "has-property-descriptors": "^1.0.0",
-        "object-keys": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/del": {
       "version": "6.1.1",
       "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz",
@@ -6657,12 +5453,12 @@
       }
     },
     "node_modules/dotenv-expand": {
-      "version": "11.0.6",
-      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.6.tgz",
-      "integrity": "sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==",
+      "version": "11.0.7",
+      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz",
+      "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==",
       "license": "BSD-2-Clause",
       "dependencies": {
-        "dotenv": "^16.4.4"
+        "dotenv": "^16.4.5"
       },
       "engines": {
         "node": ">=12"
@@ -6722,18 +5518,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/envinfo": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz",
-      "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==",
-      "license": "MIT",
-      "bin": {
-        "envinfo": "dist/cli.js"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/eol": {
       "version": "0.9.1",
       "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz",
@@ -6758,143 +5542,6 @@
         "stackframe": "^1.3.4"
       }
     },
-    "node_modules/errorhandler": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz",
-      "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==",
-      "license": "MIT",
-      "dependencies": {
-        "accepts": "~1.3.7",
-        "escape-html": "~1.0.3"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/es-abstract": {
-      "version": "1.23.3",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
-      "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
-      "license": "MIT",
-      "dependencies": {
-        "array-buffer-byte-length": "^1.0.1",
-        "arraybuffer.prototype.slice": "^1.0.3",
-        "available-typed-arrays": "^1.0.7",
-        "call-bind": "^1.0.7",
-        "data-view-buffer": "^1.0.1",
-        "data-view-byte-length": "^1.0.1",
-        "data-view-byte-offset": "^1.0.0",
-        "es-define-property": "^1.0.0",
-        "es-errors": "^1.3.0",
-        "es-object-atoms": "^1.0.0",
-        "es-set-tostringtag": "^2.0.3",
-        "es-to-primitive": "^1.2.1",
-        "function.prototype.name": "^1.1.6",
-        "get-intrinsic": "^1.2.4",
-        "get-symbol-description": "^1.0.2",
-        "globalthis": "^1.0.3",
-        "gopd": "^1.0.1",
-        "has-property-descriptors": "^1.0.2",
-        "has-proto": "^1.0.3",
-        "has-symbols": "^1.0.3",
-        "hasown": "^2.0.2",
-        "internal-slot": "^1.0.7",
-        "is-array-buffer": "^3.0.4",
-        "is-callable": "^1.2.7",
-        "is-data-view": "^1.0.1",
-        "is-negative-zero": "^2.0.3",
-        "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.3",
-        "is-string": "^1.0.7",
-        "is-typed-array": "^1.1.13",
-        "is-weakref": "^1.0.2",
-        "object-inspect": "^1.13.1",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.5",
-        "regexp.prototype.flags": "^1.5.2",
-        "safe-array-concat": "^1.1.2",
-        "safe-regex-test": "^1.0.3",
-        "string.prototype.trim": "^1.2.9",
-        "string.prototype.trimend": "^1.0.8",
-        "string.prototype.trimstart": "^1.0.8",
-        "typed-array-buffer": "^1.0.2",
-        "typed-array-byte-length": "^1.0.1",
-        "typed-array-byte-offset": "^1.0.2",
-        "typed-array-length": "^1.0.6",
-        "unbox-primitive": "^1.0.2",
-        "which-typed-array": "^1.1.15"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/es-define-property": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
-      "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
-      "license": "MIT",
-      "dependencies": {
-        "get-intrinsic": "^1.2.4"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-errors": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
-      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-object-atoms": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
-      "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-set-tostringtag": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
-      "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
-      "license": "MIT",
-      "dependencies": {
-        "get-intrinsic": "^1.2.4",
-        "has-tostringtag": "^1.0.2",
-        "hasown": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-to-primitive": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
-      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
-      "license": "MIT",
-      "dependencies": {
-        "is-callable": "^1.1.4",
-        "is-date-object": "^1.0.1",
-        "is-symbol": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/escalade": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -6988,9 +5635,9 @@
       }
     },
     "node_modules/execa/node_modules/cross-spawn": {
-      "version": "6.0.5",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
-      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "version": "6.0.6",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
+      "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
       "license": "MIT",
       "dependencies": {
         "nice-try": "^1.0.4",
@@ -7055,94 +5702,126 @@
       }
     },
     "node_modules/expo": {
-      "version": "51.0.39",
-      "resolved": "https://registry.npmjs.org/expo/-/expo-51.0.39.tgz",
-      "integrity": "sha512-Cs/9xopyzJrpXWbyVUZnr37rprdFJorRgfSp6cdBfvbjxZeKnw2MEu7wJwV/s626i5lZTPGjZPHUF9uQvt51cg==",
+      "version": "52.0.8",
+      "resolved": "https://registry.npmjs.org/expo/-/expo-52.0.8.tgz",
+      "integrity": "sha512-EQwJFRS2UUTGTe++bcLN3b7TeSpSWhQzIPt4jIh+0iannbYxgXLE6oKApTJhh0dsMWDnZzU5a8DIdadJY8VZJA==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.20.0",
-        "@expo/cli": "0.18.31",
-        "@expo/config": "9.0.4",
-        "@expo/config-plugins": "8.0.11",
-        "@expo/metro-config": "0.18.11",
-        "@expo/vector-icons": "^14.0.3",
-        "babel-preset-expo": "~11.0.15",
-        "expo-asset": "~10.0.10",
-        "expo-file-system": "~17.0.1",
-        "expo-font": "~12.0.10",
-        "expo-keep-awake": "~13.0.2",
-        "expo-modules-autolinking": "1.11.3",
-        "expo-modules-core": "1.12.26",
+        "@expo/cli": "0.21.6",
+        "@expo/config": "~10.0.4",
+        "@expo/config-plugins": "9.0.9",
+        "@expo/fingerprint": "0.11.2",
+        "@expo/metro-config": "0.19.4",
+        "@expo/vector-icons": "^14.0.0",
+        "babel-preset-expo": "~12.0.1",
+        "expo-asset": "~11.0.1",
+        "expo-constants": "~17.0.3",
+        "expo-file-system": "~18.0.4",
+        "expo-font": "~13.0.1",
+        "expo-keep-awake": "~14.0.1",
+        "expo-modules-autolinking": "2.0.2",
+        "expo-modules-core": "2.0.4",
         "fbemitter": "^3.0.0",
+        "web-streams-polyfill": "^3.3.2",
         "whatwg-url-without-unicode": "8.0.0-3"
       },
       "bin": {
         "expo": "bin/cli"
+      },
+      "peerDependencies": {
+        "@expo/dom-webview": "*",
+        "@expo/metro-runtime": "*",
+        "react": "*",
+        "react-native": "*",
+        "react-native-webview": "*"
+      },
+      "peerDependenciesMeta": {
+        "@expo/dom-webview": {
+          "optional": true
+        },
+        "@expo/metro-runtime": {
+          "optional": true
+        },
+        "react-native-webview": {
+          "optional": true
+        }
       }
     },
     "node_modules/expo-asset": {
-      "version": "10.0.10",
-      "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-10.0.10.tgz",
-      "integrity": "sha512-0qoTIihB79k+wGus9wy0JMKq7DdenziVx3iUkGvMAy2azscSgWH6bd2gJ9CGnhC6JRd3qTMFBL0ou/fx7WZl7A==",
+      "version": "11.0.1",
+      "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-11.0.1.tgz",
+      "integrity": "sha512-WatvD7JVC89EsllXFYcS/rji3ajVzE2B/USo0TqedsETixwyVCQfrrvCdCPQyuKghrxVNEj8bQ/Qbea/RZLYjg==",
       "license": "MIT",
       "dependencies": {
-        "expo-constants": "~16.0.0",
+        "@expo/image-utils": "^0.6.0",
+        "expo-constants": "~17.0.0",
         "invariant": "^2.2.4",
         "md5-file": "^3.2.3"
       },
       "peerDependencies": {
-        "expo": "*"
+        "expo": "*",
+        "react": "*",
+        "react-native": "*"
       }
     },
     "node_modules/expo-constants": {
-      "version": "16.0.2",
-      "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-16.0.2.tgz",
-      "integrity": "sha512-9tNY3OVO0jfiMzl7ngb6IOyR5VFzNoN5OOazUWoeGfmMqVB5kltTemRvKraK9JRbBKIw+SOYLEmF0sEqgFZ6OQ==",
+      "version": "17.0.3",
+      "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.0.3.tgz",
+      "integrity": "sha512-lnbcX2sAu8SucHXEXxSkhiEpqH+jGrf+TF+MO6sHWIESjwOUVVYlT8qYdjR9xbxWmqFtrI4KV44FkeJf2DaFjQ==",
       "license": "MIT",
       "dependencies": {
-        "@expo/config": "~9.0.0",
-        "@expo/env": "~0.3.0"
+        "@expo/config": "~10.0.4",
+        "@expo/env": "~0.4.0"
       },
       "peerDependencies": {
-        "expo": "*"
+        "expo": "*",
+        "react-native": "*"
       }
     },
     "node_modules/expo-file-system": {
-      "version": "17.0.1",
-      "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-17.0.1.tgz",
-      "integrity": "sha512-dYpnZJqTGj6HCYJyXAgpFkQWsiCH3HY1ek2cFZVHFoEc5tLz9gmdEgTF6nFHurvmvfmXqxi7a5CXyVm0aFYJBw==",
+      "version": "18.0.4",
+      "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-18.0.4.tgz",
+      "integrity": "sha512-aAWEDwnu0XHOBYvQ9Q0+QIa+483vYJaC4IDsXyWQ73Rtsg273NZh5kYowY+cAocvoSmA99G6htrLBn11ax2bTQ==",
       "license": "MIT",
+      "dependencies": {
+        "web-streams-polyfill": "^3.3.2"
+      },
       "peerDependencies": {
-        "expo": "*"
+        "expo": "*",
+        "react-native": "*"
       }
     },
     "node_modules/expo-font": {
-      "version": "12.0.10",
-      "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-12.0.10.tgz",
-      "integrity": "sha512-Q1i2NuYri3jy32zdnBaHHCya1wH1yMAsI+3CCmj9zlQzlhsS9Bdwcj2W3c5eU5FvH2hsNQy4O+O1NnM6o/pDaQ==",
+      "version": "13.0.1",
+      "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-13.0.1.tgz",
+      "integrity": "sha512-8JE47B+6cLeKWr5ql8gU6YsPHjhrz1vMrTqYMm72No/8iW8Sb/uL4Oc0dpmbjq3hLLXBY0xPBQOgU7FQ6Y04Vg==",
       "license": "MIT",
       "dependencies": {
         "fontfaceobserver": "^2.1.0"
       },
       "peerDependencies": {
-        "expo": "*"
+        "expo": "*",
+        "react": "*"
       }
     },
     "node_modules/expo-keep-awake": {
-      "version": "13.0.2",
-      "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz",
-      "integrity": "sha512-kKiwkVg/bY0AJ5q1Pxnm/GvpeB6hbNJhcFsoOWDh2NlpibhCLaHL826KHUM+WsnJRbVRxJ+K9vbPRHEMvFpVyw==",
+      "version": "14.0.1",
+      "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-14.0.1.tgz",
+      "integrity": "sha512-c5mGCAIk2YM+Vsdy90BlEJ4ZX+KG5Au9EkJUIxXWlpnuKmDAJ3N+5nEZ7EUO1ZTheqoSBeAo4jJ8rTWPU+JXdw==",
       "license": "MIT",
       "peerDependencies": {
-        "expo": "*"
+        "expo": "*",
+        "react": "*"
       }
     },
     "node_modules/expo-modules-autolinking": {
-      "version": "1.11.3",
-      "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.11.3.tgz",
-      "integrity": "sha512-oYh8EZEvYF5TYppxEKUTTJmbr8j7eRRnrIxzZtMvxLTXoujThVPMFS/cbnSnf2bFm1lq50TdDNABhmEi7z0ngQ==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.0.2.tgz",
+      "integrity": "sha512-n3jC7VoJLfOLGk8NWhEAvM5zSjbLh1kMUSo76nJupx5/vASxDdzihppYebrKrNXPHq5mcw8Jr+r7YB+8xHx7QQ==",
       "license": "MIT",
       "dependencies": {
+        "@expo/spawn-async": "^1.7.2",
         "chalk": "^4.1.0",
         "commander": "^7.2.0",
         "fast-glob": "^3.2.5",
@@ -7192,19 +5871,23 @@
       }
     },
     "node_modules/expo-modules-core": {
-      "version": "1.12.26",
-      "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-1.12.26.tgz",
-      "integrity": "sha512-y8yDWjOi+rQRdO+HY+LnUlz8qzHerUaw/LUjKPU/mX8PRXP4UUPEEp5fjAwBU44xjNmYSHWZDwet4IBBE+yQUA==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.0.4.tgz",
+      "integrity": "sha512-nNS40KYh1d7tWXCcEKBrSigIKCVfJwkPLhR/mniAoPzqevUDLVJNJjIgKfQL6kPlsViC3hwwgrUpKSlmWv2DFg==",
       "license": "MIT",
       "dependencies": {
         "invariant": "^2.2.4"
       }
     },
     "node_modules/expo-status-bar": {
-      "version": "1.12.1",
-      "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-1.12.1.tgz",
-      "integrity": "sha512-/t3xdbS8KB0prj5KG5w7z+wZPFlPtkgs95BsmrP/E7Q0xHXTcDcQ6Cu2FkFuRM+PKTb17cJDnLkawyS5vDLxMA==",
-      "license": "MIT"
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.0.0.tgz",
+      "integrity": "sha512-vxxdpvpNDMTEc5uTiIrbTvySKKUsOACmfl8OZuUdjNle05oGqwtq3v5YObwym/njSByjoyuZX8UpXBZnxvarwQ==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": "*",
+        "react-native": "*"
+      }
     },
     "node_modules/exponential-backoff": {
       "version": "3.1.1",
@@ -7234,27 +5917,11 @@
         "node": ">=8.6.0"
       }
     },
-    "node_modules/fast-xml-parser": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz",
-      "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/NaturalIntelligence"
-        },
-        {
-          "type": "paypal",
-          "url": "https://paypal.me/naturalintelligence"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "strnum": "^1.0.5"
-      },
-      "bin": {
-        "fxparser": "src/cli/cli.js"
-      }
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "license": "MIT"
     },
     "node_modules/fastq": {
       "version": "1.17.1",
@@ -7394,15 +6061,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/find-yarn-workspace-root": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
-      "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "micromatch": "^4.0.2"
-      }
-    },
     "node_modules/flow-enums-runtime": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz",
@@ -7424,15 +6082,6 @@
       "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==",
       "license": "BSD-2-Clause"
     },
-    "node_modules/for-each": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
-      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
-      "license": "MIT",
-      "dependencies": {
-        "is-callable": "^1.1.3"
-      }
-    },
     "node_modules/foreground-child": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
@@ -7548,33 +6197,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/function.prototype.name": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
-      "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.2.0",
-        "es-abstract": "^1.22.1",
-        "functions-have-names": "^1.2.3"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/functions-have-names": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
-      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -7593,23 +6215,13 @@
         "node": "6.* || 8.* || >= 10.*"
       }
     },
-    "node_modules/get-intrinsic": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
-      "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+    "node_modules/get-package-type": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+      "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
       "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2",
-        "has-proto": "^1.0.1",
-        "has-symbols": "^1.0.3",
-        "hasown": "^2.0.0"
-      },
       "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+        "node": ">=8.0.0"
       }
     },
     "node_modules/get-port": {
@@ -7633,23 +6245,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/get-symbol-description": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
-      "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.5",
-        "es-errors": "^1.3.0",
-        "get-intrinsic": "^1.2.4"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/getenv": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/getenv/-/getenv-1.0.0.tgz",
@@ -7701,22 +6296,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/globalthis": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
-      "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
-      "license": "MIT",
-      "dependencies": {
-        "define-properties": "^1.2.1",
-        "gopd": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/globby": {
       "version": "11.1.0",
       "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -7737,115 +6316,19 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/gopd": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
-      "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
-      "license": "MIT",
-      "dependencies": {
-        "get-intrinsic": "^1.1.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/graceful-fs": {
       "version": "4.2.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
       "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
       "license": "ISC"
     },
-    "node_modules/graphql": {
-      "version": "15.8.0",
-      "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz",
-      "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10.x"
-      }
-    },
-    "node_modules/graphql-tag": {
-      "version": "2.12.6",
-      "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz",
-      "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==",
-      "license": "MIT",
-      "dependencies": {
-        "tslib": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
-      }
-    },
-    "node_modules/has-bigints": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
-      "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
       "license": "MIT",
       "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/has-property-descriptors": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
-      "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
-      "license": "MIT",
-      "dependencies": {
-        "es-define-property": "^1.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-proto": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
-      "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-symbols": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
-      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-tostringtag": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
-      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
-      "license": "MIT",
-      "dependencies": {
-        "has-symbols": "^1.0.3"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+        "node": ">=8"
       }
     },
     "node_modules/hasown": {
@@ -7870,60 +6353,36 @@
       }
     },
     "node_modules/hermes-estree": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.19.1.tgz",
-      "integrity": "sha512-daLGV3Q2MKk8w4evNMKwS8zBE/rcpA800nu1Q5kM08IKijoSnPe9Uo1iIxzPKRkn95IxxsgBMPeYHt3VG4ej2g==",
+      "version": "0.23.1",
+      "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.23.1.tgz",
+      "integrity": "sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg==",
       "license": "MIT"
     },
     "node_modules/hermes-parser": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.19.1.tgz",
-      "integrity": "sha512-Vp+bXzxYJWrpEuJ/vXxUsLnt0+y4q9zyi4zUlkLqD8FKv4LjIfOvP69R/9Lty3dCyKh0E2BU7Eypqr63/rKT/A==",
-      "license": "MIT",
-      "dependencies": {
-        "hermes-estree": "0.19.1"
-      }
-    },
-    "node_modules/hermes-profile-transformer": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz",
-      "integrity": "sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==",
+      "version": "0.23.1",
+      "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.23.1.tgz",
+      "integrity": "sha512-oxl5h2DkFW83hT4DAUJorpah8ou4yvmweUzLJmmr6YV2cezduCdlil1AvU/a/xSsAFo4WUcNA4GoV5Bvq6JffA==",
       "license": "MIT",
       "dependencies": {
-        "source-map": "^0.7.3"
-      },
-      "engines": {
-        "node": ">=8"
+        "hermes-estree": "0.23.1"
       }
     },
     "node_modules/hosted-git-info": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
-      "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==",
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
+      "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
       "license": "ISC",
       "dependencies": {
-        "lru-cache": "^6.0.0"
+        "lru-cache": "^10.0.1"
       },
       "engines": {
-        "node": ">=10"
+        "node": "^16.14.0 || >=18.0.0"
       }
     },
     "node_modules/hosted-git-info/node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-      "license": "ISC",
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/hosted-git-info/node_modules/yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "version": "10.4.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+      "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
       "license": "ISC"
     },
     "node_modules/html-parse-stringify": {
@@ -7960,19 +6419,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/https-proxy-agent": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
-      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "6",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/human-signals": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@@ -8136,20 +6582,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/internal-slot": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
-      "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "hasown": "^2.0.0",
-        "side-channel": "^1.0.4"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/invariant": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@@ -8177,74 +6609,18 @@
         "node": ">= 0.10"
       }
     },
-    "node_modules/is-array-buffer": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
-      "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "get-intrinsic": "^1.2.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
       "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "license": "MIT"
     },
-    "node_modules/is-bigint": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
-      "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
-      "license": "MIT",
-      "dependencies": {
-        "has-bigints": "^1.0.1"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-boolean-object": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
-      "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-buffer": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
       "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
       "license": "MIT"
     },
-    "node_modules/is-callable": {
-      "version": "1.2.7",
-      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
-      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-core-module": {
       "version": "2.15.1",
       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
@@ -8260,36 +6636,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/is-data-view": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
-      "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
-      "license": "MIT",
-      "dependencies": {
-        "is-typed-array": "^1.1.13"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-date-object": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
-      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
-      "license": "MIT",
-      "dependencies": {
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-directory": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
@@ -8323,15 +6669,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-      "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/is-glob": {
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -8344,60 +6681,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-interactive": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
-      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-invalid-path": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz",
-      "integrity": "sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==",
-      "license": "MIT",
-      "dependencies": {
-        "is-glob": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-invalid-path/node_modules/is-extglob": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
-      "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-invalid-path/node_modules/is-glob": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
-      "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==",
-      "license": "MIT",
-      "dependencies": {
-        "is-extglob": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-negative-zero": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
-      "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-number": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -8407,21 +6690,6 @@
         "node": ">=0.12.0"
       }
     },
-    "node_modules/is-number-object": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
-      "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
-      "license": "MIT",
-      "dependencies": {
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-path-cwd": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
@@ -8435,142 +6703,30 @@
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
       "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-plain-object": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
-      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
-      "license": "MIT",
-      "dependencies": {
-        "isobject": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-regex": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
-      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-shared-array-buffer": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
-      "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-string": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
-      "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
-      "license": "MIT",
-      "dependencies": {
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-symbol": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
-      "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
-      "license": "MIT",
-      "dependencies": {
-        "has-symbols": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-typed-array": {
-      "version": "1.1.13",
-      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
-      "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
-      "license": "MIT",
-      "dependencies": {
-        "which-typed-array": "^1.1.14"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-unicode-supported": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
-      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/is-valid-path": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz",
-      "integrity": "sha512-+kwPrVDu9Ms03L90Qaml+79+6DZHqHyRoANI6IsZJ/g8frhnfchDOBCa0RbQ6/kdHt5CS5OeIEyrYznNuVN+8A==",
+    "node_modules/is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
       "license": "MIT",
       "dependencies": {
-        "is-invalid-path": "^0.1.0"
+        "isobject": "^3.0.1"
       },
       "engines": {
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-weakref": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
-      "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+    "node_modules/is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
       "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
     "node_modules/is-wsl": {
@@ -8606,6 +6762,31 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/istanbul-lib-coverage": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+      "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/istanbul-lib-instrument": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+      "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "@babel/core": "^7.12.3",
+        "@babel/parser": "^7.14.7",
+        "@istanbuljs/schema": "^0.1.2",
+        "istanbul-lib-coverage": "^3.2.0",
+        "semver": "^6.3.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/jackspeak": {
       "version": "3.4.3",
       "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
@@ -8638,48 +6819,38 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/jest-environment-node/node_modules/@jest/types": {
+    "node_modules/jest-get-type": {
       "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
-      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+      "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
+      "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
       "license": "MIT",
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^17.0.8",
-        "chalk": "^4.0.0"
-      },
       "engines": {
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/jest-environment-node/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/jest-environment-node/node_modules/@types/yargs": {
-      "version": "17.0.33",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
-      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+    "node_modules/jest-haste-map": {
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
+      "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
       "license": "MIT",
       "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/jest-get-type": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
-      "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
-      "license": "MIT",
+        "@jest/types": "^29.6.3",
+        "@types/graceful-fs": "^4.1.3",
+        "@types/node": "*",
+        "anymatch": "^3.0.3",
+        "fb-watchman": "^2.0.0",
+        "graceful-fs": "^4.2.9",
+        "jest-regex-util": "^29.6.3",
+        "jest-util": "^29.7.0",
+        "jest-worker": "^29.7.0",
+        "micromatch": "^4.0.4",
+        "walker": "^1.0.8"
+      },
       "engines": {
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "^2.3.2"
       }
     },
     "node_modules/jest-message-util": {
@@ -8702,73 +6873,6 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/jest-message-util/node_modules/@jest/types": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
-      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
-      "license": "MIT",
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^17.0.8",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/jest-message-util/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/jest-message-util/node_modules/@types/yargs": {
-      "version": "17.0.33",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
-      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/jest-message-util/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/jest-message-util/node_modules/pretty-format": {
-      "version": "29.7.0",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
-      "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^18.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/jest-message-util/node_modules/react-is": {
-      "version": "18.3.1",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
-      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
-      "license": "MIT"
-    },
     "node_modules/jest-mock": {
       "version": "29.7.0",
       "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
@@ -8783,41 +6887,15 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/jest-mock/node_modules/@jest/types": {
+    "node_modules/jest-regex-util": {
       "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
-      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+      "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
+      "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
       "license": "MIT",
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^17.0.8",
-        "chalk": "^4.0.0"
-      },
       "engines": {
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/jest-mock/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/jest-mock/node_modules/@types/yargs": {
-      "version": "17.0.33",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
-      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
     "node_modules/jest-util": {
       "version": "29.7.0",
       "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
@@ -8835,41 +6913,6 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/jest-util/node_modules/@jest/types": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
-      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
-      "license": "MIT",
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^17.0.8",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/jest-util/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/jest-util/node_modules/@types/yargs": {
-      "version": "17.0.33",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
-      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
     "node_modules/jest-util/node_modules/picomatch": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@@ -8899,72 +6942,17 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/jest-validate/node_modules/@jest/types": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
-      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
-      "license": "MIT",
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^17.0.8",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/jest-validate/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/jest-validate/node_modules/@types/yargs": {
-      "version": "17.0.33",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
-      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/jest-validate/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+    "node_modules/jest-validate/node_modules/camelcase": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
       "license": "MIT",
       "engines": {
         "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/jest-validate/node_modules/pretty-format": {
-      "version": "29.7.0",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
-      "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@jest/schemas": "^29.6.3",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^18.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/jest-validate/node_modules/react-is": {
-      "version": "18.3.1",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
-      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
-      "license": "MIT"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
     "node_modules/jest-worker": {
       "version": "29.7.0",
@@ -9002,19 +6990,6 @@
       "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==",
       "license": "MIT"
     },
-    "node_modules/joi": {
-      "version": "17.13.3",
-      "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
-      "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "@hapi/hoek": "^9.3.0",
-        "@hapi/topo": "^5.1.0",
-        "@sideway/address": "^4.1.5",
-        "@sideway/formula": "^3.0.1",
-        "@sideway/pinpoint": "^2.0.0"
-      }
-    },
     "node_modules/join-component": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/join-component/-/join-component-1.1.0.tgz",
@@ -9103,36 +7078,6 @@
       "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
       "license": "MIT"
     },
-    "node_modules/json-schema-deref-sync": {
-      "version": "0.13.0",
-      "resolved": "https://registry.npmjs.org/json-schema-deref-sync/-/json-schema-deref-sync-0.13.0.tgz",
-      "integrity": "sha512-YBOEogm5w9Op337yb6pAT6ZXDqlxAsQCanM3grid8lMWNxRJO/zWEJi3ZzqDL8boWfwhTFym5EFrNgWwpqcBRg==",
-      "license": "MIT",
-      "dependencies": {
-        "clone": "^2.1.2",
-        "dag-map": "~1.0.0",
-        "is-valid-path": "^0.1.1",
-        "lodash": "^4.17.13",
-        "md5": "~2.2.0",
-        "memory-cache": "~0.2.0",
-        "traverse": "~0.6.6",
-        "valid-url": "~1.0.9"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
-    "node_modules/json-schema-deref-sync/node_modules/md5": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
-      "integrity": "sha512-PlGG4z5mBANDGCKsYQe0CaUYHdZYZt8ZPZLmEt+Urf0W4GlpTX4HescwHU+dc9+Z/G/vZKYZYFrwgm9VxK6QOQ==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "charenc": "~0.0.1",
-        "crypt": "~0.0.1",
-        "is-buffer": "~1.1.1"
-      }
-    },
     "node_modules/json5": {
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -9207,9 +7152,9 @@
       "license": "MIT"
     },
     "node_modules/lightningcss": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.19.0.tgz",
-      "integrity": "sha512-yV5UR7og+Og7lQC+70DA7a8ta1uiOPnWPJfxa0wnxylev5qfo4P+4iMpzWAdYWOca4jdNQZii+bDL/l+4hUXIA==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz",
+      "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==",
       "license": "MPL-2.0",
       "dependencies": {
         "detect-libc": "^1.0.3"
@@ -9222,20 +7167,22 @@
         "url": "https://opencollective.com/parcel"
       },
       "optionalDependencies": {
-        "lightningcss-darwin-arm64": "1.19.0",
-        "lightningcss-darwin-x64": "1.19.0",
-        "lightningcss-linux-arm-gnueabihf": "1.19.0",
-        "lightningcss-linux-arm64-gnu": "1.19.0",
-        "lightningcss-linux-arm64-musl": "1.19.0",
-        "lightningcss-linux-x64-gnu": "1.19.0",
-        "lightningcss-linux-x64-musl": "1.19.0",
-        "lightningcss-win32-x64-msvc": "1.19.0"
+        "lightningcss-darwin-arm64": "1.27.0",
+        "lightningcss-darwin-x64": "1.27.0",
+        "lightningcss-freebsd-x64": "1.27.0",
+        "lightningcss-linux-arm-gnueabihf": "1.27.0",
+        "lightningcss-linux-arm64-gnu": "1.27.0",
+        "lightningcss-linux-arm64-musl": "1.27.0",
+        "lightningcss-linux-x64-gnu": "1.27.0",
+        "lightningcss-linux-x64-musl": "1.27.0",
+        "lightningcss-win32-arm64-msvc": "1.27.0",
+        "lightningcss-win32-x64-msvc": "1.27.0"
       }
     },
     "node_modules/lightningcss-darwin-arm64": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.19.0.tgz",
-      "integrity": "sha512-wIJmFtYX0rXHsXHSr4+sC5clwblEMji7HHQ4Ub1/CznVRxtCFha6JIt5JZaNf8vQrfdZnBxLLC6R8pC818jXqg==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz",
+      "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==",
       "cpu": [
         "arm64"
       ],
@@ -9253,9 +7200,9 @@
       }
     },
     "node_modules/lightningcss-darwin-x64": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.19.0.tgz",
-      "integrity": "sha512-Lif1wD6P4poaw9c/4Uh2z+gmrWhw/HtXFoeZ3bEsv6Ia4tt8rOJBdkfVaUJ6VXmpKHALve+iTyP2+50xY1wKPw==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz",
+      "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==",
       "cpu": [
         "x64"
       ],
@@ -9272,10 +7219,30 @@
         "url": "https://opencollective.com/parcel"
       }
     },
+    "node_modules/lightningcss-freebsd-x64": {
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz",
+      "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
     "node_modules/lightningcss-linux-arm-gnueabihf": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.19.0.tgz",
-      "integrity": "sha512-P15VXY5682mTXaiDtbnLYQflc8BYb774j2R84FgDLJTN6Qp0ZjWEFyN1SPqyfTj2B2TFjRHRUvQSSZ7qN4Weig==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz",
+      "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==",
       "cpu": [
         "arm"
       ],
@@ -9293,9 +7260,9 @@
       }
     },
     "node_modules/lightningcss-linux-arm64-gnu": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.19.0.tgz",
-      "integrity": "sha512-zwXRjWqpev8wqO0sv0M1aM1PpjHz6RVIsBcxKszIG83Befuh4yNysjgHVplF9RTU7eozGe3Ts7r6we1+Qkqsww==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz",
+      "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==",
       "cpu": [
         "arm64"
       ],
@@ -9313,9 +7280,9 @@
       }
     },
     "node_modules/lightningcss-linux-arm64-musl": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.19.0.tgz",
-      "integrity": "sha512-vSCKO7SDnZaFN9zEloKSZM5/kC5gbzUjoJQ43BvUpyTFUX7ACs/mDfl2Eq6fdz2+uWhUh7vf92c4EaaP4udEtA==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz",
+      "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==",
       "cpu": [
         "arm64"
       ],
@@ -9333,9 +7300,9 @@
       }
     },
     "node_modules/lightningcss-linux-x64-gnu": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.19.0.tgz",
-      "integrity": "sha512-0AFQKvVzXf9byrXUq9z0anMGLdZJS+XSDqidyijI5njIwj6MdbvX2UZK/c4FfNmeRa2N/8ngTffoIuOUit5eIQ==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz",
+      "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==",
       "cpu": [
         "x64"
       ],
@@ -9353,9 +7320,9 @@
       }
     },
     "node_modules/lightningcss-linux-x64-musl": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.19.0.tgz",
-      "integrity": "sha512-SJoM8CLPt6ECCgSuWe+g0qo8dqQYVcPiW2s19dxkmSI5+Uu1GIRzyKA0b7QqmEXolA+oSJhQqCmJpzjY4CuZAg==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz",
+      "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==",
       "cpu": [
         "x64"
       ],
@@ -9372,10 +7339,30 @@
         "url": "https://opencollective.com/parcel"
       }
     },
+    "node_modules/lightningcss-win32-arm64-msvc": {
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz",
+      "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
     "node_modules/lightningcss-win32-x64-msvc": {
-      "version": "1.19.0",
-      "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.19.0.tgz",
-      "integrity": "sha512-C+VuUTeSUOAaBZZOPT7Etn/agx/MatzJzGRkeV+zEABmPuntv1zihncsi+AyGmjkkzq3wVedEy7h0/4S84mUtg==",
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz",
+      "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==",
       "cpu": [
         "x64"
       ],
@@ -9514,159 +7501,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/logkitty": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.7.1.tgz",
-      "integrity": "sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-fragments": "^0.2.1",
-        "dayjs": "^1.8.15",
-        "yargs": "^15.1.0"
-      },
-      "bin": {
-        "logkitty": "bin/logkitty.js"
-      }
-    },
-    "node_modules/logkitty/node_modules/camelcase": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
-      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/logkitty/node_modules/cliui": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
-      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^6.2.0"
-      }
-    },
-    "node_modules/logkitty/node_modules/find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-      "license": "MIT",
-      "dependencies": {
-        "locate-path": "^5.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/logkitty/node_modules/locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-      "license": "MIT",
-      "dependencies": {
-        "p-locate": "^4.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/logkitty/node_modules/p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "license": "MIT",
-      "dependencies": {
-        "p-try": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/logkitty/node_modules/p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-      "license": "MIT",
-      "dependencies": {
-        "p-limit": "^2.2.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/logkitty/node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/logkitty/node_modules/wrap-ansi": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
-      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/logkitty/node_modules/y18n": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
-      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
-      "license": "ISC"
-    },
-    "node_modules/logkitty/node_modules/yargs": {
-      "version": "15.4.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
-      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
-      "license": "MIT",
-      "dependencies": {
-        "cliui": "^6.0.0",
-        "decamelize": "^1.2.0",
-        "find-up": "^4.1.0",
-        "get-caller-file": "^2.0.1",
-        "require-directory": "^2.1.1",
-        "require-main-filename": "^2.0.0",
-        "set-blocking": "^2.0.0",
-        "string-width": "^4.2.0",
-        "which-module": "^2.0.0",
-        "y18n": "^4.0.0",
-        "yargs-parser": "^18.1.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/logkitty/node_modules/yargs-parser": {
-      "version": "18.1.3",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
-      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
-      "license": "ISC",
-      "dependencies": {
-        "camelcase": "^5.0.0",
-        "decamelize": "^1.2.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/loose-envify": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -9757,24 +7591,12 @@
         "node": ">=0.10"
       }
     },
-    "node_modules/md5hex": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/md5hex/-/md5hex-1.0.0.tgz",
-      "integrity": "sha512-c2YOUbp33+6thdCUi34xIyOU/a7bvGKj/3DB1iaPMTuPHf/Q2d5s4sn1FaCOO43XkXggnb08y5W2PU8UNYNLKQ==",
-      "license": "MIT"
-    },
     "node_modules/memoize-one": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
       "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
       "license": "MIT"
     },
-    "node_modules/memory-cache": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz",
-      "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==",
-      "license": "BSD-2-Clause"
-    },
     "node_modules/merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -9791,18 +7613,18 @@
       }
     },
     "node_modules/metro": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro/-/metro-0.80.12.tgz",
-      "integrity": "sha512-1UsH5FzJd9quUsD1qY+zUG4JY3jo3YEMxbMYH9jT6NK3j4iORhlwTK8fYTfAUBhDKjgLfKjAh7aoazNE23oIRA==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/code-frame": "^7.0.0",
-        "@babel/core": "^7.20.0",
-        "@babel/generator": "^7.20.0",
-        "@babel/parser": "^7.20.0",
-        "@babel/template": "^7.0.0",
-        "@babel/traverse": "^7.20.0",
-        "@babel/types": "^7.20.0",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro/-/metro-0.81.0.tgz",
+      "integrity": "sha512-kzdzmpL0gKhEthZ9aOV7sTqvg6NuTxDV8SIm9pf9sO8VVEbKrQk5DNcwupOUjgPPFAuKUc2NkT0suyT62hm2xg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.24.7",
+        "@babel/core": "^7.25.2",
+        "@babel/generator": "^7.25.0",
+        "@babel/parser": "^7.25.3",
+        "@babel/template": "^7.25.0",
+        "@babel/traverse": "^7.25.3",
+        "@babel/types": "^7.25.2",
         "accepts": "^1.3.7",
         "chalk": "^4.0.0",
         "ci-info": "^2.0.0",
@@ -9812,24 +7634,24 @@
         "error-stack-parser": "^2.0.6",
         "flow-enums-runtime": "^0.0.6",
         "graceful-fs": "^4.2.4",
-        "hermes-parser": "0.23.1",
+        "hermes-parser": "0.24.0",
         "image-size": "^1.0.2",
         "invariant": "^2.2.4",
         "jest-worker": "^29.6.3",
         "jsc-safe-url": "^0.2.2",
         "lodash.throttle": "^4.1.1",
-        "metro-babel-transformer": "0.80.12",
-        "metro-cache": "0.80.12",
-        "metro-cache-key": "0.80.12",
-        "metro-config": "0.80.12",
-        "metro-core": "0.80.12",
-        "metro-file-map": "0.80.12",
-        "metro-resolver": "0.80.12",
-        "metro-runtime": "0.80.12",
-        "metro-source-map": "0.80.12",
-        "metro-symbolicate": "0.80.12",
-        "metro-transform-plugins": "0.80.12",
-        "metro-transform-worker": "0.80.12",
+        "metro-babel-transformer": "0.81.0",
+        "metro-cache": "0.81.0",
+        "metro-cache-key": "0.81.0",
+        "metro-config": "0.81.0",
+        "metro-core": "0.81.0",
+        "metro-file-map": "0.81.0",
+        "metro-resolver": "0.81.0",
+        "metro-runtime": "0.81.0",
+        "metro-source-map": "0.81.0",
+        "metro-symbolicate": "0.81.0",
+        "metro-transform-plugins": "0.81.0",
+        "metro-transform-worker": "0.81.0",
         "mime-types": "^2.1.27",
         "nullthrows": "^1.1.1",
         "serialize-error": "^2.1.0",
@@ -9843,102 +7665,102 @@
         "metro": "src/cli.js"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-babel-transformer": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.80.12.tgz",
-      "integrity": "sha512-YZziRs0MgA3pzCkkvOoQRXjIoVjvrpi/yRlJnObyIvMP6lFdtyG4nUGIwGY9VXnBvxmXD6mPY2e+NSw6JAyiRg==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.81.0.tgz",
+      "integrity": "sha512-Dc0QWK4wZIeHnyZ3sevWGTnnSkIDDn/SWyfrn99zbKbDOCoCYy71PAn9uCRrP/hduKLJQOy+tebd63Rr9D8tXg==",
       "license": "MIT",
       "dependencies": {
-        "@babel/core": "^7.20.0",
+        "@babel/core": "^7.25.2",
         "flow-enums-runtime": "^0.0.6",
-        "hermes-parser": "0.23.1",
+        "hermes-parser": "0.24.0",
         "nullthrows": "^1.1.1"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-babel-transformer/node_modules/hermes-estree": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.23.1.tgz",
-      "integrity": "sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg==",
+      "version": "0.24.0",
+      "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.24.0.tgz",
+      "integrity": "sha512-LyoXLB7IFzeZW0EvAbGZacbxBN7t6KKSDqFJPo3Ydow7wDlrDjXwsdiAHV6XOdvEN9MEuWXsSIFN4tzpyrXIHw==",
       "license": "MIT"
     },
     "node_modules/metro-babel-transformer/node_modules/hermes-parser": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.23.1.tgz",
-      "integrity": "sha512-oxl5h2DkFW83hT4DAUJorpah8ou4yvmweUzLJmmr6YV2cezduCdlil1AvU/a/xSsAFo4WUcNA4GoV5Bvq6JffA==",
+      "version": "0.24.0",
+      "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.24.0.tgz",
+      "integrity": "sha512-IJooSvvu2qNRe7oo9Rb04sUT4omtZqZqf9uq9WM25Tb6v3usmvA93UqfnnoWs5V0uYjEl9Al6MNU10MCGKLwpg==",
       "license": "MIT",
       "dependencies": {
-        "hermes-estree": "0.23.1"
+        "hermes-estree": "0.24.0"
       }
     },
     "node_modules/metro-cache": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.80.12.tgz",
-      "integrity": "sha512-p5kNHh2KJ0pbQI/H7ZBPCEwkyNcSz7OUkslzsiIWBMPQGFJ/xArMwkV7I+GJcWh+b4m6zbLxE5fk6fqbVK1xGA==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.81.0.tgz",
+      "integrity": "sha512-DyuqySicHXkHUDZFVJmh0ygxBSx6pCKUrTcSgb884oiscV/ROt1Vhye+x+OIHcsodyA10gzZtrVtxIFV4l9I4g==",
       "license": "MIT",
       "dependencies": {
         "exponential-backoff": "^3.1.1",
         "flow-enums-runtime": "^0.0.6",
-        "metro-core": "0.80.12"
+        "metro-core": "0.81.0"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-cache-key": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.80.12.tgz",
-      "integrity": "sha512-o4BspKnugg/pE45ei0LGHVuBJXwRgruW7oSFAeSZvBKA/sGr0UhOGY3uycOgWInnS3v5yTTfiBA9lHlNRhsvGA==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.81.0.tgz",
+      "integrity": "sha512-qX/IwtknP9bQZL78OK9xeSvLM/xlGfrs6SlUGgHvrxtmGTRSsxcyqxR+c+7ch1xr05n62Gin/O44QKg5V70rNQ==",
       "license": "MIT",
       "dependencies": {
         "flow-enums-runtime": "^0.0.6"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-config": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.80.12.tgz",
-      "integrity": "sha512-4rwOWwrhm62LjB12ytiuR5NgK1ZBNr24/He8mqCsC+HXZ+ATbrewLNztzbAZHtFsrxP4D4GLTGgh96pCpYLSAQ==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.81.0.tgz",
+      "integrity": "sha512-6CinEaBe3WLpRlKlYXXu8r1UblJhbwD6Gtnoib5U8j6Pjp7XxMG9h/DGMeNp9aGLDu1OieUqiXpFo7O0/rR5Kg==",
       "license": "MIT",
       "dependencies": {
         "connect": "^3.6.5",
         "cosmiconfig": "^5.0.5",
         "flow-enums-runtime": "^0.0.6",
         "jest-validate": "^29.6.3",
-        "metro": "0.80.12",
-        "metro-cache": "0.80.12",
-        "metro-core": "0.80.12",
-        "metro-runtime": "0.80.12"
+        "metro": "0.81.0",
+        "metro-cache": "0.81.0",
+        "metro-core": "0.81.0",
+        "metro-runtime": "0.81.0"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-core": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.80.12.tgz",
-      "integrity": "sha512-QqdJ/yAK+IpPs2HU/h5v2pKEdANBagSsc6DRSjnwSyJsCoHlmyJKCaCJ7KhWGx+N4OHxh37hoA8fc2CuZbx0Fw==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.81.0.tgz",
+      "integrity": "sha512-CVkM5YCOAFkNMvJai6KzA0RpztzfEKRX62/PFMOJ9J7K0uq/UkOFLxcgpcncMIrfy0PbfEj811b69tjULUQe1Q==",
       "license": "MIT",
       "dependencies": {
         "flow-enums-runtime": "^0.0.6",
         "lodash.throttle": "^4.1.1",
-        "metro-resolver": "0.80.12"
+        "metro-resolver": "0.81.0"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-file-map": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.80.12.tgz",
-      "integrity": "sha512-sYdemWSlk66bWzW2wp79kcPMzwuG32x1ZF3otI0QZTmrnTaaTiGyhE66P1z6KR4n2Eu5QXiABa6EWbAQv0r8bw==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.81.0.tgz",
+      "integrity": "sha512-zMDI5uYhQCyxbye/AuFx/pAbsz9K+vKL7h1ShUXdN2fz4VUPiyQYRsRqOoVG1DsiCgzd5B6LW0YW77NFpjDQeg==",
       "license": "MIT",
       "dependencies": {
         "anymatch": "^3.0.3",
@@ -9954,7 +7776,7 @@
         "walker": "^1.0.7"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       },
       "optionalDependencies": {
         "fsevents": "^2.3.2"
@@ -9976,81 +7798,73 @@
       "license": "MIT"
     },
     "node_modules/metro-minify-terser": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.80.12.tgz",
-      "integrity": "sha512-muWzUw3y5k+9083ZoX9VaJLWEV2Jcgi+Oan0Mmb/fBNMPqP9xVDuy4pOMn/HOiGndgfh/MK7s4bsjkyLJKMnXQ==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.81.0.tgz",
+      "integrity": "sha512-U2ramh3W822ZR1nfXgIk+emxsf5eZSg10GbQrT0ZizImK8IZ5BmJY+BHRIkQgHzWFpExOVxC7kWbGL1bZALswA==",
       "license": "MIT",
       "dependencies": {
         "flow-enums-runtime": "^0.0.6",
         "terser": "^5.15.0"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-resolver": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.80.12.tgz",
-      "integrity": "sha512-PR24gYRZnYHM3xT9pg6BdbrGbM/Cu1TcyIFBVlAk7qDAuHkUNQ1nMzWumWs+kwSvtd9eZGzHoucGJpTUEeLZAw==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.81.0.tgz",
+      "integrity": "sha512-Uu2Q+buHhm571cEwpPek8egMbdSTqmwT/5U7ZVNpK6Z2ElQBBCxd7HmFAslKXa7wgpTO2FAn6MqGeERbAtVDUA==",
       "license": "MIT",
       "dependencies": {
         "flow-enums-runtime": "^0.0.6"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-runtime": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.80.12.tgz",
-      "integrity": "sha512-LIx7+92p5rpI0i6iB4S4GBvvLxStNt6fF0oPMaUd1Weku7jZdfkCZzmrtDD9CSQ6EPb0T9NUZoyXIxlBa3wOCw==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.81.0.tgz",
+      "integrity": "sha512-6oYB5HOt37RuGz2eV4A6yhcl+PUTwJYLDlY9vhT+aVjbUWI6MdBCf69vc4f5K5Vpt+yOkjy+2LDwLS0ykWFwYw==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.25.0",
         "flow-enums-runtime": "^0.0.6"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-source-map": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.80.12.tgz",
-      "integrity": "sha512-o+AXmE7hpvM8r8MKsx7TI21/eerYYy2DCDkWfoBkv+jNkl61khvDHlQn0cXZa6lrcNZiZkl9oHSMcwLLIrFmpw==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.0.tgz",
+      "integrity": "sha512-TzsVxhH83dyxg4A4+L1nzNO12I7ps5IHLjKGZH3Hrf549eiZivkdjYiq/S5lOB+p2HiQ+Ykcwtmcja95LIC62g==",
       "license": "MIT",
       "dependencies": {
-        "@babel/traverse": "^7.20.0",
-        "@babel/types": "^7.20.0",
+        "@babel/traverse": "^7.25.3",
+        "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3",
+        "@babel/types": "^7.25.2",
         "flow-enums-runtime": "^0.0.6",
         "invariant": "^2.2.4",
-        "metro-symbolicate": "0.80.12",
+        "metro-symbolicate": "0.81.0",
         "nullthrows": "^1.1.1",
-        "ob1": "0.80.12",
+        "ob1": "0.81.0",
         "source-map": "^0.5.6",
         "vlq": "^1.0.0"
       },
       "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/metro-source-map/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-symbolicate": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.80.12.tgz",
-      "integrity": "sha512-/dIpNdHksXkGHZXARZpL7doUzHqSNxgQ8+kQGxwpJuHnDhGkENxB5PS2QBaTDdEcmyTMjS53CN1rl9n1gR6fmw==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.0.tgz",
+      "integrity": "sha512-C/1rWbNTPYp6yzID8IPuQPpVGzJ2rbWYBATxlvQ9dfK5lVNoxcwz77hjcY8ISLsRRR15hyd/zbjCNKPKeNgE1Q==",
       "license": "MIT",
       "dependencies": {
         "flow-enums-runtime": "^0.0.6",
         "invariant": "^2.2.4",
-        "metro-source-map": "0.80.12",
+        "metro-source-map": "0.81.0",
         "nullthrows": "^1.1.1",
         "source-map": "^0.5.6",
         "through2": "^2.0.1",
@@ -10060,57 +7874,48 @@
         "metro-symbolicate": "src/index.js"
       },
       "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/metro-symbolicate/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-transform-plugins": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.80.12.tgz",
-      "integrity": "sha512-WQWp00AcZvXuQdbjQbx1LzFR31IInlkCDYJNRs6gtEtAyhwpMMlL2KcHmdY+wjDO9RPcliZ+Xl1riOuBecVlPA==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.81.0.tgz",
+      "integrity": "sha512-uErLAPBvttGCrmGSCa0dNHlOTk3uJFVEVWa5WDg6tQ79PRmuYRwzUgLhVzn/9/kyr75eUX3QWXN79Jvu4txt6Q==",
       "license": "MIT",
       "dependencies": {
-        "@babel/core": "^7.20.0",
-        "@babel/generator": "^7.20.0",
-        "@babel/template": "^7.0.0",
-        "@babel/traverse": "^7.20.0",
+        "@babel/core": "^7.25.2",
+        "@babel/generator": "^7.25.0",
+        "@babel/template": "^7.25.0",
+        "@babel/traverse": "^7.25.3",
         "flow-enums-runtime": "^0.0.6",
         "nullthrows": "^1.1.1"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro-transform-worker": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.80.12.tgz",
-      "integrity": "sha512-KAPFN1y3eVqEbKLx1I8WOarHPqDMUa8WelWxaJCNKO/yHCP26zELeqTJvhsQup+8uwB6EYi/sp0b6TGoh6lOEA==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.81.0.tgz",
+      "integrity": "sha512-HrQ0twiruhKy0yA+9nK5bIe3WQXZcC66PXTvRIos61/EASLAP2DzEmW7IxN/MGsfZegN2UzqL2CG38+mOB45vg==",
       "license": "MIT",
       "dependencies": {
-        "@babel/core": "^7.20.0",
-        "@babel/generator": "^7.20.0",
-        "@babel/parser": "^7.20.0",
-        "@babel/types": "^7.20.0",
+        "@babel/core": "^7.25.2",
+        "@babel/generator": "^7.25.0",
+        "@babel/parser": "^7.25.3",
+        "@babel/types": "^7.25.2",
         "flow-enums-runtime": "^0.0.6",
-        "metro": "0.80.12",
-        "metro-babel-transformer": "0.80.12",
-        "metro-cache": "0.80.12",
-        "metro-cache-key": "0.80.12",
-        "metro-minify-terser": "0.80.12",
-        "metro-source-map": "0.80.12",
-        "metro-transform-plugins": "0.80.12",
+        "metro": "0.81.0",
+        "metro-babel-transformer": "0.81.0",
+        "metro-cache": "0.81.0",
+        "metro-cache-key": "0.81.0",
+        "metro-minify-terser": "0.81.0",
+        "metro-source-map": "0.81.0",
+        "metro-transform-plugins": "0.81.0",
         "nullthrows": "^1.1.1"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/metro/node_modules/ci-info": {
@@ -10129,18 +7934,18 @@
       }
     },
     "node_modules/metro/node_modules/hermes-estree": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.23.1.tgz",
-      "integrity": "sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg==",
+      "version": "0.24.0",
+      "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.24.0.tgz",
+      "integrity": "sha512-LyoXLB7IFzeZW0EvAbGZacbxBN7t6KKSDqFJPo3Ydow7wDlrDjXwsdiAHV6XOdvEN9MEuWXsSIFN4tzpyrXIHw==",
       "license": "MIT"
     },
     "node_modules/metro/node_modules/hermes-parser": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.23.1.tgz",
-      "integrity": "sha512-oxl5h2DkFW83hT4DAUJorpah8ou4yvmweUzLJmmr6YV2cezduCdlil1AvU/a/xSsAFo4WUcNA4GoV5Bvq6JffA==",
+      "version": "0.24.0",
+      "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.24.0.tgz",
+      "integrity": "sha512-IJooSvvu2qNRe7oo9Rb04sUT4omtZqZqf9uq9WM25Tb6v3usmvA93UqfnnoWs5V0uYjEl9Al6MNU10MCGKLwpg==",
       "license": "MIT",
       "dependencies": {
-        "hermes-estree": "0.23.1"
+        "hermes-estree": "0.24.0"
       }
     },
     "node_modules/metro/node_modules/ms": {
@@ -10149,15 +7954,6 @@
       "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "license": "MIT"
     },
-    "node_modules/metro/node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/metro/node_modules/strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -10216,18 +8012,6 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
-    "node_modules/mime": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
-      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
-      "license": "MIT",
-      "bin": {
-        "mime": "cli.js"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
     "node_modules/mime-db": {
       "version": "1.52.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -10465,15 +8249,6 @@
       "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
       "license": "MIT"
     },
-    "node_modules/nocache": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz",
-      "integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
     "node_modules/node-abort-controller": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
@@ -10533,19 +8308,6 @@
       "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
       "license": "MIT"
     },
-    "node_modules/node-stream-zip": {
-      "version": "1.15.0",
-      "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz",
-      "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.12.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/antelle"
-      }
-    },
     "node_modules/normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -10556,24 +8318,30 @@
       }
     },
     "node_modules/npm-package-arg": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-7.0.0.tgz",
-      "integrity": "sha512-xXxr8y5U0kl8dVkz2oK7yZjPBvqM2fwaO5l3Yg13p03v8+E3qQcD0JNhHzjL1vyGgxcKkD0cco+NLR72iuPk3g==",
+      "version": "11.0.3",
+      "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz",
+      "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==",
       "license": "ISC",
       "dependencies": {
-        "hosted-git-info": "^3.0.2",
-        "osenv": "^0.1.5",
-        "semver": "^5.6.0",
-        "validate-npm-package-name": "^3.0.0"
+        "hosted-git-info": "^7.0.0",
+        "proc-log": "^4.0.0",
+        "semver": "^7.3.5",
+        "validate-npm-package-name": "^5.0.0"
+      },
+      "engines": {
+        "node": "^16.14.0 || >=18.0.0"
       }
     },
     "node_modules/npm-package-arg/node_modules/semver": {
-      "version": "5.7.2",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
-      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "version": "7.6.3",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
       "license": "ISC",
       "bin": {
-        "semver": "bin/semver"
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
     "node_modules/npm-run-path": {
@@ -10604,15 +8372,15 @@
       "license": "MIT"
     },
     "node_modules/ob1": {
-      "version": "0.80.12",
-      "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.80.12.tgz",
-      "integrity": "sha512-VMArClVT6LkhUGpnuEoBuyjG9rzUyEzg4PDkav6wK1cLhOK02gPCYFxoiB4mqVnrMhDpIzJcrGNAMVi9P+hXrw==",
+      "version": "0.81.0",
+      "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.81.0.tgz",
+      "integrity": "sha512-6Cvrkxt1tqaRdWqTAMcVYEiO5i1xcF9y7t06nFdjFqkfPsEloCf8WwhXdwBpNUkVYSQlSGS7cDgVQR86miBfBQ==",
       "license": "MIT",
       "dependencies": {
         "flow-enums-runtime": "^0.0.6"
       },
       "engines": {
-        "node": ">=18"
+        "node": ">=18.18"
       }
     },
     "node_modules/object-assign": {
@@ -10624,45 +8392,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/object-inspect": {
-      "version": "1.13.3",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
-      "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/object-keys": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/object.assign": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
-      "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.5",
-        "define-properties": "^1.2.1",
-        "has-symbols": "^1.0.3",
-        "object-keys": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/on-finished": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@@ -10706,17 +8435,16 @@
       }
     },
     "node_modules/open": {
-      "version": "8.4.2",
-      "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
-      "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+      "version": "7.4.2",
+      "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+      "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
       "license": "MIT",
       "dependencies": {
-        "define-lazy-prop": "^2.0.0",
-        "is-docker": "^2.1.1",
-        "is-wsl": "^2.2.0"
+        "is-docker": "^2.0.0",
+        "is-wsl": "^2.1.1"
       },
       "engines": {
-        "node": ">=12"
+        "node": ">=8"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
@@ -10810,15 +8538,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/os-homedir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-      "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/os-tmpdir": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@@ -10828,17 +8547,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/osenv": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
-      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
-      "deprecated": "This package is no longer supported.",
-      "license": "ISC",
-      "dependencies": {
-        "os-homedir": "^1.0.0",
-        "os-tmpdir": "^1.0.0"
-      }
-    },
     "node_modules/p-finally": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
@@ -11166,19 +8874,10 @@
         "node": ">=4.0.0"
       }
     },
-    "node_modules/possible-typed-array-names": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
-      "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/postcss": {
-      "version": "8.4.47",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
-      "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
+      "version": "8.4.49",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+      "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
       "funding": [
         {
           "type": "opencollective",
@@ -11196,7 +8895,7 @@
       "license": "MIT",
       "dependencies": {
         "nanoid": "^3.3.7",
-        "picocolors": "^1.1.0",
+        "picocolors": "^1.1.1",
         "source-map-js": "^1.2.1"
       },
       "engines": {
@@ -11216,56 +8915,46 @@
       }
     },
     "node_modules/pretty-format": {
-      "version": "24.9.0",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz",
-      "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==",
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+      "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
       "license": "MIT",
       "dependencies": {
-        "@jest/types": "^24.9.0",
-        "ansi-regex": "^4.0.0",
-        "ansi-styles": "^3.2.0",
-        "react-is": "^16.8.4"
+        "@jest/schemas": "^29.6.3",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^18.0.0"
       },
       "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/pretty-format/node_modules/ansi-regex": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
-      "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
     "node_modules/pretty-format/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
       "license": "MIT",
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/pretty-format/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "1.1.3"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "node_modules/pretty-format/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+    "node_modules/pretty-format/node_modules/react-is": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
       "license": "MIT"
     },
+    "node_modules/proc-log": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
+      "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
+      "license": "ISC",
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
     "node_modules/process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -11359,16 +9048,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/querystring": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz",
-      "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==",
-      "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.4.x"
-      }
-    },
     "node_modules/queue": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
@@ -11423,9 +9102,9 @@
       }
     },
     "node_modules/react": {
-      "version": "18.2.0",
-      "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
-      "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+      "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
       "license": "MIT",
       "dependencies": {
         "loose-envify": "^1.1.0"
@@ -11506,47 +9185,48 @@
       "license": "MIT"
     },
     "node_modules/react-native": {
-      "version": "0.74.5",
-      "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.74.5.tgz",
-      "integrity": "sha512-Bgg2WvxaGODukJMTZFTZBNMKVaROHLwSb8VAGEdrlvKwfb1hHg/3aXTUICYk7dwgAnb+INbGMwnF8yeAgIUmqw==",
+      "version": "0.76.2",
+      "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.2.tgz",
+      "integrity": "sha512-mkEBKGOmJxhfq8IOsvmk0QuTzlBt9vS+uo0gwbqfUmEDqoC359v80zhUf94WimYBrBkpRQWFbEu5iqMDHrYzlQ==",
       "license": "MIT",
       "dependencies": {
         "@jest/create-cache-key-function": "^29.6.3",
-        "@react-native-community/cli": "13.6.9",
-        "@react-native-community/cli-platform-android": "13.6.9",
-        "@react-native-community/cli-platform-ios": "13.6.9",
-        "@react-native/assets-registry": "0.74.87",
-        "@react-native/codegen": "0.74.87",
-        "@react-native/community-cli-plugin": "0.74.87",
-        "@react-native/gradle-plugin": "0.74.87",
-        "@react-native/js-polyfills": "0.74.87",
-        "@react-native/normalize-colors": "0.74.87",
-        "@react-native/virtualized-lists": "0.74.87",
+        "@react-native/assets-registry": "0.76.2",
+        "@react-native/codegen": "0.76.2",
+        "@react-native/community-cli-plugin": "0.76.2",
+        "@react-native/gradle-plugin": "0.76.2",
+        "@react-native/js-polyfills": "0.76.2",
+        "@react-native/normalize-colors": "0.76.2",
+        "@react-native/virtualized-lists": "0.76.2",
         "abort-controller": "^3.0.0",
         "anser": "^1.4.9",
         "ansi-regex": "^5.0.0",
+        "babel-jest": "^29.7.0",
+        "babel-plugin-syntax-hermes-parser": "^0.23.1",
         "base64-js": "^1.5.1",
         "chalk": "^4.0.0",
+        "commander": "^12.0.0",
         "event-target-shim": "^5.0.1",
         "flow-enums-runtime": "^0.0.6",
+        "glob": "^7.1.1",
         "invariant": "^2.2.4",
         "jest-environment-node": "^29.6.3",
         "jsc-android": "^250231.0.0",
         "memoize-one": "^5.0.0",
-        "metro-runtime": "^0.80.3",
-        "metro-source-map": "^0.80.3",
+        "metro-runtime": "^0.81.0",
+        "metro-source-map": "^0.81.0",
         "mkdirp": "^0.5.1",
         "nullthrows": "^1.1.1",
-        "pretty-format": "^26.5.2",
+        "pretty-format": "^29.7.0",
         "promise": "^8.3.0",
-        "react-devtools-core": "^5.0.0",
+        "react-devtools-core": "^5.3.1",
         "react-refresh": "^0.14.0",
-        "react-shallow-renderer": "^16.15.0",
         "regenerator-runtime": "^0.13.2",
         "scheduler": "0.24.0-canary-efb381bbf-20230505",
+        "semver": "^7.1.3",
         "stacktrace-parser": "^0.1.10",
         "whatwg-fetch": "^3.0.0",
-        "ws": "^6.2.2",
+        "ws": "^6.2.3",
         "yargs": "^17.6.2"
       },
       "bin": {
@@ -11557,7 +9237,7 @@
       },
       "peerDependencies": {
         "@types/react": "^18.2.6",
-        "react": "18.2.0"
+        "react": "^18.2.0"
       },
       "peerDependenciesMeta": {
         "@types/react": {
@@ -11566,9 +9246,9 @@
       }
     },
     "node_modules/react-native-safe-area-context": {
-      "version": "4.10.5",
-      "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.10.5.tgz",
-      "integrity": "sha512-Wyb0Nqw2XJ6oZxW/cK8k5q7/UAhg/wbEG6UVf89rQqecDZTDA5ic//P9J6VvJRVZerzGmxWQpVuM7f+PRYUM4g==",
+      "version": "4.12.0",
+      "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.12.0.tgz",
+      "integrity": "sha512-ukk5PxcF4p3yu6qMZcmeiZgowhb5AsKRnil54YFUUAXVIS7PJcMHGGC+q44fCiBg44/1AJk5njGMez1m9H0BVQ==",
       "license": "MIT",
       "peerDependencies": {
         "react": "*",
@@ -11576,9 +9256,9 @@
       }
     },
     "node_modules/react-native-screens": {
-      "version": "3.31.1",
-      "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.31.1.tgz",
-      "integrity": "sha512-8fRW362pfZ9y4rS8KY5P3DFScrmwo/vu1RrRMMx0PNHbeC9TLq0Kw1ubD83591yz64gLNHFLTVkTJmWeWCXKtQ==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.1.0.tgz",
+      "integrity": "sha512-tCBwe7fRMpoi/nIgZxE86N8b2SH8d5PlfGaQO8lgqlXqIyvwqm3u1HJCaA0tsacPyzhW7vVtRfQyq9e1j0S2gA==",
       "license": "MIT",
       "dependencies": {
         "react-freeze": "^1.0.0",
@@ -11589,59 +9269,22 @@
         "react-native": "*"
       }
     },
-    "node_modules/react-native/node_modules/@jest/types": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
-      "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^15.0.0",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": ">= 10.14.2"
-      }
-    },
-    "node_modules/react-native/node_modules/@react-native/normalize-colors": {
-      "version": "0.74.87",
-      "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.87.tgz",
-      "integrity": "sha512-Xh7Nyk/MPefkb0Itl5Z+3oOobeG9lfLb7ZOY2DKpFnoCE1TzBmib9vMNdFaLdSxLIP+Ec6icgKtdzYg8QUPYzA==",
-      "license": "MIT"
-    },
-    "node_modules/react-native/node_modules/@types/istanbul-reports": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
-      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/istanbul-lib-report": "*"
-      }
-    },
-    "node_modules/react-native/node_modules/@types/yargs": {
-      "version": "15.0.19",
-      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz",
-      "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==",
+    "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": {
+      "version": "0.23.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz",
+      "integrity": "sha512-uNLD0tk2tLUjGFdmCk+u/3FEw2o+BAwW4g+z2QVlxJrzZYOOPADroEcNtTPt5lNiScctaUmnsTkVEnOwZUOLhA==",
       "license": "MIT",
       "dependencies": {
-        "@types/yargs-parser": "*"
+        "hermes-parser": "0.23.1"
       }
     },
-    "node_modules/react-native/node_modules/pretty-format": {
-      "version": "26.6.2",
-      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
-      "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+    "node_modules/react-native/node_modules/commander": {
+      "version": "12.1.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+      "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
       "license": "MIT",
-      "dependencies": {
-        "@jest/types": "^26.6.2",
-        "ansi-regex": "^5.0.0",
-        "ansi-styles": "^4.0.0",
-        "react-is": "^17.0.1"
-      },
       "engines": {
-        "node": ">= 10"
+        "node": ">=18"
       }
     },
     "node_modules/react-native/node_modules/promise": {
@@ -11653,18 +9296,24 @@
         "asap": "~2.0.6"
       }
     },
-    "node_modules/react-native/node_modules/react-is": {
-      "version": "17.0.2",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-      "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "license": "MIT"
-    },
     "node_modules/react-native/node_modules/regenerator-runtime": {
       "version": "0.13.11",
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
       "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
       "license": "MIT"
     },
+    "node_modules/react-native/node_modules/semver": {
+      "version": "7.6.3",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/react-native/node_modules/ws": {
       "version": "6.2.3",
       "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
@@ -11683,19 +9332,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/react-shallow-renderer": {
-      "version": "16.15.0",
-      "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz",
-      "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==",
-      "license": "MIT",
-      "dependencies": {
-        "object-assign": "^4.1.1",
-        "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0"
-      },
-      "peerDependencies": {
-        "react": "^16.0.0 || ^17.0.0 || ^18.0.0"
-      }
-    },
     "node_modules/readable-stream": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
@@ -11776,29 +9412,10 @@
       "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
       "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@babel/runtime": "^7.8.4"
       }
     },
-    "node_modules/regexp.prototype.flags": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
-      "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "define-properties": "^1.2.1",
-        "es-errors": "^1.3.0",
-        "set-function-name": "^2.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/regexpu-core": {
       "version": "6.1.1",
       "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz",
@@ -11858,12 +9475,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/require-main-filename": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
-      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
-      "license": "ISC"
-    },
     "node_modules/requireg": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/requireg/-/requireg-0.2.2.tgz",
@@ -11912,6 +9523,12 @@
         "node": ">=8"
       }
     },
+    "node_modules/resolve-workspace-root": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.0.tgz",
+      "integrity": "sha512-IsaBUZETJD5WsI11Wt8PKHwaIe45or6pwNc8yflvLJ4DWtImK9kuLoH5kUva/2Mmx/RdIyr4aONNSa2v9LTJsw==",
+      "license": "MIT"
+    },
     "node_modules/resolve.exports": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
@@ -11983,30 +9600,6 @@
         "queue-microtask": "^1.2.2"
       }
     },
-    "node_modules/safe-array-concat": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
-      "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "get-intrinsic": "^1.2.4",
-        "has-symbols": "^1.0.3",
-        "isarray": "^2.0.5"
-      },
-      "engines": {
-        "node": ">=0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/safe-array-concat/node_modules/isarray": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
-      "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
-      "license": "MIT"
-    },
     "node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -12027,23 +9620,6 @@
       ],
       "license": "MIT"
     },
-    "node_modules/safe-regex-test": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
-      "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.6",
-        "es-errors": "^1.3.0",
-        "is-regex": "^1.1.4"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/sax": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
@@ -12082,15 +9658,15 @@
       }
     },
     "node_modules/send": {
-      "version": "0.18.0",
-      "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
-      "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+      "version": "0.19.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.19.1.tgz",
+      "integrity": "sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==",
       "license": "MIT",
       "dependencies": {
         "debug": "2.6.9",
         "depd": "2.0.0",
         "destroy": "1.2.0",
-        "encodeurl": "~1.0.2",
+        "encodeurl": "~2.0.0",
         "escape-html": "~1.0.3",
         "etag": "~1.8.1",
         "fresh": "0.5.2",
@@ -12120,6 +9696,15 @@
       "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "license": "MIT"
     },
+    "node_modules/send/node_modules/encodeurl": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+      "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/send/node_modules/mime": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -12267,44 +9852,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/set-blocking": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
-      "license": "ISC"
-    },
-    "node_modules/set-function-length": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
-      "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
-      "license": "MIT",
-      "dependencies": {
-        "define-data-property": "^1.1.4",
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2",
-        "get-intrinsic": "^1.2.4",
-        "gopd": "^1.0.1",
-        "has-property-descriptors": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/set-function-name": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
-      "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
-      "license": "MIT",
-      "dependencies": {
-        "define-data-property": "^1.1.4",
-        "es-errors": "^1.3.0",
-        "functions-have-names": "^1.2.3",
-        "has-property-descriptors": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/setimmediate": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -12350,29 +9897,11 @@
         "node": ">=8"
       }
     },
-    "node_modules/shell-quote": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
-      "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/side-channel": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
-      "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
+    "node_modules/shell-quote": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
+      "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
       "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "es-errors": "^1.3.0",
-        "get-intrinsic": "^1.2.4",
-        "object-inspect": "^1.13.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -12430,47 +9959,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/slice-ansi": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
-      "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^3.2.0",
-        "astral-regex": "^1.0.0",
-        "is-fullwidth-code-point": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/slice-ansi/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/slice-ansi/node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "1.1.3"
-      }
-    },
-    "node_modules/slice-ansi/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
-      "license": "MIT"
-    },
     "node_modules/slugify": {
       "version": "1.6.6",
       "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
@@ -12481,12 +9969,12 @@
       }
     },
     "node_modules/source-map": {
-      "version": "0.7.4",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
-      "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
       "license": "BSD-3-Clause",
       "engines": {
-        "node": ">= 8"
+        "node": ">=0.10.0"
       }
     },
     "node_modules/source-map-js": {
@@ -12717,55 +10205,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/string.prototype.trim": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
-      "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "define-properties": "^1.2.1",
-        "es-abstract": "^1.23.0",
-        "es-object-atoms": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/string.prototype.trimend": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
-      "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "define-properties": "^1.2.1",
-        "es-object-atoms": "^1.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/string.prototype.trimstart": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
-      "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "define-properties": "^1.2.1",
-        "es-object-atoms": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/strip-ansi": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
@@ -12827,12 +10266,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/strnum": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
-      "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
-      "license": "MIT"
-    },
     "node_modules/structured-headers": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz",
@@ -12840,14 +10273,14 @@
       "license": "MIT"
     },
     "node_modules/sucrase": {
-      "version": "3.34.0",
-      "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
-      "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==",
+      "version": "3.35.0",
+      "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+      "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
       "license": "MIT",
       "dependencies": {
         "@jridgewell/gen-mapping": "^0.3.2",
         "commander": "^4.0.0",
-        "glob": "7.1.6",
+        "glob": "^10.3.10",
         "lines-and-columns": "^1.1.6",
         "mz": "^2.7.0",
         "pirates": "^4.0.1",
@@ -12858,7 +10291,16 @@
         "sucrase-node": "bin/sucrase-node"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
+    "node_modules/sucrase/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
       }
     },
     "node_modules/sucrase/node_modules/commander": {
@@ -12871,21 +10313,35 @@
       }
     },
     "node_modules/sucrase/node_modules/glob": {
-      "version": "7.1.6",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
-      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
-      "deprecated": "Glob versions prior to v9 are no longer supported",
+      "version": "10.4.5",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
       "license": "ISC",
       "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/sucrase/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
-        "node": "*"
+        "node": ">=16 || 14 >=14.17"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
@@ -13119,11 +10575,19 @@
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "license": "MIT"
     },
-    "node_modules/text-table": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
-      "license": "MIT"
+    "node_modules/test-exclude": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+      "license": "ISC",
+      "dependencies": {
+        "@istanbuljs/schema": "^0.1.2",
+        "glob": "^7.1.4",
+        "minimatch": "^3.0.4"
+      },
+      "engines": {
+        "node": ">=8"
+      }
     },
     "node_modules/thenify": {
       "version": "3.3.1",
@@ -13213,32 +10677,6 @@
       "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
       "license": "MIT"
     },
-    "node_modules/traverse": {
-      "version": "0.6.10",
-      "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.10.tgz",
-      "integrity": "sha512-hN4uFRxbK+PX56DxYiGHsTn2dME3TVr9vbNqlQGcGcPhJAn+tdP126iA+TArMpI4YSgnTkMWyoLl5bf81Hi5TA==",
-      "license": "MIT",
-      "dependencies": {
-        "gopd": "^1.0.1",
-        "typedarray.prototype.slice": "^1.0.3",
-        "which-typed-array": "^1.1.15"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/trim-right": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
-      "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/ts-interface-checker": {
       "version": "0.1.13",
       "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
@@ -13272,99 +10710,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/typed-array-buffer": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
-      "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "es-errors": "^1.3.0",
-        "is-typed-array": "^1.1.13"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/typed-array-byte-length": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
-      "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "for-each": "^0.3.3",
-        "gopd": "^1.0.1",
-        "has-proto": "^1.0.3",
-        "is-typed-array": "^1.1.13"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/typed-array-byte-offset": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
-      "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
-      "license": "MIT",
-      "dependencies": {
-        "available-typed-arrays": "^1.0.7",
-        "call-bind": "^1.0.7",
-        "for-each": "^0.3.3",
-        "gopd": "^1.0.1",
-        "has-proto": "^1.0.3",
-        "is-typed-array": "^1.1.13"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/typed-array-length": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
-      "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "for-each": "^0.3.3",
-        "gopd": "^1.0.1",
-        "has-proto": "^1.0.3",
-        "is-typed-array": "^1.1.13",
-        "possible-typed-array-names": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/typedarray.prototype.slice": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.3.tgz",
-      "integrity": "sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.7",
-        "define-properties": "^1.2.1",
-        "es-abstract": "^1.23.0",
-        "es-errors": "^1.3.0",
-        "typed-array-buffer": "^1.0.2",
-        "typed-array-byte-offset": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/typescript": {
       "version": "5.3.3",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
@@ -13405,19 +10750,13 @@
         "node": "*"
       }
     },
-    "node_modules/unbox-primitive": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
-      "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+    "node_modules/undici": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz",
+      "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==",
       "license": "MIT",
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "has-bigints": "^1.0.2",
-        "has-symbols": "^1.0.3",
-        "which-boxed-primitive": "^1.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+      "engines": {
+        "node": ">=18.17"
       }
     },
     "node_modules/undici-types": {
@@ -13550,12 +10889,6 @@
         "browserslist": ">= 4.21.0"
       }
     },
-    "node_modules/url-join": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz",
-      "integrity": "sha512-EGXjXJZhIHiQMK2pQukuFcL303nskqIRzWvPvV5O8miOfwoUb9G+a/Cld60kUyeaybEI94wvVClT10DtfeAExA==",
-      "license": "MIT"
-    },
     "node_modules/use-latest-callback": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.1.tgz",
@@ -13589,18 +10922,13 @@
         "uuid": "dist/bin/uuid"
       }
     },
-    "node_modules/valid-url": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
-      "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA=="
-    },
     "node_modules/validate-npm-package-name": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
-      "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz",
+      "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==",
       "license": "ISC",
-      "dependencies": {
-        "builtins": "^1.0.3"
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
       }
     },
     "node_modules/vary": {
@@ -13651,6 +10979,15 @@
         "defaults": "^1.0.3"
       }
     },
+    "node_modules/web-streams-polyfill": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
+      "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
     "node_modules/webidl-conversions": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
@@ -13711,51 +11048,10 @@
         "node": ">= 8"
       }
     },
-    "node_modules/which-boxed-primitive": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
-      "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
-      "license": "MIT",
-      "dependencies": {
-        "is-bigint": "^1.0.1",
-        "is-boolean-object": "^1.1.0",
-        "is-number-object": "^1.0.4",
-        "is-string": "^1.0.5",
-        "is-symbol": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/which-module": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
-      "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
-      "license": "ISC"
-    },
-    "node_modules/which-typed-array": {
-      "version": "1.1.15",
-      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
-      "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
-      "license": "MIT",
-      "dependencies": {
-        "available-typed-arrays": "^1.0.7",
-        "call-bind": "^1.0.7",
-        "for-each": "^0.3.3",
-        "gopd": "^1.0.1",
-        "has-tostringtag": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/wonka": {
-      "version": "4.0.15",
-      "resolved": "https://registry.npmjs.org/wonka/-/wonka-4.0.15.tgz",
-      "integrity": "sha512-U0IUQHKXXn6PFo9nqsHphVCE5m3IntqZNB9Jjn7EB1lrR7YTDY3YWgFvEvwniTzXSvOH/XMzAZaIfJF/LvHYXg==",
+      "version": "6.3.4",
+      "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz",
+      "integrity": "sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg==",
       "license": "MIT"
     },
     "node_modules/wrap-ansi": {
@@ -13932,18 +11228,6 @@
       "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
       "license": "ISC"
     },
-    "node_modules/yaml": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz",
-      "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==",
-      "license": "ISC",
-      "bin": {
-        "yaml": "bin.mjs"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
     "node_modules/yargs": {
       "version": "17.7.2",
       "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
@@ -13982,27 +11266,6 @@
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
-    },
-    "node_modules/zod": {
-      "version": "3.23.8",
-      "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
-      "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/colinhacks"
-      }
-    },
-    "node_modules/zod-validation-error": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-2.1.0.tgz",
-      "integrity": "sha512-VJh93e2wb4c3tWtGgTa0OF/dTt/zoPCPzXq4V11ZjxmEAFaPi/Zss1xIZdEB5RD8GD00U0/iVXgqkF77RV7pdQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=18.0.0"
-      },
-      "peerDependencies": {
-        "zod": "^3.18.0"
-      }
     }
   }
 }
diff --git a/package.json b/package.json
index a7b1842..1bd89c5 100644
--- a/package.json
+++ b/package.json
@@ -9,24 +9,24 @@
     "web": "expo start --web"
   },
   "dependencies": {
-    "@react-native-picker/picker": "2.7.5",
+    "@react-native-picker/picker": "^2.9.0",
     "@react-navigation/native": "^6.1.18",
     "@react-navigation/native-stack": "^6.11.0",
-    "expo": "~51.0.39",
-    "expo-status-bar": "~1.12.1",
+    "expo": "^52.0.8",
+    "expo-status-bar": "~2.0.0",
     "he": "^1.2.0",
     "i18n-js": "^4.5.0",
     "i18next": "^23.16.5",
-    "react": "18.2.0",
+    "react": "^18.3.1",
     "react-i18next": "^15.1.1",
-    "react-native": "0.74.5",
-    "react-native-safe-area-context": "4.10.5",
-    "react-native-screens": "3.31.1"
+    "react-native": "^0.76.2",
+    "react-native-safe-area-context": "^4.12.0",
+    "react-native-screens": "~4.1.0"
   },
   "devDependencies": {
     "@babel/core": "^7.20.0",
     "@types/he": "^1.2.3",
-    "@types/react": "~18.2.45",
+    "@types/react": "~18.3.12",
     "typescript": "~5.3.3"
   },
   "private": true
-- 
GitLab


From 3724aaf580b4577464d915ef35c2e9b48ee32525 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 19 Nov 2024 21:35:39 +0100
Subject: [PATCH 004/283] fix: correction du path

---
 screens/Home/Home.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Home/Home.tsx b/screens/Home/Home.tsx
index a4ac3f2..5e4d8d6 100644
--- a/screens/Home/Home.tsx
+++ b/screens/Home/Home.tsx
@@ -25,7 +25,7 @@ export default function Home({navigation}: Props) {
     }
     return (
         <View>
-            <Image source={require('../assets/FondTemplate.png')} style={styles.image}/>
+            <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
             <View style={styles.container}>
                 <View style={styles.titleContainer}>
                     <Text style={styles.titleText}>{"SKITSKOLA"}</Text>
-- 
GitLab


From 340e859ef04f95b2dd9a3728deff66465efedcd5 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 19 Nov 2024 22:05:19 +0100
Subject: [PATCH 005/283] feat: traduction screen Question

---
 screens/Question/QuestionHeader.tsx | 8 +++++---
 translation/languages/en.json       | 5 +++++
 translation/languages/fr.json       | 5 +++++
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/screens/Question/QuestionHeader.tsx b/screens/Question/QuestionHeader.tsx
index a06798d..6500cc6 100644
--- a/screens/Question/QuestionHeader.tsx
+++ b/screens/Question/QuestionHeader.tsx
@@ -1,20 +1,22 @@
 import { View, StyleSheet, Text } from "react-native";
 import { TextsStyles } from "../../styles/TextsStyles";
 import QuizModel from "../../model/QuizModel";
+import {useTranslation} from "react-i18next";
 
 interface Props {
     quiz?: QuizModel;
 }
 
 export default function QuestionHeader({quiz}: Props) {
+    const {t} = useTranslation();
     return (
             <View style={styles.container}>
                 <View style={styles.infoQuizContainer}>
-                    <Text style={TextsStyles.infoQuizText}>SCORE : {quiz ? quiz.score : 0}</Text>
-                    <Text style={TextsStyles.infoQuizText}>CATEGORY : {quiz ? quiz.category : "?"}</Text>
+                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.score")} : {quiz ? quiz.score : 0}</Text>
+                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.category")} : {quiz ? quiz.category : "?"}</Text>
                 </View>
                 <View style={styles.QuizNumContainer}>
-                    <Text style={TextsStyles.titleText}>QUESTION {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
+                    <Text style={TextsStyles.titleText}>{t("app.screens.question.question")} {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
                 </View>
                 <View style={styles.QuizQuestionContainer}>
                     <Text style={TextsStyles.subtitleText}>{quiz ? quiz.questions[quiz.nbActualQuestion - 1].question : "Loading..."}</Text>
diff --git a/translation/languages/en.json b/translation/languages/en.json
index eb76cb0..f9095aa 100644
--- a/translation/languages/en.json
+++ b/translation/languages/en.json
@@ -7,6 +7,11 @@
         "createQuiz": "Create a Quiz",
         "joinQuiz": "Join a Quiz",
         "codeQuiz": "Quiz Code"
+      },
+      "question": {
+        "score" : "SCORE",
+        "category" : "CATEGORIE",
+        "question" : "QUESTION"
       }
     }
   }
diff --git a/translation/languages/fr.json b/translation/languages/fr.json
index 8a93a2f..0a369d3 100644
--- a/translation/languages/fr.json
+++ b/translation/languages/fr.json
@@ -7,6 +7,11 @@
         "createQuiz": "Créer un Quizz",
         "joinQuiz": "Rejoindre un Quizz",
         "codeQuiz": "Code de la partie"
+      },
+      "question": {
+        "score" : "SCORE",
+        "category" : "CATEGORY",
+        "question" : "QUESTION"
       }
     }
   }
-- 
GitLab


From ae30001aad39f5c556bb296c8133b37a77ce135d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 19 Nov 2024 22:16:42 +0100
Subject: [PATCH 006/283] feat: traduction screen endQuiz

---
 screens/FinQuiz/FinQuiz.tsx   | 10 ++++++----
 translation/languages/en.json |  7 +++++++
 translation/languages/fr.json |  7 +++++++
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/screens/FinQuiz/FinQuiz.tsx b/screens/FinQuiz/FinQuiz.tsx
index 3320e82..aa5cfc6 100644
--- a/screens/FinQuiz/FinQuiz.tsx
+++ b/screens/FinQuiz/FinQuiz.tsx
@@ -2,6 +2,7 @@ import { View, StyleSheet, Image, Text } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { TextsStyles } from "../../styles/TextsStyles";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
+import {useTranslation} from "react-i18next";
 
 interface Props {
     navigation: any;
@@ -10,6 +11,7 @@ interface Props {
 
 export default function FinQuiz({ navigation, route }: Props) {
     const { score, quiz } = route.params;
+    const {t} = useTranslation();
     const handleButtonRePlayPressed = () => {
         quiz.nbActualQuestion = 1;
         quiz.score = 0;
@@ -31,11 +33,11 @@ export default function FinQuiz({ navigation, route }: Props) {
     return (
         <View style={styles.container}>
             <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
-            <Text style={TextsStyles.titleText}>Score : {score}</Text>
-            <Text style={TextsStyles.subtitleText}>{((score/quiz.nbQuestions)*100 > 50 ) ? "Congratulations, you won!" : "Too bad, you lost!"}</Text>
+            <Text style={TextsStyles.titleText}>{t("app.screens.endQuiz.score")} : {score}</Text>
+            <Text style={TextsStyles.subtitleText}>{((score/quiz.nbQuestions)*100 > 50 ) ? t("app.screens.endQuiz.lose") : t("app.screens.endQuiz.win")}</Text>
             <View style={styles.buttonContainer}>
-                <DefaultButton text={"Play again"} handleButtonPressed={handleButtonRePlayPressed} buttonStyle={ButtonsStyles.defaultButton}></DefaultButton>
-                <DefaultButton text={"Go to home"} handleButtonPressed={handleButtonHomePressed}></DefaultButton>
+                <DefaultButton text={t("app.screens.endQuiz.replay")} handleButtonPressed={handleButtonRePlayPressed} buttonStyle={ButtonsStyles.defaultButton}></DefaultButton>
+                <DefaultButton text={t("app.screens.endQuiz.goHome")} handleButtonPressed={handleButtonHomePressed}></DefaultButton>
             </View>
         </View>
     )
diff --git a/translation/languages/en.json b/translation/languages/en.json
index f9095aa..017e7a5 100644
--- a/translation/languages/en.json
+++ b/translation/languages/en.json
@@ -12,6 +12,13 @@
         "score" : "SCORE",
         "category" : "CATEGORIE",
         "question" : "QUESTION"
+      },
+      "endQuiz": {
+        "win": "Congratulations, you won !",
+        "lose":"Congratulations, you won !",
+        "replay": "Play again",
+        "goHome": "Go to home",
+        "score": "Score"
       }
     }
   }
diff --git a/translation/languages/fr.json b/translation/languages/fr.json
index 0a369d3..49b4ae4 100644
--- a/translation/languages/fr.json
+++ b/translation/languages/fr.json
@@ -12,6 +12,13 @@
         "score" : "SCORE",
         "category" : "CATEGORY",
         "question" : "QUESTION"
+      },
+      "endQuiz": {
+        "win": "Félicitations, vous avez gagné !",
+        "lose":"Dommage, tu as perdu !",
+        "replay": "Rejouer",
+        "goHome": "Retour à l'accueil",
+        "score": "Score"
       }
     }
   }
-- 
GitLab


From f71d074a814dc8b8db1cead4d5c8b40e0db98406 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 19 Nov 2024 22:29:05 +0100
Subject: [PATCH 007/283] feat: traduction screen createQuiz

---
 screens/CreationQuiz/CreationQuizBody.tsx | 10 ++++++----
 translation/languages/en.json             |  6 ++++++
 translation/languages/fr.json             |  6 ++++++
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/screens/CreationQuiz/CreationQuizBody.tsx b/screens/CreationQuiz/CreationQuizBody.tsx
index 82c0047..92d01c0 100644
--- a/screens/CreationQuiz/CreationQuizBody.tsx
+++ b/screens/CreationQuiz/CreationQuizBody.tsx
@@ -2,6 +2,7 @@ import ComboBox from "../../components/comboBox/ComboBox";
 import DefaultButton from "../../components/DefaultButton";
 import {StyleSheet, View, Text} from "react-native";
 import {useState} from "react";
+import {useTranslation} from "react-i18next";
 
 const optionsDifficulty = [ 'easy', 'medium', 'hard'];
 const optionsQuestions = ['1', '50'];
@@ -30,6 +31,7 @@ export default function CreationQuizBody({navigation}:Props) {
     const [difficulty, setDifficulty] = useState('easy');
     const [nbQuestions, setNbQuestions] = useState('1');
     const [theme, setTheme] = useState('General Knowledge');
+    const {t} = useTranslation();
 
     const handleAddQuizPressed = () => {
         navigation.reset({
@@ -46,12 +48,12 @@ export default function CreationQuizBody({navigation}:Props) {
     return (
         <View style={styles.container}>
             <View style={styles.comboBoxContainer}>
-                <ComboBox title={"Difficulty"} options={optionsDifficulty} selectOption={setDifficulty} type={0}/>
-                <ComboBox title={"Nb. of questions"} options={optionsQuestions} selectOption={setNbQuestions} type={1}/>
-                <ComboBox title={"Theme"} options={optionsTheme} selectOption={setTheme} type={0}/>
+                <ComboBox title={t("app.screens.creationQuiz.difficulty")} options={optionsDifficulty} selectOption={setDifficulty} type={0}/>
+                <ComboBox title={t("app.screens.creationQuiz.nbQuestions")} options={optionsQuestions} selectOption={setNbQuestions} type={1}/>
+                <ComboBox title={t("app.screens.creationQuiz.theme")} options={optionsTheme} selectOption={setTheme} type={0}/>
             </View>
             <View style={styles.buttonContainer}>
-                <DefaultButton text={"Add Quiz "} handleButtonPressed={handleAddQuizPressed} buttonStyle={styles.buttonStyle}/>
+                <DefaultButton text={t("app.screens.creationQuiz.addQuiz")} handleButtonPressed={handleAddQuizPressed} buttonStyle={styles.buttonStyle}/>
             </View>
         </View>
 
diff --git a/translation/languages/en.json b/translation/languages/en.json
index 017e7a5..d28a947 100644
--- a/translation/languages/en.json
+++ b/translation/languages/en.json
@@ -19,6 +19,12 @@
         "replay": "Play again",
         "goHome": "Go to home",
         "score": "Score"
+      },
+      "creationQuiz": {
+        "difficulty": "Difficulty",
+        "nbQuestions": "Nb. of questions",
+        "theme": "Theme",
+        "addQuiz": "Add a Quiz"
       }
     }
   }
diff --git a/translation/languages/fr.json b/translation/languages/fr.json
index 49b4ae4..ec21e0f 100644
--- a/translation/languages/fr.json
+++ b/translation/languages/fr.json
@@ -19,6 +19,12 @@
         "replay": "Rejouer",
         "goHome": "Retour à l'accueil",
         "score": "Score"
+      },
+      "creationQuiz": {
+        "difficulty": "Difficulté",
+        "nbQuestions": "Nb. de questions",
+        "theme": "Thème",
+        "addQuiz": "Ajouter un Quiz"
       }
     }
   }
-- 
GitLab


From e0e59c0e95871bd140af7d49d3f66081941bdfae Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 19 Nov 2024 22:29:52 +0100
Subject: [PATCH 008/283] =?UTF-8?q?fix:=20erreur=20dans=20la=20traduction?=
 =?UTF-8?q?=20cat=C3=A9gory=20de=20l'=C3=A9cran=20question?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 translation/languages/en.json | 2 +-
 translation/languages/fr.json | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/translation/languages/en.json b/translation/languages/en.json
index d28a947..078e5e2 100644
--- a/translation/languages/en.json
+++ b/translation/languages/en.json
@@ -10,7 +10,7 @@
       },
       "question": {
         "score" : "SCORE",
-        "category" : "CATEGORIE",
+        "category" : "CATEGORY",
         "question" : "QUESTION"
       },
       "endQuiz": {
diff --git a/translation/languages/fr.json b/translation/languages/fr.json
index ec21e0f..0d8f298 100644
--- a/translation/languages/fr.json
+++ b/translation/languages/fr.json
@@ -10,7 +10,7 @@
       },
       "question": {
         "score" : "SCORE",
-        "category" : "CATEGORY",
+        "category" : "CATEGORIE",
         "question" : "QUESTION"
       },
       "endQuiz": {
-- 
GitLab


From 5a642df9197517c2b2d216c1706be2d9951c8f10 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 20 Nov 2024 10:44:50 +0100
Subject: [PATCH 009/283] fix: rename des screens

---
 App.tsx                                              |  1 -
 routes/StackNavigator.tsx                            | 12 ++++++------
 screens/CreationQuiz/CreationQuiz.tsx                |  9 ---------
 screens/{FinQuiz/FinQuiz.tsx => EndQuiz/EndQuiz.tsx} |  4 ++--
 screens/GenerateQuiz/GenerateQuiz.tsx                |  9 +++++++++
 .../GenerateQuizBody.tsx}                            |  5 +++--
 .../GenerateQuizHeader.tsx}                          |  0
 .../Question.tsx => PlayingQuiz/PlayingQuiz.tsx}     | 12 ++++++------
 .../PlayingQuizBody.tsx}                             |  2 +-
 .../PlayingQuizHeader.tsx}                           |  2 +-
 10 files changed, 28 insertions(+), 28 deletions(-)
 delete mode 100644 screens/CreationQuiz/CreationQuiz.tsx
 rename screens/{FinQuiz/FinQuiz.tsx => EndQuiz/EndQuiz.tsx} (95%)
 create mode 100644 screens/GenerateQuiz/GenerateQuiz.tsx
 rename screens/{CreationQuiz/CreationQuizBody.tsx => GenerateQuiz/GenerateQuizBody.tsx} (95%)
 rename screens/{CreationQuiz/CreationQuizHeader.tsx => GenerateQuiz/GenerateQuizHeader.tsx} (100%)
 rename screens/{Question/Question.tsx => PlayingQuiz/PlayingQuiz.tsx} (87%)
 rename screens/{Question/QuestionBody.tsx => PlayingQuiz/PlayingQuizBody.tsx} (96%)
 rename screens/{Question/QuestionHeader.tsx => PlayingQuiz/PlayingQuizHeader.tsx} (96%)

diff --git a/App.tsx b/App.tsx
index 2633a5c..96cb4a2 100644
--- a/App.tsx
+++ b/App.tsx
@@ -3,7 +3,6 @@ import {I18nextProvider, useTranslation} from "react-i18next";
 import i18n from "./translation/i18n"; // Importez l'instance déjà initialisée
 import { SafeAreaProvider } from "react-native-safe-area-context";
 import StackNavigator from "./routes/StackNavigator";
-import Question from "./screens/Question/Question";
 export default function App() {
     LogBox.ignoreAllLogs(true);
 
diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 28b5292..eeae3a4 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -1,9 +1,9 @@
 import {createNativeStackNavigator} from "@react-navigation/native-stack";
 import {NavigationContainer} from "@react-navigation/native";
 import Home from "../screens/Home/Home";
-import Question from "../screens/Question/Question";
-import CreationQuiz from "../screens/CreationQuiz/CreationQuiz";
-import FinQuiz from "../screens/FinQuiz/FinQuiz";
+import GenerateQuiz from "../screens/GenerateQuiz/GenerateQuiz";
+import EndQuiz from "../screens/EndQuiz/EndQuiz";
+import PlayingQuiz from "../screens/PlayingQuiz/PlayingQuiz";
 
 const Stack = createNativeStackNavigator();
 
@@ -12,9 +12,9 @@ export default function StackNavigator() {
         <NavigationContainer>
             <Stack.Navigator initialRouteName="Home">
                 <Stack.Screen name="Home" component={Home} options={{ headerShown: false }}/>
-                <Stack.Screen name="CreateQuiz" component={CreationQuiz} options={{ headerShown: false }}/>
-                <Stack.Screen name="Question" component={Question} options={{ headerShown: false }}/>
-                <Stack.Screen name="FinQuiz" component={FinQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="CreateQuiz" component={GenerateQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="PlayingQuiz" component={PlayingQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="EndQuiz" component={EndQuiz} options={{ headerShown: false }}/>
             </Stack.Navigator>
         </NavigationContainer>
     );
diff --git a/screens/CreationQuiz/CreationQuiz.tsx b/screens/CreationQuiz/CreationQuiz.tsx
deleted file mode 100644
index 46c1061..0000000
--- a/screens/CreationQuiz/CreationQuiz.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import TemplateScreen from "../../templates/TemplateScreen";
-import CreationQuizBody from "./CreationQuizBody";
-
-export default function CreationQuiz({navigation}: any) {
-    return (
-        <TemplateScreen childrenBot={<CreationQuizBody navigation={navigation}></CreationQuizBody>}></TemplateScreen>
-    )
-}
-
diff --git a/screens/FinQuiz/FinQuiz.tsx b/screens/EndQuiz/EndQuiz.tsx
similarity index 95%
rename from screens/FinQuiz/FinQuiz.tsx
rename to screens/EndQuiz/EndQuiz.tsx
index aa5cfc6..ea72db6 100644
--- a/screens/FinQuiz/FinQuiz.tsx
+++ b/screens/EndQuiz/EndQuiz.tsx
@@ -9,7 +9,7 @@ interface Props {
     route: any;
 }
 
-export default function FinQuiz({ navigation, route }: Props) {
+export default function EndQuiz({ navigation, route }: Props) {
     const { score, quiz } = route.params;
     const {t} = useTranslation();
     const handleButtonRePlayPressed = () => {
@@ -19,7 +19,7 @@ export default function FinQuiz({ navigation, route }: Props) {
             index: 0,
             routes: [
                 {
-                    name: "Question",
+                    name: "PlayingQuiz",
                     params: {quiz: quiz},
                 },
             ]
diff --git a/screens/GenerateQuiz/GenerateQuiz.tsx b/screens/GenerateQuiz/GenerateQuiz.tsx
new file mode 100644
index 0000000..014f469
--- /dev/null
+++ b/screens/GenerateQuiz/GenerateQuiz.tsx
@@ -0,0 +1,9 @@
+import TemplateScreen from "../../templates/TemplateScreen";
+import GenerateQuizBody from "./GenerateQuizBody";
+
+export default function GenerateQuiz({navigation}: any) {
+    return (
+        <TemplateScreen childrenBot={<GenerateQuizBody navigation={navigation}></GenerateQuizBody>}></TemplateScreen>
+    )
+}
+
diff --git a/screens/CreationQuiz/CreationQuizBody.tsx b/screens/GenerateQuiz/GenerateQuizBody.tsx
similarity index 95%
rename from screens/CreationQuiz/CreationQuizBody.tsx
rename to screens/GenerateQuiz/GenerateQuizBody.tsx
index 92d01c0..9330c12 100644
--- a/screens/CreationQuiz/CreationQuizBody.tsx
+++ b/screens/GenerateQuiz/GenerateQuizBody.tsx
@@ -25,7 +25,7 @@ interface Props {
     navigation: any;
 }
 
-export default function CreationQuizBody({navigation}:Props) {
+export default function GenerateQuizBody({navigation}:Props) {
 
     const [isModalVisible, setIsModalVisible] = useState(false);
     const [difficulty, setDifficulty] = useState('easy');
@@ -34,11 +34,12 @@ export default function CreationQuizBody({navigation}:Props) {
     const {t} = useTranslation();
 
     const handleAddQuizPressed = () => {
+        console.log(difficulty);
         navigation.reset({
             index: 0,
             routes: [
                 {
-                    name: "Question",
+                    name: "PlayingQuiz",
                     params: {nbQuestionParam: nbQuestions, difficultyParam: difficulty, themeParam: theme},
                 },
             ]
diff --git a/screens/CreationQuiz/CreationQuizHeader.tsx b/screens/GenerateQuiz/GenerateQuizHeader.tsx
similarity index 100%
rename from screens/CreationQuiz/CreationQuizHeader.tsx
rename to screens/GenerateQuiz/GenerateQuizHeader.tsx
diff --git a/screens/Question/Question.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
similarity index 87%
rename from screens/Question/Question.tsx
rename to screens/PlayingQuiz/PlayingQuiz.tsx
index 1765397..91dc961 100644
--- a/screens/Question/Question.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -1,6 +1,6 @@
 import TemplateScreen from "../../templates/TemplateScreen";
-import QuestionBody from "./QuestionBody";
-import QuestionHeader from "./QuestionHeader";
+import PlayingQuizBody from "./PlayingQuizBody";
+import PlayingQuizHeader from "./PlayingQuizHeader";
 import {useEffect, useState} from "react";
 import {transformToQuizModel} from "../../helper/QuizHelper";
 import QuizModel from "../../model/QuizModel";
@@ -26,7 +26,7 @@ interface Props {
     navigation: any;
 }
 
-export default function Question({route, navigation}:Props) {
+export default function PlayingQuiz({route, navigation}:Props) {
     const getIdOfCategory = (category: string) => {
         for (let i = 0; i < optionsTheme.length; i++) {
             if (optionsTheme[i] === category) {
@@ -102,15 +102,15 @@ export default function Question({route, navigation}:Props) {
                 setIsAlreadyPlayed(false);
                 return { ...prevQuiz, nbActualQuestion: prevQuiz.nbActualQuestion + 1 };
             }
-            navigation.navigate("FinQuiz", { score: prevQuiz?.score, quiz: quiz });
+            navigation.navigate("EndQuiz", { score: prevQuiz?.score, quiz: quiz });
             return prevQuiz; // Fin du quiz si toutes les questions ont été posées
         });
     };
 
     return (
         <TemplateScreen
-            childrenTop={<QuestionHeader quiz={quiz} ></QuestionHeader>}
-            childrenBot={<QuestionBody quiz={quiz} onAnswerSelected={handleAnswer} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed}></QuestionBody>}
+            childrenTop={<PlayingQuizHeader quiz={quiz} ></PlayingQuizHeader>}
+            childrenBot={<PlayingQuizBody quiz={quiz} onAnswerSelected={handleAnswer} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed}></PlayingQuizBody>}
         />
     );
 }
\ No newline at end of file
diff --git a/screens/Question/QuestionBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
similarity index 96%
rename from screens/Question/QuestionBody.tsx
rename to screens/PlayingQuiz/PlayingQuizBody.tsx
index 26c3c2f..4ea806f 100644
--- a/screens/Question/QuestionBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -13,7 +13,7 @@ interface Props {
     setIsAlreadyPlayed: (isAlreadyPlayed: boolean) => void;
 }
 
-export default function QuestionBody({ quiz, onAnswerSelected, isAlreadyPlayed, setIsAlreadyPlayed }: Props) {
+export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlayed, setIsAlreadyPlayed }: Props) {
     const [selectedAnswerIndex, setSelectedAnswerIndex] = useState<number | null>(null);
     const [isCorrect, setIsCorrect] = useState<boolean | null>(null);
 
diff --git a/screens/Question/QuestionHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
similarity index 96%
rename from screens/Question/QuestionHeader.tsx
rename to screens/PlayingQuiz/PlayingQuizHeader.tsx
index 6500cc6..6151f62 100644
--- a/screens/Question/QuestionHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -7,7 +7,7 @@ interface Props {
     quiz?: QuizModel;
 }
 
-export default function QuestionHeader({quiz}: Props) {
+export default function PlayingQuizHeader({quiz}: Props) {
     const {t} = useTranslation();
     return (
             <View style={styles.container}>
-- 
GitLab


From 4f9a39809333fbf8c94c1cb7bbc882be6fc16f7f Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 20 Nov 2024 13:37:36 +0100
Subject: [PATCH 010/283] feat: ajout du template Mono

---
 assets/Name.png            | Bin 0 -> 10053 bytes
 templates/TemplateMono.tsx |  44 +++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)
 create mode 100644 assets/Name.png
 create mode 100644 templates/TemplateMono.tsx

diff --git a/assets/Name.png b/assets/Name.png
new file mode 100644
index 0000000000000000000000000000000000000000..48c1d284cce9aa4a66f1d8cfd47f84b5cfa72d2c
GIT binary patch
literal 10053
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

literal 0
HcmV?d00001

diff --git a/templates/TemplateMono.tsx b/templates/TemplateMono.tsx
new file mode 100644
index 0000000..0452982
--- /dev/null
+++ b/templates/TemplateMono.tsx
@@ -0,0 +1,44 @@
+import { View, Image, StyleSheet } from "react-native";
+
+interface Props{
+    children?: React.ReactNode
+}
+
+export default function TemplateMono({children} : Props) {
+    return(
+        <View style={styles.containerGlobal}>
+            <View style={styles.containerHeader}>
+                <Image source={require('../assets/Name.png')} style={styles.image}/>
+            </View>
+            <View style={styles.containerBody}>
+                {children}
+            </View>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+    },
+    containerHeader: {
+        height: '12%',
+        justifyContent: 'flex-end',
+        alignItems: 'center',
+        shadowColor: '#171717',
+        shadowOffset: { width: 0, height: 4 },
+        shadowOpacity: 0.2,
+        shadowRadius: 3,
+        elevation: 5,
+        backgroundColor: '#fff'
+    },
+    containerBody: {
+        height: '83%',
+    },
+    image: {
+        height: '60%',
+        width: '60%'
+    }
+});
\ No newline at end of file
-- 
GitLab


From 85c53dde12acc792452fe8f7d8a71b921db51d80 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 20 Nov 2024 13:55:42 +0100
Subject: [PATCH 011/283] feat: ajout template duo

---
 assets/FondDuo.png        | Bin 0 -> 161291 bytes
 templates/TemplateDuo.tsx |  45 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)
 create mode 100644 assets/FondDuo.png
 create mode 100644 templates/TemplateDuo.tsx

diff --git a/assets/FondDuo.png b/assets/FondDuo.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2abf1e8d90e9daf13cc5217a54b9ae861103cc2
GIT binary patch
literal 161291
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%0A&5GPFW#`1N%J9}m8ljWF9
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

literal 0
HcmV?d00001

diff --git a/templates/TemplateDuo.tsx b/templates/TemplateDuo.tsx
new file mode 100644
index 0000000..786c5ec
--- /dev/null
+++ b/templates/TemplateDuo.tsx
@@ -0,0 +1,45 @@
+import { ImageBackground, Text, View, StyleSheet } from "react-native";
+
+interface Props{
+    childrenHeader?: React.ReactNode
+    childrenBody?: React.ReactNode
+}
+
+export default function TemplateDuo({childrenHeader, childrenBody}: Props) {
+    return (
+        <View style={styles.container}>
+            <ImageBackground source={require('../assets/FondDuo.png')} style={styles.image}>
+                <View style={styles.containerHeader}>
+                    {childrenHeader}
+                </View>
+                <View style={styles.containerBody}>
+                    {childrenBody}
+                </View>
+            </ImageBackground>
+        </View>
+    );
+}
+
+
+const styles = StyleSheet.create({
+    container: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+    },
+    containerHeader: {
+        width: '100%',
+        height: '30%',
+    },
+    containerBody: {
+        width: '100%',
+        height: '70%',
+        backgroundColor: '#FFFFFF',
+        borderTopLeftRadius: 46,
+        borderTopRightRadius: 46
+    },
+    image: {
+        height: '100%',
+        width: '100%',
+    }
+});
\ No newline at end of file
-- 
GitLab


From 362122edee20d1fbd8bc5f5e0b882ef9869db30d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 20 Nov 2024 15:28:50 +0100
Subject: [PATCH 012/283] feat: creation du service

---
 helper/QuizHelper.ts                      | 93 +++++++++++++----------
 models/EDifficulty.ts                     |  5 ++
 {model => models}/QuestionModel.ts        |  1 +
 {model => models}/QuizModel.ts            |  3 +-
 screens/GenerateQuiz/GenerateQuizBody.tsx | 14 ++--
 screens/PlayingQuiz/PlayingQuiz.tsx       | 58 ++------------
 screens/PlayingQuiz/PlayingQuizBody.tsx   |  6 +-
 screens/PlayingQuiz/PlayingQuizHeader.tsx |  6 +-
 services/QuizService.ts                   | 43 +++++++++++
 9 files changed, 127 insertions(+), 102 deletions(-)
 create mode 100644 models/EDifficulty.ts
 rename {model => models}/QuestionModel.ts (82%)
 rename {model => models}/QuizModel.ts (86%)
 create mode 100644 services/QuizService.ts

diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index 090314d..132814e 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -1,50 +1,65 @@
-// src/helpers/QuizHelper.ts
-
-import QuizModel from "../model/QuizModel";
-import QuestionModel from "../model/QuestionModel";
-import he from "he";
-
-interface ApiQuestion {
-    category: string;
-    correct_answer: string;
-    difficulty: string;
-    incorrect_answers: string[];
-    question: string;
-    type: string;
-}
 
-interface ApiResponse {
-    response_code: number;
-    results: ApiQuestion[];
-}
+// Fonction utilitaire pour mélanger les réponses
+import QuizModel from "../models/QuizModel";
+import QuestionModel from "../models/QuestionModel";
+
+const optionsTheme = [
+    "General Knowledge",
+    "Entertainment: Books",
+    "Entertainment: Film",
+    "Entertainment: Music",
+    "Entertainment: Musicals & Theatres",
+    "Entertainment: Television",
+    "Entertainment: Video Games",
+    "Entertainment: Board Games",
+    "Science & Nature",
+    "Science: Computers",
+    "Science: Mathematics",
+    "Mythology",
+    "Sports",
+    "Geography"]
+
+const shuffleAnswers = (answers: string[]): string[] => {
+    for (let i = answers.length - 1; i > 0; i--) {
+        const j = Math.floor(Math.random() * (i + 1));
+        [answers[i], answers[j]] = [answers[j], answers[i]];
+    }
+    return answers;
+};
+
+export const transformToQuizModel = (data: any): QuizModel => {
+    // Transformation des questions
+    // console.log(JSON.stringify(data, null, 2));
 
-// Fonction pour transformer les données API en QuizModel
-export const transformToQuizModel = (data: ApiResponse): QuizModel => {
-    const questions: QuestionModel[] = data.results.map((item) => {
+    const questions: QuestionModel[] = data.questions.map((item: any) => {
+        const answers = shuffleAnswers(item.answers.map((answer: any) => answer.text));
         return {
-            question: he.decode(item.question),
-            answer: shuffleAnswers([...item.incorrect_answers.map((ans) => he.decode(ans)), he.decode(item.correct_answer)]),
-            correctAnswer: item.correct_answer,
-            multiple: item.type === "multiple",
+            question: item.text,
+            answer: answers, // Réponses mélangées
+            correctAnswer: item.answers[0].text, // Hypothèse : première réponse correcte (ajuste si nécessaire)
+            multiple: item.type === "multiple", // Détermine si c'est une question multiple
+            nbOfTheQuestion: item.order, // Mapping de order vers nbOfTheQuestion
         };
     });
 
-    return {
-        id: `quiz-${Date.now()}`, // Génère un ID unique pour chaque quiz
-        name: `Quiz - ${data.results[0]?.category || "General Knowledge"}`,
-        category: he.decode(data.results[0]?.category) || "General Knowledge",
+    // Création de l'objet QuizModel
+    const quiz: QuizModel = {
+        code: data.codeQuiz, // Mapping de codeQuiz vers code
+        category: data.theme.name, // Extraction du nom de la catégorie
         questions: questions,
-        nbQuestions: questions.length,
-        nbActualQuestion: 1,
-        score: 0,
+        nbQuestions: questions[questions.length-1].nbOfTheQuestion, // Nombre total de questions
+        nbActualQuestion: data.questionIndex, // Mapping de questionIndex vers nbActualQuestion
+        score: data.score, // Mapping direct
     };
+
+    return quiz;
 };
 
-// Fonction utilitaire pour mélanger les réponses
-const shuffleAnswers = (answers: string[]): string[] => {
-    for (let i = answers.length - 1; i > 0; i--) {
-        const j = Math.floor(Math.random() * (i + 1));
-        [answers[i], answers[j]] = [answers[j], answers[i]];
+export const getIdOfCategory = (category: string) => {
+    for (let i = 0; i < optionsTheme.length; i++) {
+        if (optionsTheme[i] === category) {
+            return i;
+        }
     }
-    return answers;
-};
+    return 0;
+}
diff --git a/models/EDifficulty.ts b/models/EDifficulty.ts
new file mode 100644
index 0000000..640dee4
--- /dev/null
+++ b/models/EDifficulty.ts
@@ -0,0 +1,5 @@
+export enum EDifficulty {
+    Easy = "easy",
+    Medium = "medium",
+    Hard = "hard",
+}
\ No newline at end of file
diff --git a/model/QuestionModel.ts b/models/QuestionModel.ts
similarity index 82%
rename from model/QuestionModel.ts
rename to models/QuestionModel.ts
index 48893ef..fa3cc19 100644
--- a/model/QuestionModel.ts
+++ b/models/QuestionModel.ts
@@ -3,4 +3,5 @@ export default interface QuestionModel {
     answer: string[];
     correctAnswer: string;
     multiple: boolean;
+    nbOfTheQuestion: number;
 }
\ No newline at end of file
diff --git a/model/QuizModel.ts b/models/QuizModel.ts
similarity index 86%
rename from model/QuizModel.ts
rename to models/QuizModel.ts
index fd2a720..6e1cbb9 100644
--- a/model/QuizModel.ts
+++ b/models/QuizModel.ts
@@ -1,8 +1,7 @@
 import QuestionModel from "./QuestionModel";
 
 export default interface QuizModel {
-    id: string;
-    name: string;
+    code: string;
     category: string;
     questions: QuestionModel[];
     nbQuestions: number;
diff --git a/screens/GenerateQuiz/GenerateQuizBody.tsx b/screens/GenerateQuiz/GenerateQuizBody.tsx
index 9330c12..d38e238 100644
--- a/screens/GenerateQuiz/GenerateQuizBody.tsx
+++ b/screens/GenerateQuiz/GenerateQuizBody.tsx
@@ -1,8 +1,11 @@
 import ComboBox from "../../components/comboBox/ComboBox";
 import DefaultButton from "../../components/DefaultButton";
-import {StyleSheet, View, Text} from "react-native";
+import {StyleSheet, View} from "react-native";
 import {useState} from "react";
 import {useTranslation} from "react-i18next";
+import {useQuizService} from "../../services/QuizService";
+import {EDifficulty} from "../../models/EDifficulty";
+import {getIdOfCategory} from "../../helper/QuizHelper";
 
 const optionsDifficulty = [ 'easy', 'medium', 'hard'];
 const optionsQuestions = ['1', '50'];
@@ -30,17 +33,18 @@ export default function GenerateQuizBody({navigation}:Props) {
     const [isModalVisible, setIsModalVisible] = useState(false);
     const [difficulty, setDifficulty] = useState('easy');
     const [nbQuestions, setNbQuestions] = useState('1');
-    const [theme, setTheme] = useState('General Knowledge');
+    const [theme, setTheme] = useState<string>('General Knowledge');
     const {t} = useTranslation();
+    const {createQuiz} = useQuizService();
 
-    const handleAddQuizPressed = () => {
-        console.log(difficulty);
+    const handleAddQuizPressed = async () => {
+        const quizGenerated = await createQuiz(parseInt(nbQuestions), getIdOfCategory(theme), difficulty);
         navigation.reset({
             index: 0,
             routes: [
                 {
                     name: "PlayingQuiz",
-                    params: {nbQuestionParam: nbQuestions, difficultyParam: difficulty, themeParam: theme},
+                    params: {quizGenerated: quizGenerated},
                 },
             ]
         });
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 91dc961..e7c3266 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -3,7 +3,7 @@ import PlayingQuizBody from "./PlayingQuizBody";
 import PlayingQuizHeader from "./PlayingQuizHeader";
 import {useEffect, useState} from "react";
 import {transformToQuizModel} from "../../helper/QuizHelper";
-import QuizModel from "../../model/QuizModel";
+import QuizModel from "../../models/QuizModel";
 
 const optionsTheme = [
     "General Knowledge",
@@ -27,59 +27,15 @@ interface Props {
 }
 
 export default function PlayingQuiz({route, navigation}:Props) {
-    const getIdOfCategory = (category: string) => {
-        for (let i = 0; i < optionsTheme.length; i++) {
-            if (optionsTheme[i] === category) {
-                return i+9;
-            }
-        }
-    }
-
+    const {quizGenerated} = route.params;
     const [isAlreadyPlayed, setIsAlreadyPlayed] = useState(false);
-    const [quiz, setQuiz] = useState<QuizModel>();
-    const nbQuestions = "10";
-    const difficulty = "easy";
-    const theme = "General Knowledge";
-
-    const {
-        nbQuestionParam = "10",
-        difficultyParam = "easy",
-        themeParam = "General Knowledge",
-        quiz: quizFromParams, // Quiz passé via la navigation
-    } = route.params || {};
-    const nbQuestionsToDisplay = nbQuestionParam ? nbQuestionParam : nbQuestions;
-    const difficultyToDisplay = difficultyParam ? difficultyParam : difficulty;
-    const themeToDisplay = themeParam ? getIdOfCategory(themeParam) : getIdOfCategory(theme);
-
-
-
-
-    const fetchQuestion = async () => {
-        try {
-            const response = await fetch(`https://opentdb.com/api.php?amount=${nbQuestionsToDisplay}&difficulty=${difficultyToDisplay}&category=${themeToDisplay}`);
-            const data = await response.json();
-            const quiz = transformToQuizModel(data);
-            setQuiz(quiz);
-        } catch (error) {
-            console.error(error);
-        }
-    };
-
-    useEffect(() => {
-        if (quizFromParams) {
-            setTimeout(() => {
-                setQuiz(quizFromParams);
-            }, 0);
-        } else {
-            fetchQuestion();
-        }
-    }, [quizFromParams]);
+    const [quiz, setQuiz] = useState<QuizModel>(quizGenerated);
 
 
     const handleAnswer = async (selectedAnswerIndex: number) => {
         if (!quiz) return;
 
-        const currentQuestion = quiz.questions[quiz.nbActualQuestion-1];
+        const currentQuestion = quiz.questions[quiz.nbActualQuestion];
         const correctAnswer = currentQuestion.correctAnswer;
         const selectedAnswer = currentQuestion.answer[selectedAnswerIndex];
 
@@ -99,9 +55,11 @@ export default function PlayingQuiz({route, navigation}:Props) {
         // Passer à la question suivante
         setQuiz((prevQuiz) => {
             if (prevQuiz && prevQuiz.nbActualQuestion < prevQuiz.nbQuestions) {
+                console.log("new question")
                 setIsAlreadyPlayed(false);
                 return { ...prevQuiz, nbActualQuestion: prevQuiz.nbActualQuestion + 1 };
             }
+            console.log("fin question")
             navigation.navigate("EndQuiz", { score: prevQuiz?.score, quiz: quiz });
             return prevQuiz; // Fin du quiz si toutes les questions ont été posées
         });
@@ -109,8 +67,8 @@ export default function PlayingQuiz({route, navigation}:Props) {
 
     return (
         <TemplateScreen
-            childrenTop={<PlayingQuizHeader quiz={quiz} ></PlayingQuizHeader>}
-            childrenBot={<PlayingQuizBody quiz={quiz} onAnswerSelected={handleAnswer} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed}></PlayingQuizBody>}
+            childrenTop={<PlayingQuizHeader quiz={quizGenerated} ></PlayingQuizHeader>}
+            childrenBot={<PlayingQuizBody quiz={quizGenerated} onAnswerSelected={handleAnswer} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed}></PlayingQuizBody>}
         />
     );
 }
\ No newline at end of file
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 4ea806f..8926d7d 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -2,12 +2,12 @@ import { View, StyleSheet } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
 import { TextsStyles } from "../../styles/TextsStyles";
-import QuizModel from "../../model/QuizModel";
+import QuizModel from "../../models/QuizModel";
 import { useState, useEffect } from "react";
 import { setEnabled } from "react-native/Libraries/Performance/Systrace";
 
 interface Props {
-    quiz?: QuizModel;
+    quiz: QuizModel;
     onAnswerSelected: (index: number) => void;
     isAlreadyPlayed: boolean;
     setIsAlreadyPlayed: (isAlreadyPlayed: boolean) => void;
@@ -26,7 +26,7 @@ export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlaye
 
     if (!quiz) return null;
 
-    const currentQuestion = quiz.questions[quiz.nbActualQuestion - 1];
+    const currentQuestion = quiz.questions[quiz.nbActualQuestion];
 
     const handleAnswerPress = (index: number) => {
         if (!isAlreadyPlayed) {
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 6151f62..bfe216a 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -1,10 +1,10 @@
 import { View, StyleSheet, Text } from "react-native";
 import { TextsStyles } from "../../styles/TextsStyles";
-import QuizModel from "../../model/QuizModel";
+import QuizModel from "../../models/QuizModel";
 import {useTranslation} from "react-i18next";
 
 interface Props {
-    quiz?: QuizModel;
+    quiz: QuizModel;
 }
 
 export default function PlayingQuizHeader({quiz}: Props) {
@@ -19,7 +19,7 @@ export default function PlayingQuizHeader({quiz}: Props) {
                     <Text style={TextsStyles.titleText}>{t("app.screens.question.question")} {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
                 </View>
                 <View style={styles.QuizQuestionContainer}>
-                    <Text style={TextsStyles.subtitleText}>{quiz ? quiz.questions[quiz.nbActualQuestion - 1].question : "Loading..."}</Text>
+                    <Text style={TextsStyles.subtitleText}>{quiz ? quiz.questions[quiz.nbActualQuestion].question : "Loading..."}</Text>
                 </View>
             </View>
     );
diff --git a/services/QuizService.ts b/services/QuizService.ts
new file mode 100644
index 0000000..d153099
--- /dev/null
+++ b/services/QuizService.ts
@@ -0,0 +1,43 @@
+import {EDifficulty} from "../models/EDifficulty";
+import {transformToQuizModel} from "../helper/QuizHelper";
+
+export const useQuizService =  () => {
+    const createQuiz = async (amount: number, category: number, difficulty: string) => {
+        const url = "http://klebert-host.com:33036/quiz/create"; // Remplace par l'URL de ton endpoint API
+
+        // Création du corps de la requête avec les variables passées
+        const requestBody = {
+            amount,
+            category,
+            difficulty: difficulty.toLowerCase(), // Si EDifficulty est en uppercase et l'API attend lowercase
+        };
+
+        try {
+            // Envoi de la requête POST
+            const response = await fetch(url, {
+                method: "POST",
+                headers: {
+                    "Content-Type": "application/json", // Type des données envoyées
+                },
+                body: JSON.stringify(requestBody), // Sérialisation de l'objet en JSON
+            });
+
+            // Vérification si la requête a réussi
+            if (!response.ok) {
+                throw new Error(`HTTP error! status: ${response.status}`);
+            }
+
+            // Récupération des données retournées par l'API
+            const data = await response.json();
+            const quiz = transformToQuizModel(data);
+            return quiz;
+        } catch (error) {
+            console.error("Error while creating quiz:", error);
+            throw error; // Relancer l'erreur pour la gérer au niveau de l'appelant
+        }
+    }
+
+    return {
+        createQuiz: createQuiz,
+    }
+}
\ No newline at end of file
-- 
GitLab


From c3832c91f058e409099420a82223f1a7f373f738 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 20 Nov 2024 15:39:06 +0100
Subject: [PATCH 013/283] feat: ajout des images

---
 assets/ImageGenerateQuiz.png | Bin 0 -> 79168 bytes
 assets/ImageJoinQuiz.png     | Bin 0 -> 58320 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 assets/ImageGenerateQuiz.png
 create mode 100644 assets/ImageJoinQuiz.png

diff --git a/assets/ImageGenerateQuiz.png b/assets/ImageGenerateQuiz.png
new file mode 100644
index 0000000000000000000000000000000000000000..47a561544bbad44158e1165cf92d583942b2527f
GIT binary patch
literal 79168
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%0DAAR&eoSdC8
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
ChCLSm

literal 0
HcmV?d00001

diff --git a/assets/ImageJoinQuiz.png b/assets/ImageJoinQuiz.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f83b59b59b5aab112be427fcf1e1f76e914a316
GIT binary patch
literal 58320
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
B--G}F

literal 0
HcmV?d00001

-- 
GitLab


From 9b472523716fbda7e57bd048f07db8f9fec6f0f1 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 20 Nov 2024 15:39:56 +0100
Subject: [PATCH 014/283] feat: refont page Home

---
 screens/Home/Home.tsx        | 126 +++------------------------------
 screens/Home/Home.tsx sample | 133 +++++++++++++++++++++++++++++++++++
 screens/Home/HomeChild.tsx   | 113 +++++++++++++++++++++++++++++
 3 files changed, 254 insertions(+), 118 deletions(-)
 create mode 100644 screens/Home/Home.tsx sample
 create mode 100644 screens/Home/HomeChild.tsx

diff --git a/screens/Home/Home.tsx b/screens/Home/Home.tsx
index 5e4d8d6..d0b56d4 100644
--- a/screens/Home/Home.tsx
+++ b/screens/Home/Home.tsx
@@ -1,133 +1,23 @@
-import {StyleSheet, View, Text, Modal, TextInput, Image} from "react-native";
-import DefaultButton from "../../components/DefaultButton";
-import {TextsStyles} from "../../styles/TextsStyles";
-import {useTranslation} from "react-i18next";
-import { useState } from "react";
-import { ButtonsStyles } from "../../styles/ButtonsStyles";
+import { View, StyleSheet } from "react-native";
+import TemplateMono from "../../templates/TemplateMono";
+import HomeChild from "./HomeChild";
 
 interface Props {
     navigation: any;
 }
-export default function Home({navigation}: Props) {
-    const [modalVisible, setModalVisible] = useState(false);
-
-    // const handleButtonPlayPressed = () => {
-    //     setModalVisible(true);
-    // }
-
-    const {t} = useTranslation();
-    const handleButtonCreateQuizPressed = () => {
-        navigation.navigate("CreateQuiz");
-    }
 
-    const handleButtonValidatePressed = () => {
-        setModalVisible(false);
-    }
+export default function Home({navigation}: Props) {
     return (
-        <View>
-            <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
-            <View style={styles.container}>
-                <View style={styles.titleContainer}>
-                    <Text style={styles.titleText}>{"SKITSKOLA"}</Text>
-                </View>
-
-                <View style={styles.buttonContainer}>
-                    <View style={styles.ButtonsStyle}>
-                        {/* <DefaultButton text={t("app.screens.home.play")} handleButtonPressed={handleButtonPlayPressed}></DefaultButton> */}
-                        <DefaultButton text={t("app.screens.home.createQuiz")} handleButtonPressed={handleButtonCreateQuizPressed} buttonStyle={ButtonsStyles.movingButton} buttonText={TextsStyles.defaultText}></DefaultButton>
-                    </View>
-                </View>
-                {/* <Modal
-                    animationType="slide"
-                    transparent={true}
-                    visible={modalVisible}
-                    onRequestClose={() => {
-                    setModalVisible(!modalVisible);
-                }}>
-                    <View style={styles.centeredView}>
-                        <View style={styles.modalView}>
-                            <Text style={TextsStyles.subtitleText}>{t.("app.screens.home.joinQuiz")}</Text>
-                            <TextInput placeholder={t("app.screens.home.codeQuiz")} style={styles.codeTextInput} keyboardType="numeric"/>
-                            <DefaultButton text="V" handleButtonPressed={handleButtonValidatePressed} buttonStyle={styles.button}></DefaultButton>
-                        </View>    
-                    </View>
-                </Modal> */}
-            </View>
+        <View style={styles.containerGlobal}>
+            <TemplateMono children={<HomeChild navigation={navigation}/>}/>
         </View>
-    )
+    );
 }
 
 const styles = StyleSheet.create({
-    container: {
+    containerGlobal: {
         display: 'flex',
-        alignItems: 'center',
-        justifyContent: 'center',
-        width: '100%',
-        height: '100%',
-    },
-    buttonContainer: {
-        flex: 1,
-        alignItems: 'center',
-        justifyContent: 'flex-start',
-        width: '100%',
-        paddingVertical: '5%'  
-    },
-    titleContainer: {
-        display : 'flex',
-        flexDirection: 'column',
-        justifyContent: 'flex-end',
-        alignItems: 'center',
-        width: '100%',
-        height: '40%',
-    },
-    ButtonsStyle: {
-        display : 'flex',
-        flexDirection: 'column',
-        justifyContent: 'flex-start',
-        alignItems: 'center',
-        gap: 20,
-        width: '80%',
-        height: '60%',
-        marginBottom: "20%",
-    },
-    centeredView: {
-        flex: 1,
-        justifyContent: 'center',
-        alignItems: 'center',
-    },
-    modalView: {
-        height: 250,
-        width: 320,
-        margin: 20,
-        backgroundColor: 'white',
-        borderRadius: 20,
-        padding: 35,
-        alignItems: 'center',
-        borderWidth: 2,
-        borderColor: 'black',
-        borderStyle: 'solid',  
-    },
-    codeTextInput: {
-        borderWidth: 2,
-        borderColor: 'black',
-        borderStyle: 'solid',
-        height: 40,
-        width: 200,
-        marginTop: 30,
-        marginBottom: 20,
-        padding: 10,
-    },
-    button: {
-        width: 50,
-        height: 50,
-    },
-    image: {
         width: '100%',
         height: '100%',
-        position: 'absolute',
     },
-    titleText: {
-        fontSize: 30,
-        fontStyle: 'italic'
-    }
 });
\ No newline at end of file
diff --git a/screens/Home/Home.tsx sample b/screens/Home/Home.tsx sample
new file mode 100644
index 0000000..5e4d8d6
--- /dev/null
+++ b/screens/Home/Home.tsx sample	
@@ -0,0 +1,133 @@
+import {StyleSheet, View, Text, Modal, TextInput, Image} from "react-native";
+import DefaultButton from "../../components/DefaultButton";
+import {TextsStyles} from "../../styles/TextsStyles";
+import {useTranslation} from "react-i18next";
+import { useState } from "react";
+import { ButtonsStyles } from "../../styles/ButtonsStyles";
+
+interface Props {
+    navigation: any;
+}
+export default function Home({navigation}: Props) {
+    const [modalVisible, setModalVisible] = useState(false);
+
+    // const handleButtonPlayPressed = () => {
+    //     setModalVisible(true);
+    // }
+
+    const {t} = useTranslation();
+    const handleButtonCreateQuizPressed = () => {
+        navigation.navigate("CreateQuiz");
+    }
+
+    const handleButtonValidatePressed = () => {
+        setModalVisible(false);
+    }
+    return (
+        <View>
+            <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
+            <View style={styles.container}>
+                <View style={styles.titleContainer}>
+                    <Text style={styles.titleText}>{"SKITSKOLA"}</Text>
+                </View>
+
+                <View style={styles.buttonContainer}>
+                    <View style={styles.ButtonsStyle}>
+                        {/* <DefaultButton text={t("app.screens.home.play")} handleButtonPressed={handleButtonPlayPressed}></DefaultButton> */}
+                        <DefaultButton text={t("app.screens.home.createQuiz")} handleButtonPressed={handleButtonCreateQuizPressed} buttonStyle={ButtonsStyles.movingButton} buttonText={TextsStyles.defaultText}></DefaultButton>
+                    </View>
+                </View>
+                {/* <Modal
+                    animationType="slide"
+                    transparent={true}
+                    visible={modalVisible}
+                    onRequestClose={() => {
+                    setModalVisible(!modalVisible);
+                }}>
+                    <View style={styles.centeredView}>
+                        <View style={styles.modalView}>
+                            <Text style={TextsStyles.subtitleText}>{t.("app.screens.home.joinQuiz")}</Text>
+                            <TextInput placeholder={t("app.screens.home.codeQuiz")} style={styles.codeTextInput} keyboardType="numeric"/>
+                            <DefaultButton text="V" handleButtonPressed={handleButtonValidatePressed} buttonStyle={styles.button}></DefaultButton>
+                        </View>    
+                    </View>
+                </Modal> */}
+            </View>
+        </View>
+    )
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: 'flex',
+        alignItems: 'center',
+        justifyContent: 'center',
+        width: '100%',
+        height: '100%',
+    },
+    buttonContainer: {
+        flex: 1,
+        alignItems: 'center',
+        justifyContent: 'flex-start',
+        width: '100%',
+        paddingVertical: '5%'  
+    },
+    titleContainer: {
+        display : 'flex',
+        flexDirection: 'column',
+        justifyContent: 'flex-end',
+        alignItems: 'center',
+        width: '100%',
+        height: '40%',
+    },
+    ButtonsStyle: {
+        display : 'flex',
+        flexDirection: 'column',
+        justifyContent: 'flex-start',
+        alignItems: 'center',
+        gap: 20,
+        width: '80%',
+        height: '60%',
+        marginBottom: "20%",
+    },
+    centeredView: {
+        flex: 1,
+        justifyContent: 'center',
+        alignItems: 'center',
+    },
+    modalView: {
+        height: 250,
+        width: 320,
+        margin: 20,
+        backgroundColor: 'white',
+        borderRadius: 20,
+        padding: 35,
+        alignItems: 'center',
+        borderWidth: 2,
+        borderColor: 'black',
+        borderStyle: 'solid',  
+    },
+    codeTextInput: {
+        borderWidth: 2,
+        borderColor: 'black',
+        borderStyle: 'solid',
+        height: 40,
+        width: 200,
+        marginTop: 30,
+        marginBottom: 20,
+        padding: 10,
+    },
+    button: {
+        width: 50,
+        height: 50,
+    },
+    image: {
+        width: '100%',
+        height: '100%',
+        position: 'absolute',
+    },
+    titleText: {
+        fontSize: 30,
+        fontStyle: 'italic'
+    }
+});
\ No newline at end of file
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
new file mode 100644
index 0000000..b647a16
--- /dev/null
+++ b/screens/Home/HomeChild.tsx
@@ -0,0 +1,113 @@
+import { View, StyleSheet, Image, Modal, TextInput } from "react-native";
+import DefaultButton from "../../components/DefaultButton";
+import {useTranslation} from "react-i18next";
+import { useState } from "react";
+import { TextsStyles } from "../../styles/TextsStyles";
+
+interface Props {
+    navigation: any;
+}
+
+export default function HomeChild({navigation}: Props) {
+    const [modalVisible, setModalVisible] = useState(false);
+    const {t} = useTranslation();
+
+    const handleButtonJoinPressed = () => {
+        setModalVisible(true);
+    }
+
+    const handleButtonGeneratePressed = () => {
+        navigation.navigate("CreateQuiz");
+    }
+
+    // const handleButtonValidatePressed = () => {
+    //     setModalVisible(false);
+    // }
+    return (
+        <View style={styles.containerGlobal}>
+            <View style={styles.containerAction}>
+                <Image source={require('../../assets/ImageJoinQuiz.png')} style={styles.image}/>
+                <DefaultButton text={t("app.screens.home.codeQuiz")} handleButtonPressed={handleButtonJoinPressed} buttonStyle={styles.button}/>
+            </View>
+            <View style={styles.containerAction}>
+                <Image source={require('../../assets/ImageGenerateQuiz.png')} style={styles.image}/>
+                <DefaultButton text={t("app.screens.home.createQuiz")} handleButtonPressed={handleButtonGeneratePressed} buttonStyle={styles.button}/>
+            </View>
+            {/* <Modal
+            animationType="slide"
+            transparent={true}
+            visible={modalVisible}
+            onRequestClose={() => {
+            setModalVisible(!modalVisible);
+            }}>
+                <View style={styles.centeredView}>
+                    <View style={styles.modalView}>
+                        <Text style={TextsStyles.subtitleText}>{t.("app.screens.home.joinQuiz")}</Text>
+                        <TextInput placeholder={t("app.screens.home.codeQuiz")} style={styles.codeTextInput} keyboardType="numeric"/>
+                        <DefaultButton text="V" handleButtonPressed={handleButtonValidatePressed} buttonStyle={styles.button}></DefaultButton>
+                    </View>    
+                </View>
+            </Modal> */}
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        justifyContent: 'space-around',
+        alignItems: 'center',
+    },
+    containerAction: {
+        backgroundColor: '#F3F3F3',
+        width: '90%',
+        height: '45%',
+        padding: '8%',
+        borderRadius: 40,
+        shadowColor: '#171717',
+        shadowOffset: { width: 0, height: 4 },
+        shadowOpacity: 0.2,
+        shadowRadius: 3,
+        elevation: 5,
+    },
+    image: {
+        height: '60%',
+        width: '100%',
+        borderTopLeftRadius: 40,
+        borderTopRightRadius: 40,
+    },
+    button: {
+        borderRadius: 40,
+        height: '35%',
+        marginTop: '5%'
+    },
+    // centeredView: {
+    //     flex: 1,
+    //     justifyContent: 'center',
+    //     alignItems: 'center',
+    // },
+    // modalView: {
+    //     height: 250,
+    //     width: 320,
+    //     margin: 20,
+    //     backgroundColor: 'white',
+    //     borderRadius: 20,
+    //     padding: 35,
+    //     alignItems: 'center',
+    //     borderWidth: 2,
+    //     borderColor: 'black',
+    //     borderStyle: 'solid',  
+    // },
+    // codeTextInput: {
+    //     borderWidth: 2,
+    //     borderColor: 'black',
+    //     borderStyle: 'solid',
+    //     height: 40,
+    //     width: 200,
+    //     marginTop: 30,
+    //     marginBottom: 20,
+    //     padding: 10,
+    // },
+});
\ No newline at end of file
-- 
GitLab


From 150a578a0c4491c07ddf5df57d531db63e71104a Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 20 Nov 2024 15:40:32 +0100
Subject: [PATCH 015/283] feat: modif style de boutton de base

---
 styles/ButtonsStyles.ts | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/styles/ButtonsStyles.ts b/styles/ButtonsStyles.ts
index 769f771..96dd860 100644
--- a/styles/ButtonsStyles.ts
+++ b/styles/ButtonsStyles.ts
@@ -1,11 +1,10 @@
 import { StyleSheet } from "react-native";
 export const ButtonsStyles = StyleSheet.create( {
     defaultButton: {
-        backgroundColor: "grey",
+        backgroundColor: "#45128C",
         padding: 10,
         alignItems: "center",
-        borderRadius: 10,
-        width: "100%",
+        justifyContent: 'center'
     },
     answerButton: {
         backgroundColor: "#F3F3F3",
-- 
GitLab


From 85f2d72ee1de8932de7d4f569dbea808ee990a6f Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 20 Nov 2024 15:40:42 +0100
Subject: [PATCH 016/283] feat: modif template mono

---
 templates/TemplateMono.tsx | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/templates/TemplateMono.tsx b/templates/TemplateMono.tsx
index 0452982..1c781dc 100644
--- a/templates/TemplateMono.tsx
+++ b/templates/TemplateMono.tsx
@@ -25,20 +25,24 @@ const styles = StyleSheet.create({
     },
     containerHeader: {
         height: '12%',
+        width: '100%',
         justifyContent: 'flex-end',
         alignItems: 'center',
+        backgroundColor: '#fff',
         shadowColor: '#171717',
         shadowOffset: { width: 0, height: 4 },
         shadowOpacity: 0.2,
         shadowRadius: 3,
         elevation: 5,
-        backgroundColor: '#fff'
+        zIndex: 1,
     },
     containerBody: {
-        height: '83%',
+        height: '88%',
+        width: '100%',
+        backgroundColor: '#FFFFFF'
     },
     image: {
         height: '60%',
-        width: '60%'
+        width: '60%',
     }
 });
\ No newline at end of file
-- 
GitLab


From 3541f77008348d2187d6093e16b5ec155ece1f82 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 20 Nov 2024 21:45:08 +0100
Subject: [PATCH 017/283] feat: start modal join quiz

---
 components/ModalJoinQuiz.tsx | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 components/ModalJoinQuiz.tsx

diff --git a/components/ModalJoinQuiz.tsx b/components/ModalJoinQuiz.tsx
new file mode 100644
index 0000000..2c0927c
--- /dev/null
+++ b/components/ModalJoinQuiz.tsx
@@ -0,0 +1,31 @@
+import { Modal, View, Text, StyleSheet, TextInput } from "react-native";
+import DefaultButton from "./DefaultButton";
+
+export default function ModalJoinQuiz() {
+    const handleButtonClosePressed = () => {
+    }
+
+    const handleButtonJoinQuizPressed = () => {
+    }
+
+    return (
+        <Modal>
+            <View>
+                <Text>PLAY YOUR QUIZ</Text>
+                <DefaultButton text="X" handleButtonPressed={handleButtonClosePressed}/>
+            </View>
+            <View style={styles.separator}/>
+            <Text>ENTER THE QUIZ ID</Text>
+            <TextInput placeholder="TYPE A CODE"></TextInput>
+            <DefaultButton text="PLAY" handleButtonPressed={handleButtonJoinQuizPressed}/>
+        </Modal>
+    );
+}
+
+const styles = StyleSheet.create({
+    separator: {
+        height: 1,
+        width: '100%',
+        backgroundColor: '#ccc',
+    }
+});
\ No newline at end of file
-- 
GitLab


From 01ac102cc288ba6a25a1c971127796b0f8f05a4e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 21 Nov 2024 11:01:45 +0100
Subject: [PATCH 018/283] fix: passer a la question suivante

---
 helper/QuizHelper.ts                      | 3 ++-
 screens/PlayingQuiz/PlayingQuiz.tsx       | 3 +--
 screens/PlayingQuiz/PlayingQuizBody.tsx   | 2 +-
 screens/PlayingQuiz/PlayingQuizHeader.tsx | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index 132814e..b8a03ff 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -48,7 +48,8 @@ export const transformToQuizModel = (data: any): QuizModel => {
         category: data.theme.name, // Extraction du nom de la catégorie
         questions: questions,
         nbQuestions: questions[questions.length-1].nbOfTheQuestion, // Nombre total de questions
-        nbActualQuestion: data.questionIndex, // Mapping de questionIndex vers nbActualQuestion
+        // nbActualQuestion: data.questionIndex, // Mapping de questionIndex vers nbActualQuestion
+        nbActualQuestion: 1, // Mapping de questionIndex vers nbActualQuestion
         score: data.score, // Mapping direct
     };
 
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index e7c3266..64fa416 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -35,7 +35,7 @@ export default function PlayingQuiz({route, navigation}:Props) {
     const handleAnswer = async (selectedAnswerIndex: number) => {
         if (!quiz) return;
 
-        const currentQuestion = quiz.questions[quiz.nbActualQuestion];
+        const currentQuestion = quiz.questions[quiz.nbActualQuestion - 1];
         const correctAnswer = currentQuestion.correctAnswer;
         const selectedAnswer = currentQuestion.answer[selectedAnswerIndex];
 
@@ -59,7 +59,6 @@ export default function PlayingQuiz({route, navigation}:Props) {
                 setIsAlreadyPlayed(false);
                 return { ...prevQuiz, nbActualQuestion: prevQuiz.nbActualQuestion + 1 };
             }
-            console.log("fin question")
             navigation.navigate("EndQuiz", { score: prevQuiz?.score, quiz: quiz });
             return prevQuiz; // Fin du quiz si toutes les questions ont été posées
         });
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 8926d7d..2b82b4d 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -26,7 +26,7 @@ export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlaye
 
     if (!quiz) return null;
 
-    const currentQuestion = quiz.questions[quiz.nbActualQuestion];
+    const currentQuestion = quiz.questions[quiz.nbActualQuestion-1];
 
     const handleAnswerPress = (index: number) => {
         if (!isAlreadyPlayed) {
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index bfe216a..c756900 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -19,7 +19,7 @@ export default function PlayingQuizHeader({quiz}: Props) {
                     <Text style={TextsStyles.titleText}>{t("app.screens.question.question")} {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
                 </View>
                 <View style={styles.QuizQuestionContainer}>
-                    <Text style={TextsStyles.subtitleText}>{quiz ? quiz.questions[quiz.nbActualQuestion].question : "Loading..."}</Text>
+                    <Text style={TextsStyles.subtitleText}>{quiz ? quiz.questions[quiz.nbActualQuestion-1].question : "Loading..."}</Text>
                 </View>
             </View>
     );
-- 
GitLab


From 11520b96f667c30c6aa82573f95c91c3f79701b5 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 21 Nov 2024 11:24:36 +0100
Subject: [PATCH 019/283] style: commentaire dans le code

---
 helper/QuizHelper.ts | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index b8a03ff..b3acceb 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -31,14 +31,16 @@ export const transformToQuizModel = (data: any): QuizModel => {
     // Transformation des questions
     // console.log(JSON.stringify(data, null, 2));
 
-    const questions: QuestionModel[] = data.questions.map((item: any) => {
-        const answers = shuffleAnswers(item.answers.map((answer: any) => answer.text));
+    const questions: QuestionModel[] = data.questions.map((question: any) => {
+        const answers = shuffleAnswers(question.answers.map((answer: any) => answer.text));
         return {
-            question: item.text,
+            question: question.text,
             answer: answers, // Réponses mélangées
-            correctAnswer: item.answers[0].text, // Hypothèse : première réponse correcte (ajuste si nécessaire)
-            multiple: item.type === "multiple", // Détermine si c'est une question multiple
-            nbOfTheQuestion: item.order, // Mapping de order vers nbOfTheQuestion
+            // TODO
+            // Pour l'instant la bonne réponse est la premiere le temps qu'on puisse récupérer la bonne réponse depuis l'API
+            correctAnswer: question.answers[0].text, // Hypothèse : première réponse correcte (ajuste si nécessaire)
+            multiple: question.type === "multiple", // Détermine si c'est une question multiple
+            nbOfTheQuestion: question.order, // Mapping de order vers nbOfTheQuestion
         };
     });
 
@@ -48,6 +50,8 @@ export const transformToQuizModel = (data: any): QuizModel => {
         category: data.theme.name, // Extraction du nom de la catégorie
         questions: questions,
         nbQuestions: questions[questions.length-1].nbOfTheQuestion, // Nombre total de questions
+        // TODO
+        // nbAcutealQuestion devra pas commencer à 0 (Faute de l'API)
         // nbActualQuestion: data.questionIndex, // Mapping de questionIndex vers nbActualQuestion
         nbActualQuestion: 1, // Mapping de questionIndex vers nbActualQuestion
         score: data.score, // Mapping direct
-- 
GitLab


From 985e69b4e78c3e1b70fd9642013770a76a640114 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 21 Nov 2024 11:32:50 +0100
Subject: [PATCH 020/283] style: commentaire dans le code

---
 services/QuizService.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index d153099..2680d02 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -2,8 +2,9 @@ import {EDifficulty} from "../models/EDifficulty";
 import {transformToQuizModel} from "../helper/QuizHelper";
 
 export const useQuizService =  () => {
+    const url = "http://klebert-host.com:33036/quiz/create"; // Remplace par l'URL de ton endpoint API
+
     const createQuiz = async (amount: number, category: number, difficulty: string) => {
-        const url = "http://klebert-host.com:33036/quiz/create"; // Remplace par l'URL de ton endpoint API
 
         // Création du corps de la requête avec les variables passées
         const requestBody = {
-- 
GitLab


From 5760b190a84ad4f7beada780735814d2e2b0dce7 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 21 Nov 2024 11:41:10 +0100
Subject: [PATCH 021/283] style: createQuiz -> generateQuiz

---
 screens/GenerateQuiz/GenerateQuizBody.tsx | 4 ++--
 services/QuizService.ts                   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/screens/GenerateQuiz/GenerateQuizBody.tsx b/screens/GenerateQuiz/GenerateQuizBody.tsx
index d38e238..8c8a977 100644
--- a/screens/GenerateQuiz/GenerateQuizBody.tsx
+++ b/screens/GenerateQuiz/GenerateQuizBody.tsx
@@ -35,10 +35,10 @@ export default function GenerateQuizBody({navigation}:Props) {
     const [nbQuestions, setNbQuestions] = useState('1');
     const [theme, setTheme] = useState<string>('General Knowledge');
     const {t} = useTranslation();
-    const {createQuiz} = useQuizService();
+    const {generateQuiz} = useQuizService();
 
     const handleAddQuizPressed = async () => {
-        const quizGenerated = await createQuiz(parseInt(nbQuestions), getIdOfCategory(theme), difficulty);
+        const quizGenerated = await generateQuiz(parseInt(nbQuestions), getIdOfCategory(theme), difficulty);
         navigation.reset({
             index: 0,
             routes: [
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 2680d02..7abd894 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -4,7 +4,7 @@ import {transformToQuizModel} from "../helper/QuizHelper";
 export const useQuizService =  () => {
     const url = "http://klebert-host.com:33036/quiz/create"; // Remplace par l'URL de ton endpoint API
 
-    const createQuiz = async (amount: number, category: number, difficulty: string) => {
+    const generateQuiz = async (amount: number, category: number, difficulty: string) => {
 
         // Création du corps de la requête avec les variables passées
         const requestBody = {
@@ -39,6 +39,6 @@ export const useQuizService =  () => {
     }
 
     return {
-        createQuiz: createQuiz,
+        generateQuiz: generateQuiz,
     }
 }
\ No newline at end of file
-- 
GitLab


From 34bedf9bfbbd02808707368a9317236293da0265 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 21 Nov 2024 16:53:14 +0100
Subject: [PATCH 022/283] feat: add modal

---
 components/ModalJoinQuiz.tsx | 97 +++++++++++++++++++++++++++++++-----
 1 file changed, 85 insertions(+), 12 deletions(-)

diff --git a/components/ModalJoinQuiz.tsx b/components/ModalJoinQuiz.tsx
index 2c0927c..e05bb57 100644
--- a/components/ModalJoinQuiz.tsx
+++ b/components/ModalJoinQuiz.tsx
@@ -1,31 +1,104 @@
 import { Modal, View, Text, StyleSheet, TextInput } from "react-native";
 import DefaultButton from "./DefaultButton";
 
-export default function ModalJoinQuiz() {
+interface Props {
+    navigation: any;
+    modalVisible: boolean;
+    setModalVisible: (newModalVisible: boolean) => void;
+}
+
+export default function ModalJoinQuiz({ navigation, modalVisible, setModalVisible }: Props) {
     const handleButtonClosePressed = () => {
+        setModalVisible(!modalVisible);
     }
 
     const handleButtonJoinQuizPressed = () => {
+        setModalVisible(!modalVisible);
+        navigation.navigate("CreateQuiz");//TODO: changer la direction
     }
 
     return (
-        <Modal>
-            <View>
-                <Text>PLAY YOUR QUIZ</Text>
-                <DefaultButton text="X" handleButtonPressed={handleButtonClosePressed}/>
+        <Modal
+            animationType="slide"
+            transparent={true}
+            visible={modalVisible}
+            onRequestClose={() => {
+                setModalVisible(!modalVisible);
+            }}
+        >
+            <View style={styles.centeredView}>
+                <View style={styles.modalView}>
+                    <View style={styles.containerMenu}>
+                        <Text style={styles.textMenu}>PLAY YOUR QUIZ</Text>
+                        <DefaultButton text="X" handleButtonPressed={handleButtonClosePressed} buttonStyle={styles.buttonMenu} buttonText={styles.buttonTextMenu}/>
+                    </View>
+                    <View style={styles.containerCode}>
+                        <Text style={styles.textCode}>ENTER THE QUIZ ID</Text>
+                        <TextInput placeholder="TYPE A CODE" style={styles.textInputCode}></TextInput>
+                        <DefaultButton text="PLAY" handleButtonPressed={handleButtonJoinQuizPressed} buttonStyle={styles.buttonCode}/>
+                    </View>
+                </View>
             </View>
-            <View style={styles.separator}/>
-            <Text>ENTER THE QUIZ ID</Text>
-            <TextInput placeholder="TYPE A CODE"></TextInput>
-            <DefaultButton text="PLAY" handleButtonPressed={handleButtonJoinQuizPressed}/>
         </Modal>
     );
 }
 
 const styles = StyleSheet.create({
-    separator: {
-        height: 1,
+    centeredView: {
+        flex: 1,
+        justifyContent: 'center',
+        alignItems: 'center',
+    },
+    modalView: {
+        height: '35%',
+        width: '80%',
+        margin: '10%',
+        padding: '10%',
+        backgroundColor: 'white',
+        borderRadius: 20,
+        alignItems: 'center',
+        shadowColor: '#000',
+        shadowOffset: {
+            width: 0,
+            height: 2,
+        },
+        shadowOpacity: 0.25,
+        shadowRadius: 4,
+        elevation: 5,
+    },
+    containerMenu: {
+        flexDirection: 'row', 
+        alignItems: 'center',
+        justifyContent: 'space-between', 
+        height: '30%', 
+    },
+    textMenu: {
+        flex: 1,
+        textAlign: 'center',
+        fontSize: 20,
+        fontWeight: 'bold',
+    },
+    buttonMenu: {
+        padding: 10,
+        backgroundColor: '#FFFFFF',
+    },
+    buttonTextMenu: {
+        color: '#D5D5D5',
+        fontSize: 24,
+    },
+    containerCode: {
+        height: '100%',
         width: '100%',
-        backgroundColor: '#ccc',
+    },
+    textCode: {
+        fontSize: 14
+    },
+    textInputCode: {
+        borderColor: '#1FA9FF',
+        borderRadius: 10,
+        borderWidth: 2,
+    },
+    buttonCode: {
+        margin: 20
     }
 });
\ No newline at end of file
-- 
GitLab


From 4faf9eed0acf3c2bc4674059183ac36b8f821afb Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 21 Nov 2024 16:54:21 +0100
Subject: [PATCH 023/283] feat: remplacement de la nouvelle modal

---
 screens/Home/HomeChild.tsx | 47 ++------------------------------------
 1 file changed, 2 insertions(+), 45 deletions(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index b647a16..a03a84a 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -3,6 +3,7 @@ import DefaultButton from "../../components/DefaultButton";
 import {useTranslation} from "react-i18next";
 import { useState } from "react";
 import { TextsStyles } from "../../styles/TextsStyles";
+import ModalJoinQuiz from "../../components/ModalJoinQuiz";
 
 interface Props {
     navigation: any;
@@ -20,9 +21,6 @@ export default function HomeChild({navigation}: Props) {
         navigation.navigate("CreateQuiz");
     }
 
-    // const handleButtonValidatePressed = () => {
-    //     setModalVisible(false);
-    // }
     return (
         <View style={styles.containerGlobal}>
             <View style={styles.containerAction}>
@@ -33,21 +31,7 @@ export default function HomeChild({navigation}: Props) {
                 <Image source={require('../../assets/ImageGenerateQuiz.png')} style={styles.image}/>
                 <DefaultButton text={t("app.screens.home.createQuiz")} handleButtonPressed={handleButtonGeneratePressed} buttonStyle={styles.button}/>
             </View>
-            {/* <Modal
-            animationType="slide"
-            transparent={true}
-            visible={modalVisible}
-            onRequestClose={() => {
-            setModalVisible(!modalVisible);
-            }}>
-                <View style={styles.centeredView}>
-                    <View style={styles.modalView}>
-                        <Text style={TextsStyles.subtitleText}>{t.("app.screens.home.joinQuiz")}</Text>
-                        <TextInput placeholder={t("app.screens.home.codeQuiz")} style={styles.codeTextInput} keyboardType="numeric"/>
-                        <DefaultButton text="V" handleButtonPressed={handleButtonValidatePressed} buttonStyle={styles.button}></DefaultButton>
-                    </View>    
-                </View>
-            </Modal> */}
+            <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
         </View>
     );
 }
@@ -83,31 +67,4 @@ const styles = StyleSheet.create({
         height: '35%',
         marginTop: '5%'
     },
-    // centeredView: {
-    //     flex: 1,
-    //     justifyContent: 'center',
-    //     alignItems: 'center',
-    // },
-    // modalView: {
-    //     height: 250,
-    //     width: 320,
-    //     margin: 20,
-    //     backgroundColor: 'white',
-    //     borderRadius: 20,
-    //     padding: 35,
-    //     alignItems: 'center',
-    //     borderWidth: 2,
-    //     borderColor: 'black',
-    //     borderStyle: 'solid',  
-    // },
-    // codeTextInput: {
-    //     borderWidth: 2,
-    //     borderColor: 'black',
-    //     borderStyle: 'solid',
-    //     height: 40,
-    //     width: 200,
-    //     marginTop: 30,
-    //     marginBottom: 20,
-    //     padding: 10,
-    // },
 });
\ No newline at end of file
-- 
GitLab


From 519a3b25c2774b4cf7657b62a5162559ac5eb7f5 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 21 Nov 2024 16:55:19 +0100
Subject: [PATCH 024/283] feat: add modal

---
 screens/PlayingQuiz/PlayingQuiz.tsx       | 7 ++++---
 screens/PlayingQuiz/PlayingQuizHeader.tsx | 9 ++++++++-
 styles/ButtonsStyles.ts                   | 3 ++-
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 91dc961..00b21ac 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -4,6 +4,7 @@ import PlayingQuizHeader from "./PlayingQuizHeader";
 import {useEffect, useState} from "react";
 import {transformToQuizModel} from "../../helper/QuizHelper";
 import QuizModel from "../../model/QuizModel";
+import TemplateDuo from "../../templates/TemplateDuo";
 
 const optionsTheme = [
     "General Knowledge",
@@ -108,9 +109,9 @@ export default function PlayingQuiz({route, navigation}:Props) {
     };
 
     return (
-        <TemplateScreen
-            childrenTop={<PlayingQuizHeader quiz={quiz} ></PlayingQuizHeader>}
-            childrenBot={<PlayingQuizBody quiz={quiz} onAnswerSelected={handleAnswer} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed}></PlayingQuizBody>}
+        <TemplateDuo
+            childrenHeader={<PlayingQuizHeader quiz={quiz} ></PlayingQuizHeader>}
+            childrenBody={<PlayingQuizBody quiz={quiz} onAnswerSelected={handleAnswer} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed}></PlayingQuizBody>}
         />
     );
 }
\ No newline at end of file
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 6151f62..f2a318b 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -2,6 +2,7 @@ import { View, StyleSheet, Text } from "react-native";
 import { TextsStyles } from "../../styles/TextsStyles";
 import QuizModel from "../../model/QuizModel";
 import {useTranslation} from "react-i18next";
+import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
     quiz?: QuizModel;
@@ -9,11 +10,17 @@ interface Props {
 
 export default function PlayingQuizHeader({quiz}: Props) {
     const {t} = useTranslation();
+    const handleButtonBackToHomePressed = () => {
+    }
     return (
             <View style={styles.container}>
+                <View>
+                    <DefaultButton text="<" handleButtonPressed={handleButtonBackToHomePressed}/> 
+                    <Text>ID QUIZZ : 7</Text>
+                </View>
                 <View style={styles.infoQuizContainer}>
-                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.score")} : {quiz ? quiz.score : 0}</Text>
                     <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.category")} : {quiz ? quiz.category : "?"}</Text>
+                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.score")} : {quiz ? quiz.score : 0}</Text>
                 </View>
                 <View style={styles.QuizNumContainer}>
                     <Text style={TextsStyles.titleText}>{t("app.screens.question.question")} {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
diff --git a/styles/ButtonsStyles.ts b/styles/ButtonsStyles.ts
index 96dd860..ebe03d7 100644
--- a/styles/ButtonsStyles.ts
+++ b/styles/ButtonsStyles.ts
@@ -4,7 +4,8 @@ export const ButtonsStyles = StyleSheet.create( {
         backgroundColor: "#45128C",
         padding: 10,
         alignItems: "center",
-        justifyContent: 'center'
+        justifyContent: 'center',
+        borderRadius: 10,
     },
     answerButton: {
         backgroundColor: "#F3F3F3",
-- 
GitLab


From e7b42052fec4ea48834f09f28cead05d2e84cdda Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 27 Nov 2024 10:01:21 +0100
Subject: [PATCH 025/283] feat: remaining (pas encore fonctionnel)

---
 services/QuizService.ts | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index 7abd894..b377da5 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -2,7 +2,7 @@ import {EDifficulty} from "../models/EDifficulty";
 import {transformToQuizModel} from "../helper/QuizHelper";
 
 export const useQuizService =  () => {
-    const url = "http://klebert-host.com:33036/quiz/create"; // Remplace par l'URL de ton endpoint API
+    const url = "https://klebert-host.com:33037/quiz/create"; // Remplace par l'URL de ton endpoint API
 
     const generateQuiz = async (amount: number, category: number, difficulty: string) => {
 
@@ -38,6 +38,18 @@ export const useQuizService =  () => {
         }
     }
 
+    // const remainingQuiz = async (quizId: number) => {
+    //     try {
+    //         // Envoi de la requête GET
+    //         const response = await fetch(`${url}/${quizId}/remaining`, {
+    //             method: "GET",
+    //             headers: {
+    //                 "Content-Type": "application/json",
+    //             },
+    //         });
+    //
+    //         // Vérification si la requête a réussi
+    //
     return {
         generateQuiz: generateQuiz,
     }
-- 
GitLab


From 4d94a7c292394a1326d27c99348c568b84e2439b Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 27 Nov 2024 10:55:22 +0100
Subject: [PATCH 026/283] feat: remaining quiz

---
 screens/PlayingQuiz/PlayingQuizBody.tsx |  5 ++
 services/QuizService.ts                 | 77 ++++++++++++++++++++-----
 2 files changed, 66 insertions(+), 16 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 2b82b4d..ab06055 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -5,6 +5,7 @@ import { TextsStyles } from "../../styles/TextsStyles";
 import QuizModel from "../../models/QuizModel";
 import { useState, useEffect } from "react";
 import { setEnabled } from "react-native/Libraries/Performance/Systrace";
+import {useQuizService} from "../../services/QuizService";
 
 interface Props {
     quiz: QuizModel;
@@ -17,6 +18,8 @@ export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlaye
     const [selectedAnswerIndex, setSelectedAnswerIndex] = useState<number | null>(null);
     const [isCorrect, setIsCorrect] = useState<boolean | null>(null);
 
+    const {getAnswerQuiz} = useQuizService();
+
     useEffect(() => {
         if (quiz) {
             setSelectedAnswerIndex(null);
@@ -30,6 +33,8 @@ export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlaye
 
     const handleAnswerPress = (index: number) => {
         if (!isAlreadyPlayed) {
+            getAnswerQuiz(quiz.code);
+
             const isAnswerCorrect = currentQuestion.correctAnswer === currentQuestion.answer[index];
             setSelectedAnswerIndex(index);
             setIsCorrect(isAnswerCorrect);
diff --git a/services/QuizService.ts b/services/QuizService.ts
index b377da5..d262bab 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -14,13 +14,12 @@ export const useQuizService =  () => {
         };
 
         try {
-            // Envoi de la requête POST
-            const response = await fetch(url, {
+            const response = await fetch(url + "/quiz/create", {
                 method: "POST",
                 headers: {
-                    "Content-Type": "application/json", // Type des données envoyées
+                    "Content-Type": "application/json",
                 },
-                body: JSON.stringify(requestBody), // Sérialisation de l'objet en JSON
+                body: JSON.stringify(requestBody),
             });
 
             // Vérification si la requête a réussi
@@ -38,19 +37,65 @@ export const useQuizService =  () => {
         }
     }
 
-    // const remainingQuiz = async (quizId: number) => {
-    //     try {
-    //         // Envoi de la requête GET
-    //         const response = await fetch(`${url}/${quizId}/remaining`, {
-    //             method: "GET",
-    //             headers: {
-    //                 "Content-Type": "application/json",
-    //             },
-    //         });
-    //
-    //         // Vérification si la requête a réussi
-    //
+    const remainingQuiz = async (codeQuiz: string) => {
+
+        // Création du corps de la requête avec les variables passées
+        const requestBody = {
+            codeQuiz
+        };
+
+        try {
+            const response = await fetch(url + "/quiz/remaining", {
+                method: "POST",
+                headers: {
+                    "Content-Type": "application/json",
+                },
+                body: JSON.stringify(requestBody),
+            });
+
+            // Vérification si la requête a réussi
+            if (!response.ok) {
+                throw new Error(`HTTP error! status: ${response.status}`);
+            }
+
+            // Récupération des données retournées par l'API
+            const data = await response.json();
+            const quiz = transformToQuizModel(data);
+            return quiz;
+        } catch (error) {
+            console.error("Error while creating quiz:", error);
+            throw error; // Relancer l'erreur pour la gérer au niveau de l'appelant
+        }
+    }
+
+    const getAnswerQuiz = async (codeQuiz: string, questionID: number, answerID: number) => {
+        try {
+            const requestBody = {
+                codeQuiz,
+                questionID,
+                answerID
+            };
+            const response = await fetch(url + "/quiz/answer", {
+                method: "POST",
+                headers: {
+                    "Content-Type": "application/json",
+                },
+                body: JSON.stringify(requestBody),
+            });
+            const data = await response.json();
+            const answer = transformToQuizModel(data);
+            return answer;
+        } catch (error) {
+            console.error("Error while fetching remaining quiz:", error);
+            throw error;
+        }
+
+        // Vérification si la requête a réussi
+
+
+    }
     return {
         generateQuiz: generateQuiz,
+        getAnswerQuiz: getAnswerQuiz,
     }
 }
\ No newline at end of file
-- 
GitLab


From 28095c99154006164dab76c6c874b7faace65caa Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 27 Nov 2024 21:37:04 +0100
Subject: [PATCH 027/283] feat: answer + HttpError

---
 App.tsx                                   |  2 +-
 helper/QuizHelper.ts                      | 49 ++++++++----
 models/AnswerModel.ts                     |  6 ++
 models/QuestionModel.ts                   |  7 +-
 screens/EndQuiz/EndQuiz.tsx               | 18 +++--
 screens/PlayingQuiz/PlayingQuiz.tsx       | 43 ++--------
 screens/PlayingQuiz/PlayingQuizBody.tsx   | 95 ++++++++++++++++-------
 screens/PlayingQuiz/PlayingQuizHeader.tsx |  2 +-
 services/HttpError.ts                     | 14 ++++
 services/QuizService.ts                   | 63 ++++++++++-----
 10 files changed, 188 insertions(+), 111 deletions(-)
 create mode 100644 models/AnswerModel.ts
 create mode 100644 services/HttpError.ts

diff --git a/App.tsx b/App.tsx
index 96cb4a2..8d4b928 100644
--- a/App.tsx
+++ b/App.tsx
@@ -4,7 +4,7 @@ import i18n from "./translation/i18n"; // Importez l'instance déjà initialisé
 import { SafeAreaProvider } from "react-native-safe-area-context";
 import StackNavigator from "./routes/StackNavigator";
 export default function App() {
-    LogBox.ignoreAllLogs(true);
+    // LogBox.ignoreAllLogs(true);
 
   const { t } = useTranslation();
   return (
diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index b3acceb..c42135d 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -2,6 +2,7 @@
 // Fonction utilitaire pour mélanger les réponses
 import QuizModel from "../models/QuizModel";
 import QuestionModel from "../models/QuestionModel";
+import AnswerModel from "../models/AnswerModel";
 
 const optionsTheme = [
     "General Knowledge",
@@ -27,20 +28,38 @@ const shuffleAnswers = (answers: string[]): string[] => {
     return answers;
 };
 
+// Cette méthode est utilisée quand on récupère les réponses d'une question
+export const transformToAnswerModel = (data: any): AnswerModel[] => {
+    console.log(JSON.stringify(data, null, 2));
+    const answers: AnswerModel[] = data.answers.map((answer: any) => {
+        return {
+            id: answer.id,
+            text: answer.text,
+            isCorrect: answer.isCorrect,
+            questionId: answer.questionId,
+        };
+    });
+    return answers;
+};
+
 export const transformToQuizModel = (data: any): QuizModel => {
     // Transformation des questions
-    // console.log(JSON.stringify(data, null, 2));
-
     const questions: QuestionModel[] = data.questions.map((question: any) => {
-        const answers = shuffleAnswers(question.answers.map((answer: any) => answer.text));
+        // Transformation des réponses pour cette question
+        const answers: AnswerModel[] = question.answers.map((answer: any) => {
+            return {
+                id: answer.id,
+                text: answer.text,
+            };
+        });
+
         return {
-            question: question.text,
-            answer: answers, // Réponses mélangées
-            // TODO
-            // Pour l'instant la bonne réponse est la premiere le temps qu'on puisse récupérer la bonne réponse depuis l'API
-            correctAnswer: question.answers[0].text, // Hypothèse : première réponse correcte (ajuste si nécessaire)
+            id: question.id,
+            question: question.text, // Texte de la question
+            category: question.theme.name,
+            answers: answers, // Réponses associées
             multiple: question.type === "multiple", // Détermine si c'est une question multiple
-            nbOfTheQuestion: question.order, // Mapping de order vers nbOfTheQuestion
+            nbOfTheQuestion: question.order, // Numéro de la question
         };
     });
 
@@ -48,18 +67,16 @@ export const transformToQuizModel = (data: any): QuizModel => {
     const quiz: QuizModel = {
         code: data.codeQuiz, // Mapping de codeQuiz vers code
         category: data.theme.name, // Extraction du nom de la catégorie
-        questions: questions,
-        nbQuestions: questions[questions.length-1].nbOfTheQuestion, // Nombre total de questions
-        // TODO
-        // nbAcutealQuestion devra pas commencer à 0 (Faute de l'API)
-        // nbActualQuestion: data.questionIndex, // Mapping de questionIndex vers nbActualQuestion
-        nbActualQuestion: 1, // Mapping de questionIndex vers nbActualQuestion
-        score: data.score, // Mapping direct
+        questions: questions, // Questions transformées
+        nbQuestions: questions.length, // Nombre total de questions
+        nbActualQuestion: data.questionIndex, // Index actuel de la question
+        score: data.score, // Score actuel
     };
 
     return quiz;
 };
 
+
 export const getIdOfCategory = (category: string) => {
     for (let i = 0; i < optionsTheme.length; i++) {
         if (optionsTheme[i] === category) {
diff --git a/models/AnswerModel.ts b/models/AnswerModel.ts
new file mode 100644
index 0000000..4e66a15
--- /dev/null
+++ b/models/AnswerModel.ts
@@ -0,0 +1,6 @@
+export default interface AnswerModel {
+    id: number;
+    text: string;
+    isCorrect?: boolean;
+    questionId?: number;
+}
\ No newline at end of file
diff --git a/models/QuestionModel.ts b/models/QuestionModel.ts
index fa3cc19..527e1fc 100644
--- a/models/QuestionModel.ts
+++ b/models/QuestionModel.ts
@@ -1,7 +1,10 @@
+import AnswerModel from "./AnswerModel";
+
 export default interface QuestionModel {
+    id: number;
     question: string;
-    answer: string[];
-    correctAnswer: string;
+    category: string;
+    answers: AnswerModel[];
     multiple: boolean;
     nbOfTheQuestion: number;
 }
\ No newline at end of file
diff --git a/screens/EndQuiz/EndQuiz.tsx b/screens/EndQuiz/EndQuiz.tsx
index ea72db6..12db032 100644
--- a/screens/EndQuiz/EndQuiz.tsx
+++ b/screens/EndQuiz/EndQuiz.tsx
@@ -3,14 +3,22 @@ import DefaultButton from "../../components/DefaultButton";
 import { TextsStyles } from "../../styles/TextsStyles";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
 import {useTranslation} from "react-i18next";
+import QuizModel from "../../models/QuizModel";
+import {NavigationProp, RouteProp} from "@react-navigation/native";
+
+type RoutePropsType = {
+    EndQuiz: {
+        quiz: QuizModel;
+    };
+};
 
 interface Props {
-    navigation: any;
-    route: any;
+    navigation: NavigationProp<any>;
+    route: RouteProp<RoutePropsType, "EndQuiz">;
 }
 
 export default function EndQuiz({ navigation, route }: Props) {
-    const { score, quiz } = route.params;
+    const { quiz } = route.params;
     const {t} = useTranslation();
     const handleButtonRePlayPressed = () => {
         quiz.nbActualQuestion = 1;
@@ -33,8 +41,8 @@ export default function EndQuiz({ navigation, route }: Props) {
     return (
         <View style={styles.container}>
             <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
-            <Text style={TextsStyles.titleText}>{t("app.screens.endQuiz.score")} : {score}</Text>
-            <Text style={TextsStyles.subtitleText}>{((score/quiz.nbQuestions)*100 > 50 ) ? t("app.screens.endQuiz.lose") : t("app.screens.endQuiz.win")}</Text>
+            <Text style={TextsStyles.titleText}>{t("app.screens.endQuiz.score")} : {quiz.score}</Text>
+            <Text style={TextsStyles.subtitleText}>{((quiz.score/quiz.nbQuestions)*100 > 50 ) ? t("app.screens.endQuiz.lose") : t("app.screens.endQuiz.win")}</Text>
             <View style={styles.buttonContainer}>
                 <DefaultButton text={t("app.screens.endQuiz.replay")} handleButtonPressed={handleButtonRePlayPressed} buttonStyle={ButtonsStyles.defaultButton}></DefaultButton>
                 <DefaultButton text={t("app.screens.endQuiz.goHome")} handleButtonPressed={handleButtonHomePressed}></DefaultButton>
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 559abdc..dc838f5 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -1,10 +1,10 @@
-import TemplateScreen from "../../templates/TemplateScreen";
 import PlayingQuizBody from "./PlayingQuizBody";
 import PlayingQuizHeader from "./PlayingQuizHeader";
 import {useEffect, useState} from "react";
-import {transformToQuizModel} from "../../helper/QuizHelper";
-import QuizModel from "../../model/QuizModel";
 import TemplateDuo from "../../templates/TemplateDuo";
+import QuestionModel from "../../models/QuestionModel";
+import QuizModel from "../../models/QuizModel";
+import {NavigationProp} from "@react-navigation/native";
 
 const optionsTheme = [
     "General Knowledge",
@@ -24,7 +24,7 @@ const optionsTheme = [
 
 interface Props {
     route: any;
-    navigation: any;
+    navigation: NavigationProp<any>;
 }
 
 export default function PlayingQuiz({route, navigation}:Props) {
@@ -32,43 +32,10 @@ export default function PlayingQuiz({route, navigation}:Props) {
     const [isAlreadyPlayed, setIsAlreadyPlayed] = useState(false);
     const [quiz, setQuiz] = useState<QuizModel>(quizGenerated);
 
-
-    const handleAnswer = async (selectedAnswerIndex: number) => {
-        if (!quiz) return;
-
-        const currentQuestion = quiz.questions[quiz.nbActualQuestion - 1];
-        const correctAnswer = currentQuestion.correctAnswer;
-        const selectedAnswer = currentQuestion.answer[selectedAnswerIndex];
-
-        // Vérifier si la réponse est correcte
-        if (selectedAnswer === correctAnswer) {
-            setQuiz((prevQuiz) => {
-                if (prevQuiz) {
-                    return { ...prevQuiz, score: prevQuiz.score + 1 };
-                }
-                return prevQuiz;
-            });
-        }
-
-        // Attendre 2 secondes avant de passer à la question suivante
-        await new Promise((resolve) => setTimeout(resolve, 2000));
-
-        // Passer à la question suivante
-        setQuiz((prevQuiz) => {
-            if (prevQuiz && prevQuiz.nbActualQuestion < prevQuiz.nbQuestions) {
-                console.log("new question")
-                setIsAlreadyPlayed(false);
-                return { ...prevQuiz, nbActualQuestion: prevQuiz.nbActualQuestion + 1 };
-            }
-            navigation.navigate("EndQuiz", { score: prevQuiz?.score, quiz: quiz });
-            return prevQuiz; // Fin du quiz si toutes les questions ont été posées
-        });
-    };
-
     return (
         <TemplateDuo
             childrenHeader={<PlayingQuizHeader quiz={quiz} ></PlayingQuizHeader>}
-            childrenBody={<PlayingQuizBody quiz={quiz} onAnswerSelected={handleAnswer} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed}></PlayingQuizBody>}
+            childrenBody={<PlayingQuizBody quiz={quiz} setQuiz={setQuiz} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed} navigation={navigation}></PlayingQuizBody>}
         />
     );
 }
\ No newline at end of file
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index ab06055..44afa35 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -1,48 +1,80 @@
-import { View, StyleSheet } from "react-native";
+import { View, StyleSheet, Text } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
 import { TextsStyles } from "../../styles/TextsStyles";
 import QuizModel from "../../models/QuizModel";
-import { useState, useEffect } from "react";
-import { setEnabled } from "react-native/Libraries/Performance/Systrace";
-import {useQuizService} from "../../services/QuizService";
+import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
+import { useQuizService } from "../../services/QuizService";
+import QuestionModel from "../../models/QuestionModel";
+import AnswerModel from "../../models/AnswerModel";
+import {NavigationProp} from "@react-navigation/native";
+import HttpError from "../../services/HttpError";
 
 interface Props {
     quiz: QuizModel;
-    onAnswerSelected: (index: number) => void;
+    setQuiz: Dispatch<SetStateAction<QuizModel>>;
     isAlreadyPlayed: boolean;
     setIsAlreadyPlayed: (isAlreadyPlayed: boolean) => void;
+    navigation: NavigationProp<any>;
 }
 
-export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlayed, setIsAlreadyPlayed }: Props) {
+export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsAlreadyPlayed, navigation }: Props) {
     const [selectedAnswerIndex, setSelectedAnswerIndex] = useState<number | null>(null);
     const [isCorrect, setIsCorrect] = useState<boolean | null>(null);
+    const [correctAnswer, setCorrectAnswer] = useState<AnswerModel | null>(null);
 
-    const {getAnswerQuiz} = useQuizService();
+    const { getAnswerQuiz } = useQuizService();
 
     useEffect(() => {
         if (quiz) {
             setSelectedAnswerIndex(null);
             setIsCorrect(null);
+            setCorrectAnswer(null);
         }
     }, [quiz?.nbActualQuestion]);
 
     if (!quiz) return null;
 
-    const currentQuestion = quiz.questions[quiz.nbActualQuestion-1];
+    const currentQuestion: QuestionModel = quiz.questions[quiz.nbActualQuestion - 1];
 
-    const handleAnswerPress = (index: number) => {
-        if (!isAlreadyPlayed) {
-            getAnswerQuiz(quiz.code);
+    const handleAnswerPress = async (index: number) => {
+        if (isAlreadyPlayed) return;
 
-            const isAnswerCorrect = currentQuestion.correctAnswer === currentQuestion.answer[index];
-            setSelectedAnswerIndex(index);
-            setIsCorrect(isAnswerCorrect);
+        const answers = await getAnswerQuiz(quiz.code, currentQuestion.id, currentQuestion.answers[index].id);
 
-            onAnswerSelected(index);
+        if(HttpError.isHttpError(answers))
+        {
+            navigation.navigate("Home");
+            return;
+        }
+
+        const correctAnswer = getCorrectAnswer(answers);
+        const isAnswerCorrect = currentQuestion.answers[index].id === correctAnswer.id;
+
+        setSelectedAnswerIndex(index);
+        setIsCorrect(isAnswerCorrect);
+        setCorrectAnswer(correctAnswer);
+        setIsAlreadyPlayed(true);
 
-            setIsAlreadyPlayed(true);
+        await new Promise((resolve) => setTimeout(resolve, 2000));
+
+        if(quiz.nbActualQuestion === quiz.questions.length) {
+            navigation.navigate("EndQuiz", { quiz: quiz });
         }
+
+        setQuiz((prevQuiz) => ({
+            ...prevQuiz,
+            nbActualQuestion: prevQuiz.nbActualQuestion + 1,
+            score: isAnswerCorrect ? prevQuiz.score + 1 : prevQuiz.score
+        }));
+        setIsAlreadyPlayed(false);
+
+    };
+
+    const getCorrectAnswer = (answers: AnswerModel[]): AnswerModel => {
+        const correctAnswer = answers.find((answer) => answer.isCorrect);
+        if (!correctAnswer) throw new Error("No correct answer found");
+        return correctAnswer;
     };
 
     const getButtonStyle = (index: number) => {
@@ -51,7 +83,7 @@ export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlaye
         if (index === selectedAnswerIndex) {
             return isCorrect ? styles.correctAnswer : styles.incorrectAnswer;
         }
-        if (currentQuestion.correctAnswer === currentQuestion.answer[index]) {
+        if (currentQuestion.answers[index].id === correctAnswer?.id) {
             return styles.correctAnswer;
         }
         return ButtonsStyles.answerButton;
@@ -63,7 +95,7 @@ export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlaye
         if (index === selectedAnswerIndex) {
             return isCorrect ? styles.correctText : styles.incorrectText;
         }
-        if (currentQuestion.correctAnswer === currentQuestion.answer[index]) {
+        if (currentQuestion.answers[index].id === correctAnswer?.id) {
             return styles.correctText;
         }
         return TextsStyles.defaultText;
@@ -71,15 +103,19 @@ export default function PlayingQuizBody({ quiz, onAnswerSelected, isAlreadyPlaye
 
     return (
         <View style={styles.buttonContainer}>
-            {currentQuestion.answer.map((answer, index) => (
-                <DefaultButton
-                    key={index}
-                    text={answer}
-                    handleButtonPressed={() => handleAnswerPress(index)}
-                    buttonStyle={getButtonStyle(index)}
-                    buttonText={getTextStyle(index)} // Applique le style de texte dynamique
-                />
-            ))}
+            {currentQuestion ? (
+                currentQuestion.answers.map((answer, index) => (
+                    <DefaultButton
+                        key={index}
+                        text={answer.text}
+                        handleButtonPressed={() => handleAnswerPress(index)}
+                        buttonStyle={getButtonStyle(index)}
+                        buttonText={getTextStyle(index)}
+                    />
+                ))
+            ) : (
+                <Text style={styles.loadingText}>Loading...</Text>
+            )}
         </View>
     );
 }
@@ -111,4 +147,9 @@ const styles = StyleSheet.create({
         fontWeight: 'bold',
         color: 'red',
     },
+    loadingText: {
+        fontSize: 18,
+        color: 'gray',
+        textAlign: 'center',
+    },
 });
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 76eb64a..8014894 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -19,7 +19,7 @@ export default function PlayingQuizHeader({quiz}: Props) {
                     <Text>ID QUIZZ : 7</Text>
                 </View>
                 <View style={styles.infoQuizContainer}>
-                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.category")} : {quiz ? quiz.category : "?"}</Text>
+                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.category")} : {quiz ? quiz.questions[quiz.nbActualQuestion-1].category : "Loading..."}</Text>
                     <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.score")} : {quiz ? quiz.score : 0}</Text>
                 </View>
                 <View style={styles.QuizNumContainer}>
diff --git a/services/HttpError.ts b/services/HttpError.ts
new file mode 100644
index 0000000..82fd80f
--- /dev/null
+++ b/services/HttpError.ts
@@ -0,0 +1,14 @@
+export default class HttpError extends Error {
+    statusCode: number;
+
+    constructor(statusCode: number, message: string) {
+        super(message); // Appelle le constructeur de Error
+        this.statusCode = statusCode;
+        this.name = "HttpError"; // Nom de l'erreur
+    }
+
+    // Méthode pour vérifier si une erreur est un HttpError
+    static isHttpError(error: unknown): error is HttpError {
+        return error instanceof HttpError;
+    }
+}
diff --git a/services/QuizService.ts b/services/QuizService.ts
index d262bab..831fe57 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -1,8 +1,10 @@
 import {EDifficulty} from "../models/EDifficulty";
-import {transformToQuizModel} from "../helper/QuizHelper";
+import {transformToAnswerModel, transformToQuizModel} from "../helper/QuizHelper";
+import AnswerModel from "../models/AnswerModel";
+import HttpError from "./HttpError";
 
 export const useQuizService =  () => {
-    const url = "https://klebert-host.com:33037/quiz/create"; // Remplace par l'URL de ton endpoint API
+    const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
 
     const generateQuiz = async (amount: number, category: number, difficulty: string) => {
 
@@ -22,18 +24,23 @@ export const useQuizService =  () => {
                 body: JSON.stringify(requestBody),
             });
 
-            // Vérification si la requête a réussi
             if (!response.ok) {
-                throw new Error(`HTTP error! status: ${response.status}`);
+                throw new HttpError(response.status, "HTTP error! status: " + response.status);
             }
 
             // Récupération des données retournées par l'API
             const data = await response.json();
+            console.log(JSON.stringify(data, null, 2));
             const quiz = transformToQuizModel(data);
             return quiz;
         } catch (error) {
-            console.error("Error while creating quiz:", error);
-            throw error; // Relancer l'erreur pour la gérer au niveau de l'appelant
+            console.error("Error while generating quiz:", error);
+
+            if (HttpError.isHttpError(error)) {
+                return error;
+            } else {
+                return new HttpError(500, "Unexpected error: " + error);
+            }
         }
     }
 
@@ -53,9 +60,8 @@ export const useQuizService =  () => {
                 body: JSON.stringify(requestBody),
             });
 
-            // Vérification si la requête a réussi
             if (!response.ok) {
-                throw new Error(`HTTP error! status: ${response.status}`);
+                throw new HttpError(response.status, "HTTP error! status: " + response.status);
             }
 
             // Récupération des données retournées par l'API
@@ -64,17 +70,26 @@ export const useQuizService =  () => {
             return quiz;
         } catch (error) {
             console.error("Error while creating quiz:", error);
-            throw error; // Relancer l'erreur pour la gérer au niveau de l'appelant
+
+            if (HttpError.isHttpError(error)) {
+                return error;
+            } else {
+                return new HttpError(500, "Unexpected error: " + error);
+            }
         }
     }
 
-    const getAnswerQuiz = async (codeQuiz: string, questionID: number, answerID: number) => {
+    const getAnswerQuiz = async (codeQuiz: string, questionID: number, answerID: number) : Promise<AnswerModel[] | HttpError> => {
+        console.log("codeQuiz : " + codeQuiz);
+        console.log("questionID : " + questionID);
+        console.log("answerID : " + answerID);
         try {
             const requestBody = {
-                codeQuiz,
-                questionID,
-                answerID
+                codeQuiz: codeQuiz,
+                questionID: questionID,
+                answerID: answerID
             };
+
             const response = await fetch(url + "/quiz/answer", {
                 method: "POST",
                 headers: {
@@ -82,17 +97,23 @@ export const useQuizService =  () => {
                 },
                 body: JSON.stringify(requestBody),
             });
-            const data = await response.json();
-            const answer = transformToQuizModel(data);
-            return answer;
-        } catch (error) {
-            console.error("Error while fetching remaining quiz:", error);
-            throw error;
-        }
 
-        // Vérification si la requête a réussi
+            if (!response.ok) {
+                throw new HttpError(response.status, "HTTP error! status: " + response.status);
+            }
 
+            const data = await response.json();
+            const answers = transformToAnswerModel(data);
+            return answers;
+        } catch (error) {
+            console.log("Error while fetching answers:", error);
 
+            if (HttpError.isHttpError(error)) {
+                return error;
+            } else {
+                return new HttpError(500, "Unexpected error: " + error);
+            }
+        }
     }
     return {
         generateQuiz: generateQuiz,
-- 
GitLab


From 3fef0b4eaf9912e1a3dc1050b2c4892c7cec6ef4 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 28 Nov 2024 14:39:40 +0100
Subject: [PATCH 028/283] feat: lancer le quizz avec le code depuis la modal
 dans le home

---
 components/ModalJoinQuiz.tsx              | 43 ++++++++++++++++++++---
 helper/QuizHelper.ts                      |  2 +-
 screens/GenerateQuiz/GenerateQuizBody.tsx |  2 +-
 screens/PlayingQuiz/PlayingQuiz.tsx       | 14 +++++---
 screens/PlayingQuiz/PlayingQuizHeader.tsx |  1 +
 services/QuizService.ts                   |  7 ++--
 6 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/components/ModalJoinQuiz.tsx b/components/ModalJoinQuiz.tsx
index e05bb57..d2ce415 100644
--- a/components/ModalJoinQuiz.tsx
+++ b/components/ModalJoinQuiz.tsx
@@ -1,5 +1,8 @@
 import { Modal, View, Text, StyleSheet, TextInput } from "react-native";
 import DefaultButton from "./DefaultButton";
+import {useState} from "react";
+import {useQuizService} from "../services/QuizService";
+import HttpError from "../services/HttpError";
 
 interface Props {
     navigation: any;
@@ -8,13 +11,40 @@ interface Props {
 }
 
 export default function ModalJoinQuiz({ navigation, modalVisible, setModalVisible }: Props) {
+
+    const [isError, setIsError] = useState<boolean>(false);
+    const [errorMessage, setErrorMessage] = useState<string>("");
+    const [codeQuiz, setCodeQuiz] = useState<string>("");
+    const {remainingQuiz} = useQuizService();
     const handleButtonClosePressed = () => {
         setModalVisible(!modalVisible);
+        setIsError(false);
+        setErrorMessage("");
     }
 
-    const handleButtonJoinQuizPressed = () => {
-        setModalVisible(!modalVisible);
-        navigation.navigate("CreateQuiz");//TODO: changer la direction
+    const handleButtonJoinQuizPressed = async () => {
+        const quiz = await remainingQuiz(codeQuiz);
+        if(HttpError.isHttpError(quiz)){
+            setIsError(true);
+            setErrorMessage("Code quiz invalide");
+            return;
+        }
+
+        if(!quiz){
+            console.log("vvvvvvvvvvv");
+        }
+
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quizRecovered: quiz},
+                },
+            ]
+        });
+
+
     }
 
     return (
@@ -34,7 +64,8 @@ export default function ModalJoinQuiz({ navigation, modalVisible, setModalVisibl
                     </View>
                     <View style={styles.containerCode}>
                         <Text style={styles.textCode}>ENTER THE QUIZ ID</Text>
-                        <TextInput placeholder="TYPE A CODE" style={styles.textInputCode}></TextInput>
+                        {isError && <Text style={styles.textError}>{errorMessage}</Text>}
+                        <TextInput placeholder="TYPE A CODE" style={styles.textInputCode} onChangeText={(text) => setCodeQuiz(text)}></TextInput>
                         <DefaultButton text="PLAY" handleButtonPressed={handleButtonJoinQuizPressed} buttonStyle={styles.buttonCode}/>
                     </View>
                 </View>
@@ -93,6 +124,10 @@ const styles = StyleSheet.create({
     textCode: {
         fontSize: 14
     },
+    textError: {
+        fontSize: 14,
+        color: "red"
+    },
     textInputCode: {
         borderColor: '#1FA9FF',
         borderRadius: 10,
diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index c42135d..1eb2b4f 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -68,7 +68,7 @@ export const transformToQuizModel = (data: any): QuizModel => {
         code: data.codeQuiz, // Mapping de codeQuiz vers code
         category: data.theme.name, // Extraction du nom de la catégorie
         questions: questions, // Questions transformées
-        nbQuestions: questions.length, // Nombre total de questions
+        nbQuestions: data.questionCount, // Nombre total de questions
         nbActualQuestion: data.questionIndex, // Index actuel de la question
         score: data.score, // Score actuel
     };
diff --git a/screens/GenerateQuiz/GenerateQuizBody.tsx b/screens/GenerateQuiz/GenerateQuizBody.tsx
index 8c8a977..198f438 100644
--- a/screens/GenerateQuiz/GenerateQuizBody.tsx
+++ b/screens/GenerateQuiz/GenerateQuizBody.tsx
@@ -44,7 +44,7 @@ export default function GenerateQuizBody({navigation}:Props) {
             routes: [
                 {
                     name: "PlayingQuiz",
-                    params: {quizGenerated: quizGenerated},
+                    params: {quizRecovered: quizGenerated},
                 },
             ]
         });
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index dc838f5..9ea3d2e 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -4,7 +4,7 @@ import {useEffect, useState} from "react";
 import TemplateDuo from "../../templates/TemplateDuo";
 import QuestionModel from "../../models/QuestionModel";
 import QuizModel from "../../models/QuizModel";
-import {NavigationProp} from "@react-navigation/native";
+import {NavigationProp, RouteProp} from "@react-navigation/native";
 
 const optionsTheme = [
     "General Knowledge",
@@ -22,15 +22,21 @@ const optionsTheme = [
     "Sports",
     "Geography"]
 
+type RoutePropsType = {
+    PlayingQuiz: {
+        quizRecovered: QuizModel;
+    };
+};
+
 interface Props {
-    route: any;
+    route: RouteProp<RoutePropsType, "PlayingQuiz">;
     navigation: NavigationProp<any>;
 }
 
 export default function PlayingQuiz({route, navigation}:Props) {
-    const {quizGenerated} = route.params;
+    const {quizRecovered} = route.params;
     const [isAlreadyPlayed, setIsAlreadyPlayed] = useState(false);
-    const [quiz, setQuiz] = useState<QuizModel>(quizGenerated);
+    const [quiz, setQuiz] = useState<QuizModel>(quizRecovered);
 
     return (
         <TemplateDuo
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 8014894..56ad134 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -10,6 +10,7 @@ interface Props {
 
 export default function PlayingQuizHeader({quiz}: Props) {
     const {t} = useTranslation();
+
     const handleButtonBackToHomePressed = () => {
     }
     return (
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 831fe57..a3e9b37 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -2,11 +2,12 @@ import {EDifficulty} from "../models/EDifficulty";
 import {transformToAnswerModel, transformToQuizModel} from "../helper/QuizHelper";
 import AnswerModel from "../models/AnswerModel";
 import HttpError from "./HttpError";
+import QuizModel from "../models/QuizModel";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
 
-    const generateQuiz = async (amount: number, category: number, difficulty: string) => {
+    const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<QuizModel | HttpError> => {
 
         // Création du corps de la requête avec les variables passées
         const requestBody = {
@@ -44,7 +45,7 @@ export const useQuizService =  () => {
         }
     }
 
-    const remainingQuiz = async (codeQuiz: string) => {
+    const remainingQuiz = async (codeQuiz: string) : Promise<QuizModel | HttpError> => {
 
         // Création du corps de la requête avec les variables passées
         const requestBody = {
@@ -66,6 +67,7 @@ export const useQuizService =  () => {
 
             // Récupération des données retournées par l'API
             const data = await response.json();
+            console.log(JSON.stringify(data, null, 2));
             const quiz = transformToQuizModel(data);
             return quiz;
         } catch (error) {
@@ -118,5 +120,6 @@ export const useQuizService =  () => {
     return {
         generateQuiz: generateQuiz,
         getAnswerQuiz: getAnswerQuiz,
+        remainingQuiz: remainingQuiz
     }
 }
\ No newline at end of file
-- 
GitLab


From 88143df93175e6991a23f68e9b7cec49eafd58a3 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 29 Nov 2024 09:42:30 +0100
Subject: [PATCH 029/283] =?UTF-8?q?fix:=20crash=20sur=20la=20derni=C3=A8re?=
 =?UTF-8?q?=20question=20du=20quizz?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/ModalJoinQuiz.tsx              | 4 ----
 helper/QuizHelper.ts                      | 1 -
 screens/PlayingQuiz/PlayingQuizHeader.tsx | 6 ++++--
 services/QuizService.ts                   | 5 -----
 4 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/components/ModalJoinQuiz.tsx b/components/ModalJoinQuiz.tsx
index d2ce415..77320ad 100644
--- a/components/ModalJoinQuiz.tsx
+++ b/components/ModalJoinQuiz.tsx
@@ -30,10 +30,6 @@ export default function ModalJoinQuiz({ navigation, modalVisible, setModalVisibl
             return;
         }
 
-        if(!quiz){
-            console.log("vvvvvvvvvvv");
-        }
-
         navigation.reset({
             index: 0,
             routes: [
diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index 1eb2b4f..3ff16ac 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -30,7 +30,6 @@ const shuffleAnswers = (answers: string[]): string[] => {
 
 // Cette méthode est utilisée quand on récupère les réponses d'une question
 export const transformToAnswerModel = (data: any): AnswerModel[] => {
-    console.log(JSON.stringify(data, null, 2));
     const answers: AnswerModel[] = data.answers.map((answer: any) => {
         return {
             id: answer.id,
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 56ad134..0b0b803 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -11,6 +11,8 @@ interface Props {
 export default function PlayingQuizHeader({quiz}: Props) {
     const {t} = useTranslation();
 
+    if (quiz.nbQuestions <= quiz.nbActualQuestion - 1) return;
+
     const handleButtonBackToHomePressed = () => {
     }
     return (
@@ -20,14 +22,14 @@ export default function PlayingQuizHeader({quiz}: Props) {
                     <Text>ID QUIZZ : 7</Text>
                 </View>
                 <View style={styles.infoQuizContainer}>
-                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.category")} : {quiz ? quiz.questions[quiz.nbActualQuestion-1].category : "Loading..."}</Text>
+                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.category")} : {quiz.questions[quiz.nbActualQuestion-1].category ? quiz.questions[quiz.nbActualQuestion-1].category : "Loading..."}</Text>
                     <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.score")} : {quiz ? quiz.score : 0}</Text>
                 </View>
                 <View style={styles.QuizNumContainer}>
                     <Text style={TextsStyles.titleText}>{t("app.screens.question.question")} {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
                 </View>
                 <View style={styles.QuizQuestionContainer}>
-                    <Text style={TextsStyles.subtitleText}>{quiz ? quiz.questions[quiz.nbActualQuestion-1].question : "Loading..."}</Text>
+                    <Text style={TextsStyles.subtitleText}>{quiz.questions[quiz.nbActualQuestion-1].question ? quiz.questions[quiz.nbActualQuestion-1].question : "Loading..."}</Text>
                 </View>
             </View>
     );
diff --git a/services/QuizService.ts b/services/QuizService.ts
index a3e9b37..690a15a 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -31,7 +31,6 @@ export const useQuizService =  () => {
 
             // Récupération des données retournées par l'API
             const data = await response.json();
-            console.log(JSON.stringify(data, null, 2));
             const quiz = transformToQuizModel(data);
             return quiz;
         } catch (error) {
@@ -67,7 +66,6 @@ export const useQuizService =  () => {
 
             // Récupération des données retournées par l'API
             const data = await response.json();
-            console.log(JSON.stringify(data, null, 2));
             const quiz = transformToQuizModel(data);
             return quiz;
         } catch (error) {
@@ -82,9 +80,6 @@ export const useQuizService =  () => {
     }
 
     const getAnswerQuiz = async (codeQuiz: string, questionID: number, answerID: number) : Promise<AnswerModel[] | HttpError> => {
-        console.log("codeQuiz : " + codeQuiz);
-        console.log("questionID : " + questionID);
-        console.log("answerID : " + answerID);
         try {
             const requestBody = {
                 codeQuiz: codeQuiz,
-- 
GitLab


From e7b9ce08ad90392a7e96e31e12d0635c1bea6b23 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 29 Nov 2024 12:06:40 +0100
Subject: [PATCH 030/283] feat: refonte du screen Home

---
 components/buttons/MenuButton.tsx |  32 +++++++
 screens/Home/HeaderNavigation.tsx |  41 +++++++++
 screens/Home/Home.tsx             |  14 +++-
 screens/Home/Home.tsx sample      | 133 ------------------------------
 screens/Home/HomeChild.tsx        |  51 ++++++------
 templates/TemplateMenu.tsx        |  45 ++++++++++
 6 files changed, 155 insertions(+), 161 deletions(-)
 create mode 100644 components/buttons/MenuButton.tsx
 create mode 100644 screens/Home/HeaderNavigation.tsx
 delete mode 100644 screens/Home/Home.tsx sample
 create mode 100644 templates/TemplateMenu.tsx

diff --git a/components/buttons/MenuButton.tsx b/components/buttons/MenuButton.tsx
new file mode 100644
index 0000000..a7d38f7
--- /dev/null
+++ b/components/buttons/MenuButton.tsx
@@ -0,0 +1,32 @@
+import React from "react";
+import {TouchableOpacity, StyleSheet, Text} from "react-native";
+
+interface Props{
+    text: string
+    handleButtonPressed:() => void;
+}
+/**
+ * MenuButton : Bouton du menu principal
+ * @param text - Texte du bouton
+ * @param handleButtonPressed - Fonction qui sera exécutée lorsque le bouton sera pressé
+ */
+export default function MenuButton({text, handleButtonPressed}: Props) {
+    return (
+        <TouchableOpacity onPress={handleButtonPressed}>
+            <Text style={styles.textStyle}>{text}</Text>
+        </TouchableOpacity>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+    },
+    textStyle: {
+        color: '#2ec7ff',
+        fontSize: 50,
+        fontWeight: 'bold',
+    }
+});
\ No newline at end of file
diff --git a/screens/Home/HeaderNavigation.tsx b/screens/Home/HeaderNavigation.tsx
new file mode 100644
index 0000000..5b71d9c
--- /dev/null
+++ b/screens/Home/HeaderNavigation.tsx
@@ -0,0 +1,41 @@
+import { View, StyleSheet, Image, TouchableOpacity } from "react-native";
+import { NavigationProp } from "@react-navigation/native";
+
+interface Props {
+    navigation: NavigationProp<any>;
+}
+
+/**
+ * HeaderNavigation : Header qui permet de remonter à l'écran précédent
+ * @param navigation - navigation
+ */
+export default function HeaderNavigation({ navigation }: Props) {
+    return (
+        <View style={styles.container}>
+            <TouchableOpacity onPress={() => navigation.goBack()} style={styles.goBackContainer}>
+                <Image source={require('../../assets/GoBackNavigation.png')}/>
+            </TouchableOpacity>
+            <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage} />
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flexDirection: 'row', // Alignement en ligne
+        alignItems: 'center', // Centrer les éléments verticalement
+        justifyContent: 'center', // Centrer les éléments horizontalement
+        width: '100%',
+        height: 60, // Ajustez en fonction de votre design
+        position: 'relative', // Pour positionner l'élément de gauche
+    },
+    goBackContainer: {
+        position: 'absolute', // Place l'élément indépendamment
+        left: 10, // Décalé à gauche
+    },
+    titleImage: {
+        width: 170, // Ajustez en fonction de la taille de l'image
+        height: 80,
+        resizeMode: 'contain', // Pour conserver les proportions
+    },
+});
diff --git a/screens/Home/Home.tsx b/screens/Home/Home.tsx
index d0b56d4..53bb379 100644
--- a/screens/Home/Home.tsx
+++ b/screens/Home/Home.tsx
@@ -1,15 +1,22 @@
-import { View, StyleSheet } from "react-native";
+import { View, StyleSheet, Text } from "react-native";
 import TemplateMono from "../../templates/TemplateMono";
 import HomeChild from "./HomeChild";
+import TemplateMenu from "../../templates/TemplateMenu";
+import {NavigationProp} from "@react-navigation/native";
+import HeaderNavigation from "./HeaderNavigation";
 
 interface Props {
-    navigation: any;
+    navigation: NavigationProp<any>;
 }
 
 export default function Home({navigation}: Props) {
     return (
         <View style={styles.containerGlobal}>
-            <TemplateMono children={<HomeChild navigation={navigation}/>}/>
+                <TemplateMenu navigation={navigation} headerNavigation={false}>
+                    <View>
+                        <HomeChild navigation={navigation}/>
+                    </View>
+                </TemplateMenu>
         </View>
     );
 }
@@ -19,5 +26,6 @@ const styles = StyleSheet.create({
         display: 'flex',
         width: '100%',
         height: '100%',
+        flexDirection: 'column',
     },
 });
\ No newline at end of file
diff --git a/screens/Home/Home.tsx sample b/screens/Home/Home.tsx sample
deleted file mode 100644
index 5e4d8d6..0000000
--- a/screens/Home/Home.tsx sample	
+++ /dev/null
@@ -1,133 +0,0 @@
-import {StyleSheet, View, Text, Modal, TextInput, Image} from "react-native";
-import DefaultButton from "../../components/DefaultButton";
-import {TextsStyles} from "../../styles/TextsStyles";
-import {useTranslation} from "react-i18next";
-import { useState } from "react";
-import { ButtonsStyles } from "../../styles/ButtonsStyles";
-
-interface Props {
-    navigation: any;
-}
-export default function Home({navigation}: Props) {
-    const [modalVisible, setModalVisible] = useState(false);
-
-    // const handleButtonPlayPressed = () => {
-    //     setModalVisible(true);
-    // }
-
-    const {t} = useTranslation();
-    const handleButtonCreateQuizPressed = () => {
-        navigation.navigate("CreateQuiz");
-    }
-
-    const handleButtonValidatePressed = () => {
-        setModalVisible(false);
-    }
-    return (
-        <View>
-            <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
-            <View style={styles.container}>
-                <View style={styles.titleContainer}>
-                    <Text style={styles.titleText}>{"SKITSKOLA"}</Text>
-                </View>
-
-                <View style={styles.buttonContainer}>
-                    <View style={styles.ButtonsStyle}>
-                        {/* <DefaultButton text={t("app.screens.home.play")} handleButtonPressed={handleButtonPlayPressed}></DefaultButton> */}
-                        <DefaultButton text={t("app.screens.home.createQuiz")} handleButtonPressed={handleButtonCreateQuizPressed} buttonStyle={ButtonsStyles.movingButton} buttonText={TextsStyles.defaultText}></DefaultButton>
-                    </View>
-                </View>
-                {/* <Modal
-                    animationType="slide"
-                    transparent={true}
-                    visible={modalVisible}
-                    onRequestClose={() => {
-                    setModalVisible(!modalVisible);
-                }}>
-                    <View style={styles.centeredView}>
-                        <View style={styles.modalView}>
-                            <Text style={TextsStyles.subtitleText}>{t.("app.screens.home.joinQuiz")}</Text>
-                            <TextInput placeholder={t("app.screens.home.codeQuiz")} style={styles.codeTextInput} keyboardType="numeric"/>
-                            <DefaultButton text="V" handleButtonPressed={handleButtonValidatePressed} buttonStyle={styles.button}></DefaultButton>
-                        </View>    
-                    </View>
-                </Modal> */}
-            </View>
-        </View>
-    )
-}
-
-const styles = StyleSheet.create({
-    container: {
-        display: 'flex',
-        alignItems: 'center',
-        justifyContent: 'center',
-        width: '100%',
-        height: '100%',
-    },
-    buttonContainer: {
-        flex: 1,
-        alignItems: 'center',
-        justifyContent: 'flex-start',
-        width: '100%',
-        paddingVertical: '5%'  
-    },
-    titleContainer: {
-        display : 'flex',
-        flexDirection: 'column',
-        justifyContent: 'flex-end',
-        alignItems: 'center',
-        width: '100%',
-        height: '40%',
-    },
-    ButtonsStyle: {
-        display : 'flex',
-        flexDirection: 'column',
-        justifyContent: 'flex-start',
-        alignItems: 'center',
-        gap: 20,
-        width: '80%',
-        height: '60%',
-        marginBottom: "20%",
-    },
-    centeredView: {
-        flex: 1,
-        justifyContent: 'center',
-        alignItems: 'center',
-    },
-    modalView: {
-        height: 250,
-        width: 320,
-        margin: 20,
-        backgroundColor: 'white',
-        borderRadius: 20,
-        padding: 35,
-        alignItems: 'center',
-        borderWidth: 2,
-        borderColor: 'black',
-        borderStyle: 'solid',  
-    },
-    codeTextInput: {
-        borderWidth: 2,
-        borderColor: 'black',
-        borderStyle: 'solid',
-        height: 40,
-        width: 200,
-        marginTop: 30,
-        marginBottom: 20,
-        padding: 10,
-    },
-    button: {
-        width: 50,
-        height: 50,
-    },
-    image: {
-        width: '100%',
-        height: '100%',
-        position: 'absolute',
-    },
-    titleText: {
-        fontSize: 30,
-        fontStyle: 'italic'
-    }
-});
\ No newline at end of file
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index a03a84a..67ae101 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -4,11 +4,17 @@ import {useTranslation} from "react-i18next";
 import { useState } from "react";
 import { TextsStyles } from "../../styles/TextsStyles";
 import ModalJoinQuiz from "../../components/ModalJoinQuiz";
+import MenuButton from "../../components/buttons/MenuButton";
+import {NavigationProp} from "@react-navigation/native";
 
 interface Props {
-    navigation: any;
+    navigation: NavigationProp<any>;
 }
 
+/**
+ * HomeChild : Enfant de l'écran Home, il contient le menu principal
+ * @param navigation - navigation
+ */
 export default function HomeChild({navigation}: Props) {
     const [modalVisible, setModalVisible] = useState(false);
     const {t} = useTranslation();
@@ -23,15 +29,15 @@ export default function HomeChild({navigation}: Props) {
 
     return (
         <View style={styles.containerGlobal}>
-            <View style={styles.containerAction}>
-                <Image source={require('../../assets/ImageJoinQuiz.png')} style={styles.image}/>
-                <DefaultButton text={t("app.screens.home.codeQuiz")} handleButtonPressed={handleButtonJoinPressed} buttonStyle={styles.button}/>
+            <View style={styles.imageContainer}>
+                <Image source={require('../../assets/TitleApp.png')} style={styles.image} />
             </View>
-            <View style={styles.containerAction}>
-                <Image source={require('../../assets/ImageGenerateQuiz.png')} style={styles.image}/>
-                <DefaultButton text={t("app.screens.home.createQuiz")} handleButtonPressed={handleButtonGeneratePressed} buttonStyle={styles.button}/>
+            <View style={styles.buttonContainer}>
+                <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonJoinPressed}/>
+                <MenuButton text={"PLAY A GAME"} handleButtonPressed={handleButtonGeneratePressed}/>
+                <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonJoinPressed}/>
             </View>
-            <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
+             <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
         </View>
     );
 }
@@ -41,30 +47,25 @@ const styles = StyleSheet.create({
         display: 'flex',
         width: '100%',
         height: '100%',
-        justifyContent: 'space-around',
+        justifyContent: 'flex-start',
         alignItems: 'center',
     },
-    containerAction: {
-        backgroundColor: '#F3F3F3',
-        width: '90%',
-        height: '45%',
-        padding: '8%',
-        borderRadius: 40,
-        shadowColor: '#171717',
-        shadowOffset: { width: 0, height: 4 },
-        shadowOpacity: 0.2,
-        shadowRadius: 3,
-        elevation: 5,
-    },
     image: {
-        height: '60%',
-        width: '100%',
-        borderTopLeftRadius: 40,
-        borderTopRightRadius: 40,
     },
     button: {
         borderRadius: 40,
         height: '35%',
         marginTop: '5%'
     },
+    imageContainer: {
+        display: 'flex',
+        alignItems: 'center',
+        marginTop: '15%',
+        marginBottom: '35%',
+    },
+    buttonContainer: {
+        display: 'flex',
+        flexDirection: 'column',
+        gap: '7%',
+    }
 });
\ No newline at end of file
diff --git a/templates/TemplateMenu.tsx b/templates/TemplateMenu.tsx
new file mode 100644
index 0000000..ee54727
--- /dev/null
+++ b/templates/TemplateMenu.tsx
@@ -0,0 +1,45 @@
+import {ImageBackground, Text, View, StyleSheet, SafeAreaView} from "react-native";
+import HeaderNavigation from "../screens/Home/HeaderNavigation";
+import {NavigationProp} from "@react-navigation/native";
+
+interface Props{
+    children: React.ReactNode
+    navigation: NavigationProp<any>;
+    headerNavigation: boolean;
+}
+
+/**
+ * TemplateMenu : Template du menu principal
+ * @param children - Contenu du menu
+ * @param navigation - Navigation
+ * @param headerNavigation - Si le menu est en haut de page
+ */
+export default function TemplateMenu({children, navigation, headerNavigation}: Props) {
+    return (
+        <View style={styles.container}>
+
+            <ImageBackground source={require('../assets/MenuBackground.png')} style={styles.image}>
+                <SafeAreaView>
+                    {headerNavigation && <HeaderNavigation navigation={navigation}/>}
+                <View style={styles.container}>
+                    {children}
+                </View>
+                </SafeAreaView>
+            </ImageBackground>
+
+        </View>
+    );
+}
+
+
+const styles = StyleSheet.create({
+    container: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+    },
+    image: {
+        height: '100%',
+        width: '100%',
+    }
+});
\ No newline at end of file
-- 
GitLab


From 8f3dab7a83af8a3604b04eaca38e4e72049c684c Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 29 Nov 2024 14:23:12 +0100
Subject: [PATCH 031/283] fix: push des images

---
 assets/GoBackNavigation.png | Bin 0 -> 390 bytes
 assets/MenuBackground.png   | Bin 0 -> 9992 bytes
 assets/TitleApp.png         | Bin 0 -> 18261 bytes
 3 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 assets/GoBackNavigation.png
 create mode 100644 assets/MenuBackground.png
 create mode 100644 assets/TitleApp.png

diff --git a/assets/GoBackNavigation.png b/assets/GoBackNavigation.png
new file mode 100644
index 0000000000000000000000000000000000000000..6ce5f9c1812181299641b7ecf871b5f404a0d05f
GIT binary patch
literal 390
zcmeAS@N?(olHy`uVBq!ia0vp^B0#Ln!3HF!eAAKuQk(@Ik;M!Q+`=Ht$S`XTNRY8O
z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBIcZN9$B+ufwbu@E9x@PNd+^^?<Vv^lj>f(P
z%wHa`?P`=>0pv()STsmFn!n(X6XEYN%oWu2y}U=oe#wPpH3Cj?a*8U)Z+qC6SM_|I
zAh6c*pt<ET6^G{i>o4(}Bv<}ez<Sy8vx9XRtCev11xDvfJAp<=e7nSBv>|Om=S@fc
zHF95$oJn8^V`biGB*FN*apDH1o{m((6R#s>-f;Kz8gsGhePdl(*k*A2<31+onyq3A
zUS}_7optSwy=UK+vEM%+E8_EQDbIT5bOWU*J59k0uOj(e&R$hxSi8P`-ip0R)eFv+
za|xI3{wlHJ_ue-hpRC&5LUexa?d1*iVBImZG}z|om52b2aJvlGmk;h2q-jpuf64o*
g=zNt)_r5X5em~KovSe}}FxVJ8UHx3vIVCg!0H<q}O#lD@

literal 0
HcmV?d00001

diff --git a/assets/MenuBackground.png b/assets/MenuBackground.png
new file mode 100644
index 0000000000000000000000000000000000000000..7e9ece3d28dbf3b8b4e92329d3e6486d13561184
GIT binary patch
literal 9992
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

literal 0
HcmV?d00001

diff --git a/assets/TitleApp.png b/assets/TitleApp.png
new file mode 100644
index 0000000000000000000000000000000000000000..40dba7c972a9121502a2e3fa6bac3af9072cea51
GIT binary patch
literal 18261
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
IhLu<BpSU?IEdT%j

literal 0
HcmV?d00001

-- 
GitLab


From fc3522e5ed4748076f3d487d562e02ae0eff6bf5 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sat, 30 Nov 2024 14:45:33 +0100
Subject: [PATCH 032/283] style: style home

---
 screens/Home/HomeChild.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 67ae101..3718b10 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -34,7 +34,7 @@ export default function HomeChild({navigation}: Props) {
             </View>
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonJoinPressed}/>
-                <MenuButton text={"PLAY A GAME"} handleButtonPressed={handleButtonGeneratePressed}/>
+                <MenuButton text={"PLAY A QUIZ"} handleButtonPressed={handleButtonGeneratePressed}/>
                 <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonJoinPressed}/>
             </View>
              <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
@@ -64,8 +64,10 @@ const styles = StyleSheet.create({
         marginBottom: '35%',
     },
     buttonContainer: {
+        width: '100%',
         display: 'flex',
         flexDirection: 'column',
-        gap: '7%',
+        paddingLeft: '8%',
+        gap: '9%',
     }
 });
\ No newline at end of file
-- 
GitLab


From 78783a3e8963ae6d7d656b86c015fa41ac117e7d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sat, 30 Nov 2024 15:49:03 +0100
Subject: [PATCH 033/283] feat: SelectMode box

---
 components/PlayQuiz/PlayQuizMod.tsx |  9 ++++
 components/PlayQuiz/SelectMode.tsx  | 74 +++++++++++++++++++++++++++++
 models/SelectModeType.ts            |  1 +
 routes/StackNavigator.tsx           |  2 +
 screens/Home/HomeChild.tsx          |  2 +-
 screens/PlayQuiz/PlayQuiz.tsx       | 31 ++++++++++++
 screens/PlayQuiz/PlayQuizChild.tsx  | 36 ++++++++++++++
 7 files changed, 154 insertions(+), 1 deletion(-)
 create mode 100644 components/PlayQuiz/PlayQuizMod.tsx
 create mode 100644 components/PlayQuiz/SelectMode.tsx
 create mode 100644 models/SelectModeType.ts
 create mode 100644 screens/PlayQuiz/PlayQuiz.tsx
 create mode 100644 screens/PlayQuiz/PlayQuizChild.tsx

diff --git a/components/PlayQuiz/PlayQuizMod.tsx b/components/PlayQuiz/PlayQuizMod.tsx
new file mode 100644
index 0000000..803b117
--- /dev/null
+++ b/components/PlayQuiz/PlayQuizMod.tsx
@@ -0,0 +1,9 @@
+import {View, Text} from "react-native";
+
+export default function PlayQuizMod() {
+    return (
+        <View>
+            <Text>PlayQuizMod</Text>
+        </View>
+    )
+}
\ No newline at end of file
diff --git a/components/PlayQuiz/SelectMode.tsx b/components/PlayQuiz/SelectMode.tsx
new file mode 100644
index 0000000..17a6535
--- /dev/null
+++ b/components/PlayQuiz/SelectMode.tsx
@@ -0,0 +1,74 @@
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import { SelectModeType } from "../../models/SelectModeType";
+
+interface Props {
+    mode: SelectModeType;
+    setMode: (mode: SelectModeType) => void;
+}
+
+export default function SelectMode({ mode, setMode }: Props) {
+    return (
+        <View style={styles.container}>
+            <View style={styles.buttonContainer}>
+                <TouchableOpacity onPress={() => setMode("play")} style={{marginLeft: '10%'}}>
+                    <Text style={[styles.text, mode === "play" && styles.activeText]}>Play a quiz</Text>
+                </TouchableOpacity>
+                <View style={[styles.bar, mode === "play" ? styles.activeBar : styles.inactiveBar]} />
+            </View>
+
+            <View style={styles.buttonContainer}>
+                <TouchableOpacity onPress={() => setMode("join")} style={{marginRight: '10%'}}>
+                    <Text style={[styles.text, mode === "join" && styles.activeText]}>Join a quiz</Text>
+                </TouchableOpacity>
+                <View style={[styles.bar, mode === "join" ? styles.activeBar : styles.inactiveBar]} />
+            </View>
+
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: 'flex',
+        width: '100%',
+        height: '10%',
+        flexDirection: 'row',
+        backgroundColor: '#f3f3f3',
+        borderRadius: 10,
+        justifyContent: 'space-around',
+        alignItems: 'center',
+        // Ombre pour Android
+        elevation: 5,
+        // Ombre pour iOS
+        shadowColor: '#000',
+        shadowOffset: { width: 0, height: 4 }, // Décalage de l'ombre en bas
+        shadowOpacity: 0.25, // Opacité de l'ombre
+        shadowRadius: 3.84, // Flou de l'ombre
+    },
+    buttonContainer: {
+        display: 'flex',
+        flexDirection: 'column',
+        width: '40%',
+        alignItems: 'center',
+        gap: "5%",
+    },
+    text: {
+        fontSize: 25,
+        color: '#bebebe',
+    },
+    activeText: {
+        color: '#2ec7ff',
+    },
+    bar: {
+        width: '100%',
+        height: 4,
+        marginTop: 4,
+        borderRadius: 10,
+    },
+    activeBar: {
+        backgroundColor: '#2ec7ff', // Couleur pour le bouton actif
+    },
+    inactiveBar: {
+        backgroundColor: '#bebebe', // Couleur grise pour les boutons inactifs
+    },
+});
diff --git a/models/SelectModeType.ts b/models/SelectModeType.ts
new file mode 100644
index 0000000..b664180
--- /dev/null
+++ b/models/SelectModeType.ts
@@ -0,0 +1 @@
+export type SelectModeType = "play" | "join";
\ No newline at end of file
diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index eeae3a4..0283a97 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -4,6 +4,7 @@ import Home from "../screens/Home/Home";
 import GenerateQuiz from "../screens/GenerateQuiz/GenerateQuiz";
 import EndQuiz from "../screens/EndQuiz/EndQuiz";
 import PlayingQuiz from "../screens/PlayingQuiz/PlayingQuiz";
+import PlayQuiz from "../screens/PlayQuiz/PlayQuiz";
 
 const Stack = createNativeStackNavigator();
 
@@ -14,6 +15,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="Home" component={Home} options={{ headerShown: false }}/>
                 <Stack.Screen name="CreateQuiz" component={GenerateQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="PlayingQuiz" component={PlayingQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="PlayQuiz" component={PlayQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="EndQuiz" component={EndQuiz} options={{ headerShown: false }}/>
             </Stack.Navigator>
         </NavigationContainer>
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 3718b10..a750275 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -24,7 +24,7 @@ export default function HomeChild({navigation}: Props) {
     }
 
     const handleButtonGeneratePressed = () => {
-        navigation.navigate("CreateQuiz");
+        navigation.navigate("PlayQuiz");
     }
 
     return (
diff --git a/screens/PlayQuiz/PlayQuiz.tsx b/screens/PlayQuiz/PlayQuiz.tsx
new file mode 100644
index 0000000..25fe9f8
--- /dev/null
+++ b/screens/PlayQuiz/PlayQuiz.tsx
@@ -0,0 +1,31 @@
+import {NavigationProp} from "@react-navigation/native";
+import TemplateMenu from "../../templates/TemplateMenu";
+import {StyleSheet, View} from "react-native";
+import HomeChild from "../Home/HomeChild";
+import React from "react";
+import PlayQuizChild from "./PlayQuizChild";
+
+interface Props{
+    navigation: NavigationProp<any>
+}
+export default function PlayQuiz({navigation}: Props) {
+
+    return (
+        <View style={styles.containerGlobal}>
+            <TemplateMenu navigation={navigation} headerNavigation={true}>
+                <View>
+                    <PlayQuizChild navigation={navigation}/>
+                </View>
+            </TemplateMenu>
+        </View>
+    )
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        flexDirection: 'column',
+    },
+});
\ No newline at end of file
diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
new file mode 100644
index 0000000..5227194
--- /dev/null
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -0,0 +1,36 @@
+import {Text, View, StyleSheet} from "react-native";
+import {NavigationProp} from "@react-navigation/native";
+import PlayQuizMod from "../../components/PlayQuiz/PlayQuizMod";
+import SelectMode from "../../components/PlayQuiz/SelectMode";
+import {useState} from "react";
+import {SelectModeType} from "../../models/SelectModeType";
+
+interface Props {
+    navigation: NavigationProp<any>
+}
+
+export default function PlayQuizChild({navigation}: Props){
+ const [mode, setMode] = useState<SelectModeType>("play");
+
+    return (
+        <View style={styles.containerGlobal}>
+            <View style={styles.contentContainer}>
+                <SelectMode mode={mode} setMode={setMode}/>
+            </View>
+        </View>
+    )
+}
+const styles = StyleSheet.create({
+    containerGlobal: {
+        width: '100%',
+        height: '100%',
+        alignItems: 'center',
+        justifyContent: 'center',
+    },
+    contentContainer: {
+        display: 'flex',
+        width: '90%',
+        height: '100%',
+        flexDirection: 'column',
+    },
+});
\ No newline at end of file
-- 
GitLab


From f6000310767ec1362a6a4863c2b41d5b107ec21d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sat, 30 Nov 2024 16:43:19 +0100
Subject: [PATCH 034/283] feat: SelectListBox

---
 components/PlayQuiz/SelectListBox.tsx | 78 +++++++++++++++++++++++++++
 package-lock.json                     |  7 +++
 package.json                          |  1 +
 screens/PlayQuiz/PlayQuizChild.tsx    |  3 ++
 4 files changed, 89 insertions(+)
 create mode 100644 components/PlayQuiz/SelectListBox.tsx

diff --git a/components/PlayQuiz/SelectListBox.tsx b/components/PlayQuiz/SelectListBox.tsx
new file mode 100644
index 0000000..791be54
--- /dev/null
+++ b/components/PlayQuiz/SelectListBox.tsx
@@ -0,0 +1,78 @@
+import { View, StyleSheet, Text } from "react-native";
+import { SelectList } from "react-native-dropdown-select-list";
+import React from "react";
+
+export default function SelectListBox() {
+    const [selected, setSelected] = React.useState("");
+
+    const data = [
+        { key: "1", value: "Mobiles", disabled: true },
+        { key: "2", value: "Appliances" },
+        { key: "3", value: "Cameras" },
+        { key: "4", value: "Computers", disabled: true },
+        { key: "5", value: "Vegetables" },
+        { key: "6", value: "Diary Products" },
+        { key: "7", value: "Drinks" },
+    ];
+
+    return (
+        <View style={styles.container}>
+            <View style={styles.dropdownContainer}>
+                <Text style={styles.title}>Choose a Category</Text> {/* Ajout du titre */}
+                <SelectList
+                    setSelected={(val: any) => setSelected(val)}
+                    data={data}
+                    save="value"
+                    dropdownStyles={styles.dropdownStyles} // Applique un style personnalisé au menu déroulant
+                    boxStyles={styles.boxStyles} // Applique un style personnalisé au champ de saisie
+                    inputStyles={styles.inputStyles}
+                />
+            </View>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        paddingTop: 50,
+        alignItems: "center",
+    },
+    dropdownContainer: {
+        width: "90%",
+    },
+    title: {
+        fontSize: 20,
+        fontWeight: "bold", // Met le texte en gras
+        marginBottom: 5, // Ajoute un espace entre le titre et la boîte déroulante
+        color: "#333", // Couleur du texte
+        textAlign: "left", // Aligne le texte à gauche
+    },
+    dropdownStyles: {
+        position: "absolute", // Rend le dropdown flottant
+        width: "100%", // Ajustez la largeur du dropdown
+        top: 40, // Ajustez la position verticale
+        zIndex: 2, // Assure que le menu apparaît au-dessus
+        backgroundColor: "white", // Ajoute une couleur de fond
+        borderColor: "black", // Optionnel : bordure de couleur
+        borderWidth: 1, // Optionnel : épaisseur de la bordure
+        borderRadius: 8, // Optionnel : coins arrondis
+    },
+    boxStyles: {
+        backgroundColor: "white",
+        borderColor: "#bebebe",
+        borderWidth: 2,
+        borderRadius: 8,
+        height: 70, // Hauteur augmentée
+        alignItems: "center",
+        elevation: 5,
+        // Ombre pour iOS
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 4 }, // Décalage de l'ombre en bas
+        shadowOpacity: 0.25, // Opacité de l'ombre
+        shadowRadius: 3.84, // Flou de l'ombre
+    },
+    inputStyles: {
+        fontSize: 18, // Taille du texte augmentée
+        color: "black", // Couleur du texte
+    },
+});
diff --git a/package-lock.json b/package-lock.json
index 393cf26..2160b04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,6 +19,7 @@
         "react": "^18.3.1",
         "react-i18next": "^15.1.1",
         "react-native": "^0.76.2",
+        "react-native-dropdown-select-list": "^2.0.5",
         "react-native-safe-area-context": "^4.12.0",
         "react-native-screens": "~4.1.0"
       },
@@ -9245,6 +9246,12 @@
         }
       }
     },
+    "node_modules/react-native-dropdown-select-list": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/react-native-dropdown-select-list/-/react-native-dropdown-select-list-2.0.5.tgz",
+      "integrity": "sha512-TepbcagQVUMB6nLuIlVU2ghRpQHAECOeZWe8K04ymW6NqbKbxuczZSDFfdCiABiiQ2dFD+8Dz65y4K7/uUEqGg==",
+      "license": "MIT"
+    },
     "node_modules/react-native-safe-area-context": {
       "version": "4.12.0",
       "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.12.0.tgz",
diff --git a/package.json b/package.json
index 1bd89c5..a1e4bf5 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
     "react": "^18.3.1",
     "react-i18next": "^15.1.1",
     "react-native": "^0.76.2",
+    "react-native-dropdown-select-list": "^2.0.5",
     "react-native-safe-area-context": "^4.12.0",
     "react-native-screens": "~4.1.0"
   },
diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
index 5227194..e85a6a0 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -4,6 +4,7 @@ import PlayQuizMod from "../../components/PlayQuiz/PlayQuizMod";
 import SelectMode from "../../components/PlayQuiz/SelectMode";
 import {useState} from "react";
 import {SelectModeType} from "../../models/SelectModeType";
+import SelectListBox from "../../components/PlayQuiz/SelectListBox";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -16,6 +17,8 @@ export default function PlayQuizChild({navigation}: Props){
         <View style={styles.containerGlobal}>
             <View style={styles.contentContainer}>
                 <SelectMode mode={mode} setMode={setMode}/>
+                <SelectListBox/>
+                <SelectListBox/>
             </View>
         </View>
     )
-- 
GitLab


From 15aa018067c237f741aa9ae8a3ff1263a9704822 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 1 Dec 2024 15:16:37 +0100
Subject: [PATCH 035/283] feat: input + play button

---
 components/PlayQuiz/InputPlayQuiz.tsx | 48 +++++++++++++++++++++++++++
 components/PlayQuiz/PlayButton.tsx    | 32 ++++++++++++++++++
 components/PlayQuiz/SelectListBox.tsx |  3 +-
 screens/PlayQuiz/PlayQuizChild.tsx    | 23 ++++++++-----
 4 files changed, 95 insertions(+), 11 deletions(-)
 create mode 100644 components/PlayQuiz/InputPlayQuiz.tsx
 create mode 100644 components/PlayQuiz/PlayButton.tsx

diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
new file mode 100644
index 0000000..a95071f
--- /dev/null
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -0,0 +1,48 @@
+import React from "react";
+import { TextInput, View, StyleSheet, Text } from "react-native";
+
+export default function InputPlayQuiz() {
+    return (
+        <View style={styles.container}>
+            <Text style={styles.title}>Choose a Category</Text> {/* Ajout du titre */}
+            <TextInput
+                style={styles.input}
+                placeholderTextColor="#bebebe"
+                keyboardType="numeric"
+                onChangeText={(text) => console.log(text)}
+            />
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        flexDirection: "column",
+        alignItems: "flex-start", // Aligne les éléments à gauche
+        width: "100%", // S'assure que le conteneur prend toute la largeur
+    },
+    input: {
+        width: "100%",
+        height: 70, // Hauteur augmentée comme dans boxStyles
+        backgroundColor: "white", // Fond blanc comme dans boxStyles
+        borderColor: "#2ec7ff",
+        borderWidth: 3,
+        borderRadius: 8,
+        paddingLeft: 10, // Espacement à gauche pour le texte
+        elevation: 5, // Ombre pour Android
+        // Ombre pour iOS
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 4 }, // Décalage de l'ombre en bas
+        shadowOpacity: 0.25, // Opacité de l'ombre
+        shadowRadius: 3.84, // Flou de l'ombre
+    },
+    title: {
+        fontSize: 20,
+        fontWeight: "bold", // Met le texte en gras
+        marginBottom: 5, // Ajoute un espace entre le titre et la boîte déroulante
+        color: "#333", // Couleur du texte
+        textAlign: "left", // Aligne le texte à gauche
+        width: "100%", // S'assure que le texte utilise toute la largeur disponible
+    },
+});
diff --git a/components/PlayQuiz/PlayButton.tsx b/components/PlayQuiz/PlayButton.tsx
new file mode 100644
index 0000000..6411702
--- /dev/null
+++ b/components/PlayQuiz/PlayButton.tsx
@@ -0,0 +1,32 @@
+import {View, Text, StyleSheet, TouchableOpacity} from "react-native";
+import {NavigationProp} from "@react-navigation/native";
+
+interface Props {
+    onPress: () => void
+    text: string
+}
+export default function PlayButton({onPress, text} : Props) {
+    return (
+        <TouchableOpacity style={styles.container} onPress={onPress}>
+            <Text style={styles.text}>{text}</Text>
+        </TouchableOpacity>
+    );
+}
+
+const styles = StyleSheet.create({
+
+    container: {
+        width: '100%',
+        height: '10%',
+        alignItems: 'center',
+        justifyContent: 'center',
+        backgroundColor: '#2b73fe',
+        borderRadius: 10,
+    },
+    text: {
+        color: 'white',
+        fontSize: 28,
+        fontWeight: 'bold',
+    }
+
+});
\ No newline at end of file
diff --git a/components/PlayQuiz/SelectListBox.tsx b/components/PlayQuiz/SelectListBox.tsx
index 791be54..a3e9bfe 100644
--- a/components/PlayQuiz/SelectListBox.tsx
+++ b/components/PlayQuiz/SelectListBox.tsx
@@ -34,11 +34,10 @@ export default function SelectListBox() {
 
 const styles = StyleSheet.create({
     container: {
-        paddingTop: 50,
         alignItems: "center",
     },
     dropdownContainer: {
-        width: "90%",
+        width: "100%",
     },
     title: {
         fontSize: 20,
diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
index e85a6a0..ef87046 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -1,10 +1,11 @@
-import {Text, View, StyleSheet} from "react-native";
+import {Text, View, StyleSheet, TouchableWithoutFeedback, Keyboard} from "react-native";
 import {NavigationProp} from "@react-navigation/native";
-import PlayQuizMod from "../../components/PlayQuiz/PlayQuizMod";
 import SelectMode from "../../components/PlayQuiz/SelectMode";
 import {useState} from "react";
 import {SelectModeType} from "../../models/SelectModeType";
 import SelectListBox from "../../components/PlayQuiz/SelectListBox";
+import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import PlayButton from "../../components/PlayQuiz/PlayButton";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -14,13 +15,17 @@ export default function PlayQuizChild({navigation}: Props){
  const [mode, setMode] = useState<SelectModeType>("play");
 
     return (
-        <View style={styles.containerGlobal}>
-            <View style={styles.contentContainer}>
-                <SelectMode mode={mode} setMode={setMode}/>
-                <SelectListBox/>
-                <SelectListBox/>
+        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
+            <View style={styles.containerGlobal}>
+                <View style={styles.contentContainer}>
+                    <SelectMode mode={mode} setMode={setMode}/>
+                    <SelectListBox/>
+                    <SelectListBox/>
+                    <InputPlayQuiz />
+                    <PlayButton onPress={() =>  {}} text="PLAY"/>
+                </View>
             </View>
-        </View>
+        </TouchableWithoutFeedback>
     )
 }
 const styles = StyleSheet.create({
@@ -32,7 +37,7 @@ const styles = StyleSheet.create({
     },
     contentContainer: {
         display: 'flex',
-        width: '90%',
+        width: '95%',
         height: '100%',
         flexDirection: 'column',
     },
-- 
GitLab


From 3c5a07dd8424e339991c0ae240bfdc5da049fd3f Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 1 Dec 2024 17:47:12 +0100
Subject: [PATCH 036/283] feat: PlayQuizGenerateQuiz

---
 components/PlayQuiz/InputPlayQuiz.tsx     |  8 ++-
 components/PlayQuiz/PlayButton.tsx        |  2 +-
 components/PlayQuiz/SelectListBox.tsx     | 21 +++----
 screens/PlayQuiz/PlayQuizChild.tsx        |  6 +-
 screens/PlayQuiz/PlayQuizGenerateQuiz.tsx | 77 +++++++++++++++++++++++
 5 files changed, 95 insertions(+), 19 deletions(-)
 create mode 100644 screens/PlayQuiz/PlayQuizGenerateQuiz.tsx

diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
index a95071f..318524a 100644
--- a/components/PlayQuiz/InputPlayQuiz.tsx
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -1,10 +1,14 @@
 import React from "react";
 import { TextInput, View, StyleSheet, Text } from "react-native";
 
-export default function InputPlayQuiz() {
+interface Props {
+    title: string,
+    setText: (text: string) => void,
+}
+export default function InputPlayQuiz({title, setText}:Props) {
     return (
         <View style={styles.container}>
-            <Text style={styles.title}>Choose a Category</Text> {/* Ajout du titre */}
+            <Text style={styles.title}>{title}</Text> {/* Ajout du titre */}
             <TextInput
                 style={styles.input}
                 placeholderTextColor="#bebebe"
diff --git a/components/PlayQuiz/PlayButton.tsx b/components/PlayQuiz/PlayButton.tsx
index 6411702..2a68248 100644
--- a/components/PlayQuiz/PlayButton.tsx
+++ b/components/PlayQuiz/PlayButton.tsx
@@ -17,7 +17,7 @@ const styles = StyleSheet.create({
 
     container: {
         width: '100%',
-        height: '10%',
+        height: 70,
         alignItems: 'center',
         justifyContent: 'center',
         backgroundColor: '#2b73fe',
diff --git a/components/PlayQuiz/SelectListBox.tsx b/components/PlayQuiz/SelectListBox.tsx
index a3e9bfe..5ce90d7 100644
--- a/components/PlayQuiz/SelectListBox.tsx
+++ b/components/PlayQuiz/SelectListBox.tsx
@@ -2,23 +2,19 @@ import { View, StyleSheet, Text } from "react-native";
 import { SelectList } from "react-native-dropdown-select-list";
 import React from "react";
 
-export default function SelectListBox() {
-    const [selected, setSelected] = React.useState("");
+interface Props {
+    data: any,
+    setSelected: (val: string) => void,
+    title: string,
 
-    const data = [
-        { key: "1", value: "Mobiles", disabled: true },
-        { key: "2", value: "Appliances" },
-        { key: "3", value: "Cameras" },
-        { key: "4", value: "Computers", disabled: true },
-        { key: "5", value: "Vegetables" },
-        { key: "6", value: "Diary Products" },
-        { key: "7", value: "Drinks" },
-    ];
+}
+
+export default function SelectListBox({data, setSelected, title} : Props) {
 
     return (
         <View style={styles.container}>
             <View style={styles.dropdownContainer}>
-                <Text style={styles.title}>Choose a Category</Text> {/* Ajout du titre */}
+                <Text style={styles.title}>{title}</Text> {/* Ajout du titre */}
                 <SelectList
                     setSelected={(val: any) => setSelected(val)}
                     data={data}
@@ -35,6 +31,7 @@ export default function SelectListBox() {
 const styles = StyleSheet.create({
     container: {
         alignItems: "center",
+        width: '100%',
     },
     dropdownContainer: {
         width: "100%",
diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
index ef87046..f5151bd 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -6,6 +6,7 @@ import {SelectModeType} from "../../models/SelectModeType";
 import SelectListBox from "../../components/PlayQuiz/SelectListBox";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
 import PlayButton from "../../components/PlayQuiz/PlayButton";
+import PlayQuizGenerateQuiz from "./PlayQuizGenerateQuiz";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -19,10 +20,7 @@ export default function PlayQuizChild({navigation}: Props){
             <View style={styles.containerGlobal}>
                 <View style={styles.contentContainer}>
                     <SelectMode mode={mode} setMode={setMode}/>
-                    <SelectListBox/>
-                    <SelectListBox/>
-                    <InputPlayQuiz />
-                    <PlayButton onPress={() =>  {}} text="PLAY"/>
+                    <PlayQuizGenerateQuiz />
                 </View>
             </View>
         </TouchableWithoutFeedback>
diff --git a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
new file mode 100644
index 0000000..438202c
--- /dev/null
+++ b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -0,0 +1,77 @@
+import { Text,View, StyleSheet } from "react-native";
+import SelectListBox from "../../components/PlayQuiz/SelectListBox";
+import React from "react";
+import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import PlayButton from "../../components/PlayQuiz/PlayButton";
+
+const difficulty = [
+    { key: "easy", value: "Easy" },
+    { key: "medium", value: "Medium" },
+    { key: "hard", value: "Hard" },
+];
+
+const categories = [
+    { key: "9", value: "General Knowledge"},
+    { key: "10", value: "Entertainment: Books" },
+    { key: "11", value: "Entertainment: Film" },
+    { key: "12", value: "Entertainment: Music"},
+    { key: "13", value: "Entertainment: Musicals & Theatres" },
+    { key: "14", value: "Entertainment: Television" },
+    { key: "15", value: "Entertainment: Video Games" },
+    { key: "16", value: "Entertainment: Board Games" },
+    { key: "17", value: "Science & Nature" },
+    { key: "18", value: "Science: Computers" },
+    { key: "19", value: "Science: Mathematics" },
+    { key: "20", value: "Mythology" },
+    { key: "21", value: "Sports" },
+    { key: "22", value: "Geography" },
+];
+
+export default function PlayQuizGenerateQuiz() {
+    const [difficutlyChoose, setDifficutlyChoose] = React.useState("");
+    const [categoryChoose, setCategoryChoose] = React.useState("");
+
+    const handlePlayButtonPress = () => {
+        console.log("Play button pressed");
+    };
+
+    return (
+        <View style={styles.container}>
+            <View style={styles.contentContainer}>
+                <View style={styles.fieldContainer}>
+                    <SelectListBox title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
+                    <SelectListBox title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
+                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={() => {}} />
+                </View>
+                <View style={styles.buttonPlayContainer}>
+                    <PlayButton onPress={handlePlayButtonPress} text={"PLAY"} />
+                </View>
+            </View>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        width: "100%",
+        height: "75%",
+        justifyContent: "space-between",
+    },
+    contentContainer: {
+        flex: 1, // Prend toute la hauteur disponible
+        flexDirection: "column",
+        justifyContent: "space-between",
+    },
+    fieldContainer: {
+        width: "100%",
+        flexDirection: "column",
+        justifyContent: "space-between",
+        marginTop: 20,
+        gap: 20,
+    },
+    buttonPlayContainer: {
+        alignItems: "center",
+        paddingVertical: 20,
+    },
+});
-- 
GitLab


From a739f04f20bd181e6406270716bb6260d6f8659d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 2 Dec 2024 21:36:31 +0100
Subject: [PATCH 037/283] feat: PlayQuizJoinQuiz

---
 components/PlayQuiz/AboutAQuiz.tsx    | 55 +++++++++++++++++++++++++++
 components/PlayQuiz/InputPlayQuiz.tsx | 14 ++++---
 screens/PlayQuiz/PlayQuizChild.tsx    |  9 ++++-
 screens/PlayQuiz/PlayQuizJoinQuiz.tsx | 54 ++++++++++++++++++++++++++
 4 files changed, 125 insertions(+), 7 deletions(-)
 create mode 100644 components/PlayQuiz/AboutAQuiz.tsx
 create mode 100644 screens/PlayQuiz/PlayQuizJoinQuiz.tsx

diff --git a/components/PlayQuiz/AboutAQuiz.tsx b/components/PlayQuiz/AboutAQuiz.tsx
new file mode 100644
index 0000000..1e2249a
--- /dev/null
+++ b/components/PlayQuiz/AboutAQuiz.tsx
@@ -0,0 +1,55 @@
+import React from "react";
+import { View, Text, StyleSheet } from "react-native";
+import QuizModel from "../../models/QuizModel";
+
+interface Props {
+    quiz?: QuizModel;
+}
+export default function AboutAQuiz({quiz} : Props) {
+    return (
+        <View style={styles.container}>
+            <Text style={styles.title}>About this quiz</Text>
+            <View style={styles.separator} />
+            <View style={styles.infoContainer}>
+                <Text style={styles.text}>Category : {quiz ? quiz.category : "?"}</Text>
+                <Text style={styles.text}>Question : {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
+                <Text style={styles.text}>Score : {quiz ? quiz.score : "?"}</Text>
+            </View>
+
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        backgroundColor: "white", // Fond blanc
+        borderRadius: 10, // Coins arrondis
+        padding: 20, // Espacement intérieur
+        shadowColor: "#000", // Couleur de l'ombre
+        shadowOffset: { width: 0, height: 4 }, // Décalage de l'ombre
+        shadowOpacity: 0.25, // Opacité de l'ombre
+        shadowRadius: 3.84, // Flou de l'ombre
+        elevation: 5, // Ombre pour Android
+        marginVertical: 10, // Espacement vertical
+    },
+    title: {
+        fontSize: 18,
+        fontWeight: "bold",
+        marginBottom: 10, // Espacement entre le titre et le séparateur
+    },
+    separator: {
+        height: 3, // Épaisseur de la ligne
+        backgroundColor: "#ddd", // Couleur de la ligne
+        marginBottom: 15, // Espacement entre la ligne et le contenu
+    },
+    text: {
+        fontSize: 16,
+        fontWeight: "bold",
+        marginBottom: 10, // Espacement entre la catégorie et les informations
+    },
+    infoContainer: {
+        flexDirection: "column", // Aligne les éléments horizontalement
+        justifyContent: "space-between", // Aligne les éléments verticalement
+        gap: 10, // Espacement entre les informations
+    },
+});
diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
index 318524a..0f6d7e0 100644
--- a/components/PlayQuiz/InputPlayQuiz.tsx
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -2,18 +2,22 @@ import React from "react";
 import { TextInput, View, StyleSheet, Text } from "react-native";
 
 interface Props {
-    title: string,
-    setText: (text: string) => void,
+    title?: string;
+    setText: (text: string) => void;
+    noTitle?: boolean;
+    placeholder?: string;
 }
-export default function InputPlayQuiz({title, setText}:Props) {
+
+export default function InputPlayQuiz({ title, setText, noTitle, placeholder }: Props) {
     return (
         <View style={styles.container}>
-            <Text style={styles.title}>{title}</Text> {/* Ajout du titre */}
+            {!noTitle && title && <Text style={styles.title}>{title}</Text>}
             <TextInput
                 style={styles.input}
+                placeholder={placeholder || ""}
                 placeholderTextColor="#bebebe"
                 keyboardType="numeric"
-                onChangeText={(text) => console.log(text)}
+                onChangeText={(text) => setText(text)}
             />
         </View>
     );
diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
index f5151bd..ffd4f08 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -1,12 +1,13 @@
 import {Text, View, StyleSheet, TouchableWithoutFeedback, Keyboard} from "react-native";
 import {NavigationProp} from "@react-navigation/native";
 import SelectMode from "../../components/PlayQuiz/SelectMode";
-import {useState} from "react";
+import React, {useState} from "react";
 import {SelectModeType} from "../../models/SelectModeType";
 import SelectListBox from "../../components/PlayQuiz/SelectListBox";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
 import PlayButton from "../../components/PlayQuiz/PlayButton";
 import PlayQuizGenerateQuiz from "./PlayQuizGenerateQuiz";
+import PlayQuizJoinQuiz from "./PlayQuizJoinQuiz";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -20,7 +21,11 @@ export default function PlayQuizChild({navigation}: Props){
             <View style={styles.containerGlobal}>
                 <View style={styles.contentContainer}>
                     <SelectMode mode={mode} setMode={setMode}/>
-                    <PlayQuizGenerateQuiz />
+                    {mode === "play" ? (
+                        <PlayQuizGenerateQuiz />
+                    ) : (
+                        <PlayQuizJoinQuiz />
+                    )}
                 </View>
             </View>
         </TouchableWithoutFeedback>
diff --git a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
new file mode 100644
index 0000000..b5117f2
--- /dev/null
+++ b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -0,0 +1,54 @@
+import {StyleSheet, View} from "react-native";
+import AboutAQuiz from "../../components/PlayQuiz/AboutAQuiz";
+import PlayButton from "../../components/PlayQuiz/PlayButton";
+import React from "react";
+import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import QuizModel from "../../models/QuizModel";
+
+export default function PlayQuizJoinQuiz() {
+    const [codeQuiz, setCodeQuiz] = React.useState("");
+    const [quiz, setQuiz] = React.useState<QuizModel>();
+    const handlePlayButtonPress = () => {
+        console.log("Play button pressed");
+    };
+
+    return (
+        <View style={styles.container}>
+            <View style={styles.contentContainer}>
+                <View style={styles.fieldContainer}>
+                    <InputPlayQuiz placeholder={"Enter quiz ID"} setText={setCodeQuiz} noTitle={true}/>
+                    <AboutAQuiz />
+                </View>
+                <View style={styles.buttonPlayContainer}>
+                    <PlayButton onPress={handlePlayButtonPress} text={"PLAY"} />
+                </View>
+            </View>
+        </View>
+    );
+}
+
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        width: "100%",
+        height: "75%",
+        justifyContent: "space-between",
+    },
+    contentContainer: {
+        flex: 1, // Prend toute la hauteur disponible
+        flexDirection: "column",
+        justifyContent: "space-between",
+    },
+    fieldContainer: {
+        width: "100%",
+        flexDirection: "column",
+        justifyContent: "space-between",
+        marginTop: 20,
+        gap: 20,
+    },
+    buttonPlayContainer: {
+        alignItems: "center",
+        paddingVertical: 20,
+    },
+});
\ No newline at end of file
-- 
GitLab


From e1bff228ed2a6b8b810c7187876ee69f6339afb7 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 2 Dec 2024 22:24:36 +0100
Subject: [PATCH 038/283] feat: barre de navigation avec icon

---
 package-lock.json         | 126 +++++++++++++++++++++++++++++++++++++-
 package.json              |   4 +-
 routes/StackNavigator.tsx |   4 +-
 routes/TabNavigation.tsx  |  40 ++++++++++++
 4 files changed, 171 insertions(+), 3 deletions(-)
 create mode 100644 routes/TabNavigation.tsx

diff --git a/package-lock.json b/package-lock.json
index 393cf26..ac741d8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
       "version": "1.0.0",
       "dependencies": {
         "@react-native-picker/picker": "^2.9.0",
+        "@react-navigation/bottom-tabs": "^6.6.1",
         "@react-navigation/native": "^6.1.18",
         "@react-navigation/native-stack": "^6.11.0",
         "expo": "^52.0.8",
@@ -20,7 +21,8 @@
         "react-i18next": "^15.1.1",
         "react-native": "^0.76.2",
         "react-native-safe-area-context": "^4.12.0",
-        "react-native-screens": "~4.1.0"
+        "react-native-screens": "~4.1.0",
+        "react-native-vector-icons": "^10.2.0"
       },
       "devDependencies": {
         "@babel/core": "^7.20.0",
@@ -3836,6 +3838,24 @@
         }
       }
     },
+    "node_modules/@react-navigation/bottom-tabs": {
+      "version": "6.6.1",
+      "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.6.1.tgz",
+      "integrity": "sha512-9oD4cypEBjPuaMiu9tevWGiQ4w/d6l3HNhcJ1IjXZ24xvYDSs0mqjUcdt8SWUolCvRrYc/DmNBLlT83bk0bHTw==",
+      "license": "MIT",
+      "dependencies": {
+        "@react-navigation/elements": "^1.3.31",
+        "color": "^4.2.3",
+        "warn-once": "^0.1.0"
+      },
+      "peerDependencies": {
+        "@react-navigation/native": "^6.0.0",
+        "react": "*",
+        "react-native": "*",
+        "react-native-safe-area-context": ">= 3.0.0",
+        "react-native-screens": ">= 3.0.0"
+      }
+    },
     "node_modules/@react-navigation/core": {
       "version": "6.4.17",
       "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.17.tgz",
@@ -5035,6 +5055,19 @@
         "node": ">=6"
       }
     },
+    "node_modules/color": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
+      "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^2.0.1",
+        "color-string": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=12.5.0"
+      }
+    },
     "node_modules/color-convert": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -5053,6 +5086,16 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "license": "MIT"
     },
+    "node_modules/color-string": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+      "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
     "node_modules/combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -9269,6 +9312,72 @@
         "react-native": "*"
       }
     },
+    "node_modules/react-native-vector-icons": {
+      "version": "10.2.0",
+      "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-10.2.0.tgz",
+      "integrity": "sha512-n5HGcxUuVaTf9QJPs/W22xQpC2Z9u0nb0KgLPnVltP8vdUvOp6+R26gF55kilP/fV4eL4vsAHUqUjewppJMBOQ==",
+      "license": "MIT",
+      "dependencies": {
+        "prop-types": "^15.7.2",
+        "yargs": "^16.1.1"
+      },
+      "bin": {
+        "fa-upgrade.sh": "bin/fa-upgrade.sh",
+        "fa5-upgrade": "bin/fa5-upgrade.sh",
+        "fa6-upgrade": "bin/fa6-upgrade.sh",
+        "generate-icon": "bin/generate-icon.js"
+      }
+    },
+    "node_modules/react-native-vector-icons/node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "license": "ISC",
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "node_modules/react-native-vector-icons/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/react-native-vector-icons/node_modules/yargs": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "license": "MIT",
+      "dependencies": {
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/react-native-vector-icons/node_modules/yargs-parser": {
+      "version": "20.2.9",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": {
       "version": "0.23.1",
       "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.23.1.tgz",
@@ -9944,6 +10053,21 @@
         "node": ">= 5.10.0"
       }
     },
+    "node_modules/simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+      "license": "MIT",
+      "dependencies": {
+        "is-arrayish": "^0.3.1"
+      }
+    },
+    "node_modules/simple-swizzle/node_modules/is-arrayish": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+      "license": "MIT"
+    },
     "node_modules/sisteransi": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
diff --git a/package.json b/package.json
index 1bd89c5..d6ad328 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "@react-native-picker/picker": "^2.9.0",
+    "@react-navigation/bottom-tabs": "^6.6.1",
     "@react-navigation/native": "^6.1.18",
     "@react-navigation/native-stack": "^6.11.0",
     "expo": "^52.0.8",
@@ -21,7 +22,8 @@
     "react-i18next": "^15.1.1",
     "react-native": "^0.76.2",
     "react-native-safe-area-context": "^4.12.0",
-    "react-native-screens": "~4.1.0"
+    "react-native-screens": "~4.1.0",
+    "react-native-vector-icons": "^10.2.0"
   },
   "devDependencies": {
     "@babel/core": "^7.20.0",
diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index eeae3a4..799e70c 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -4,13 +4,15 @@ import Home from "../screens/Home/Home";
 import GenerateQuiz from "../screens/GenerateQuiz/GenerateQuiz";
 import EndQuiz from "../screens/EndQuiz/EndQuiz";
 import PlayingQuiz from "../screens/PlayingQuiz/PlayingQuiz";
+import TabNavigator from "./TabNavigation";
 
 const Stack = createNativeStackNavigator();
 
 export default function StackNavigator() {
     return (
         <NavigationContainer>
-            <Stack.Navigator initialRouteName="Home">
+            <Stack.Navigator initialRouteName="TabNavigator">
+                <Stack.Screen name="TabNavigator" component={TabNavigator} options={{ headerShown: false }}/>
                 <Stack.Screen name="Home" component={Home} options={{ headerShown: false }}/>
                 <Stack.Screen name="CreateQuiz" component={GenerateQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="PlayingQuiz" component={PlayingQuiz} options={{ headerShown: false }}/>
diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
new file mode 100644
index 0000000..719a7d8
--- /dev/null
+++ b/routes/TabNavigation.tsx
@@ -0,0 +1,40 @@
+import * as React from "react";
+import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
+import Home from "../screens/Home/Home";
+import Icon from "react-native-vector-icons/MaterialIcons";
+
+const Tab = createBottomTabNavigator();
+
+export default function TabNavigator() {
+    return (
+        <Tab.Navigator
+            initialRouteName="Home"
+            screenOptions={({ route }) => ({
+                headerShown: false,
+                tabBarActiveTintColor: "#383b41",
+                tabBarInactiveTintColor: "#c1c7d0",
+                tabBarShowLabel: false,
+                tabBarStyle: {
+                    height: 100, // Augmenter la hauteur de la barre pour plus d'espace
+                    backgroundColor: "#f4f5f7",
+                },
+                tabBarLabelStyle: {
+                    fontSize: 16, // Tu peux aussi ajuster la taille du texte ici
+                },
+                tabBarIcon: ({ color, size }) => {
+                    // Définir des icônes pour chaque route
+                    let iconName;
+                    if (route.name === "Home") {
+                        iconName = "home"; // Icône pour Home
+                    }
+                    return <Icon name={iconName} size={64} color={color} />;
+                },
+            })}
+        >
+            <Tab.Screen
+                name="Home"
+                component={Home}
+            />
+        </Tab.Navigator>
+    );
+}
-- 
GitLab


From 5d9b7985757d2c47b988a5244516c1c8bf8776f2 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 3 Dec 2024 18:38:54 +0100
Subject: [PATCH 039/283] feat: quiz list

---
 components/lists/QuizList.tsx   | 98 +++++++++++++++++++++++++++++++++
 routes/TabNavigation.tsx        |  7 +++
 screens/MyQuizzes/MyQuizzes.tsx | 49 +++++++++++++++++
 templates/TemplateQuizList.tsx  | 16 ++++++
 4 files changed, 170 insertions(+)
 create mode 100644 components/lists/QuizList.tsx
 create mode 100644 screens/MyQuizzes/MyQuizzes.tsx
 create mode 100644 templates/TemplateQuizList.tsx

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
new file mode 100644
index 0000000..e5bc4c4
--- /dev/null
+++ b/components/lists/QuizList.tsx
@@ -0,0 +1,98 @@
+import React from "react";
+import { FlatList, View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import QuizModel from "../../models/QuizModel";
+
+const quizzes: QuizModel[] = [
+    {
+        code: "QUIZ123",
+        category: "General Knowledge",
+        questions: [],
+        nbQuestions: 3,
+        nbActualQuestion: 1,
+        score: 0,
+    },
+    {
+        code: "QUIZ456",
+        category: "Science",
+        questions: [],
+        nbQuestions: 5,
+        nbActualQuestion: 1,
+        score: 0,
+    },
+    {
+        code: "QUIZ789",
+        category: "Entertainment",
+        questions: [],
+        nbQuestions: 10,
+        nbActualQuestion: 1,
+        score: 0,
+    },
+];
+
+export default function QuizList() {
+    const renderQuizItem = ({ item }: { item: QuizModel }) => (
+        <TouchableOpacity style={styles.quizItem}>
+            <Text style={styles.quizTitle}>{item.code}</Text> {/* Titre du quiz */}
+            <Text style={styles.quizDetails}>
+                {item.nbQuestions} QUESTIONS | {item.category.toUpperCase()}
+            </Text>
+        </TouchableOpacity>
+    );
+
+    return (
+        <View style={styles.container}>
+            <FlatList
+                data={quizzes}
+                renderItem={renderQuizItem}
+                keyExtractor={(item) => item.code}
+                showsVerticalScrollIndicator={true}
+                contentContainerStyle={styles.listContent}
+            />
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        backgroundColor: "white",
+        padding: 10,
+        borderRadius: 10,
+        borderColor: "#fafafa",
+        borderWidth: 3,
+        elevation: 5, // Ombre pour Android
+        shadowColor: "#000", // Ombre pour iOS
+        shadowOffset: { width: 0, height: 4 },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.84,
+        width: "100%", // Assurez-vous que le conteneur occupe toute la largeur
+    },
+    listContent: {
+        paddingVertical: 10,
+    },
+    quizItem: {
+        backgroundColor: "#f3f3f3",
+        padding: 15,
+        borderRadius: 10,
+        marginVertical: 5,
+        elevation: 3, // Ombre pour Android
+        shadowColor: "#000", // Ombre pour iOS
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.2,
+        shadowRadius: 2,
+        width: "100%",
+        alignSelf: "center", // Centre les éléments dans leur conteneur
+    },
+    quizTitle: {
+        fontSize: 22,
+        fontWeight: "bold",
+        color: "#000",
+        marginBottom: 5,
+        textAlign: "center",
+    },
+    quizDetails: {
+        fontSize: 18,
+        color: "#555",
+        textAlign: "center",
+    },
+});
diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index 719a7d8..ea8a005 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -2,6 +2,7 @@ import * as React from "react";
 import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
 import Home from "../screens/Home/Home";
 import Icon from "react-native-vector-icons/MaterialIcons";
+import MyQuizzes from "../screens/MyQuizzes/MyQuizzes";
 
 const Tab = createBottomTabNavigator();
 
@@ -26,6 +27,8 @@ export default function TabNavigator() {
                     let iconName;
                     if (route.name === "Home") {
                         iconName = "home"; // Icône pour Home
+                    } else if (route.name === "MyQuizzes") {
+                        iconName = "person"; // Icône pour Stats
                     }
                     return <Icon name={iconName} size={64} color={color} />;
                 },
@@ -35,6 +38,10 @@ export default function TabNavigator() {
                 name="Home"
                 component={Home}
             />
+            <Tab.Screen
+                name="MyQuizzes"
+                component={MyQuizzes}
+            />
         </Tab.Navigator>
     );
 }
diff --git a/screens/MyQuizzes/MyQuizzes.tsx b/screens/MyQuizzes/MyQuizzes.tsx
new file mode 100644
index 0000000..291acc2
--- /dev/null
+++ b/screens/MyQuizzes/MyQuizzes.tsx
@@ -0,0 +1,49 @@
+import React from "react";
+import { View, Text, StyleSheet } from "react-native";
+import TemplateQuizList from "../../templates/TemplateQuizList";
+import { NavigationProp } from "@react-navigation/native";
+import QuizList from "../../components/lists/QuizList";
+import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+
+interface Props {
+    navigation: NavigationProp<any>;
+}
+
+export default function MyQuizzes({ navigation }: Props) {
+    return (
+        <TemplateQuizList navigation={navigation}>
+            <View style={styles.globalContainer}>
+                <Text style={styles.title}>COMMUNITY</Text>
+                <View style={styles.contentContainer}>
+                    <InputPlayQuiz setText={(text) => console.log(text)} noTitle={true} />
+                    <QuizList />
+                </View>
+            </View>
+        </TemplateQuizList>
+    );
+}
+
+const styles = StyleSheet.create({
+    globalContainer: {
+        display: "flex",
+        height: "100%",
+        width: "100%",
+        paddingHorizontal: "3%", // Ajoute une marge de 5% à gauche et à droite
+        alignItems: "center", // Centre tous les enfants horizontalement
+    },
+    title: {
+        fontSize: 40,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+        alignSelf: "center", // Centre uniquement le titre
+    },
+    contentContainer: {
+        display: "flex",
+        flexDirection: "column",
+        width: "100%", // Utilise tout l'espace restant à l'intérieur de `globalContainer`
+        height: "80%",
+        alignItems: "center", // Centre tous les enfants horizontalement
+        gap: "2%",
+    },
+});
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
new file mode 100644
index 0000000..5125d01
--- /dev/null
+++ b/templates/TemplateQuizList.tsx
@@ -0,0 +1,16 @@
+import React from "react";
+import {View, Text} from "react-native";
+import TemplateMenu from "./TemplateMenu";
+import {NavigationProp} from "@react-navigation/native";
+
+interface Props {
+    navigation: NavigationProp<any>
+    children: React.ReactNode
+}
+export default function TemplateQuizList({navigation, children}: Props) {
+    return (
+        <TemplateMenu navigation={navigation} headerNavigation={true}>
+            {children}
+        </TemplateMenu>
+    );
+}
\ No newline at end of file
-- 
GitLab


From 255b9ca6ae20c52364ea146eecb92f568053ee47 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 3 Dec 2024 18:42:50 +0100
Subject: [PATCH 040/283] feat: setup fin

---
 routes/TabNavigation.tsx        |  5 +---
 screens/MyQuizzes/MyQuizzes.tsx | 49 ---------------------------------
 templates/TemplateQuizList.tsx  | 46 +++++++++++++++++++++++++++----
 3 files changed, 42 insertions(+), 58 deletions(-)
 delete mode 100644 screens/MyQuizzes/MyQuizzes.tsx

diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index ea8a005..7cfb72c 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -38,10 +38,7 @@ export default function TabNavigator() {
                 name="Home"
                 component={Home}
             />
-            <Tab.Screen
-                name="MyQuizzes"
-                component={MyQuizzes}
-            />
+
         </Tab.Navigator>
     );
 }
diff --git a/screens/MyQuizzes/MyQuizzes.tsx b/screens/MyQuizzes/MyQuizzes.tsx
deleted file mode 100644
index 291acc2..0000000
--- a/screens/MyQuizzes/MyQuizzes.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import React from "react";
-import { View, Text, StyleSheet } from "react-native";
-import TemplateQuizList from "../../templates/TemplateQuizList";
-import { NavigationProp } from "@react-navigation/native";
-import QuizList from "../../components/lists/QuizList";
-import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-
-interface Props {
-    navigation: NavigationProp<any>;
-}
-
-export default function MyQuizzes({ navigation }: Props) {
-    return (
-        <TemplateQuizList navigation={navigation}>
-            <View style={styles.globalContainer}>
-                <Text style={styles.title}>COMMUNITY</Text>
-                <View style={styles.contentContainer}>
-                    <InputPlayQuiz setText={(text) => console.log(text)} noTitle={true} />
-                    <QuizList />
-                </View>
-            </View>
-        </TemplateQuizList>
-    );
-}
-
-const styles = StyleSheet.create({
-    globalContainer: {
-        display: "flex",
-        height: "100%",
-        width: "100%",
-        paddingHorizontal: "3%", // Ajoute une marge de 5% à gauche et à droite
-        alignItems: "center", // Centre tous les enfants horizontalement
-    },
-    title: {
-        fontSize: 40,
-        fontWeight: "bold",
-        color: "#00b3f4",
-        marginBottom: 10,
-        alignSelf: "center", // Centre uniquement le titre
-    },
-    contentContainer: {
-        display: "flex",
-        flexDirection: "column",
-        width: "100%", // Utilise tout l'espace restant à l'intérieur de `globalContainer`
-        height: "80%",
-        alignItems: "center", // Centre tous les enfants horizontalement
-        gap: "2%",
-    },
-});
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 5125d01..e540474 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -1,16 +1,52 @@
 import React from "react";
-import {View, Text} from "react-native";
+import {View, Text, StyleSheet} from "react-native";
 import TemplateMenu from "./TemplateMenu";
 import {NavigationProp} from "@react-navigation/native";
+import InputPlayQuiz from "../components/PlayQuiz/InputPlayQuiz";
+import QuizList from "../components/lists/QuizList";
+import QuizModel from "../models/QuizModel";
 
 interface Props {
     navigation: NavigationProp<any>
-    children: React.ReactNode
+    title: string
+    setTextInInput: (text: string) => void
+    quizList: QuizModel[]
 }
-export default function TemplateQuizList({navigation, children}: Props) {
+export default function TemplateQuizList({navigation, title, setTextInInput, quizList}: Props) {
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true}>
-            {children}
+            <View style={styles.globalContainer}>
+                <Text style={styles.title}>{title}</Text>
+                <View style={styles.contentContainer}>
+                    <InputPlayQuiz setText={(text) => console.log(text)} noTitle={true} />
+                    <QuizList />
+                </View>
+            </View>
         </TemplateMenu>
     );
-}
\ No newline at end of file
+}
+
+const styles = StyleSheet.create({
+    globalContainer: {
+        display: "flex",
+        height: "100%",
+        width: "100%",
+        paddingHorizontal: "3%", // Ajoute une marge de 5% à gauche et à droite
+        alignItems: "center", // Centre tous les enfants horizontalement
+    },
+    title: {
+        fontSize: 40,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+        alignSelf: "center", // Centre uniquement le titre
+    },
+    contentContainer: {
+        display: "flex",
+        flexDirection: "column",
+        width: "100%", // Utilise tout l'espace restant à l'intérieur de `globalContainer`
+        height: "80%",
+        alignItems: "center", // Centre tous les enfants horizontalement
+        gap: "2%",
+    },
+});
-- 
GitLab


From b553fac3cbbebae7211cad783541fd53e2af1dd9 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 3 Dec 2024 18:47:59 +0100
Subject: [PATCH 041/283] style: commentaires d'explications

---
 components/lists/QuizList.tsx  | 19 +++++++++++++++++++
 templates/TemplateQuizList.tsx | 10 ++++++++++
 2 files changed, 29 insertions(+)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index e5bc4c4..225ac3c 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -29,6 +29,25 @@ const quizzes: QuizModel[] = [
     },
 ];
 
+/**
+ * QuizList : Un composant affichant une liste de quiz avec leur titre, nombre de questions et catégorie.
+ *
+ * @component
+ *
+ * @example
+ * // Exemple d'utilisation :
+ * <QuizList />
+ *
+ * @description
+ * - Ce composant utilise un `FlatList` pour afficher les quiz.
+ * - Chaque élément de la liste contient :
+ *    - Le code du quiz comme titre.
+ *    - Le nombre total de questions.
+ *    - La catégorie du quiz, en majuscules.
+ * - Les quiz sont définis dans une liste statique en haut du fichier pour cet exemple.
+ *
+ * @returns Un composant React contenant une liste interactive de quiz.
+ */
 export default function QuizList() {
     const renderQuizItem = ({ item }: { item: QuizModel }) => (
         <TouchableOpacity style={styles.quizItem}>
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index e540474..25e82aa 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -12,6 +12,16 @@ interface Props {
     setTextInInput: (text: string) => void
     quizList: QuizModel[]
 }
+
+/**
+ * TemplateQuizList : Un composant principal pour afficher une liste de quiz.
+ * Il inclut un menu, un titre, un champ d'entrée pour les recherches et une liste de quiz.
+ *
+ * @param navigation - L'objet de navigation pour naviguer entre les écrans
+ * @param title - Le titre affiché en haut de la liste
+ * @param setTextInInput - Fonction pour gérer les modifications dans le champ d'entrée
+ * @param quizList - La liste des quiz à afficher
+ */
 export default function TemplateQuizList({navigation, title, setTextInInput, quizList}: Props) {
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true}>
-- 
GitLab


From 137e241160ac6d21523c3ffc04c0f8df80080753 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 3 Dec 2024 20:22:12 +0100
Subject: [PATCH 042/283] fix: bug Text rendered

---
 components/PlayQuiz/SelectListBox.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/PlayQuiz/SelectListBox.tsx b/components/PlayQuiz/SelectListBox.tsx
index 5ce90d7..12612f6 100644
--- a/components/PlayQuiz/SelectListBox.tsx
+++ b/components/PlayQuiz/SelectListBox.tsx
@@ -14,7 +14,7 @@ export default function SelectListBox({data, setSelected, title} : Props) {
     return (
         <View style={styles.container}>
             <View style={styles.dropdownContainer}>
-                <Text style={styles.title}>{title}</Text> {/* Ajout du titre */}
+                <Text style={styles.title}>{title}</Text>
                 <SelectList
                     setSelected={(val: any) => setSelected(val)}
                     data={data}
-- 
GitLab


From edd86fd24b5ba6d73903afa5d97b2bc2e783d97d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 3 Dec 2024 20:23:19 +0100
Subject: [PATCH 043/283] =?UTF-8?q?add:=20initialisation=20de=20l'=C3=A9cr?=
 =?UTF-8?q?an=20profil?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 screens/Profil/Profil.tsx | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 screens/Profil/Profil.tsx

diff --git a/screens/Profil/Profil.tsx b/screens/Profil/Profil.tsx
new file mode 100644
index 0000000..2dd614e
--- /dev/null
+++ b/screens/Profil/Profil.tsx
@@ -0,0 +1,9 @@
+import { View } from "react-native";
+
+export default function Profil() {
+    return (
+        <View>
+
+        </View>
+    );
+}
\ No newline at end of file
-- 
GitLab


From 7140a954374287aea2a442a3b914fb21a0149534 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 3 Dec 2024 20:23:36 +0100
Subject: [PATCH 044/283] feat: screen MyQuizzes

---
 components/lists/QuizList.tsx   | 31 +++++++++++++++++-------
 routes/TabNavigation.tsx        |  4 +++
 screens/MyQuizzes/MyQuizzes.tsx | 43 +++++++++++++++++++++++++++++++++
 templates/TemplateQuizList.tsx  |  6 ++---
 4 files changed, 72 insertions(+), 12 deletions(-)
 create mode 100644 screens/MyQuizzes/MyQuizzes.tsx

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 225ac3c..085b34a 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -48,10 +48,13 @@ const quizzes: QuizModel[] = [
  *
  * @returns Un composant React contenant une liste interactive de quiz.
  */
-export default function QuizList() {
+interface Props{
+    quizList: QuizModel[] | null
+}
+export default function QuizList({quizList}: Props) {
     const renderQuizItem = ({ item }: { item: QuizModel }) => (
         <TouchableOpacity style={styles.quizItem}>
-            <Text style={styles.quizTitle}>{item.code}</Text> {/* Titre du quiz */}
+            <Text style={styles.quizTitle}>{item.code}</Text>
             <Text style={styles.quizDetails}>
                 {item.nbQuestions} QUESTIONS | {item.category.toUpperCase()}
             </Text>
@@ -60,13 +63,17 @@ export default function QuizList() {
 
     return (
         <View style={styles.container}>
-            <FlatList
-                data={quizzes}
-                renderItem={renderQuizItem}
-                keyExtractor={(item) => item.code}
-                showsVerticalScrollIndicator={true}
-                contentContainerStyle={styles.listContent}
-            />
+            {quizList && quizList.length > 0 ? (
+                <FlatList
+                    data={quizList}
+                    renderItem={renderQuizItem}
+                    keyExtractor={(item) => item.code}
+                    showsVerticalScrollIndicator={true}
+                    contentContainerStyle={styles.listContent}
+                />
+            ) : (
+                <Text style={styles.emptyMessage}>No quizzes available.</Text> // Message si la liste est vide
+            )}
         </View>
     );
 }
@@ -114,4 +121,10 @@ const styles = StyleSheet.create({
         color: "#555",
         textAlign: "center",
     },
+    emptyMessage: {
+        fontSize: 18,
+        color: "#888",
+        textAlign: "center",
+        marginTop: 20,
+    },
 });
diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index 7cfb72c..305a8cf 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -38,6 +38,10 @@ export default function TabNavigator() {
                 name="Home"
                 component={Home}
             />
+            <Tab.Screen
+                name="MyQuizzes"
+                component={MyQuizzes}
+            />
 
         </Tab.Navigator>
     );
diff --git a/screens/MyQuizzes/MyQuizzes.tsx b/screens/MyQuizzes/MyQuizzes.tsx
new file mode 100644
index 0000000..7364854
--- /dev/null
+++ b/screens/MyQuizzes/MyQuizzes.tsx
@@ -0,0 +1,43 @@
+import {View, Text} from "react-native";
+import TemplateQuizList from "../../templates/TemplateQuizList";
+import {NavigationProp} from "@react-navigation/native";
+import {useState} from "react";
+import QuizModel from "../../models/QuizModel";
+
+interface Props {
+    navigation: NavigationProp<any>
+}
+export default function MyQuizzes({navigation}: Props) {
+    const [quizList, setQuizList] = useState<QuizModel[] | null>([
+        {
+            code: "QUIZ123",
+            category: "General Knowledge",
+            questions: [],
+            nbQuestions: 3,
+            nbActualQuestion: 1,
+            score: 0,
+        },
+        {
+            code: "QUIZ456",
+            category: "Science",
+            questions: [],
+            nbQuestions: 5,
+            nbActualQuestion: 1,
+            score: 0,
+        },
+        {
+            code: "QUIZ789",
+            category: "Entertainment",
+            questions: [],
+            nbQuestions: 10,
+            nbActualQuestion: 1,
+            score: 0,
+        },
+    ])
+    const [input, setInput] = useState<string>("")
+
+
+    return (
+        <TemplateQuizList title={"My quizzes"} setTextInInput={setInput} quizList={quizList} navigation={navigation}/>
+    );
+}
\ No newline at end of file
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 25e82aa..8d49146 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -10,7 +10,7 @@ interface Props {
     navigation: NavigationProp<any>
     title: string
     setTextInInput: (text: string) => void
-    quizList: QuizModel[]
+    quizList: QuizModel[] | null
 }
 
 /**
@@ -28,8 +28,8 @@ export default function TemplateQuizList({navigation, title, setTextInInput, qui
             <View style={styles.globalContainer}>
                 <Text style={styles.title}>{title}</Text>
                 <View style={styles.contentContainer}>
-                    <InputPlayQuiz setText={(text) => console.log(text)} noTitle={true} />
-                    <QuizList />
+                    <InputPlayQuiz setText={setTextInInput} noTitle={true} />
+                    <QuizList  quizList={quizList}/>
                 </View>
             </View>
         </TemplateMenu>
-- 
GitLab


From aeddb1fb6b419392eda2cd6cd54db610e720837b Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 3 Dec 2024 20:28:00 +0100
Subject: [PATCH 045/283] add: gestion du tab

---
 routes/TabNavigation.tsx | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index 7cfb72c..67900be 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -3,6 +3,7 @@ import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
 import Home from "../screens/Home/Home";
 import Icon from "react-native-vector-icons/MaterialIcons";
 import MyQuizzes from "../screens/MyQuizzes/MyQuizzes";
+import Profil from "../screens/Profil/Profil";
 
 const Tab = createBottomTabNavigator();
 
@@ -29,6 +30,8 @@ export default function TabNavigator() {
                         iconName = "home"; // Icône pour Home
                     } else if (route.name === "MyQuizzes") {
                         iconName = "person"; // Icône pour Stats
+                    } else if (route.name === "Profil") {
+                        iconName = "person";
                     }
                     return <Icon name={iconName} size={64} color={color} />;
                 },
@@ -39,6 +42,10 @@ export default function TabNavigator() {
                 component={Home}
             />
 
+            <Tab.Screen
+                name="Profil"
+                component={Profil}
+            />
         </Tab.Navigator>
     );
 }
-- 
GitLab


From c9ff21d1b06c5a0b20eca7fa6316edfc16061b4d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 3 Dec 2024 20:40:34 +0100
Subject: [PATCH 046/283] add: ajout du contenu de la page profil

---
 assets/ProfilBaseImage.png     | Bin 0 -> 8808 bytes
 screens/Profil/Profil.tsx      |  30 +++++++++++++++++++++++++-----
 screens/Profil/ProfilChild.tsx |  33 +++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 5 deletions(-)
 create mode 100644 assets/ProfilBaseImage.png
 create mode 100644 screens/Profil/ProfilChild.tsx

diff --git a/assets/ProfilBaseImage.png b/assets/ProfilBaseImage.png
new file mode 100644
index 0000000000000000000000000000000000000000..123c902c001c1d4dd715c364adb55b21d129860d
GIT binary patch
literal 8808
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

literal 0
HcmV?d00001

diff --git a/screens/Profil/Profil.tsx b/screens/Profil/Profil.tsx
index 2dd614e..a226e78 100644
--- a/screens/Profil/Profil.tsx
+++ b/screens/Profil/Profil.tsx
@@ -1,9 +1,29 @@
-import { View } from "react-native";
+import { View, StyleSheet } from "react-native";
+import TemplateMenu from "../../templates/TemplateMenu";
+import { NavigationProp } from "@react-navigation/native";
+import ProfilChild from "./ProfilChild";
 
-export default function Profil() {
-    return (
-        <View>
+interface Props {
+    navigation: NavigationProp<any>;
+}
 
+export default function Profil({navigation}: Props) {
+    return (
+        <View style={styles.containerGlobal}>
+                <TemplateMenu navigation={navigation} headerNavigation={false}>
+                    <View>
+                        <ProfilChild navigation={navigation}/>
+                    </View>
+                </TemplateMenu>
         </View>
     );
-}
\ No newline at end of file
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        flexDirection: 'column',
+    },
+});
\ No newline at end of file
diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
new file mode 100644
index 0000000..23a46b8
--- /dev/null
+++ b/screens/Profil/ProfilChild.tsx
@@ -0,0 +1,33 @@
+import { NavigationProp } from "@react-navigation/native";
+import { View, StyleSheet, Image, Text } from "react-native";
+
+interface Props {
+    navigation: NavigationProp<any>;
+}
+
+export default function ProfilChild({navigation}: Props) {
+    return (
+        <View style={styles.containerGlobal}>
+            <View>
+                <Image source={require('../../assets/TitleApp.png')}/>
+                <Image source={require('../../assets/ProfilBaseImage.png')}/>
+                <Text>_Pseudo_</Text>
+            </View>
+            <View>
+                <Text>Played quiz : _123_</Text>
+                <Text>right answer rate : _43%_</Text>
+                <Text>Favorit category : _HISTORY AND CULTURE_</Text>
+            </View>
+        </View>
+    )
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        justifyContent: 'flex-start',
+        alignItems: 'center',
+    },
+});
\ No newline at end of file
-- 
GitLab


From 65d468fede71861547bfd77d031d5f860b19cd37 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 3 Dec 2024 20:51:39 +0100
Subject: [PATCH 047/283] feat: Community

---
 routes/StackNavigator.tsx       |  2 ++
 routes/TabNavigation.tsx        | 15 +++++++++---
 screens/Community/Community.tsx | 43 +++++++++++++++++++++++++++++++++
 screens/Home/HomeChild.tsx      |  8 +++---
 templates/TemplateQuizList.tsx  |  2 +-
 5 files changed, 61 insertions(+), 9 deletions(-)
 create mode 100644 screens/Community/Community.tsx

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 3eb2d53..c34183c 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -6,6 +6,7 @@ import EndQuiz from "../screens/EndQuiz/EndQuiz";
 import PlayingQuiz from "../screens/PlayingQuiz/PlayingQuiz";
 import TabNavigator from "./TabNavigation";
 import PlayQuiz from "../screens/PlayQuiz/PlayQuiz";
+import MyQuizzes from "../screens/MyQuizzes/MyQuizzes";
 
 const Stack = createNativeStackNavigator();
 
@@ -19,6 +20,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="PlayingQuiz" component={PlayingQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="PlayQuiz" component={PlayQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="EndQuiz" component={EndQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="MyQuizzes" component={MyQuizzes} options={{ headerShown: false }}/>
             </Stack.Navigator>
         </NavigationContainer>
     );
diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index 305a8cf..61338eb 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -3,6 +3,7 @@ import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
 import Home from "../screens/Home/Home";
 import Icon from "react-native-vector-icons/MaterialIcons";
 import MyQuizzes from "../screens/MyQuizzes/MyQuizzes";
+import Community from "../screens/Community/Community";
 
 const Tab = createBottomTabNavigator();
 
@@ -26,9 +27,11 @@ export default function TabNavigator() {
                     // Définir des icônes pour chaque route
                     let iconName;
                     if (route.name === "Home") {
-                        iconName = "home"; // Icône pour Home
+                        iconName = "home";
                     } else if (route.name === "MyQuizzes") {
-                        iconName = "person"; // Icône pour Stats
+                        iconName = "person";
+                    } else if (route.name === "Community") {
+                        iconName = "people";
                     }
                     return <Icon name={iconName} size={64} color={color} />;
                 },
@@ -38,9 +41,13 @@ export default function TabNavigator() {
                 name="Home"
                 component={Home}
             />
+            {/*<Tab.Screen*/}
+            {/*    name="Profil"*/}
+            {/*    component={Profil}*/}
+            {/*/>*/}
             <Tab.Screen
-                name="MyQuizzes"
-                component={MyQuizzes}
+                name="Community"
+                component={Community}
             />
 
         </Tab.Navigator>
diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
new file mode 100644
index 0000000..3381b65
--- /dev/null
+++ b/screens/Community/Community.tsx
@@ -0,0 +1,43 @@
+import {View, Text} from "react-native";
+import TemplateQuizList from "../../templates/TemplateQuizList";
+import {NavigationProp} from "@react-navigation/native";
+import {useState} from "react";
+import QuizModel from "../../models/QuizModel";
+
+interface Props {
+    navigation: NavigationProp<any>
+}
+export default function Community({navigation}: Props) {
+    const [quizList, setQuizList] = useState<QuizModel[] | null>([
+        {
+            code: "QUIZ123",
+            category: "General Knowledge",
+            questions: [],
+            nbQuestions: 3,
+            nbActualQuestion: 1,
+            score: 0,
+        },
+        {
+            code: "QUIZ456",
+            category: "Science",
+            questions: [],
+            nbQuestions: 5,
+            nbActualQuestion: 1,
+            score: 0,
+        },
+        {
+            code: "QUIZ789",
+            category: "Entertainment",
+            questions: [],
+            nbQuestions: 10,
+            nbActualQuestion: 1,
+            score: 0,
+        },
+    ])
+    const [input, setInput] = useState<string>("")
+
+
+    return (
+        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={quizList} navigation={navigation}/>
+    );
+}
\ No newline at end of file
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index a750275..9589ac5 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -19,8 +19,8 @@ export default function HomeChild({navigation}: Props) {
     const [modalVisible, setModalVisible] = useState(false);
     const {t} = useTranslation();
 
-    const handleButtonJoinPressed = () => {
-        setModalVisible(true);
+    const handleButtonMyQuizzesPressed = () => {
+        navigation.navigate("MyQuizzes");
     }
 
     const handleButtonGeneratePressed = () => {
@@ -33,9 +33,9 @@ export default function HomeChild({navigation}: Props) {
                 <Image source={require('../../assets/TitleApp.png')} style={styles.image} />
             </View>
             <View style={styles.buttonContainer}>
-                <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonJoinPressed}/>
+                <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
                 <MenuButton text={"PLAY A QUIZ"} handleButtonPressed={handleButtonGeneratePressed}/>
-                <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonJoinPressed}/>
+                <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
             </View>
              <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
         </View>
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 8d49146..963da5e 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -55,7 +55,7 @@ const styles = StyleSheet.create({
         display: "flex",
         flexDirection: "column",
         width: "100%", // Utilise tout l'espace restant à l'intérieur de `globalContainer`
-        height: "80%",
+        height: "75%",
         alignItems: "center", // Centre tous les enfants horizontalement
         gap: "2%",
     },
-- 
GitLab


From df81b6756c69eab911604405b83d2090d5430e1a Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 3 Dec 2024 21:08:12 +0100
Subject: [PATCH 048/283] feat: bouton goback optionnel dans le header

---
 screens/Community/Community.tsx   |  2 +-
 screens/Home/HeaderNavigation.tsx | 12 ++++++++----
 screens/Home/Home.tsx             |  3 +--
 screens/MyQuizzes/MyQuizzes.tsx   |  2 +-
 screens/PlayQuiz/PlayQuiz.tsx     |  2 +-
 templates/TemplateMenu.tsx        |  6 ++++--
 templates/TemplateQuizList.tsx    |  6 ++++--
 7 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index 3381b65..ec8bfa5 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -38,6 +38,6 @@ export default function Community({navigation}: Props) {
 
 
     return (
-        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={quizList} navigation={navigation}/>
+        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={quizList} navigation={navigation} buttonGoBack={false}/>
     );
 }
\ No newline at end of file
diff --git a/screens/Home/HeaderNavigation.tsx b/screens/Home/HeaderNavigation.tsx
index 5b71d9c..1a5e961 100644
--- a/screens/Home/HeaderNavigation.tsx
+++ b/screens/Home/HeaderNavigation.tsx
@@ -3,18 +3,22 @@ import { NavigationProp } from "@react-navigation/native";
 
 interface Props {
     navigation: NavigationProp<any>;
+    buttonGoBack: boolean
 }
 
 /**
  * HeaderNavigation : Header qui permet de remonter à l'écran précédent
  * @param navigation - navigation
+ * @param buttonGoBack - boolean qui dit si le bouton de retour doit être affiché
  */
-export default function HeaderNavigation({ navigation }: Props) {
+export default function HeaderNavigation({ navigation, buttonGoBack }: Props) {
     return (
         <View style={styles.container}>
-            <TouchableOpacity onPress={() => navigation.goBack()} style={styles.goBackContainer}>
-                <Image source={require('../../assets/GoBackNavigation.png')}/>
-            </TouchableOpacity>
+            {buttonGoBack && ( // Affiche le bouton uniquement si buttonGoBack est true
+                <TouchableOpacity onPress={() => navigation.goBack()} style={styles.goBackContainer}>
+                    <Image source={require('../../assets/GoBackNavigation.png')} />
+                </TouchableOpacity>
+            )}
             <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage} />
         </View>
     );
diff --git a/screens/Home/Home.tsx b/screens/Home/Home.tsx
index 53bb379..dc3b638 100644
--- a/screens/Home/Home.tsx
+++ b/screens/Home/Home.tsx
@@ -3,7 +3,6 @@ import TemplateMono from "../../templates/TemplateMono";
 import HomeChild from "./HomeChild";
 import TemplateMenu from "../../templates/TemplateMenu";
 import {NavigationProp} from "@react-navigation/native";
-import HeaderNavigation from "./HeaderNavigation";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -12,7 +11,7 @@ interface Props {
 export default function Home({navigation}: Props) {
     return (
         <View style={styles.containerGlobal}>
-                <TemplateMenu navigation={navigation} headerNavigation={false}>
+                <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}>
                     <View>
                         <HomeChild navigation={navigation}/>
                     </View>
diff --git a/screens/MyQuizzes/MyQuizzes.tsx b/screens/MyQuizzes/MyQuizzes.tsx
index 7364854..7419d53 100644
--- a/screens/MyQuizzes/MyQuizzes.tsx
+++ b/screens/MyQuizzes/MyQuizzes.tsx
@@ -38,6 +38,6 @@ export default function MyQuizzes({navigation}: Props) {
 
 
     return (
-        <TemplateQuizList title={"My quizzes"} setTextInInput={setInput} quizList={quizList} navigation={navigation}/>
+        <TemplateQuizList title={"My quizzes"} setTextInInput={setInput} quizList={quizList} navigation={navigation} buttonGoBack={true}/>
     );
 }
\ No newline at end of file
diff --git a/screens/PlayQuiz/PlayQuiz.tsx b/screens/PlayQuiz/PlayQuiz.tsx
index 25fe9f8..991c6ba 100644
--- a/screens/PlayQuiz/PlayQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuiz.tsx
@@ -12,7 +12,7 @@ export default function PlayQuiz({navigation}: Props) {
 
     return (
         <View style={styles.containerGlobal}>
-            <TemplateMenu navigation={navigation} headerNavigation={true}>
+            <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
                 <View>
                     <PlayQuizChild navigation={navigation}/>
                 </View>
diff --git a/templates/TemplateMenu.tsx b/templates/TemplateMenu.tsx
index ee54727..6be8186 100644
--- a/templates/TemplateMenu.tsx
+++ b/templates/TemplateMenu.tsx
@@ -6,6 +6,7 @@ interface Props{
     children: React.ReactNode
     navigation: NavigationProp<any>;
     headerNavigation: boolean;
+    buttonGoBack: boolean
 }
 
 /**
@@ -13,14 +14,15 @@ interface Props{
  * @param children - Contenu du menu
  * @param navigation - Navigation
  * @param headerNavigation - Si le menu est en haut de page
+ * @param buttonGoBack - boolean qui dit si le bouton de retour doit être affiché
  */
-export default function TemplateMenu({children, navigation, headerNavigation}: Props) {
+export default function TemplateMenu({children, navigation, headerNavigation, buttonGoBack}: Props) {
     return (
         <View style={styles.container}>
 
             <ImageBackground source={require('../assets/MenuBackground.png')} style={styles.image}>
                 <SafeAreaView>
-                    {headerNavigation && <HeaderNavigation navigation={navigation}/>}
+                    {headerNavigation && <HeaderNavigation navigation={navigation} buttonGoBack={buttonGoBack}/>}
                 <View style={styles.container}>
                     {children}
                 </View>
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 963da5e..5c6eda4 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -11,6 +11,7 @@ interface Props {
     title: string
     setTextInInput: (text: string) => void
     quizList: QuizModel[] | null
+    buttonGoBack: boolean
 }
 
 /**
@@ -21,10 +22,11 @@ interface Props {
  * @param title - Le titre affiché en haut de la liste
  * @param setTextInInput - Fonction pour gérer les modifications dans le champ d'entrée
  * @param quizList - La liste des quiz à afficher
+ * @param buttonGoBack - boolean qui dit si le bouton de retour doit être affiché
  */
-export default function TemplateQuizList({navigation, title, setTextInInput, quizList}: Props) {
+export default function TemplateQuizList({navigation, title, setTextInInput, quizList, buttonGoBack}: Props) {
     return (
-        <TemplateMenu navigation={navigation} headerNavigation={true}>
+        <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={buttonGoBack}>
             <View style={styles.globalContainer}>
                 <Text style={styles.title}>{title}</Text>
                 <View style={styles.contentContainer}>
-- 
GitLab


From 0283c9784aef26bca54fba65216122fe07fbfb59 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 3 Dec 2024 21:19:39 +0100
Subject: [PATCH 049/283] add: ajout du style de la page profil

---
 screens/Profil/ProfilChild.tsx | 44 +++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 23a46b8..5bcad82 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -8,15 +8,15 @@ interface Props {
 export default function ProfilChild({navigation}: Props) {
     return (
         <View style={styles.containerGlobal}>
-            <View>
-                <Image source={require('../../assets/TitleApp.png')}/>
-                <Image source={require('../../assets/ProfilBaseImage.png')}/>
-                <Text>_Pseudo_</Text>
+            <View style={styles.containerPlayerInfos}>
+                <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage}/>
+                <Image source={require('../../assets/ProfilBaseImage.png')} style={styles.profilImage}/>
+                <Text style={styles.pseudoText}>_Pseudo_</Text>
             </View>
-            <View>
-                <Text>Played quiz : _123_</Text>
-                <Text>right answer rate : _43%_</Text>
-                <Text>Favorit category : _HISTORY AND CULTURE_</Text>
+            <View style={styles.containerPlayerStats}>
+                <Text style={styles.statsText}>Played quiz : _123_</Text>
+                <Text style={styles.statsText}>right answer rate : _43%_</Text>
+                <Text style={styles.statsText}>Favorit category : _HISTORY AND CULTURE_</Text>
             </View>
         </View>
     )
@@ -30,4 +30,32 @@ const styles = StyleSheet.create({
         justifyContent: 'flex-start',
         alignItems: 'center',
     },
+    containerPlayerInfos: {
+        width: '100%',
+        display: 'flex',
+        alignItems: 'center',   
+    },
+    titleImage: {
+        width: 170, // Ajustez en fonction de la taille de l'image
+        height: 80,
+        resizeMode: 'contain', // Pour conserver les proportions
+    },
+    profilImage: {
+        height: 200,
+        width: 200,
+        borderRadius: 100,
+    },
+    pseudoText: {
+        fontSize: 35,
+        fontWeight: 'bold',
+        color: '#00B3F4',
+    },
+    containerPlayerStats: {
+        width: '100%',
+        padding: 30,
+    },
+    statsText: {
+        fontSize: 17,
+        fontWeight: 'bold',
+    },
 });
\ No newline at end of file
-- 
GitLab


From 4b4da25f3bfd056bb0215b64c480d1445769176d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 3 Dec 2024 21:54:37 +0100
Subject: [PATCH 050/283] feat: InformationsOfQuiz

---
 components/lists/QuizList.tsx                 |  9 +-
 routes/StackNavigator.tsx                     |  2 +
 .../InformationsOfQuiz/InformationsOfQuiz.tsx | 98 +++++++++++++++++++
 templates/TemplateQuizList.tsx                |  2 +-
 4 files changed, 108 insertions(+), 3 deletions(-)
 create mode 100644 screens/InformationsOfQuiz/InformationsOfQuiz.tsx

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 085b34a..13cc1e4 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -1,6 +1,7 @@
 import React from "react";
 import { FlatList, View, Text, StyleSheet, TouchableOpacity } from "react-native";
 import QuizModel from "../../models/QuizModel";
+import {NavigationProp} from "@react-navigation/native";
 
 const quizzes: QuizModel[] = [
     {
@@ -49,11 +50,15 @@ const quizzes: QuizModel[] = [
  * @returns Un composant React contenant une liste interactive de quiz.
  */
 interface Props{
+    navigation: NavigationProp<any>;
     quizList: QuizModel[] | null
 }
-export default function QuizList({quizList}: Props) {
+export default function QuizList({navigation,quizList}: Props) {
+    const onQuizPressed = (quiz: QuizModel) => {
+        navigation.navigate('InformationsOfQuiz', {quiz: quiz});
+    };
     const renderQuizItem = ({ item }: { item: QuizModel }) => (
-        <TouchableOpacity style={styles.quizItem}>
+        <TouchableOpacity style={styles.quizItem} onPress={() => onQuizPressed(item)}>
             <Text style={styles.quizTitle}>{item.code}</Text>
             <Text style={styles.quizDetails}>
                 {item.nbQuestions} QUESTIONS | {item.category.toUpperCase()}
diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index c34183c..e2c2b96 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -7,6 +7,7 @@ import PlayingQuiz from "../screens/PlayingQuiz/PlayingQuiz";
 import TabNavigator from "./TabNavigation";
 import PlayQuiz from "../screens/PlayQuiz/PlayQuiz";
 import MyQuizzes from "../screens/MyQuizzes/MyQuizzes";
+import InformationsOfQuiz from "../screens/InformationsOfQuiz/InformationsOfQuiz";
 
 const Stack = createNativeStackNavigator();
 
@@ -21,6 +22,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="PlayQuiz" component={PlayQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="EndQuiz" component={EndQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="MyQuizzes" component={MyQuizzes} options={{ headerShown: false }}/>
+                <Stack.Screen name="InformationsOfQuiz" component={InformationsOfQuiz} options={{ headerShown: false }}/>
             </Stack.Navigator>
         </NavigationContainer>
     );
diff --git a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
new file mode 100644
index 0000000..2fdfb96
--- /dev/null
+++ b/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -0,0 +1,98 @@
+import React from "react";
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import TemplateMenu from "../../templates/TemplateMenu";
+import {NavigationProp, RouteProp} from "@react-navigation/native";
+import QuizModel from "../../models/QuizModel";
+
+type RoutePropsType = {
+    InformationsOfQuiz: {
+        quiz: QuizModel;
+    };
+};
+interface Props {
+    navigation: NavigationProp<any>;
+    route: RouteProp<RoutePropsType, "InformationsOfQuiz">;
+}
+
+export default function InformationsOfQuiz({ navigation, route }: Props) {
+    const { quiz } = route.params;
+
+    const onPlay = () => {
+        // navigation.navigate('PlayQuiz', {quiz: quiz});
+    }
+
+    return (
+        <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
+            <View style={styles.container}>
+                <Text style={styles.quizTitle}>{quiz.category}</Text>
+                <Text style={styles.quizDescription}>{quiz.category}</Text>
+
+                <View style={styles.aboutContainer}>
+                    <Text style={styles.aboutTitle}>About this quiz :</Text>
+                    <Text style={styles.aboutDetails}>{quiz.nbQuestions} questions</Text>
+                    <Text style={styles.aboutDetails}>By : Unknown</Text>
+                </View>
+
+                <TouchableOpacity style={styles.playButton} onPress={onPlay}>
+                    <Text style={styles.playButtonText}>PLAY</Text>
+                </TouchableOpacity>
+            </View>
+        </TemplateMenu>
+
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        paddingHorizontal: 20,
+        paddingVertical: 20,
+        justifyContent: "flex-start",
+        backgroundColor: "#f4f4f4",
+    },
+    quizTitle: {
+        fontSize: 24,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+    },
+    quizDescription: {
+        fontSize: 16,
+        color: "#555",
+        marginBottom: 20,
+    },
+    aboutContainer: {
+        backgroundColor: "white",
+        borderRadius: 10,
+        padding: 15,
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.2,
+        shadowRadius: 3,
+        elevation: 5,
+    },
+    aboutTitle: {
+        fontSize: 18,
+        fontWeight: "bold",
+        marginBottom: 10,
+        color: "#000",
+    },
+    aboutDetails: {
+        fontSize: 16,
+        color: "#555",
+        marginBottom: 5,
+    },
+    playButton: {
+        backgroundColor: "#007BFF",
+        paddingVertical: 15,
+        borderRadius: 10,
+        alignItems: "center",
+        justifyContent: "center",
+        marginTop: 20,
+    },
+    playButtonText: {
+        fontSize: 18,
+        fontWeight: "bold",
+        color: "white",
+    },
+});
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 5c6eda4..5abce9e 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -31,7 +31,7 @@ export default function TemplateQuizList({navigation, title, setTextInInput, qui
                 <Text style={styles.title}>{title}</Text>
                 <View style={styles.contentContainer}>
                     <InputPlayQuiz setText={setTextInInput} noTitle={true} />
-                    <QuizList  quizList={quizList}/>
+                    <QuizList  quizList={quizList} navigation={navigation}/>
                 </View>
             </View>
         </TemplateMenu>
-- 
GitLab


From 14572aaae516b764b97d5696a66e3c7656da2b2f Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 3 Dec 2024 22:41:33 +0100
Subject: [PATCH 051/283] =?UTF-8?q?add:=20d=C3=A9but=20de=20la=20modal=20l?=
 =?UTF-8?q?oginsignup?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 screens/Profil/ProfilChild.tsx |  5 ++-
 screens/Profil/ProfilModal.tsx | 72 ++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 screens/Profil/ProfilModal.tsx

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 5bcad82..c74af25 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -1,5 +1,7 @@
 import { NavigationProp } from "@react-navigation/native";
-import { View, StyleSheet, Image, Text } from "react-native";
+import { View, StyleSheet, Image, Text, Modal, Button } from "react-native";
+import ProfilModal from "./ProfilModal";
+import React, { useState } from "react";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -18,6 +20,7 @@ export default function ProfilChild({navigation}: Props) {
                 <Text style={styles.statsText}>right answer rate : _43%_</Text>
                 <Text style={styles.statsText}>Favorit category : _HISTORY AND CULTURE_</Text>
             </View>
+            <ProfilModal/>
         </View>
     )
 }
diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
new file mode 100644
index 0000000..a94b70d
--- /dev/null
+++ b/screens/Profil/ProfilModal.tsx
@@ -0,0 +1,72 @@
+import React, { useState } from "react";
+import { Modal, View, StyleSheet, Button, TextInput } from "react-native";
+
+export default function ProfilModal() {
+    const [modalVisible, setModalVisible] = useState(true);
+    return (
+        <Modal
+            animationType="slide"
+            transparent={true}
+            visible={modalVisible}
+            onRequestClose={() => {
+                setModalVisible(!modalVisible);
+            }}>
+            <View style={styles.container}>
+                <View style={styles.backgroundShadow}/>
+                <View style={styles.containerModal}>
+                    <View style={styles.containerNav}>
+                        <Button title="LOGIN"></Button>
+                        <Button title="SIGNUP"></Button>
+                    </View>
+                    <View>
+                        <TextInput placeholder="EMAIL..." style={styles.textInput}/>
+                        <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
+                        <TextInput placeholder="REPEAT PASSWORD..." style={styles.textInput}/>
+                    </View>
+                    <Button title="SIGNUP"/>
+                </View>
+            </View>
+        </Modal>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+      flex: 1,
+      justifyContent: 'center',
+      alignItems: 'center',
+      height: '100%',
+      width: '100%',
+    },
+    backgroundShadow: {
+        height: '100%',
+        width: '100%',
+        backgroundColor: '#000000',
+        opacity: 0.55,
+        position: 'absolute',
+    },
+    containerModal: {
+        height: '90%',
+        width: '90%',
+      backgroundColor: '#D9D9D9',
+      borderRadius: 40,
+      padding: 30
+    },
+    containerNav: {
+        height: '20%',
+        width: '90%',
+        padding: '10%',
+        backgroundColor: '#FFFFFF',
+        borderRadius: 10,
+        display: 'flex',
+        flexDirection: 'row'
+    },
+    textInput: {
+        height: '20%',
+        width: '90%',
+        backgroundColor: '#FFFFFF',
+        borderWidth: 4,
+        borderColor: '#1FA9FF',
+        borderRadius: 10
+    }  
+  });
\ No newline at end of file
-- 
GitLab


From ecc5161f912f49f2f1273a9cef867667dac4b9b6 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 09:40:09 +0100
Subject: [PATCH 052/283] add: style modal signup

---
 screens/Profil/ProfilModal.tsx | 89 +++++++++++++++++++++++++++-------
 1 file changed, 72 insertions(+), 17 deletions(-)

diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index a94b70d..0661c1a 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -1,8 +1,23 @@
 import React, { useState } from "react";
 import { Modal, View, StyleSheet, Button, TextInput } from "react-native";
+import DefaultButton from "../../components/DefaultButton";
 
 export default function ProfilModal() {
     const [modalVisible, setModalVisible] = useState(true);
+
+    const handleLoginPressed = () => {
+
+    };
+    
+    const handleSignupPressed = () => {
+
+    };
+
+    const handleSubmitPressed = () => {
+
+    }
+
+
     return (
         <Modal
             animationType="slide"
@@ -15,15 +30,15 @@ export default function ProfilModal() {
                 <View style={styles.backgroundShadow}/>
                 <View style={styles.containerModal}>
                     <View style={styles.containerNav}>
-                        <Button title="LOGIN"></Button>
-                        <Button title="SIGNUP"></Button>
+                        <DefaultButton text="LOGIN" handleButtonPressed={handleLoginPressed} buttonStyle={styles.navButton} buttonText={styles.navButtonText}/>
+                        <DefaultButton text="SIGNUP" handleButtonPressed={handleSignupPressed} buttonStyle={styles.navButton} buttonText={styles.navButtonText}/>
                     </View>
-                    <View>
+                    <View style={styles.containerForm}>
                         <TextInput placeholder="EMAIL..." style={styles.textInput}/>
                         <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
                         <TextInput placeholder="REPEAT PASSWORD..." style={styles.textInput}/>
                     </View>
-                    <Button title="SIGNUP"/>
+                    <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
                 </View>
             </View>
         </Modal>
@@ -46,27 +61,67 @@ const styles = StyleSheet.create({
         position: 'absolute',
     },
     containerModal: {
-        height: '90%',
+        height: 680,
         width: '90%',
-      backgroundColor: '#D9D9D9',
-      borderRadius: 40,
-      padding: 30
+        backgroundColor: '#D9D9D9',
+        borderRadius: 40,
+        padding: 30
     },
     containerNav: {
-        height: '20%',
-        width: '90%',
-        padding: '10%',
+        height: 80,
+        width: '100%',
+        display: 'flex',
+        flexDirection: 'row',
+        justifyContent: 'space-around',
+        alignItems: 'center',
         backgroundColor: '#FFFFFF',
         borderRadius: 10,
+        shadowColor: "#000",
+        shadowOffset: {
+            width: 0,
+            height: 3,
+        },
+        shadowOpacity: 0.29,
+        shadowRadius: 4.65,
+        elevation: 7,
+    },
+    navButton: {
+        height: 50,
+        width: '45%',
+        backgroundColor: '#FFFFFF',
+        borderBottomColor: '#B9B9B9',
+        borderBottomWidth: 3,
+        borderStyle: 'solid',
+    },
+    navButtonText: {
+        color: '#B9B9B9'
+    },
+    containerForm: {
+        height: 450,
+        width: '100%',
         display: 'flex',
-        flexDirection: 'row'
+        flexDirection: 'column',
+        justifyContent: 'space-around'
     },
     textInput: {
-        height: '20%',
-        width: '90%',
+        height: 80,
+        width: '100%',
         backgroundColor: '#FFFFFF',
         borderWidth: 4,
         borderColor: '#1FA9FF',
-        borderRadius: 10
-    }  
-  });
\ No newline at end of file
+        borderRadius: 10,
+        color: '#DFDFDF',
+        fontWeight: 'bold'
+    },
+    SubmitButton: {
+        height: 80,
+        width: '100%',
+        backgroundColor: '#1FA9FF',
+        borderRadius: 10,
+    },
+    SubmitText: {
+        fontSize: 20,
+        fontWeight: 'bold',
+        color: '#FFFFFF',
+    },
+});
\ No newline at end of file
-- 
GitLab


From 94c10697359f15ae155a1904758f0a08e6039aac Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 09:56:05 +0100
Subject: [PATCH 053/283] feat: PlayingQuiz UX refait

---
 assets/ImageJoinQuiz.png                      | Bin 58320 -> 0 bytes
 .../{PlayButton.tsx => BlueButton.tsx}        |   5 ++-
 routes/StackNavigator.tsx                     |   2 +-
 screens/Home/HomeChild.tsx                    |   5 ++-
 screens/PlayQuiz/PlayQuizChild.tsx            |   2 +-
 screens/PlayQuiz/PlayQuizGenerateQuiz.tsx     |   4 +-
 screens/PlayQuiz/PlayQuizJoinQuiz.tsx         |   4 +-
 screens/PlayingQuiz/PlayingQuizBody.tsx       |  35 ++++++++++-----
 screens/PlayingQuiz/PlayingQuizHeader.tsx     |  41 +++++++++++++-----
 styles/ButtonsStyles.ts                       |   2 +-
 styles/TextsStyles.ts                         |   4 +-
 templates/TemplateDuo.tsx                     |  22 +++++-----
 12 files changed, 82 insertions(+), 44 deletions(-)
 delete mode 100644 assets/ImageJoinQuiz.png
 rename components/PlayQuiz/{PlayButton.tsx => BlueButton.tsx} (77%)

diff --git a/assets/ImageJoinQuiz.png b/assets/ImageJoinQuiz.png
deleted file mode 100644
index 1f83b59b59b5aab112be427fcf1e1f76e914a316..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 58320
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
B--G}F

diff --git a/components/PlayQuiz/PlayButton.tsx b/components/PlayQuiz/BlueButton.tsx
similarity index 77%
rename from components/PlayQuiz/PlayButton.tsx
rename to components/PlayQuiz/BlueButton.tsx
index 2a68248..4e04f8d 100644
--- a/components/PlayQuiz/PlayButton.tsx
+++ b/components/PlayQuiz/BlueButton.tsx
@@ -4,10 +4,11 @@ import {NavigationProp} from "@react-navigation/native";
 interface Props {
     onPress: () => void
     text: string
+    buttonStyle?: any
 }
-export default function PlayButton({onPress, text} : Props) {
+export default function BlueButton({onPress, text, buttonStyle} : Props) {
     return (
-        <TouchableOpacity style={styles.container} onPress={onPress}>
+        <TouchableOpacity style={[styles.container, buttonStyle]} onPress={onPress}>
             <Text style={styles.text}>{text}</Text>
         </TouchableOpacity>
     );
diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index e2c2b96..cbfdc43 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -17,7 +17,7 @@ export default function StackNavigator() {
             <Stack.Navigator initialRouteName="TabNavigator">
                 <Stack.Screen name="TabNavigator" component={TabNavigator} options={{ headerShown: false }}/>
                 <Stack.Screen name="Home" component={Home} options={{ headerShown: false }}/>
-                <Stack.Screen name="CreateQuiz" component={GenerateQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="GenerateQuiz" component={GenerateQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="PlayingQuiz" component={PlayingQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="PlayQuiz" component={PlayQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="EndQuiz" component={EndQuiz} options={{ headerShown: false }}/>
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 9589ac5..cc792b7 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -19,6 +19,9 @@ export default function HomeChild({navigation}: Props) {
     const [modalVisible, setModalVisible] = useState(false);
     const {t} = useTranslation();
 
+    const handleButtonQuickGamePressed = () => {
+        navigation.navigate("GenerateQuiz");
+    }
     const handleButtonMyQuizzesPressed = () => {
         navigation.navigate("MyQuizzes");
     }
@@ -33,7 +36,7 @@ export default function HomeChild({navigation}: Props) {
                 <Image source={require('../../assets/TitleApp.png')} style={styles.image} />
             </View>
             <View style={styles.buttonContainer}>
-                <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
+                <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
                 <MenuButton text={"PLAY A QUIZ"} handleButtonPressed={handleButtonGeneratePressed}/>
                 <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
             </View>
diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
index ffd4f08..6f2089c 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -5,7 +5,7 @@ import React, {useState} from "react";
 import {SelectModeType} from "../../models/SelectModeType";
 import SelectListBox from "../../components/PlayQuiz/SelectListBox";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import PlayButton from "../../components/PlayQuiz/PlayButton";
+import BlueButton from "../../components/PlayQuiz/BlueButton";
 import PlayQuizGenerateQuiz from "./PlayQuizGenerateQuiz";
 import PlayQuizJoinQuiz from "./PlayQuizJoinQuiz";
 
diff --git a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
index 438202c..7a2d380 100644
--- a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -2,7 +2,7 @@ import { Text,View, StyleSheet } from "react-native";
 import SelectListBox from "../../components/PlayQuiz/SelectListBox";
 import React from "react";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import PlayButton from "../../components/PlayQuiz/PlayButton";
+import BlueButton from "../../components/PlayQuiz/BlueButton";
 
 const difficulty = [
     { key: "easy", value: "Easy" },
@@ -44,7 +44,7 @@ export default function PlayQuizGenerateQuiz() {
                     <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={() => {}} />
                 </View>
                 <View style={styles.buttonPlayContainer}>
-                    <PlayButton onPress={handlePlayButtonPress} text={"PLAY"} />
+                    <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} />
                 </View>
             </View>
         </View>
diff --git a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
index b5117f2..93f5310 100644
--- a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -1,6 +1,6 @@
 import {StyleSheet, View} from "react-native";
 import AboutAQuiz from "../../components/PlayQuiz/AboutAQuiz";
-import PlayButton from "../../components/PlayQuiz/PlayButton";
+import BlueButton from "../../components/PlayQuiz/BlueButton";
 import React from "react";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
 import QuizModel from "../../models/QuizModel";
@@ -20,7 +20,7 @@ export default function PlayQuizJoinQuiz() {
                     <AboutAQuiz />
                 </View>
                 <View style={styles.buttonPlayContainer}>
-                    <PlayButton onPress={handlePlayButtonPress} text={"PLAY"} />
+                    <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} />
                 </View>
             </View>
         </View>
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 44afa35..1b2c895 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -9,6 +9,7 @@ import QuestionModel from "../../models/QuestionModel";
 import AnswerModel from "../../models/AnswerModel";
 import {NavigationProp} from "@react-navigation/native";
 import HttpError from "../../services/HttpError";
+import BlueButton from "../../components/PlayQuiz/BlueButton";
 
 interface Props {
     quiz: QuizModel;
@@ -104,22 +105,28 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
     return (
         <View style={styles.buttonContainer}>
             {currentQuestion ? (
-                currentQuestion.answers.map((answer, index) => (
-                    <DefaultButton
-                        key={index}
-                        text={answer.text}
-                        handleButtonPressed={() => handleAnswerPress(index)}
-                        buttonStyle={getButtonStyle(index)}
-                        buttonText={getTextStyle(index)}
-                    />
-                ))
+                <>
+                    {currentQuestion.answers.map((answer, index) => (
+                        <DefaultButton
+                            key={index}
+                            text={answer.text}
+                            handleButtonPressed={() => handleAnswerPress(index)}
+                            buttonStyle={getButtonStyle(index)}
+                            buttonText={getTextStyle(index)}
+                        />
+                    ))}
+                    {/* Ajout du PlayButton à la fin */}
+                    <View style={styles.playButtonContainer}>
+                        <BlueButton onPress={() => console.log("Play button pressed")} text="Play" buttonStyle={{borderRadius: 50}}/>
+                    </View>
+                </>
             ) : (
                 <Text style={styles.loadingText}>Loading...</Text>
             )}
         </View>
     );
-}
 
+}
 const styles = StyleSheet.create({
     buttonContainer: {
         display: 'flex',
@@ -127,7 +134,12 @@ const styles = StyleSheet.create({
         alignItems: 'center',
         justifyContent: 'flex-start',
         width: '100%',
-        marginVertical: '10%',
+        marginVertical: '3%',
+    },
+    playButtonContainer: {
+        marginTop: 20, // Ajoute un espacement au-dessus du bouton Play
+        width: '80%', // S'assure que le bouton prend toute la largeur disponible
+        alignItems: 'center', // Centre le bouton horizontalement
     },
     correctAnswer: {
         ...ButtonsStyles.answerButton,
@@ -153,3 +165,4 @@ const styles = StyleSheet.create({
         textAlign: 'center',
     },
 });
+
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 0b0b803..a04bded 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -5,6 +5,7 @@ import {useTranslation} from "react-i18next";
 import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
+
     quiz: QuizModel;
 }
 
@@ -18,15 +19,17 @@ export default function PlayingQuizHeader({quiz}: Props) {
     return (
             <View style={styles.container}>
                 <View>
-                    <DefaultButton text="<" handleButtonPressed={handleButtonBackToHomePressed}/> 
-                    <Text>ID QUIZZ : 7</Text>
-                </View>
-                <View style={styles.infoQuizContainer}>
-                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.category")} : {quiz.questions[quiz.nbActualQuestion-1].category ? quiz.questions[quiz.nbActualQuestion-1].category : "Loading..."}</Text>
-                    <Text style={TextsStyles.infoQuizText}>{t("app.screens.question.score")} : {quiz ? quiz.score : 0}</Text>
+                    <Text style={styles.codeQuizText}>ID QUIZZ : {quiz ? quiz.code : "?"}</Text>
                 </View>
-                <View style={styles.QuizNumContainer}>
-                    <Text style={TextsStyles.titleText}>{t("app.screens.question.question")} {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
+                <View style={styles.questionAndScoreContainer}>
+                    <View style={styles.InformationsContainer}>
+                        <Text style={TextsStyles.titleText}>{t("app.screens.question.question")}</Text>
+                        <Text style={TextsStyles.titleText}>{quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
+                    </View>
+                    <View style={styles.InformationsContainer}>
+                        <Text style={TextsStyles.titleText}>{t("app.screens.question.score")}</Text>
+                        <Text style={TextsStyles.titleText}>{quiz ? quiz.score : 0}/{quiz ? quiz.nbQuestions : "?"}</Text>
+                    </View>
                 </View>
                 <View style={styles.QuizQuestionContainer}>
                     <Text style={TextsStyles.subtitleText}>{quiz.questions[quiz.nbActualQuestion-1].question ? quiz.questions[quiz.nbActualQuestion-1].question : "Loading..."}</Text>
@@ -37,11 +40,23 @@ export default function PlayingQuizHeader({quiz}: Props) {
 
 const styles = StyleSheet.create({
     container: {
-        marginVertical: "10%",
-        marginHorizontal: "5%",
+        marginHorizontal: '5%',
+    },
+    questionAndScoreContainer: {
+        display: 'flex',
+        flexDirection: 'row',
+        justifyContent: 'space-around',
+        alignItems: 'center',
+        marginVertical: '2%',
+    },
+    InformationsContainer: {
+        display: 'flex',
+        flexDirection: 'column',
+        justifyContent: 'center',
+        alignItems: 'center',
+        gap: '5%',
     },
     QuizNumContainer: {
-        marginVertical: "2.5%",
     },
     QuizQuestionContainer: {
         marginVertical: "2.5%",
@@ -49,4 +64,8 @@ const styles = StyleSheet.create({
     infoQuizContainer: {
         marginBottom: '5%',
     },
+    codeQuizText: {
+        fontSize: 18,
+        color: '#000000',
+    },
 });
\ No newline at end of file
diff --git a/styles/ButtonsStyles.ts b/styles/ButtonsStyles.ts
index ebe03d7..4f56435 100644
--- a/styles/ButtonsStyles.ts
+++ b/styles/ButtonsStyles.ts
@@ -9,7 +9,7 @@ export const ButtonsStyles = StyleSheet.create( {
     },
     answerButton: {
         backgroundColor: "#F3F3F3",
-        height: '20%',
+        height: '15%',
         alignItems: 'center',
         width: '80%',
         marginVertical: '3%',
diff --git a/styles/TextsStyles.ts b/styles/TextsStyles.ts
index a6bdfb9..1f80ebd 100644
--- a/styles/TextsStyles.ts
+++ b/styles/TextsStyles.ts
@@ -2,11 +2,11 @@ import { StyleSheet } from "react-native";
 export const TextsStyles = StyleSheet.create( {
     defaultText: {
         color: 'black',
-        fontSize: 20,
+        fontSize: 17,
     },
     defaultButtonText: {
         color: "white",
-        fontSize: 20,
+        fontSize: 17,
     },
     titleText: {
         fontSize: 24,
diff --git a/templates/TemplateDuo.tsx b/templates/TemplateDuo.tsx
index 786c5ec..97a225e 100644
--- a/templates/TemplateDuo.tsx
+++ b/templates/TemplateDuo.tsx
@@ -1,4 +1,4 @@
-import { ImageBackground, Text, View, StyleSheet } from "react-native";
+import {ImageBackground, Text, View, StyleSheet, SafeAreaView} from "react-native";
 
 interface Props{
     childrenHeader?: React.ReactNode
@@ -8,13 +8,15 @@ interface Props{
 export default function TemplateDuo({childrenHeader, childrenBody}: Props) {
     return (
         <View style={styles.container}>
-            <ImageBackground source={require('../assets/FondDuo.png')} style={styles.image}>
-                <View style={styles.containerHeader}>
-                    {childrenHeader}
-                </View>
-                <View style={styles.containerBody}>
-                    {childrenBody}
-                </View>
+            <ImageBackground source={require('../assets/BackgroundQuestion.png')} style={styles.image}>
+                    <SafeAreaView>
+                    <View style={styles.containerHeader}>
+                        {childrenHeader}
+                    </View>
+                    <View style={styles.containerBody}>
+                        {childrenBody}
+                    </View>
+                </SafeAreaView>
             </ImageBackground>
         </View>
     );
@@ -29,11 +31,11 @@ const styles = StyleSheet.create({
     },
     containerHeader: {
         width: '100%',
-        height: '30%',
+        height: '26%',
     },
     containerBody: {
         width: '100%',
-        height: '70%',
+        height: '78%',
         backgroundColor: '#FFFFFF',
         borderTopLeftRadius: 46,
         borderTopRightRadius: 46
-- 
GitLab


From dde2a789e49f341588210ac3f0359e1481008ab2 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 10:00:09 +0100
Subject: [PATCH 054/283] =?UTF-8?q?add:=20header=20pour=20cr=C3=A9er=20un?=
 =?UTF-8?q?=20compte?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 screens/Profil/ProfilChild.tsx | 39 +++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index c74af25..05672f8 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -1,5 +1,5 @@
 import { NavigationProp } from "@react-navigation/native";
-import { View, StyleSheet, Image, Text, Modal, Button } from "react-native";
+import { View, StyleSheet, Image, Text, Modal, Button, TouchableOpacity } from "react-native";
 import ProfilModal from "./ProfilModal";
 import React, { useState } from "react";
 
@@ -10,6 +10,7 @@ interface Props {
 export default function ProfilChild({navigation}: Props) {
     return (
         <View style={styles.containerGlobal}>
+            
             <View style={styles.containerPlayerInfos}>
                 <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage}/>
                 <Image source={require('../../assets/ProfilBaseImage.png')} style={styles.profilImage}/>
@@ -20,6 +21,22 @@ export default function ProfilChild({navigation}: Props) {
                 <Text style={styles.statsText}>right answer rate : _43%_</Text>
                 <Text style={styles.statsText}>Favorit category : _HISTORY AND CULTURE_</Text>
             </View>
+
+
+            <View style={styles.containerHeader}>
+                <Text style={styles.textHeader}>
+                    <TouchableOpacity onPress={() => handlePress('bouton 1')}>
+                    <Text style={styles.buttonHeader}>LOGIN</Text>
+                    </TouchableOpacity>
+                    {'  OR  '}
+                    <TouchableOpacity onPress={() => handlePress('bouton 2')}>
+                    <Text style={styles.buttonHeader}>CREATE AN ACCOUNT</Text>
+                    </TouchableOpacity>
+                </Text>
+            </View>
+
+
+
             <ProfilModal/>
         </View>
     )
@@ -61,4 +78,24 @@ const styles = StyleSheet.create({
         fontSize: 17,
         fontWeight: 'bold',
     },
+    containerHeader: {
+        backgroundColor: '#D9D9D9',
+        height: '10%',
+        width: '100%',
+        position: 'absolute',
+        display: 'flex', 
+        justifyContent: 'center',
+        alignItems: 'center'
+    },
+    textHeader: {
+        color: '#000000',
+        fontSize: 15,
+        fontWeight: 'bold',
+    },
+    buttonHeader: {
+        textDecorationLine: 'underline',
+        color: '#000000',
+        fontSize: 15,
+        fontWeight: 'bold',
+    }
 });
\ No newline at end of file
-- 
GitLab


From 2db7d5baba58670c0f328293d7a1f0cbd5911ab2 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 10:06:34 +0100
Subject: [PATCH 055/283] add: gestion de l'affichage de la modal

---
 screens/Profil/ProfilChild.tsx | 12 +++++++++---
 screens/Profil/ProfilModal.tsx |  9 +++++++--
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 05672f8..0e56187 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -8,6 +8,12 @@ interface Props {
 }
 
 export default function ProfilChild({navigation}: Props) {
+    const [modalVisible, setModalVisible] = useState(false);
+
+    const handleAccountPress = (IsLogin:Boolean) => {
+        setModalVisible(true);
+    };
+
     return (
         <View style={styles.containerGlobal}>
             
@@ -25,11 +31,11 @@ export default function ProfilChild({navigation}: Props) {
 
             <View style={styles.containerHeader}>
                 <Text style={styles.textHeader}>
-                    <TouchableOpacity onPress={() => handlePress('bouton 1')}>
+                    <TouchableOpacity onPress={() => handleAccountPress(true)}>
                     <Text style={styles.buttonHeader}>LOGIN</Text>
                     </TouchableOpacity>
                     {'  OR  '}
-                    <TouchableOpacity onPress={() => handlePress('bouton 2')}>
+                    <TouchableOpacity onPress={() => handleAccountPress(false)}>
                     <Text style={styles.buttonHeader}>CREATE AN ACCOUNT</Text>
                     </TouchableOpacity>
                 </Text>
@@ -37,7 +43,7 @@ export default function ProfilChild({navigation}: Props) {
 
 
 
-            <ProfilModal/>
+            <ProfilModal modalVisible={modalVisible} setModalVisible={setModalVisible}/>
         </View>
     )
 }
diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index 0661c1a..418c0a7 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -2,8 +2,13 @@ import React, { useState } from "react";
 import { Modal, View, StyleSheet, Button, TextInput } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 
-export default function ProfilModal() {
-    const [modalVisible, setModalVisible] = useState(true);
+interface Props{
+    modalVisible: boolean;
+    setModalVisible: (visible: boolean) => void;
+}
+
+export default function ProfilModal({modalVisible ,setModalVisible}: Props) {
+    
 
     const handleLoginPressed = () => {
 
-- 
GitLab


From eab8795090b654662d85f834b290184a683e6606 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 10:11:38 +0100
Subject: [PATCH 056/283] refactor: creation d'un composant profilheaderaccount

---
 screens/Profil/ProfilChild.tsx         | 47 ++++--------------------
 screens/Profil/ProfilHeaderAccount.tsx | 49 ++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 41 deletions(-)
 create mode 100644 screens/Profil/ProfilHeaderAccount.tsx

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 0e56187..1916f1f 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -2,6 +2,7 @@ import { NavigationProp } from "@react-navigation/native";
 import { View, StyleSheet, Image, Text, Modal, Button, TouchableOpacity } from "react-native";
 import ProfilModal from "./ProfilModal";
 import React, { useState } from "react";
+import ProfilHeaderAccount from "./ProfilHeaderAccount";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -10,13 +11,10 @@ interface Props {
 export default function ProfilChild({navigation}: Props) {
     const [modalVisible, setModalVisible] = useState(false);
 
-    const handleAccountPress = (IsLogin:Boolean) => {
-        setModalVisible(true);
-    };
+    
 
     return (
         <View style={styles.containerGlobal}>
-            
             <View style={styles.containerPlayerInfos}>
                 <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage}/>
                 <Image source={require('../../assets/ProfilBaseImage.png')} style={styles.profilImage}/>
@@ -28,21 +26,7 @@ export default function ProfilChild({navigation}: Props) {
                 <Text style={styles.statsText}>Favorit category : _HISTORY AND CULTURE_</Text>
             </View>
 
-
-            <View style={styles.containerHeader}>
-                <Text style={styles.textHeader}>
-                    <TouchableOpacity onPress={() => handleAccountPress(true)}>
-                    <Text style={styles.buttonHeader}>LOGIN</Text>
-                    </TouchableOpacity>
-                    {'  OR  '}
-                    <TouchableOpacity onPress={() => handleAccountPress(false)}>
-                    <Text style={styles.buttonHeader}>CREATE AN ACCOUNT</Text>
-                    </TouchableOpacity>
-                </Text>
-            </View>
-
-
-
+            <ProfilHeaderAccount setModalVisible={setModalVisible}/>
             <ProfilModal modalVisible={modalVisible} setModalVisible={setModalVisible}/>
         </View>
     )
@@ -62,9 +46,9 @@ const styles = StyleSheet.create({
         alignItems: 'center',   
     },
     titleImage: {
-        width: 170, // Ajustez en fonction de la taille de l'image
+        width: 170,
         height: 80,
-        resizeMode: 'contain', // Pour conserver les proportions
+        resizeMode: 'contain',
     },
     profilImage: {
         height: 200,
@@ -84,24 +68,5 @@ const styles = StyleSheet.create({
         fontSize: 17,
         fontWeight: 'bold',
     },
-    containerHeader: {
-        backgroundColor: '#D9D9D9',
-        height: '10%',
-        width: '100%',
-        position: 'absolute',
-        display: 'flex', 
-        justifyContent: 'center',
-        alignItems: 'center'
-    },
-    textHeader: {
-        color: '#000000',
-        fontSize: 15,
-        fontWeight: 'bold',
-    },
-    buttonHeader: {
-        textDecorationLine: 'underline',
-        color: '#000000',
-        fontSize: 15,
-        fontWeight: 'bold',
-    }
+    
 });
\ No newline at end of file
diff --git a/screens/Profil/ProfilHeaderAccount.tsx b/screens/Profil/ProfilHeaderAccount.tsx
new file mode 100644
index 0000000..c508ce9
--- /dev/null
+++ b/screens/Profil/ProfilHeaderAccount.tsx
@@ -0,0 +1,49 @@
+import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
+
+interface Props {
+    setModalVisible: (visible:boolean) => void;
+}
+
+export default function ProfilHeaderAccount({ setModalVisible }: Props) {
+    const handleAccountPress = (IsLogin:Boolean) => {
+        setModalVisible(true);
+    };
+
+    return (
+        <View style={styles.containerHeader}>
+            <Text style={styles.textHeader}>
+                <TouchableOpacity onPress={() => handleAccountPress(true)}>
+                <Text style={styles.buttonHeader}>LOGIN</Text>
+                </TouchableOpacity>
+                {'  OR  '}
+                <TouchableOpacity onPress={() => handleAccountPress(false)}>
+                <Text style={styles.buttonHeader}>CREATE AN ACCOUNT</Text>
+                </TouchableOpacity>
+            </Text>
+        </View>
+    )
+}
+
+
+const styles = StyleSheet.create({
+    containerHeader: {
+        backgroundColor: '#D9D9D9',
+        height: '10%',
+        width: '100%',
+        position: 'absolute',
+        display: 'flex', 
+        justifyContent: 'center',
+        alignItems: 'center'
+    },
+    textHeader: {
+        color: '#000000',
+        fontSize: 15,
+        fontWeight: 'bold',
+    },
+    buttonHeader: {
+        textDecorationLine: 'underline',
+        color: '#000000',
+        fontSize: 15,
+        fontWeight: 'bold',
+    },
+});
\ No newline at end of file
-- 
GitLab


From 1ac49130e82c4327748851b7a68e3b3ebb925d3b Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 11:14:28 +0100
Subject: [PATCH 057/283] add: utilisation du composat selectmode pour la modal
 profil

---
 models/SelectModeType.ts            |  3 +-
 screens/Profil/ProfilModal.tsx      | 19 ++++++--
 screens/Profil/ProfilSelectMode.tsx | 74 +++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+), 6 deletions(-)
 create mode 100644 screens/Profil/ProfilSelectMode.tsx

diff --git a/models/SelectModeType.ts b/models/SelectModeType.ts
index b664180..8c155fa 100644
--- a/models/SelectModeType.ts
+++ b/models/SelectModeType.ts
@@ -1 +1,2 @@
-export type SelectModeType = "play" | "join";
\ No newline at end of file
+export type SelectModeType = "play" | "join";
+export type ProfilSelectModeType = "login" | "signup";
\ No newline at end of file
diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index 418c0a7..bee2b5f 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -1,6 +1,9 @@
 import React, { useState } from "react";
 import { Modal, View, StyleSheet, Button, TextInput } from "react-native";
-import DefaultButton from "../../components/DefaultButton";
+import ProfilSelectMode from "./ProfilSelectMode";
+import { ProfilSelectModeType } from "../../models/SelectModeType";
+import ProfilModalLogin from "./ProfilModalLogin";
+import ProfilModalSignup from "./ProfilModalSignup";
 
 interface Props{
     modalVisible: boolean;
@@ -8,7 +11,7 @@ interface Props{
 }
 
 export default function ProfilModal({modalVisible ,setModalVisible}: Props) {
-    
+    const [mode, setMode] = useState<ProfilSelectModeType>("login");
 
     const handleLoginPressed = () => {
 
@@ -34,7 +37,13 @@ export default function ProfilModal({modalVisible ,setModalVisible}: Props) {
             <View style={styles.container}>
                 <View style={styles.backgroundShadow}/>
                 <View style={styles.containerModal}>
-                    <View style={styles.containerNav}>
+                    <ProfilSelectMode mode={mode} setMode={setMode}/>
+                    {mode === "login" ? (
+                        <ProfilModalLogin />
+                    ) : (
+                        <ProfilModalSignup />
+                    )}
+                    {/* <View style={styles.containerNav}>
                         <DefaultButton text="LOGIN" handleButtonPressed={handleLoginPressed} buttonStyle={styles.navButton} buttonText={styles.navButtonText}/>
                         <DefaultButton text="SIGNUP" handleButtonPressed={handleSignupPressed} buttonStyle={styles.navButton} buttonText={styles.navButtonText}/>
                     </View>
@@ -43,8 +52,8 @@ export default function ProfilModal({modalVisible ,setModalVisible}: Props) {
                         <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
                         <TextInput placeholder="REPEAT PASSWORD..." style={styles.textInput}/>
                     </View>
-                    <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
-                </View>
+                    <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/> */}
+                </View> 
             </View>
         </Modal>
     );
diff --git a/screens/Profil/ProfilSelectMode.tsx b/screens/Profil/ProfilSelectMode.tsx
new file mode 100644
index 0000000..7a6d0d7
--- /dev/null
+++ b/screens/Profil/ProfilSelectMode.tsx
@@ -0,0 +1,74 @@
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import { ProfilSelectModeType } from "../../models/SelectModeType";
+
+interface Props {
+    mode: ProfilSelectModeType;
+    setMode: (mode: ProfilSelectModeType) => void;
+}
+
+export default function ProfilSelectMode({ mode, setMode }: Props) {
+    return (
+        <View style={styles.container}>
+            <View style={styles.buttonContainer}>
+                <TouchableOpacity onPress={() => setMode("login")} style={{marginLeft: '10%'}}>
+                    <Text style={[styles.text, mode === "login" && styles.activeText]}>LOGIN</Text>
+                </TouchableOpacity>
+                <View style={[styles.bar, mode === "login" ? styles.activeBar : styles.inactiveBar]} />
+            </View>
+
+            <View style={styles.buttonContainer}>
+                <TouchableOpacity onPress={() => setMode("signup")} style={{marginRight: '10%'}}>
+                    <Text style={[styles.text, mode === "signup" && styles.activeText]}>SIGNUP</Text>
+                </TouchableOpacity>
+                <View style={[styles.bar, mode === "signup" ? styles.activeBar : styles.inactiveBar]} />
+            </View>
+
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: 'flex',
+        width: '100%',
+        height: '10%',
+        flexDirection: 'row',
+        backgroundColor: '#f3f3f3',
+        borderRadius: 10,
+        justifyContent: 'space-around',
+        alignItems: 'center',
+        // Ombre pour Android
+        elevation: 5,
+        // Ombre pour iOS
+        shadowColor: '#000',
+        shadowOffset: { width: 0, height: 4 }, // Décalage de l'ombre en bas
+        shadowOpacity: 0.25, // Opacité de l'ombre
+        shadowRadius: 3.84, // Flou de l'ombre
+    },
+    buttonContainer: {
+        display: 'flex',
+        flexDirection: 'column',
+        width: '40%',
+        alignItems: 'center',
+        gap: "5%",
+    },
+    text: {
+        fontSize: 25,
+        color: '#bebebe',
+    },
+    activeText: {
+        color: '#2ec7ff',
+    },
+    bar: {
+        width: '100%',
+        height: 4,
+        marginTop: 4,
+        borderRadius: 10,
+    },
+    activeBar: {
+        backgroundColor: '#2ec7ff', // Couleur pour le bouton actif
+    },
+    inactiveBar: {
+        backgroundColor: '#bebebe', // Couleur grise pour les boutons inactifs
+    },
+});
-- 
GitLab


From 73f39aaa7567b4878a903b3f0f5daf67a2a0d583 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 11:15:01 +0100
Subject: [PATCH 058/283] refactor: creation de composant pour les soous partie
 de la modal

---
 screens/Profil/ProfilModalLogin.tsx  | 51 +++++++++++++++++++++++++++
 screens/Profil/ProfilModalSignup.tsx | 52 ++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+)
 create mode 100644 screens/Profil/ProfilModalLogin.tsx
 create mode 100644 screens/Profil/ProfilModalSignup.tsx

diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/ProfilModalLogin.tsx
new file mode 100644
index 0000000..d4fbbe8
--- /dev/null
+++ b/screens/Profil/ProfilModalLogin.tsx
@@ -0,0 +1,51 @@
+import { TextInput, View, StyleSheet } from "react-native";
+import DefaultButton from "../../components/DefaultButton";
+
+export default function ProfilModalLogin() {
+    const handleSubmitPressed = () => {
+
+    }
+
+    return (
+        <View>
+            <View style={styles.containerForm}>
+                <TextInput placeholder="EMAIL..." style={styles.textInput}/>
+                <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
+            </View>
+            <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
+        </View>
+    )
+}
+
+const styles = StyleSheet.create({
+    containerForm: {
+        height: 400,
+        width: '100%',
+        display: 'flex',
+        flexDirection: 'column',
+        justifyContent: 'flex-start',
+        rowGap: 50,
+        marginTop: 50,
+    },
+    textInput: {
+        height: 80,
+        width: '100%',
+        backgroundColor: '#FFFFFF',
+        borderWidth: 4,
+        borderColor: '#1FA9FF',
+        borderRadius: 10,
+        color: '#DFDFDF',
+        fontWeight: 'bold'
+    },
+    SubmitButton: {
+        height: 80,
+        width: '100%',
+        backgroundColor: '#1FA9FF',
+        borderRadius: 10,
+    },
+    SubmitText: {
+        fontSize: 20,
+        fontWeight: 'bold',
+        color: '#FFFFFF',
+    },
+});
\ No newline at end of file
diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/ProfilModalSignup.tsx
new file mode 100644
index 0000000..43fa0f2
--- /dev/null
+++ b/screens/Profil/ProfilModalSignup.tsx
@@ -0,0 +1,52 @@
+import { TextInput, View, StyleSheet } from "react-native";
+import DefaultButton from "../../components/DefaultButton";
+
+export default function ProfilModalSignup() {
+    const handleSubmitPressed = () => {
+
+    }
+
+    return (
+        <View>
+            <View style={styles.containerForm}>
+                <TextInput placeholder="EMAIL..." style={styles.textInput}/>
+                <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
+                <TextInput placeholder="REPEAT PASSWORD..." style={styles.textInput}/>
+            </View>
+            <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
+        </View>
+    )
+}
+
+const styles = StyleSheet.create({
+    containerForm: {
+        height: 400,
+        width: '100%',
+        display: 'flex',
+        flexDirection: 'column',
+        justifyContent: 'flex-start',
+        rowGap: 50,
+        marginTop: 50
+    },
+    textInput: {
+        height: 80,
+        width: '100%',
+        backgroundColor: '#FFFFFF',
+        borderWidth: 4,
+        borderColor: '#1FA9FF',
+        borderRadius: 10,
+        color: '#DFDFDF',
+        fontWeight: 'bold'
+    },
+    SubmitButton: {
+        height: 80,
+        width: '100%',
+        backgroundColor: '#1FA9FF',
+        borderRadius: 10,
+    },
+    SubmitText: {
+        fontSize: 20,
+        fontWeight: 'bold',
+        color: '#FFFFFF',
+    },
+});
\ No newline at end of file
-- 
GitLab


From 352b58091c2a270b308855aae21f94f0cff36f7d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 11:21:27 +0100
Subject: [PATCH 059/283] add: redirection vers la bonne sous page de la modal

---
 screens/Profil/ProfilChild.tsx         |  8 ++++----
 screens/Profil/ProfilHeaderAccount.tsx | 11 +++++++----
 screens/Profil/ProfilModal.tsx         | 16 +++-------------
 3 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 1916f1f..f5f6ecb 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -3,6 +3,7 @@ import { View, StyleSheet, Image, Text, Modal, Button, TouchableOpacity } from "
 import ProfilModal from "./ProfilModal";
 import React, { useState } from "react";
 import ProfilHeaderAccount from "./ProfilHeaderAccount";
+import { ProfilSelectModeType } from "../../models/SelectModeType";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -10,8 +11,7 @@ interface Props {
 
 export default function ProfilChild({navigation}: Props) {
     const [modalVisible, setModalVisible] = useState(false);
-
-    
+    const [mode, setMode] = useState<ProfilSelectModeType>("login");
 
     return (
         <View style={styles.containerGlobal}>
@@ -26,8 +26,8 @@ export default function ProfilChild({navigation}: Props) {
                 <Text style={styles.statsText}>Favorit category : _HISTORY AND CULTURE_</Text>
             </View>
 
-            <ProfilHeaderAccount setModalVisible={setModalVisible}/>
-            <ProfilModal modalVisible={modalVisible} setModalVisible={setModalVisible}/>
+            <ProfilHeaderAccount setModalVisible={setModalVisible} setMode={setMode}/>
+            <ProfilModal modalVisible={modalVisible} setModalVisible={setModalVisible} mode={mode} setMode={setMode}/>
         </View>
     )
 }
diff --git a/screens/Profil/ProfilHeaderAccount.tsx b/screens/Profil/ProfilHeaderAccount.tsx
index c508ce9..c6e4a3d 100644
--- a/screens/Profil/ProfilHeaderAccount.tsx
+++ b/screens/Profil/ProfilHeaderAccount.tsx
@@ -1,22 +1,25 @@
 import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
+import { ProfilSelectModeType } from "../../models/SelectModeType";
 
 interface Props {
     setModalVisible: (visible:boolean) => void;
+    setMode: (mode: ProfilSelectModeType) => void;
 }
 
-export default function ProfilHeaderAccount({ setModalVisible }: Props) {
-    const handleAccountPress = (IsLogin:Boolean) => {
+export default function ProfilHeaderAccount({ setModalVisible, setMode }: Props) {
+    const handleAccountPress = (mode:ProfilSelectModeType) => {
+        setMode(mode);
         setModalVisible(true);
     };
 
     return (
         <View style={styles.containerHeader}>
             <Text style={styles.textHeader}>
-                <TouchableOpacity onPress={() => handleAccountPress(true)}>
+                <TouchableOpacity onPress={() => handleAccountPress('login')}>
                 <Text style={styles.buttonHeader}>LOGIN</Text>
                 </TouchableOpacity>
                 {'  OR  '}
-                <TouchableOpacity onPress={() => handleAccountPress(false)}>
+                <TouchableOpacity onPress={() => handleAccountPress('signup')}>
                 <Text style={styles.buttonHeader}>CREATE AN ACCOUNT</Text>
                 </TouchableOpacity>
             </Text>
diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index bee2b5f..4049c6d 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -8,11 +8,11 @@ import ProfilModalSignup from "./ProfilModalSignup";
 interface Props{
     modalVisible: boolean;
     setModalVisible: (visible: boolean) => void;
+    mode: ProfilSelectModeType;
+    setMode: (mode: ProfilSelectModeType) => void;
 }
 
-export default function ProfilModal({modalVisible ,setModalVisible}: Props) {
-    const [mode, setMode] = useState<ProfilSelectModeType>("login");
-
+export default function ProfilModal({modalVisible ,setModalVisible, mode, setMode}: Props) {
     const handleLoginPressed = () => {
 
     };
@@ -43,16 +43,6 @@ export default function ProfilModal({modalVisible ,setModalVisible}: Props) {
                     ) : (
                         <ProfilModalSignup />
                     )}
-                    {/* <View style={styles.containerNav}>
-                        <DefaultButton text="LOGIN" handleButtonPressed={handleLoginPressed} buttonStyle={styles.navButton} buttonText={styles.navButtonText}/>
-                        <DefaultButton text="SIGNUP" handleButtonPressed={handleSignupPressed} buttonStyle={styles.navButton} buttonText={styles.navButtonText}/>
-                    </View>
-                    <View style={styles.containerForm}>
-                        <TextInput placeholder="EMAIL..." style={styles.textInput}/>
-                        <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
-                        <TextInput placeholder="REPEAT PASSWORD..." style={styles.textInput}/>
-                    </View>
-                    <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/> */}
                 </View> 
             </View>
         </Modal>
-- 
GitLab


From 245deeb73620718d36fd5f48eb31668c17b91f43 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 11:37:22 +0100
Subject: [PATCH 060/283] refactor: suppression du code inutile

---
 package-lock.json        | 22 ++++++++++++++++++++++
 package.json             |  1 +
 routes/TabNavigation.tsx |  4 ----
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 82b5a9e..b4a0a5f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,6 +29,7 @@
         "@babel/core": "^7.20.0",
         "@types/he": "^1.2.3",
         "@types/react": "~18.3.12",
+        "@types/react-native-vector-icons": "^6.4.18",
         "typescript": "~5.3.3"
       }
     },
@@ -4078,6 +4079,27 @@
         "csstype": "^3.0.2"
       }
     },
+    "node_modules/@types/react-native": {
+      "version": "0.70.19",
+      "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.70.19.tgz",
+      "integrity": "sha512-c6WbyCgWTBgKKMESj/8b4w+zWcZSsCforson7UdXtXMecG3MxCinYi6ihhrHVPyUrVzORsvEzK8zg32z4pK6Sg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/react": "*"
+      }
+    },
+    "node_modules/@types/react-native-vector-icons": {
+      "version": "6.4.18",
+      "resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.18.tgz",
+      "integrity": "sha512-YGlNWb+k5laTBHd7+uZowB9DpIK3SXUneZqAiKQaj1jnJCZM0x71GDim5JCTMi4IFkhc9m8H/Gm28T5BjyivUw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/react": "*",
+        "@types/react-native": "^0.70"
+      }
+    },
     "node_modules/@types/stack-utils": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
diff --git a/package.json b/package.json
index 6193974..c8ebea8 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
     "@babel/core": "^7.20.0",
     "@types/he": "^1.2.3",
     "@types/react": "~18.3.12",
+    "@types/react-native-vector-icons": "^6.4.18",
     "typescript": "~5.3.3"
   },
   "private": true
diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index 4dc8def..834245c 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -44,10 +44,6 @@ export default function TabNavigator() {
                 name="Home"
                 component={Home}
             />
-            {/*<Tab.Screen*/}
-            {/*    name="Profil"*/}
-            {/*    component={Profil}*/}
-            {/*/>*/}
             <Tab.Screen
                 name="Community"
                 component={Community}
-- 
GitLab


From 82ab3618cf6d79972290b5fbda11b1d0ff5287b1 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 11:45:10 +0100
Subject: [PATCH 061/283] fix: alignement texte header

---
 screens/Profil/ProfilHeaderAccount.tsx | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/screens/Profil/ProfilHeaderAccount.tsx b/screens/Profil/ProfilHeaderAccount.tsx
index c6e4a3d..6afcc5d 100644
--- a/screens/Profil/ProfilHeaderAccount.tsx
+++ b/screens/Profil/ProfilHeaderAccount.tsx
@@ -14,15 +14,13 @@ export default function ProfilHeaderAccount({ setModalVisible, setMode }: Props)
 
     return (
         <View style={styles.containerHeader}>
-            <Text style={styles.textHeader}>
-                <TouchableOpacity onPress={() => handleAccountPress('login')}>
+            <TouchableOpacity onPress={() => handleAccountPress('login')}>
                 <Text style={styles.buttonHeader}>LOGIN</Text>
-                </TouchableOpacity>
-                {'  OR  '}
-                <TouchableOpacity onPress={() => handleAccountPress('signup')}>
+            </TouchableOpacity>
+            <Text style={styles.textHeader}>{' OR '}</Text>
+            <TouchableOpacity onPress={() => handleAccountPress('signup')}>
                 <Text style={styles.buttonHeader}>CREATE AN ACCOUNT</Text>
-                </TouchableOpacity>
-            </Text>
+            </TouchableOpacity>
         </View>
     )
 }
@@ -35,18 +33,19 @@ const styles = StyleSheet.create({
         width: '100%',
         position: 'absolute',
         display: 'flex', 
+        flexDirection: 'row',
         justifyContent: 'center',
         alignItems: 'center'
     },
     textHeader: {
         color: '#000000',
-        fontSize: 15,
+        fontSize: 20,
         fontWeight: 'bold',
     },
     buttonHeader: {
         textDecorationLine: 'underline',
         color: '#000000',
-        fontSize: 15,
+        fontSize: 20,
         fontWeight: 'bold',
     },
 });
\ No newline at end of file
-- 
GitLab


From 8a00ae459599edebe1295a08d8ec9835e8b89c30 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 13:08:34 +0100
Subject: [PATCH 062/283] fix: image

---
 assets/BackgroundQuestion.png | Bin 0 -> 53750 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 assets/BackgroundQuestion.png

diff --git a/assets/BackgroundQuestion.png b/assets/BackgroundQuestion.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa5cdaa069e93679016f12bd8b8989e1b15ed607
GIT binary patch
literal 53750
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
PObitg3=e7zjLrWK`#i+y

literal 0
HcmV?d00001

-- 
GitLab


From 99f9a7eac6531bf8ef8673863c202b28ae572d1d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 13:55:03 +0100
Subject: [PATCH 063/283] add: ajout du boutton quit modal

---
 screens/Profil/Profil.tsx      |  2 +-
 screens/Profil/ProfilModal.tsx | 36 ++++++++++++++++++++++++++--------
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/screens/Profil/Profil.tsx b/screens/Profil/Profil.tsx
index a226e78..87201d9 100644
--- a/screens/Profil/Profil.tsx
+++ b/screens/Profil/Profil.tsx
@@ -10,7 +10,7 @@ interface Props {
 export default function Profil({navigation}: Props) {
     return (
         <View style={styles.containerGlobal}>
-                <TemplateMenu navigation={navigation} headerNavigation={false}>
+                <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack>
                     <View>
                         <ProfilChild navigation={navigation}/>
                     </View>
diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index 4049c6d..f947a97 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -1,9 +1,10 @@
-import React, { useState } from "react";
-import { Modal, View, StyleSheet, Button, TextInput } from "react-native";
+import React from "react";
+import { Modal, View, StyleSheet, Button, TextInput, TouchableOpacity } from "react-native";
 import ProfilSelectMode from "./ProfilSelectMode";
 import { ProfilSelectModeType } from "../../models/SelectModeType";
 import ProfilModalLogin from "./ProfilModalLogin";
 import ProfilModalSignup from "./ProfilModalSignup";
+import Icon from "react-native-vector-icons/MaterialIcons"; 
 
 interface Props{
     modalVisible: boolean;
@@ -25,6 +26,10 @@ export default function ProfilModal({modalVisible ,setModalVisible, mode, setMod
 
     }
 
+    const handleBackPressed = () => {
+        
+    }
+
 
     return (
         <Modal
@@ -35,8 +40,15 @@ export default function ProfilModal({modalVisible ,setModalVisible, mode, setMod
                 setModalVisible(!modalVisible);
             }}>
             <View style={styles.container}>
+                <TouchableOpacity
+                    style={styles.closeButton}
+                    onPress={() => setModalVisible(false)} // Ferme la modal
+                >
+                    <Icon name="close" size={30} color="#000" />
+                </TouchableOpacity>
                 <View style={styles.backgroundShadow}/>
                 <View style={styles.containerModal}>
+                
                     <ProfilSelectMode mode={mode} setMode={setMode}/>
                     {mode === "login" ? (
                         <ProfilModalLogin />
@@ -51,11 +63,11 @@ export default function ProfilModal({modalVisible ,setModalVisible, mode, setMod
 
 const styles = StyleSheet.create({
     container: {
-      flex: 1,
-      justifyContent: 'center',
-      alignItems: 'center',
-      height: '100%',
-      width: '100%',
+        flex: 1,
+        justifyContent: 'center',
+        alignItems: 'center',
+        height: '100%',
+        width: '100%',
     },
     backgroundShadow: {
         height: '100%',
@@ -65,7 +77,7 @@ const styles = StyleSheet.create({
         position: 'absolute',
     },
     containerModal: {
-        height: 680,
+        height: 650,
         width: '90%',
         backgroundColor: '#D9D9D9',
         borderRadius: 40,
@@ -128,4 +140,12 @@ const styles = StyleSheet.create({
         fontWeight: 'bold',
         color: '#FFFFFF',
     },
+    closeButton: {
+        position: "absolute",
+        top: 10,
+        right: 10,
+        zIndex: 1,
+        backgroundColor: 'white',
+        borderRadius: 10
+    },
 });
\ No newline at end of file
-- 
GitLab


From 582d207e5edd349f5c25ebfe27b5abc3af93849b Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 13:58:06 +0100
Subject: [PATCH 064/283] add: rename bouton pour login

---
 screens/Profil/ProfilModalLogin.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/ProfilModalLogin.tsx
index d4fbbe8..3fd32dd 100644
--- a/screens/Profil/ProfilModalLogin.tsx
+++ b/screens/Profil/ProfilModalLogin.tsx
@@ -12,7 +12,7 @@ export default function ProfilModalLogin() {
                 <TextInput placeholder="EMAIL..." style={styles.textInput}/>
                 <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
             </View>
-            <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
+            <DefaultButton text="LOGIN" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
         </View>
     )
 }
-- 
GitLab


From c610ec5c7d9320050e47467d6a27fbb1ce313890 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 14:03:40 +0100
Subject: [PATCH 065/283] add: modif pos croix back

---
 screens/Profil/ProfilModal.tsx | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index f947a97..b3c90ec 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -146,6 +146,7 @@ const styles = StyleSheet.create({
         right: 10,
         zIndex: 1,
         backgroundColor: 'white',
-        borderRadius: 10
+        borderRadius: 10,
+        margin: 10,
     },
 });
\ No newline at end of file
-- 
GitLab


From a4cf7d67fd22cdbab206437e128449bee072e3e4 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 14:14:41 +0100
Subject: [PATCH 066/283] feat: touchable feed back

---
 screens/Profil/ProfilModal.tsx | 163 +++++++++++----------------------
 1 file changed, 52 insertions(+), 111 deletions(-)

diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index b3c90ec..4398c76 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -1,36 +1,32 @@
 import React from "react";
-import { Modal, View, StyleSheet, Button, TextInput, TouchableOpacity } from "react-native";
+import {
+    Modal,
+    View,
+    StyleSheet,
+    TextInput,
+    TouchableOpacity,
+    Keyboard,
+    TouchableWithoutFeedback,
+} from "react-native";
 import ProfilSelectMode from "./ProfilSelectMode";
 import { ProfilSelectModeType } from "../../models/SelectModeType";
 import ProfilModalLogin from "./ProfilModalLogin";
 import ProfilModalSignup from "./ProfilModalSignup";
-import Icon from "react-native-vector-icons/MaterialIcons"; 
+import Icon from "react-native-vector-icons/MaterialIcons";
 
-interface Props{
+interface Props {
     modalVisible: boolean;
     setModalVisible: (visible: boolean) => void;
     mode: ProfilSelectModeType;
     setMode: (mode: ProfilSelectModeType) => void;
 }
 
-export default function ProfilModal({modalVisible ,setModalVisible, mode, setMode}: Props) {
-    const handleLoginPressed = () => {
-
-    };
-    
-    const handleSignupPressed = () => {
-
-    };
-
-    const handleSubmitPressed = () => {
-
-    }
-
-    const handleBackPressed = () => {
-        
-    }
-
-
+export default function ProfilModal({
+                                        modalVisible,
+                                        setModalVisible,
+                                        mode,
+                                        setMode,
+                                    }: Props) {
     return (
         <Modal
             animationType="slide"
@@ -38,25 +34,27 @@ export default function ProfilModal({modalVisible ,setModalVisible, mode, setMod
             visible={modalVisible}
             onRequestClose={() => {
                 setModalVisible(!modalVisible);
-            }}>
-            <View style={styles.container}>
-                <TouchableOpacity
-                    style={styles.closeButton}
-                    onPress={() => setModalVisible(false)} // Ferme la modal
-                >
-                    <Icon name="close" size={30} color="#000" />
-                </TouchableOpacity>
-                <View style={styles.backgroundShadow}/>
-                <View style={styles.containerModal}>
-                
-                    <ProfilSelectMode mode={mode} setMode={setMode}/>
-                    {mode === "login" ? (
-                        <ProfilModalLogin />
-                    ) : (
-                        <ProfilModalSignup />
-                    )}
-                </View> 
-            </View>
+            }}
+        >
+            <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
+                <View style={styles.container}>
+                    <TouchableOpacity
+                        style={styles.closeButton}
+                        onPress={() => setModalVisible(false)} // Ferme la modal
+                    >
+                        <Icon name="close" size={50} color="#000" />
+                    </TouchableOpacity>
+                    <View style={styles.backgroundShadow} />
+                    <View style={styles.containerModal}>
+                        <ProfilSelectMode mode={mode} setMode={setMode} />
+                        {mode === "login" ? (
+                            <ProfilModalLogin />
+                        ) : (
+                            <ProfilModalSignup />
+                        )}
+                    </View>
+                </View>
+            </TouchableWithoutFeedback>
         </Modal>
     );
 }
@@ -64,89 +62,32 @@ export default function ProfilModal({modalVisible ,setModalVisible, mode, setMod
 const styles = StyleSheet.create({
     container: {
         flex: 1,
-        justifyContent: 'center',
-        alignItems: 'center',
-        height: '100%',
-        width: '100%',
+        justifyContent: "center",
+        alignItems: "center",
+        height: "100%",
+        width: "100%",
     },
     backgroundShadow: {
-        height: '100%',
-        width: '100%',
-        backgroundColor: '#000000',
+        height: "100%",
+        width: "100%",
+        backgroundColor: "#000000",
         opacity: 0.55,
-        position: 'absolute',
+        position: "absolute",
     },
     containerModal: {
         height: 650,
-        width: '90%',
-        backgroundColor: '#D9D9D9',
+        width: "90%",
+        backgroundColor: "#D9D9D9",
         borderRadius: 40,
-        padding: 30
-    },
-    containerNav: {
-        height: 80,
-        width: '100%',
-        display: 'flex',
-        flexDirection: 'row',
-        justifyContent: 'space-around',
-        alignItems: 'center',
-        backgroundColor: '#FFFFFF',
-        borderRadius: 10,
-        shadowColor: "#000",
-        shadowOffset: {
-            width: 0,
-            height: 3,
-        },
-        shadowOpacity: 0.29,
-        shadowRadius: 4.65,
-        elevation: 7,
-    },
-    navButton: {
-        height: 50,
-        width: '45%',
-        backgroundColor: '#FFFFFF',
-        borderBottomColor: '#B9B9B9',
-        borderBottomWidth: 3,
-        borderStyle: 'solid',
-    },
-    navButtonText: {
-        color: '#B9B9B9'
-    },
-    containerForm: {
-        height: 450,
-        width: '100%',
-        display: 'flex',
-        flexDirection: 'column',
-        justifyContent: 'space-around'
-    },
-    textInput: {
-        height: 80,
-        width: '100%',
-        backgroundColor: '#FFFFFF',
-        borderWidth: 4,
-        borderColor: '#1FA9FF',
-        borderRadius: 10,
-        color: '#DFDFDF',
-        fontWeight: 'bold'
-    },
-    SubmitButton: {
-        height: 80,
-        width: '100%',
-        backgroundColor: '#1FA9FF',
-        borderRadius: 10,
-    },
-    SubmitText: {
-        fontSize: 20,
-        fontWeight: 'bold',
-        color: '#FFFFFF',
+        padding: 30,
     },
     closeButton: {
         position: "absolute",
         top: 10,
         right: 10,
         zIndex: 1,
-        backgroundColor: 'white',
+        backgroundColor: "white",
         borderRadius: 10,
-        margin: 10,
+        margin: 20,
     },
-});
\ No newline at end of file
+});
-- 
GitLab


From ad48bba7cee26f1e925dc089ff6105db23a956ab Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 14:22:25 +0100
Subject: [PATCH 067/283] fix: taille des modals en fix

---
 screens/Profil/ProfilModal.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index 4398c76..c5aadb4 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -75,7 +75,7 @@ const styles = StyleSheet.create({
         position: "absolute",
     },
     containerModal: {
-        height: 650,
+        height: "80%",
         width: "90%",
         backgroundColor: "#D9D9D9",
         borderRadius: 40,
-- 
GitLab


From c419416e10fefc7dea85dd640ae378c197d62ef1 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 14:52:05 +0100
Subject: [PATCH 068/283] =?UTF-8?q?fix:=20passer=20=C3=A0=20la=20prochaine?=
 =?UTF-8?q?=20question?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/PlayQuiz/BlueButton.tsx      |  5 +--
 helper/QuizHelper.ts                    |  6 ++--
 screens/PlayingQuiz/PlayingQuizBody.tsx | 45 ++++++++++++++++---------
 services/QuizService.ts                 |  2 +-
 4 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/components/PlayQuiz/BlueButton.tsx b/components/PlayQuiz/BlueButton.tsx
index 4e04f8d..1d39741 100644
--- a/components/PlayQuiz/BlueButton.tsx
+++ b/components/PlayQuiz/BlueButton.tsx
@@ -1,12 +1,13 @@
-import {View, Text, StyleSheet, TouchableOpacity} from "react-native";
+import {View, Text, StyleSheet, TouchableOpacity, GestureResponderEvent} from "react-native";
 import {NavigationProp} from "@react-navigation/native";
 
 interface Props {
-    onPress: () => void
+    onPress:  ((event: GestureResponderEvent) => void) | undefined
     text: string
     buttonStyle?: any
 }
 export default function BlueButton({onPress, text, buttonStyle} : Props) {
+
     return (
         <TouchableOpacity style={[styles.container, buttonStyle]} onPress={onPress}>
             <Text style={styles.text}>{text}</Text>
diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index 3ff16ac..6456903 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -55,7 +55,7 @@ export const transformToQuizModel = (data: any): QuizModel => {
         return {
             id: question.id,
             question: question.text, // Texte de la question
-            category: question.theme.name,
+            category: question.category.name,
             answers: answers, // Réponses associées
             multiple: question.type === "multiple", // Détermine si c'est une question multiple
             nbOfTheQuestion: question.order, // Numéro de la question
@@ -64,8 +64,8 @@ export const transformToQuizModel = (data: any): QuizModel => {
 
     // Création de l'objet QuizModel
     const quiz: QuizModel = {
-        code: data.codeQuiz, // Mapping de codeQuiz vers code
-        category: data.theme.name, // Extraction du nom de la catégorie
+        code: data.id, // Mapping de codeQuiz vers code
+        category: data.category.name, // Extraction du nom de la catégorie
         questions: questions, // Questions transformées
         nbQuestions: data.questionCount, // Nombre total de questions
         nbActualQuestion: data.questionIndex, // Index actuel de la question
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 1b2c895..560ef21 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -23,6 +23,7 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
     const [selectedAnswerIndex, setSelectedAnswerIndex] = useState<number | null>(null);
     const [isCorrect, setIsCorrect] = useState<boolean | null>(null);
     const [correctAnswer, setCorrectAnswer] = useState<AnswerModel | null>(null);
+    const [isAnswered, setIsAnswered] = useState<boolean>(false);
 
     const { getAnswerQuiz } = useQuizService();
 
@@ -31,6 +32,7 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
             setSelectedAnswerIndex(null);
             setIsCorrect(null);
             setCorrectAnswer(null);
+            setIsAnswered(false);
         }
     }, [quiz?.nbActualQuestion]);
 
@@ -38,29 +40,28 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
 
     const currentQuestion: QuestionModel = quiz.questions[quiz.nbActualQuestion - 1];
 
-    const handleAnswerPress = async (index: number) => {
-        if (isAlreadyPlayed) return;
+    const handleConfirmAnswerPressed = async () => {
+        if(selectedAnswerIndex === null) return;
+        setIsAnswered(true);
 
-        const answers = await getAnswerQuiz(quiz.code, currentQuestion.id, currentQuestion.answers[index].id);
+        const answers = await getAnswerQuiz(quiz.code, currentQuestion.id, currentQuestion.answers[selectedAnswerIndex].id);
 
-        if(HttpError.isHttpError(answers))
-        {
+        if (HttpError.isHttpError(answers)) {
             navigation.navigate("Home");
             return;
         }
 
         const correctAnswer = getCorrectAnswer(answers);
-        const isAnswerCorrect = currentQuestion.answers[index].id === correctAnswer.id;
+        const isAnswerCorrect = currentQuestion.answers[selectedAnswerIndex].id === correctAnswer.id;
 
-        setSelectedAnswerIndex(index);
+        setSelectedAnswerIndex(selectedAnswerIndex);
         setIsCorrect(isAnswerCorrect);
         setCorrectAnswer(correctAnswer);
-        setIsAlreadyPlayed(true);
 
         await new Promise((resolve) => setTimeout(resolve, 2000));
 
-        if(quiz.nbActualQuestion === quiz.questions.length) {
-            navigation.navigate("EndQuiz", { quiz: quiz });
+        if (quiz.nbActualQuestion === quiz.questions.length) {
+            navigation.navigate("EndQuiz", {quiz: quiz});
         }
 
         setQuiz((prevQuiz) => ({
@@ -68,8 +69,12 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
             nbActualQuestion: prevQuiz.nbActualQuestion + 1,
             score: isAnswerCorrect ? prevQuiz.score + 1 : prevQuiz.score
         }));
-        setIsAlreadyPlayed(false);
+    }
 
+    const handleAnswerPress = async (index: number) => {
+        if (isAnswered) return
+        console.log(index);
+        setSelectedAnswerIndex(index);
     };
 
     const getCorrectAnswer = (answers: AnswerModel[]): AnswerModel => {
@@ -81,7 +86,10 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
     const getButtonStyle = (index: number) => {
         if (selectedAnswerIndex === null) return ButtonsStyles.answerButton;
 
-        if (index === selectedAnswerIndex) {
+        if(!isAnswered && index === selectedAnswerIndex && !isCorrect) return styles.selectedAnswer;
+
+        if (index === selectedAnswerIndex && isCorrect !== null) {
+            console.log(isCorrect);
             return isCorrect ? styles.correctAnswer : styles.incorrectAnswer;
         }
         if (currentQuestion.answers[index].id === correctAnswer?.id) {
@@ -91,9 +99,11 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
     };
 
     const getTextStyle = (index: number) => {
-        if (selectedAnswerIndex === null) return TextsStyles.defaultText;
+        if (selectedAnswerIndex === null || !isAnswered && index === selectedAnswerIndex) return TextsStyles.defaultText;
 
-        if (index === selectedAnswerIndex) {
+
+
+        if (index === selectedAnswerIndex && isCorrect !== null) {
             return isCorrect ? styles.correctText : styles.incorrectText;
         }
         if (currentQuestion.answers[index].id === correctAnswer?.id) {
@@ -117,7 +127,7 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
                     ))}
                     {/* Ajout du PlayButton à la fin */}
                     <View style={styles.playButtonContainer}>
-                        <BlueButton onPress={() => console.log("Play button pressed")} text="Play" buttonStyle={{borderRadius: 50}}/>
+                        <BlueButton onPress={handleConfirmAnswerPressed} text="Confirm" buttonStyle={{borderRadius: 50}}/>
                     </View>
                 </>
             ) : (
@@ -151,6 +161,11 @@ const styles = StyleSheet.create({
         borderColor: 'red',
         borderWidth: 2,
     },
+    selectedAnswer: {
+        ...ButtonsStyles.answerButton,
+        borderColor: '#45128c',
+        borderWidth: 2,
+    },
     correctText: {
         fontWeight: 'bold',
         color: 'green',
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 690a15a..5a34173 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -82,7 +82,7 @@ export const useQuizService =  () => {
     const getAnswerQuiz = async (codeQuiz: string, questionID: number, answerID: number) : Promise<AnswerModel[] | HttpError> => {
         try {
             const requestBody = {
-                codeQuiz: codeQuiz,
+                id: codeQuiz,
                 questionID: questionID,
                 answerID: answerID
             };
-- 
GitLab


From 602400dbb34c118e323aa37f6bafae2dc8193544 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 15:18:16 +0100
Subject: [PATCH 069/283] feat: connection between playquiz and quiz
 playingquiz

---
 screens/PlayQuiz/PlayQuizChild.tsx        |  2 +-
 screens/PlayQuiz/PlayQuizGenerateQuiz.tsx | 40 ++++++++++++++++++-----
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
index 6f2089c..92ca46a 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -22,7 +22,7 @@ export default function PlayQuizChild({navigation}: Props){
                 <View style={styles.contentContainer}>
                     <SelectMode mode={mode} setMode={setMode}/>
                     {mode === "play" ? (
-                        <PlayQuizGenerateQuiz />
+                        <PlayQuizGenerateQuiz navigation={navigation}/>
                     ) : (
                         <PlayQuizJoinQuiz />
                     )}
diff --git a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
index 7a2d380..066ccc7 100644
--- a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -1,13 +1,16 @@
 import { Text,View, StyleSheet } from "react-native";
 import SelectListBox from "../../components/PlayQuiz/SelectListBox";
-import React from "react";
+import React, {useEffect} from "react";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
+import {getIdOfCategory} from "../../helper/QuizHelper";
+import {useQuizService} from "../../services/QuizService";
+import {NavigationProp} from "@react-navigation/native";
 
 const difficulty = [
-    { key: "easy", value: "Easy" },
-    { key: "medium", value: "Medium" },
-    { key: "hard", value: "Hard" },
+    { key: "easy", value: "easy" },
+    { key: "medium", value: "medium" },
+    { key: "hard", value: "hard" },
 ];
 
 const categories = [
@@ -26,13 +29,34 @@ const categories = [
     { key: "21", value: "Sports" },
     { key: "22", value: "Geography" },
 ];
+interface Props {
+    navigation: NavigationProp<any>;
+}
 
-export default function PlayQuizGenerateQuiz() {
+export default function PlayQuizGenerateQuiz({navigation}: Props) {
     const [difficutlyChoose, setDifficutlyChoose] = React.useState("");
     const [categoryChoose, setCategoryChoose] = React.useState("");
+    const [nbQuestions, setNbQuestions] = React.useState("");
+    const {generateQuiz} = useQuizService();
+
+    useEffect(() => {
+        console.log(difficutlyChoose + ", " + getIdOfCategory(categoryChoose) + ", " + nbQuestions);
+    }, [difficutlyChoose,categoryChoose,nbQuestions]);
+
+
+    const handlePlayButtonPress = async () => {
+        if (nbQuestions === "" && difficutlyChoose === "" && categoryChoose === "") return;
 
-    const handlePlayButtonPress = () => {
-        console.log("Play button pressed");
+        const quizGenerated = await generateQuiz(parseInt(nbQuestions), getIdOfCategory(categoryChoose), difficutlyChoose);
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quizRecovered: quizGenerated},
+                },
+            ]
+        });
     };
 
     return (
@@ -41,7 +65,7 @@ export default function PlayQuizGenerateQuiz() {
                 <View style={styles.fieldContainer}>
                     <SelectListBox title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
                     <SelectListBox title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
-                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={() => {}} />
+                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} />
                 </View>
                 <View style={styles.buttonPlayContainer}>
                     <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} />
-- 
GitLab


From 4c06e4506f9df17a80dda8c6a26d3e1a01689a2a Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 16:19:16 +0100
Subject: [PATCH 070/283] add: responsive profil

---
 screens/Profil/ProfilChild.tsx       | 10 ++++------
 screens/Profil/ProfilModal.tsx       | 18 +++++++++---------
 screens/Profil/ProfilModalLogin.tsx  |  8 ++++----
 screens/Profil/ProfilModalSignup.tsx |  8 ++++----
 screens/Profil/ProfilSelectMode.tsx  |  6 +++---
 5 files changed, 24 insertions(+), 26 deletions(-)

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index f5f6ecb..17911d9 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -46,14 +46,12 @@ const styles = StyleSheet.create({
         alignItems: 'center',   
     },
     titleImage: {
-        width: 170,
-        height: 80,
+        width: '45%',
         resizeMode: 'contain',
     },
     profilImage: {
-        height: 200,
-        width: 200,
-        borderRadius: 100,
+        width: '45%',
+        aspectRatio: 1
     },
     pseudoText: {
         fontSize: 35,
@@ -62,7 +60,7 @@ const styles = StyleSheet.create({
     },
     containerPlayerStats: {
         width: '100%',
-        padding: 30,
+        padding: '5%',
     },
     statsText: {
         fontSize: 17,
diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index c5aadb4..bec04df 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -22,11 +22,11 @@ interface Props {
 }
 
 export default function ProfilModal({
-                                        modalVisible,
-                                        setModalVisible,
-                                        mode,
-                                        setMode,
-                                    }: Props) {
+        modalVisible,
+        setModalVisible,
+        mode,
+        setMode,
+    }: Props) {
     return (
         <Modal
             animationType="slide"
@@ -79,15 +79,15 @@ const styles = StyleSheet.create({
         width: "90%",
         backgroundColor: "#D9D9D9",
         borderRadius: 40,
-        padding: 30,
+        padding: '7%',
     },
     closeButton: {
         position: "absolute",
-        top: 10,
-        right: 10,
+        top: '1%',
+        right: '1%',
         zIndex: 1,
         backgroundColor: "white",
         borderRadius: 10,
-        margin: 20,
+        margin: '5%',
     },
 });
diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/ProfilModalLogin.tsx
index 3fd32dd..4f0e723 100644
--- a/screens/Profil/ProfilModalLogin.tsx
+++ b/screens/Profil/ProfilModalLogin.tsx
@@ -19,16 +19,16 @@ export default function ProfilModalLogin() {
 
 const styles = StyleSheet.create({
     containerForm: {
-        height: 400,
+        height: '67%',
         width: '100%',
         display: 'flex',
         flexDirection: 'column',
         justifyContent: 'flex-start',
-        rowGap: 50,
+        rowGap: '10%',
         marginTop: 50,
     },
     textInput: {
-        height: 80,
+        height: '20%',
         width: '100%',
         backgroundColor: '#FFFFFF',
         borderWidth: 4,
@@ -38,7 +38,7 @@ const styles = StyleSheet.create({
         fontWeight: 'bold'
     },
     SubmitButton: {
-        height: 80,
+        height: '15%',
         width: '100%',
         backgroundColor: '#1FA9FF',
         borderRadius: 10,
diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/ProfilModalSignup.tsx
index 43fa0f2..0356718 100644
--- a/screens/Profil/ProfilModalSignup.tsx
+++ b/screens/Profil/ProfilModalSignup.tsx
@@ -20,16 +20,16 @@ export default function ProfilModalSignup() {
 
 const styles = StyleSheet.create({
     containerForm: {
-        height: 400,
+        height: '67%',
         width: '100%',
         display: 'flex',
         flexDirection: 'column',
         justifyContent: 'flex-start',
-        rowGap: 50,
+        rowGap: '10%',
         marginTop: 50
     },
     textInput: {
-        height: 80,
+        height: '20%',
         width: '100%',
         backgroundColor: '#FFFFFF',
         borderWidth: 4,
@@ -39,7 +39,7 @@ const styles = StyleSheet.create({
         fontWeight: 'bold'
     },
     SubmitButton: {
-        height: 80,
+        height: '15%',
         width: '100%',
         backgroundColor: '#1FA9FF',
         borderRadius: 10,
diff --git a/screens/Profil/ProfilSelectMode.tsx b/screens/Profil/ProfilSelectMode.tsx
index 7a6d0d7..4d67988 100644
--- a/screens/Profil/ProfilSelectMode.tsx
+++ b/screens/Profil/ProfilSelectMode.tsx
@@ -31,7 +31,7 @@ const styles = StyleSheet.create({
     container: {
         display: 'flex',
         width: '100%',
-        height: '10%',
+        height: '15%',
         flexDirection: 'row',
         backgroundColor: '#f3f3f3',
         borderRadius: 10,
@@ -61,8 +61,8 @@ const styles = StyleSheet.create({
     },
     bar: {
         width: '100%',
-        height: 4,
-        marginTop: 4,
+        height: '4%',
+        marginTop: '4%',
         borderRadius: 10,
     },
     activeBar: {
-- 
GitLab


From 4cd84232f0c0a77ba6b934b52ea51a6ebe2b14eb Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 16:24:44 +0100
Subject: [PATCH 071/283] feat: join quiz

---
 components/PlayQuiz/InputPlayQuiz.tsx |  7 +++-
 screens/PlayQuiz/PlayQuizChild.tsx    |  2 +-
 screens/PlayQuiz/PlayQuizJoinQuiz.tsx | 56 +++++++++++++++++++++++----
 services/QuizService.ts               |  8 ++--
 4 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
index 0f6d7e0..e0b00e4 100644
--- a/components/PlayQuiz/InputPlayQuiz.tsx
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -16,8 +16,11 @@ export default function InputPlayQuiz({ title, setText, noTitle, placeholder }:
                 style={styles.input}
                 placeholder={placeholder || ""}
                 placeholderTextColor="#bebebe"
-                keyboardType="numeric"
-                onChangeText={(text) => setText(text)}
+                keyboardType="default"
+                onChangeText={(text) =>{
+                    setText(text)
+                    console.log("test")
+                }}
             />
         </View>
     );
diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
index 92ca46a..6fb6902 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -24,7 +24,7 @@ export default function PlayQuizChild({navigation}: Props){
                     {mode === "play" ? (
                         <PlayQuizGenerateQuiz navigation={navigation}/>
                     ) : (
-                        <PlayQuizJoinQuiz />
+                        <PlayQuizJoinQuiz navigation={navigation}/>
                     )}
                 </View>
             </View>
diff --git a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
index 93f5310..2e1a023 100644
--- a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -1,23 +1,58 @@
-import {StyleSheet, View} from "react-native";
+import { StyleSheet, View, Text } from "react-native";
 import AboutAQuiz from "../../components/PlayQuiz/AboutAQuiz";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
-import React from "react";
+import React, { useEffect } from "react";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
 import QuizModel from "../../models/QuizModel";
+import { useQuizService } from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
+import {getIdOfCategory} from "../../helper/QuizHelper";
+import {NavigationProp} from "@react-navigation/native";
 
-export default function PlayQuizJoinQuiz() {
+interface Props {
+    navigation: NavigationProp<any>;
+}
+export default function PlayQuizJoinQuiz({navigation}: Props) {
     const [codeQuiz, setCodeQuiz] = React.useState("");
     const [quiz, setQuiz] = React.useState<QuizModel>();
+    const [error, setError] = React.useState<string>("");
+
+    const { remainingQuiz } = useQuizService();
+
+    useEffect(() => {
+        fetchQuiz();
+    }, [codeQuiz]);
+
+    const fetchQuiz = async () => {
+        const quizFetched = await remainingQuiz(codeQuiz);
+        if (quizFetched instanceof HttpError) {
+            setError("The quiz does not exist");
+            return;
+        }
+        setError("");
+        setQuiz(quizFetched);
+    };
+
     const handlePlayButtonPress = () => {
-        console.log("Play button pressed");
+        if(error !== "") return;
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quizRecovered: quiz},
+                },
+            ]
+        });
     };
 
     return (
         <View style={styles.container}>
             <View style={styles.contentContainer}>
                 <View style={styles.fieldContainer}>
-                    <InputPlayQuiz placeholder={"Enter quiz ID"} setText={setCodeQuiz} noTitle={true}/>
-                    <AboutAQuiz />
+                    {error ? <Text style={styles.errorText}>{error}</Text> : null}
+                    <InputPlayQuiz placeholder={"Enter quiz ID"} setText={setCodeQuiz} noTitle={true} />
+                    <AboutAQuiz quiz={quiz} />
                 </View>
                 <View style={styles.buttonPlayContainer}>
                     <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} />
@@ -27,7 +62,6 @@ export default function PlayQuizJoinQuiz() {
     );
 }
 
-
 const styles = StyleSheet.create({
     container: {
         display: "flex",
@@ -51,4 +85,10 @@ const styles = StyleSheet.create({
         alignItems: "center",
         paddingVertical: 20,
     },
-});
\ No newline at end of file
+    errorText: {
+        color: "red",
+        fontSize: 16,
+        marginBottom: 5,
+        textAlign: "left", // Aligne le texte à gauche
+    },
+});
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 5a34173..d2bed7c 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -44,12 +44,13 @@ export const useQuizService =  () => {
         }
     }
 
-    const remainingQuiz = async (codeQuiz: string) : Promise<QuizModel | HttpError> => {
+    const remainingQuiz = async (id: string) : Promise<QuizModel | HttpError> => {
 
         // Création du corps de la requête avec les variables passées
         const requestBody = {
-            codeQuiz
+            id
         };
+        console.log(requestBody);
 
         try {
             const response = await fetch(url + "/quiz/remaining", {
@@ -67,9 +68,10 @@ export const useQuizService =  () => {
             // Récupération des données retournées par l'API
             const data = await response.json();
             const quiz = transformToQuizModel(data);
+            console.log(quiz);
             return quiz;
         } catch (error) {
-            console.error("Error while creating quiz:", error);
+            console.log("Error while remaining quiz:", error);
 
             if (HttpError.isHttpError(error)) {
                 return error;
-- 
GitLab


From 72e8d136511b71153018f0d6a49ad538d1264b53 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 17:20:30 +0100
Subject: [PATCH 072/283] add: creation de la page end statiquement

---
 assets/uWin.png                  | Bin 0 -> 32604 bytes
 screens/EndQuiz/EndQuiz.tsx      | 144 +++++++++++++++++++------------
 screens/EndQuiz/EndQuizChild.tsx |  54 ++++++++++++
 3 files changed, 141 insertions(+), 57 deletions(-)
 create mode 100644 assets/uWin.png
 create mode 100644 screens/EndQuiz/EndQuizChild.tsx

diff --git a/assets/uWin.png b/assets/uWin.png
new file mode 100644
index 0000000000000000000000000000000000000000..9456efb9f5b9be207760a222ab4871ea3d73eac8
GIT binary patch
literal 32604
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

literal 0
HcmV?d00001

diff --git a/screens/EndQuiz/EndQuiz.tsx b/screens/EndQuiz/EndQuiz.tsx
index 12db032..cb13d78 100644
--- a/screens/EndQuiz/EndQuiz.tsx
+++ b/screens/EndQuiz/EndQuiz.tsx
@@ -1,74 +1,104 @@
+import { NavigationProp } from "@react-navigation/native";
 import { View, StyleSheet, Image, Text } from "react-native";
-import DefaultButton from "../../components/DefaultButton";
-import { TextsStyles } from "../../styles/TextsStyles";
-import { ButtonsStyles } from "../../styles/ButtonsStyles";
-import {useTranslation} from "react-i18next";
-import QuizModel from "../../models/QuizModel";
-import {NavigationProp, RouteProp} from "@react-navigation/native";
-
-type RoutePropsType = {
-    EndQuiz: {
-        quiz: QuizModel;
-    };
-};
+import EndQuizChild from "./EndQuizChild";
+import TemplateMenu from "../../templates/TemplateMenu";
 
 interface Props {
     navigation: NavigationProp<any>;
-    route: RouteProp<RoutePropsType, "EndQuiz">;
 }
 
-export default function EndQuiz({ navigation, route }: Props) {
-    const { quiz } = route.params;
-    const {t} = useTranslation();
-    const handleButtonRePlayPressed = () => {
-        quiz.nbActualQuestion = 1;
-        quiz.score = 0;
-        navigation.reset({
-            index: 0,
-            routes: [
-                {
-                    name: "PlayingQuiz",
-                    params: {quiz: quiz},
-                },
-            ]
-        });
-    }
-
-    const handleButtonHomePressed = () => {
-        navigation.navigate('Home');
-    }
-
+export default function EndQuiz({navigation}: Props) {
     return (
-        <View style={styles.container}>
-            <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
-            <Text style={TextsStyles.titleText}>{t("app.screens.endQuiz.score")} : {quiz.score}</Text>
-            <Text style={TextsStyles.subtitleText}>{((quiz.score/quiz.nbQuestions)*100 > 50 ) ? t("app.screens.endQuiz.lose") : t("app.screens.endQuiz.win")}</Text>
-            <View style={styles.buttonContainer}>
-                <DefaultButton text={t("app.screens.endQuiz.replay")} handleButtonPressed={handleButtonRePlayPressed} buttonStyle={ButtonsStyles.defaultButton}></DefaultButton>
-                <DefaultButton text={t("app.screens.endQuiz.goHome")} handleButtonPressed={handleButtonHomePressed}></DefaultButton>
-            </View>
+        <View style={styles.containerGlobal}>
+            <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}>
+                <View>
+                    <EndQuizChild navigation={navigation}/>
+                </View>
+            </TemplateMenu>
         </View>
-    )
+    );
 }
 
 const styles = StyleSheet.create({
-    container: {
+    containerGlobal: {
         display: 'flex',
         width: '100%',
         height: '100%',
-        alignItems: 'center',
-        justifyContent: 'center',
-        gap: 10,  
-    },
-    buttonContainer: {
-        width: '80%',
-        margin: '10%',
-        gap: 20
-    },
-    image: {
-        width: '100%',
-        height: '100%',
-        position: 'absolute',
+        flexDirection: 'column',
     },
 });
 
+
+
+// import DefaultButton from "../../components/DefaultButton";
+// import { TextsStyles } from "../../styles/TextsStyles";
+// import { ButtonsStyles } from "../../styles/ButtonsStyles";
+// import {useTranslation} from "react-i18next";
+// import QuizModel from "../../models/QuizModel";
+// import {NavigationProp, RouteProp} from "@react-navigation/native";
+
+// type RoutePropsType = {
+//     EndQuiz: {
+//         quiz: QuizModel;
+//     };
+// };
+
+// interface Props {
+//     navigation: NavigationProp<any>;
+//     route: RouteProp<RoutePropsType, "EndQuiz">;
+// }
+
+// export default function EndQuiz({ navigation, route }: Props) {
+//     const { quiz } = route.params;
+//     const {t} = useTranslation();
+//     const handleButtonRePlayPressed = () => {
+//         quiz.nbActualQuestion = 1;
+//         quiz.score = 0;
+//         navigation.reset({
+//             index: 0,
+//             routes: [
+//                 {
+//                     name: "PlayingQuiz",
+//                     params: {quiz: quiz},
+//                 },
+//             ]
+//         });
+//     }
+
+//     const handleButtonHomePressed = () => {
+//         navigation.navigate('Home');
+//     }
+
+//     return (
+//         <View style={styles.container}>
+//             <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
+//             <Text style={TextsStyles.titleText}>{t("app.screens.endQuiz.score")} : {quiz.score}</Text>
+//             <Text style={TextsStyles.subtitleText}>{((quiz.score/quiz.nbQuestions)*100 > 50 ) ? t("app.screens.endQuiz.lose") : t("app.screens.endQuiz.win")}</Text>
+//             <View style={styles.buttonContainer}>
+//                 <DefaultButton text={t("app.screens.endQuiz.replay")} handleButtonPressed={handleButtonRePlayPressed} buttonStyle={ButtonsStyles.defaultButton}></DefaultButton>
+//                 <DefaultButton text={t("app.screens.endQuiz.goHome")} handleButtonPressed={handleButtonHomePressed}></DefaultButton>
+//             </View>
+//         </View>
+//     )
+// }
+
+// const styles = StyleSheet.create({
+//     container: {
+//         display: 'flex',
+//         width: '100%',
+//         height: '100%',
+//         alignItems: 'center',
+//         justifyContent: 'center',
+//         gap: 10,  
+//     },
+//     buttonContainer: {
+//         width: '80%',
+//         margin: '10%',
+//         gap: 20
+//     },
+//     image: {
+//         width: '100%',
+//         height: '100%',
+//         position: 'absolute',
+//     },
+// });
\ No newline at end of file
diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
new file mode 100644
index 0000000..57e4750
--- /dev/null
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -0,0 +1,54 @@
+import { View, Image, Text, StyleSheet } from "react-native";
+import DefaultButton from "../../components/DefaultButton";
+import { NavigationProp } from "@react-navigation/native";
+
+// type RoutePropsType = {
+//     EndQuiz: {
+//         quiz: QuizModel;
+//     };
+// };
+
+interface Props {
+    navigation: NavigationProp<any>;
+    // route: RouteProp<RoutePropsType, "EndQuiz">;
+}
+
+export default function EndQuizChild({ navigation/* , route */}: Props) {
+    // const { quiz } = route.params;
+
+    const handleRestartPress = () => {
+        // quiz.nbActualQuestion = 1;
+        // quiz.score = 0;
+        // navigation.reset({
+        //     index: 0,
+        //     routes: [
+        //         {
+        //             name: "PlayingQuiz",
+        //             params: {quiz: quiz},
+        //         },
+        //     ]
+        // });
+    };
+
+    const handleBackToMenu = () => {
+        navigation.navigate('Home');
+    };
+
+    return (
+        <View>
+            <View>
+                <Image source={require('../../assets/TitleApp.png')} />
+            </View>
+            <View>
+                <Text>CONGRATS !</Text>
+                <Text>you finish the test with a score of 12/20 ! </Text>
+                <Image source={require('../../assets/uWin.png')} />
+                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress}></DefaultButton>
+                <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu}></DefaultButton>
+            </View>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+});
\ No newline at end of file
-- 
GitLab


From fafa32ef2a2610a28def464256f3071a08ec2ecd Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 17:55:28 +0100
Subject: [PATCH 073/283] =?UTF-8?q?add:=20ajout=20du=20style=20de=20l'?=
 =?UTF-8?q?=C3=A9cran=20de=20fin?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 screens/EndQuiz/EndQuizChild.tsx | 80 ++++++++++++++++++++++++++++----
 1 file changed, 72 insertions(+), 8 deletions(-)

diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index 57e4750..f4add94 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -35,20 +35,84 @@ export default function EndQuizChild({ navigation/* , route */}: Props) {
     };
 
     return (
-        <View>
-            <View>
-                <Image source={require('../../assets/TitleApp.png')} />
+        <View style={styles.container}>
+            <View style={styles.containerHeader}>
+                <Image source={require('../../assets/TitleApp.png')}/>
             </View>
-            <View>
-                <Text>CONGRATS !</Text>
-                <Text>you finish the test with a score of 12/20 ! </Text>
+            <View style={styles.containerBody}>
+                <Text style={styles.TextBody}>CONGRATS !</Text>
+                <Text style={styles.TextBody}>you finish the test with a score of 12/20 ! </Text>
                 <Image source={require('../../assets/uWin.png')} />
-                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress}></DefaultButton>
-                <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu}></DefaultButton>
+                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
+                <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
             </View>
         </View>
     );
 }
 
 const styles = StyleSheet.create({
+    container: {
+        height: '100%',
+        width: '100%',
+        display: 'flex',
+        flexDirection: 'column',
+        alignItems: 'center',
+        justifyContent: 'space-around'
+    },
+    containerHeader: {
+        height: '10%',
+        width: '100%',
+        alignItems: 'center',
+    },
+    containerBody: {
+        height: '80%',
+        width: '90%',
+        display: 'flex',
+        flexDirection: 'column',
+        alignItems: 'center',
+        justifyContent: 'space-around',
+        backgroundColor: '#F3F3F3',
+        borderRadius: 40,
+        padding: '10%',
+        shadowColor: "#000",
+        shadowOffset: {
+            width: 0,
+            height: 2,
+        },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.84,
+
+        elevation: 5,
+    },
+    TextBody: {
+        textAlign: 'center',
+        fontSize: 20,
+        fontWeight: 'bold',
+    },
+    whiteButton: {
+        height: '12%',
+        width: '80%',
+        backgroundColor: '#FFFFFF',
+        borderColor: '#2B73FE',
+        borderWidth: 4,
+        borderRadius: 10,
+        padding: 0
+    },
+    whiteButtonText: {
+        fontSize: 24,
+        fontWeight: 'bold',
+        color: '#2B73FE',
+    },
+    blueButton: {
+        height: '12%',
+        width: '80%',
+        backgroundColor: '#2B73FE',
+        borderRadius: 10,
+        padding: 0
+    },
+    blueButtonText: {
+        fontSize: 24,
+        fontWeight: 'bold',
+        color: '#FFFFFF',
+    },
 });
\ No newline at end of file
-- 
GitLab


From a7d1b319d9a5debefe3ac847e96b8c4850645925 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 18:05:46 +0100
Subject: [PATCH 074/283] style: color blue or account modal

---
 screens/Profil/ProfilModalLogin.tsx  | 4 ++--
 screens/Profil/ProfilModalSignup.tsx | 4 ++--
 screens/Profil/ProfilSelectMode.tsx  | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/ProfilModalLogin.tsx
index 4f0e723..3d86621 100644
--- a/screens/Profil/ProfilModalLogin.tsx
+++ b/screens/Profil/ProfilModalLogin.tsx
@@ -32,7 +32,7 @@ const styles = StyleSheet.create({
         width: '100%',
         backgroundColor: '#FFFFFF',
         borderWidth: 4,
-        borderColor: '#1FA9FF',
+        borderColor: '#1fa9ff',
         borderRadius: 10,
         color: '#DFDFDF',
         fontWeight: 'bold'
@@ -40,7 +40,7 @@ const styles = StyleSheet.create({
     SubmitButton: {
         height: '15%',
         width: '100%',
-        backgroundColor: '#1FA9FF',
+        backgroundColor: '#2b73fe',
         borderRadius: 10,
     },
     SubmitText: {
diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/ProfilModalSignup.tsx
index 0356718..7ced6dd 100644
--- a/screens/Profil/ProfilModalSignup.tsx
+++ b/screens/Profil/ProfilModalSignup.tsx
@@ -33,7 +33,7 @@ const styles = StyleSheet.create({
         width: '100%',
         backgroundColor: '#FFFFFF',
         borderWidth: 4,
-        borderColor: '#1FA9FF',
+        borderColor: '#1fa9ff',
         borderRadius: 10,
         color: '#DFDFDF',
         fontWeight: 'bold'
@@ -41,7 +41,7 @@ const styles = StyleSheet.create({
     SubmitButton: {
         height: '15%',
         width: '100%',
-        backgroundColor: '#1FA9FF',
+        backgroundColor: '#2b73fe',
         borderRadius: 10,
     },
     SubmitText: {
diff --git a/screens/Profil/ProfilSelectMode.tsx b/screens/Profil/ProfilSelectMode.tsx
index 4d67988..0abae69 100644
--- a/screens/Profil/ProfilSelectMode.tsx
+++ b/screens/Profil/ProfilSelectMode.tsx
@@ -57,7 +57,7 @@ const styles = StyleSheet.create({
         color: '#bebebe',
     },
     activeText: {
-        color: '#2ec7ff',
+        color: '#2b73fe',
     },
     bar: {
         width: '100%',
@@ -66,7 +66,7 @@ const styles = StyleSheet.create({
         borderRadius: 10,
     },
     activeBar: {
-        backgroundColor: '#2ec7ff', // Couleur pour le bouton actif
+        backgroundColor: '#2b73fe', // Couleur pour le bouton actif
     },
     inactiveBar: {
         backgroundColor: '#bebebe', // Couleur grise pour les boutons inactifs
-- 
GitLab


From ce82034c283aa0f9b497a2649a08863cb725ceb7 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 18:15:06 +0100
Subject: [PATCH 075/283] style: font size

---
 screens/EndQuiz/EndQuizChild.tsx | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index f4add94..b811860 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -40,7 +40,7 @@ export default function EndQuizChild({ navigation/* , route */}: Props) {
                 <Image source={require('../../assets/TitleApp.png')}/>
             </View>
             <View style={styles.containerBody}>
-                <Text style={styles.TextBody}>CONGRATS !</Text>
+                <Text style={styles.TextBodyTitle}>CONGRATS !</Text>
                 <Text style={styles.TextBody}>you finish the test with a score of 12/20 ! </Text>
                 <Image source={require('../../assets/uWin.png')} />
                 <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
@@ -84,9 +84,14 @@ const styles = StyleSheet.create({
 
         elevation: 5,
     },
+    TextBodyTitle: {
+        textAlign: 'center',
+        fontSize: 24,
+        fontWeight: 'bold',
+    },
     TextBody: {
         textAlign: 'center',
-        fontSize: 20,
+        fontSize: 22,
         fontWeight: 'bold',
     },
     whiteButton: {
-- 
GitLab


From af280b7e03c70730d416b726084386f6ed84295a Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 18:45:39 +0100
Subject: [PATCH 076/283] feat: go back to the menu in quiz

---
 components/PlayingQuiz/ComfirmModal.tsx   | 105 ++++++++++++++++++++++
 components/PlayingQuiz/GoHomeButton.tsx   |  21 +++++
 screens/Home/HeaderNavigation.tsx         |   1 +
 screens/PlayingQuiz/PlayingQuiz.tsx       |   3 +-
 screens/PlayingQuiz/PlayingQuizHeader.tsx |  33 +++++--
 5 files changed, 157 insertions(+), 6 deletions(-)
 create mode 100644 components/PlayingQuiz/ComfirmModal.tsx
 create mode 100644 components/PlayingQuiz/GoHomeButton.tsx

diff --git a/components/PlayingQuiz/ComfirmModal.tsx b/components/PlayingQuiz/ComfirmModal.tsx
new file mode 100644
index 0000000..f31241c
--- /dev/null
+++ b/components/PlayingQuiz/ComfirmModal.tsx
@@ -0,0 +1,105 @@
+import React from "react";
+import {
+    Modal,
+    View,
+    Text,
+    StyleSheet,
+    TouchableOpacity,
+    TouchableWithoutFeedback,
+} from "react-native";
+import Icon from "react-native-vector-icons/MaterialIcons";
+import BlueButton from "../PlayQuiz/BlueButton"; // Pour l'icône de fermeture
+
+interface Props {
+    visible: boolean;
+    onClose: () => void;
+    onConfirm: () => void;
+}
+
+export default function ConfirmModal({ visible, onClose, onConfirm }: Props) {
+    return (
+        <Modal
+            animationType="slide"
+            transparent={true}
+            visible={visible}
+            onRequestClose={onClose} // Ferme la modal en cas d'interaction système
+        >
+            <TouchableWithoutFeedback onPress={onClose}>
+                <View style={styles.overlay} />
+            </TouchableWithoutFeedback>
+            <View style={styles.modalContainer}>
+                <TouchableOpacity style={styles.closeButton} onPress={onClose}>
+                    <Icon name="close" size={24} color="#000" />
+                </TouchableOpacity>
+                <Text style={styles.title}>WOULD YOU LIKE TO RETURN TO THE MENU ?</Text>
+                <View style={styles.separator} />
+                <View style={styles.buttonContainer}>
+                    <BlueButton text={"CONFIRM"} onPress={onConfirm}/>
+                </View>
+            </View>
+        </Modal>
+    );
+}
+
+const styles = StyleSheet.create({
+    overlay: {
+        flex: 1,
+        backgroundColor: "rgba(0, 0, 0, 0.5)",
+    },
+    modalContainer: {
+        position: "absolute",
+        top: "40%",
+        left: "10%",
+        right: "10%",
+        backgroundColor: "white",
+        borderRadius: 10,
+        padding: 20,
+        alignItems: "center",
+        elevation: 5,
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.25,
+        shadowRadius: 4,
+    },
+    closeButton: {
+        position: "absolute",
+        top: 10,
+        right: 10,
+        zIndex: 1,
+    },
+    title: {
+        fontSize: 16,
+        fontWeight: "bold",
+        color: "#000",
+        textAlign: "center",
+        marginVertical: 20,
+    },
+    separator: {
+        width: "100%",
+        height: 2,
+        backgroundColor: "#bebebe",
+        marginVertical: 10,
+    },
+    confirmButton: {
+        backgroundColor: "#1FA9FF",
+        borderRadius: 8,
+        paddingVertical: 10,
+        paddingHorizontal: 20,
+        alignItems: "center",
+        justifyContent: "center",
+        marginTop: 10,
+        width: "80%",
+    },
+    confirmButtonText: {
+        color: "#fff",
+        fontSize: 16,
+        fontWeight: "bold",
+    },
+    buttonContainer: {
+        flexDirection: "row",
+        justifyContent: "space-between",
+        alignItems: "center",
+        width: "80%",
+        marginTop: 10,
+    },
+});
diff --git a/components/PlayingQuiz/GoHomeButton.tsx b/components/PlayingQuiz/GoHomeButton.tsx
new file mode 100644
index 0000000..56f2476
--- /dev/null
+++ b/components/PlayingQuiz/GoHomeButton.tsx
@@ -0,0 +1,21 @@
+import {Image, StyleSheet, TouchableOpacity} from "react-native";
+import {NavigationProp} from "@react-navigation/native";
+
+interface Props{
+    navigation: NavigationProp<any>
+    onPress: (bool:boolean) => void
+}
+
+
+export default function GoHomeButton({navigation, onPress}: Props){
+    const handleGoHomeButtonPressed = () =>{
+        onPress(true);
+    }
+
+    return (
+        <TouchableOpacity onPress={handleGoHomeButtonPressed}>
+            <Image source={require('../../assets/GoHomeNavigation.png')} />
+        </TouchableOpacity>
+    )
+}
+
diff --git a/screens/Home/HeaderNavigation.tsx b/screens/Home/HeaderNavigation.tsx
index 1a5e961..03370bb 100644
--- a/screens/Home/HeaderNavigation.tsx
+++ b/screens/Home/HeaderNavigation.tsx
@@ -1,5 +1,6 @@
 import { View, StyleSheet, Image, TouchableOpacity } from "react-native";
 import { NavigationProp } from "@react-navigation/native";
+import ConfirmModal from "../../components/PlayingQuiz/ComfirmModal";
 
 interface Props {
     navigation: NavigationProp<any>;
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 9ea3d2e..e16dd84 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -5,6 +5,7 @@ import TemplateDuo from "../../templates/TemplateDuo";
 import QuestionModel from "../../models/QuestionModel";
 import QuizModel from "../../models/QuizModel";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
+import ConfirmModal from "../../components/PlayingQuiz/ComfirmModal";
 
 const optionsTheme = [
     "General Knowledge",
@@ -40,7 +41,7 @@ export default function PlayingQuiz({route, navigation}:Props) {
 
     return (
         <TemplateDuo
-            childrenHeader={<PlayingQuizHeader quiz={quiz} ></PlayingQuizHeader>}
+            childrenHeader={<PlayingQuizHeader quiz={quiz} navigation={navigation}></PlayingQuizHeader>}
             childrenBody={<PlayingQuizBody quiz={quiz} setQuiz={setQuiz} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed} navigation={navigation}></PlayingQuizBody>}
         />
     );
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index a04bded..fa1747f 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -3,22 +3,37 @@ import { TextsStyles } from "../../styles/TextsStyles";
 import QuizModel from "../../models/QuizModel";
 import {useTranslation} from "react-i18next";
 import DefaultButton from "../../components/DefaultButton";
+import GoHomeButton from "../../components/PlayingQuiz/GoHomeButton";
+import {NavigationProp} from "@react-navigation/native";
+import ConfirmModal from "../../components/PlayingQuiz/ComfirmModal";
+import {useState} from "react";
 
 interface Props {
-
+    navigation: NavigationProp<any>
     quiz: QuizModel;
 }
 
-export default function PlayingQuizHeader({quiz}: Props) {
+export default function PlayingQuizHeader({navigation, quiz}: Props) {
+    const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);
     const {t} = useTranslation();
 
+    const handleConfirmModalConfirm = () => {
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "Home",
+                },
+            ]
+        });
+    }
+
     if (quiz.nbQuestions <= quiz.nbActualQuestion - 1) return;
 
-    const handleButtonBackToHomePressed = () => {
-    }
     return (
             <View style={styles.container}>
-                <View>
+                <View style={styles.header}>
+                    <GoHomeButton navigation={navigation} onPress={setIsConfirmModalVisible}/>
                     <Text style={styles.codeQuizText}>ID QUIZZ : {quiz ? quiz.code : "?"}</Text>
                 </View>
                 <View style={styles.questionAndScoreContainer}>
@@ -34,6 +49,8 @@ export default function PlayingQuizHeader({quiz}: Props) {
                 <View style={styles.QuizQuestionContainer}>
                     <Text style={TextsStyles.subtitleText}>{quiz.questions[quiz.nbActualQuestion-1].question ? quiz.questions[quiz.nbActualQuestion-1].question : "Loading..."}</Text>
                 </View>
+                <ConfirmModal visible={isConfirmModalVisible} onClose={()=>setIsConfirmModalVisible(false)} onConfirm={handleConfirmModalConfirm}/>
+
             </View>
     );
 }
@@ -68,4 +85,10 @@ const styles = StyleSheet.create({
         fontSize: 18,
         color: '#000000',
     },
+    header: {
+        display: "flex",
+        flexDirection: "row",
+        justifyContent: "flex-start",
+        gap: '5%',
+    }
 });
\ No newline at end of file
-- 
GitLab


From 37034b4479d4f0c7243e866772aa4b41188291ae Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 18:56:28 +0100
Subject: [PATCH 077/283] feat: UserModel

---
 assets/GoHomeNavigation.png | Bin 0 -> 231 bytes
 models/UserModel.ts         |  13 +++++++++++++
 2 files changed, 13 insertions(+)
 create mode 100644 assets/GoHomeNavigation.png
 create mode 100644 models/UserModel.ts

diff --git a/assets/GoHomeNavigation.png b/assets/GoHomeNavigation.png
new file mode 100644
index 0000000000000000000000000000000000000000..68b716cb9fcb970acf527989ac09384f53062bf9
GIT binary patch
literal 231
zcmeAS@N?(olHy`uVBq!ia0vp^B0#Lf!3HGbSN+@zq&N#aB8wRqxP?KOkzv*x37{Zj
zage(c!@6@aFM%AEbVpxD28NCO+<y{Tf&3az7srqa#<$llayBRk9Q(LiEu%RsQ`o(L
zC3BKn=8`)PezDYYXa(^r?XZ_=;<x|en)1rSMP{0$upzgxdlqlRgktHfWsOtSR=s8P
z?wu83aK_;9zJo?PRwrgCye$w~U-h(y&6(Hq%leF}t*`be>0dDWz!tmGTtUxKBK{kn
Y=c*NVB2Sj51Kq*k>FVdQ&MBb@0PV_4{Qv*}

literal 0
HcmV?d00001

diff --git a/models/UserModel.ts b/models/UserModel.ts
new file mode 100644
index 0000000..f206e7d
--- /dev/null
+++ b/models/UserModel.ts
@@ -0,0 +1,13 @@
+export default class UserModel {
+    id: number;
+    name: string;
+    token: string;
+
+    constructor(id: number, name: string, token: string) {
+        this.id = id;
+        this.name = name;
+        this.token = token;
+    }
+}
+
+
-- 
GitLab


From c858610e1ca8171b1554869d4400b17a8e8e7b7b Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 4 Dec 2024 19:21:11 +0100
Subject: [PATCH 078/283] feat: useState user

---
 hooks/UseUser.ts  | 60 +++++++++++++++++++++++++++++++++++++++++++++++
 package-lock.json | 34 +++++++++++++++++++++++++++
 package.json      |  1 +
 3 files changed, 95 insertions(+)
 create mode 100644 hooks/UseUser.ts

diff --git a/hooks/UseUser.ts b/hooks/UseUser.ts
new file mode 100644
index 0000000..810fc17
--- /dev/null
+++ b/hooks/UseUser.ts
@@ -0,0 +1,60 @@
+import AsyncStorage from "@react-native-async-storage/async-storage";
+export const useUser = () => {
+    const getUser = async <T>(key: string): Promise<T | undefined> => {
+        try {
+            const item = await AsyncStorage.getItem(key);
+            if (!item) {
+                return undefined;
+            }
+            console.log("User informations loaded");
+            return JSON.parse(item);
+        } catch (error) {
+            console.error("Erreur lors de la récupération de la donnée des informations utilisateur", error);
+            return undefined;
+        }
+    };
+
+    const setUser = async <T>(key: string, newValue: T) => {
+        try {
+            await AsyncStorage.setItem(key, JSON.stringify(newValue));
+            console.log("User informations saved");
+        } catch (error) {
+            console.error("Erreur lors de l'enregistrement de la donnée", error);
+        }
+    };
+
+    const getAnonymousUser = async <T>(): Promise<T | undefined> => {
+        return getUser("anonymousUser");
+    }
+
+    const setAnonymousUser = async <T>(newValue: T) => {
+        return setUser("anonymousUser", newValue);
+    }
+
+    const getRealUser = async <T>(): Promise<T | undefined> => {
+        return getUser("realUser");
+    }
+
+    const setRealUser = async <T>(newValue: T) => {
+        return setUser("realUser", newValue);
+    }
+
+    const connectUser = async <T>(user: T) => {
+        // TODO: Implement
+    }
+
+    const logOutUser = async () => {
+        // TODO: Implement
+    }
+
+    return {
+        getAnonymousUser: getAnonymousUser,
+        setAnonymousUser: setAnonymousUser,
+        getRealUser: getRealUser,
+        setRealUser: setRealUser,
+        connectUser: connectUser,
+        logOutUser: logOutUser,
+    };
+}
+
+
diff --git a/package-lock.json b/package-lock.json
index b4a0a5f..2fa9495 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
       "name": "vili",
       "version": "1.0.0",
       "dependencies": {
+        "@react-native-async-storage/async-storage": "^2.1.0",
         "@react-native-picker/picker": "^2.9.0",
         "@react-navigation/bottom-tabs": "^6.6.1",
         "@react-navigation/native": "^6.1.18",
@@ -3483,6 +3484,18 @@
         "node": ">=14"
       }
     },
+    "node_modules/@react-native-async-storage/async-storage": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.1.0.tgz",
+      "integrity": "sha512-eAGQGPTAuFNEoIQSB5j2Jh1zm5NPyBRTfjRMfCN0W1OakC5WIB5vsDyIQhUweKN9XOE2/V07lqTMGsL0dGXNkA==",
+      "license": "MIT",
+      "dependencies": {
+        "merge-options": "^3.0.4"
+      },
+      "peerDependencies": {
+        "react-native": "^0.0.0-0 || >=0.65 <1.0"
+      }
+    },
     "node_modules/@react-native-picker/picker": {
       "version": "2.9.0",
       "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.9.0.tgz",
@@ -6774,6 +6787,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/is-plain-obj": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+      "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/is-plain-object": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -7663,6 +7685,18 @@
       "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
       "license": "MIT"
     },
+    "node_modules/merge-options": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
+      "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==",
+      "license": "MIT",
+      "dependencies": {
+        "is-plain-obj": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
diff --git a/package.json b/package.json
index c8ebea8..a87f186 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
     "web": "expo start --web"
   },
   "dependencies": {
+    "@react-native-async-storage/async-storage": "^2.1.0",
     "@react-native-picker/picker": "^2.9.0",
     "@react-navigation/bottom-tabs": "^6.6.1",
     "@react-navigation/native": "^6.1.18",
-- 
GitLab


From e108df1c31ab4c195daba48a458f46133cf22f76 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 4 Dec 2024 19:29:53 +0100
Subject: [PATCH 079/283] add: ajout du splashscreen

---
 App.tsx                 |  18 ++++++++++++++++++
 app.json                |   2 +-
 assets/splashscreen.png | Bin 0 -> 39550 bytes
 3 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 assets/splashscreen.png

diff --git a/App.tsx b/App.tsx
index 8d4b928..41a0a91 100644
--- a/App.tsx
+++ b/App.tsx
@@ -3,8 +3,26 @@ import {I18nextProvider, useTranslation} from "react-i18next";
 import i18n from "./translation/i18n"; // Importez l'instance déjà initialisée
 import { SafeAreaProvider } from "react-native-safe-area-context";
 import StackNavigator from "./routes/StackNavigator";
+import { useEffect } from 'react';
+import * as SplashScreen from 'expo-splash-screen';
+
 export default function App() {
     // LogBox.ignoreAllLogs(true);
+    useEffect(() => {
+      async function prepare() {
+        try {
+          await SplashScreen.preventAutoHideAsync(); // affichage
+          
+          // Chargement des fonts, appels API externes, etc...
+          
+          // On fait une pause 2 sec pour simuler un chargement lent
+          await new Promise(resolve => setTimeout(resolve, 2000));
+  
+        } catch (e) { console.warn(e); } finally {
+          await SplashScreen.hideAsync(); // masquage
+        }
+      } prepare(); }, []);
+
 
   const { t } = useTranslation();
   return (
diff --git a/app.json b/app.json
index 0363479..409bd9c 100644
--- a/app.json
+++ b/app.json
@@ -8,7 +8,7 @@
     "icon": "./assets/icon.png",
     "userInterfaceStyle": "light",
     "splash": {
-      "image": "./assets/splash.png",
+      "image": "./assets/splashscreen.png",
       "resizeMode": "contain",
       "backgroundColor": "#ffffff"
     },
diff --git a/assets/splashscreen.png b/assets/splashscreen.png
new file mode 100644
index 0000000000000000000000000000000000000000..7fb90c52530abcbaf7a7f980aeef669199e6d076
GIT binary patch
literal 39550
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
G3I7EeDe3$G

literal 0
HcmV?d00001

-- 
GitLab


From 206611d229c2d871610b507a9ddba2d145aeff5f Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 08:56:28 +0100
Subject: [PATCH 080/283] feat: numeric param in InputPlayQuiz

---
 components/PlayQuiz/InputPlayQuiz.tsx     | 40 +++++++++++------------
 screens/PlayQuiz/PlayQuizGenerateQuiz.tsx |  2 +-
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
index e0b00e4..be655db 100644
--- a/components/PlayQuiz/InputPlayQuiz.tsx
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -6,9 +6,10 @@ interface Props {
     setText: (text: string) => void;
     noTitle?: boolean;
     placeholder?: string;
+    numeric?: boolean;
 }
 
-export default function InputPlayQuiz({ title, setText, noTitle, placeholder }: Props) {
+export default function InputPlayQuiz({ title, setText, noTitle, placeholder, numeric }: Props) {
     return (
         <View style={styles.container}>
             {!noTitle && title && <Text style={styles.title}>{title}</Text>}
@@ -16,10 +17,10 @@ export default function InputPlayQuiz({ title, setText, noTitle, placeholder }:
                 style={styles.input}
                 placeholder={placeholder || ""}
                 placeholderTextColor="#bebebe"
-                keyboardType="default"
-                onChangeText={(text) =>{
-                    setText(text)
-                    console.log("test")
+                keyboardType={numeric ? "numeric" : "default"} // Clavier conditionnel
+                onChangeText={(text) => {
+                    setText(text);
+                    console.log("Input changed:", text);
                 }}
             />
         </View>
@@ -30,30 +31,29 @@ const styles = StyleSheet.create({
     container: {
         display: "flex",
         flexDirection: "column",
-        alignItems: "flex-start", // Aligne les éléments à gauche
-        width: "100%", // S'assure que le conteneur prend toute la largeur
+        alignItems: "flex-start",
+        width: "100%",
     },
     input: {
         width: "100%",
-        height: 70, // Hauteur augmentée comme dans boxStyles
-        backgroundColor: "white", // Fond blanc comme dans boxStyles
+        height: 70,
+        backgroundColor: "white",
         borderColor: "#2ec7ff",
         borderWidth: 3,
         borderRadius: 8,
-        paddingLeft: 10, // Espacement à gauche pour le texte
-        elevation: 5, // Ombre pour Android
-        // Ombre pour iOS
+        paddingLeft: 10,
+        elevation: 5,
         shadowColor: "#000",
-        shadowOffset: { width: 0, height: 4 }, // Décalage de l'ombre en bas
-        shadowOpacity: 0.25, // Opacité de l'ombre
-        shadowRadius: 3.84, // Flou de l'ombre
+        shadowOffset: { width: 0, height: 4 },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.84,
     },
     title: {
         fontSize: 20,
-        fontWeight: "bold", // Met le texte en gras
-        marginBottom: 5, // Ajoute un espace entre le titre et la boîte déroulante
-        color: "#333", // Couleur du texte
-        textAlign: "left", // Aligne le texte à gauche
-        width: "100%", // S'assure que le texte utilise toute la largeur disponible
+        fontWeight: "bold",
+        marginBottom: 5,
+        color: "#333",
+        textAlign: "left",
+        width: "100%",
     },
 });
diff --git a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
index 066ccc7..b8368ae 100644
--- a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -65,7 +65,7 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
                 <View style={styles.fieldContainer}>
                     <SelectListBox title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
                     <SelectListBox title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
-                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} />
+                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} />
                 </View>
                 <View style={styles.buttonPlayContainer}>
                     <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} />
-- 
GitLab


From e71d794e9e670c3934361c57965ed653bca65b24 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 08:57:52 +0100
Subject: [PATCH 081/283] style: console.log

---
 components/PlayQuiz/InputPlayQuiz.tsx     | 1 -
 screens/PlayQuiz/PlayQuizGenerateQuiz.tsx | 4 ----
 screens/PlayingQuiz/PlayingQuizBody.tsx   | 2 --
 services/QuizService.ts                   | 2 --
 4 files changed, 9 deletions(-)

diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
index be655db..4df76b8 100644
--- a/components/PlayQuiz/InputPlayQuiz.tsx
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -20,7 +20,6 @@ export default function InputPlayQuiz({ title, setText, noTitle, placeholder, nu
                 keyboardType={numeric ? "numeric" : "default"} // Clavier conditionnel
                 onChangeText={(text) => {
                     setText(text);
-                    console.log("Input changed:", text);
                 }}
             />
         </View>
diff --git a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
index b8368ae..2cad214 100644
--- a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -39,10 +39,6 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
     const [nbQuestions, setNbQuestions] = React.useState("");
     const {generateQuiz} = useQuizService();
 
-    useEffect(() => {
-        console.log(difficutlyChoose + ", " + getIdOfCategory(categoryChoose) + ", " + nbQuestions);
-    }, [difficutlyChoose,categoryChoose,nbQuestions]);
-
 
     const handlePlayButtonPress = async () => {
         if (nbQuestions === "" && difficutlyChoose === "" && categoryChoose === "") return;
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 560ef21..dfce563 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -73,7 +73,6 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
 
     const handleAnswerPress = async (index: number) => {
         if (isAnswered) return
-        console.log(index);
         setSelectedAnswerIndex(index);
     };
 
@@ -89,7 +88,6 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
         if(!isAnswered && index === selectedAnswerIndex && !isCorrect) return styles.selectedAnswer;
 
         if (index === selectedAnswerIndex && isCorrect !== null) {
-            console.log(isCorrect);
             return isCorrect ? styles.correctAnswer : styles.incorrectAnswer;
         }
         if (currentQuestion.answers[index].id === correctAnswer?.id) {
diff --git a/services/QuizService.ts b/services/QuizService.ts
index d2bed7c..fbbf5de 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -50,7 +50,6 @@ export const useQuizService =  () => {
         const requestBody = {
             id
         };
-        console.log(requestBody);
 
         try {
             const response = await fetch(url + "/quiz/remaining", {
@@ -68,7 +67,6 @@ export const useQuizService =  () => {
             // Récupération des données retournées par l'API
             const data = await response.json();
             const quiz = transformToQuizModel(data);
-            console.log(quiz);
             return quiz;
         } catch (error) {
             console.log("Error while remaining quiz:", error);
-- 
GitLab


From c17f13f8aef937dd44207ab39f0a1eaf974caf18 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 09:04:09 +0100
Subject: [PATCH 082/283] style: to much imports

---
 screens/PlayQuiz/PlayQuizChild.tsx | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/PlayQuiz/PlayQuizChild.tsx
index 6fb6902..ad6e515 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/PlayQuiz/PlayQuizChild.tsx
@@ -3,9 +3,6 @@ import {NavigationProp} from "@react-navigation/native";
 import SelectMode from "../../components/PlayQuiz/SelectMode";
 import React, {useState} from "react";
 import {SelectModeType} from "../../models/SelectModeType";
-import SelectListBox from "../../components/PlayQuiz/SelectListBox";
-import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import BlueButton from "../../components/PlayQuiz/BlueButton";
 import PlayQuizGenerateQuiz from "./PlayQuizGenerateQuiz";
 import PlayQuizJoinQuiz from "./PlayQuizJoinQuiz";
 
-- 
GitLab


From fabffed7be47cfe6baa1d0fa613429c77be714c6 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 09:11:45 +0100
Subject: [PATCH 083/283] feat: BlueButton can be disabled

---
 components/PlayQuiz/BlueButton.tsx | 50 +++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/components/PlayQuiz/BlueButton.tsx b/components/PlayQuiz/BlueButton.tsx
index 1d39741..21e78e7 100644
--- a/components/PlayQuiz/BlueButton.tsx
+++ b/components/PlayQuiz/BlueButton.tsx
@@ -1,34 +1,48 @@
-import {View, Text, StyleSheet, TouchableOpacity, GestureResponderEvent} from "react-native";
-import {NavigationProp} from "@react-navigation/native";
+import { View, Text, StyleSheet, TouchableOpacity, GestureResponderEvent } from "react-native";
 
 interface Props {
-    onPress:  ((event: GestureResponderEvent) => void) | undefined
-    text: string
-    buttonStyle?: any
+    onPress: ((event: GestureResponderEvent) => void) | undefined;
+    text: string;
+    buttonStyle?: any;
+    isDisabled: boolean;
 }
-export default function BlueButton({onPress, text, buttonStyle} : Props) {
 
+export default function BlueButton({ onPress, text, buttonStyle, isDisabled }: Props) {
     return (
-        <TouchableOpacity style={[styles.container, buttonStyle]} onPress={onPress}>
-            <Text style={styles.text}>{text}</Text>
+        <TouchableOpacity
+            style={[
+                styles.container,
+                isDisabled ? styles.disabledContainer : styles.enabledContainer,
+                buttonStyle,
+            ]}
+            onPress={onPress}
+            disabled={isDisabled}
+        >
+            <Text style={[styles.text, isDisabled && styles.disabledText]}>{text}</Text>
         </TouchableOpacity>
     );
 }
 
 const styles = StyleSheet.create({
-
     container: {
-        width: '100%',
+        width: "100%",
         height: 70,
-        alignItems: 'center',
-        justifyContent: 'center',
-        backgroundColor: '#2b73fe',
+        alignItems: "center",
+        justifyContent: "center",
         borderRadius: 10,
     },
+    enabledContainer: {
+        backgroundColor: "#2b73fe", // Couleur bleue par défaut
+    },
+    disabledContainer: {
+        backgroundColor: "#b0b0b0", // Gris désactivé
+    },
     text: {
-        color: 'white',
         fontSize: 28,
-        fontWeight: 'bold',
-    }
-
-});
\ No newline at end of file
+        color: "white",
+        fontWeight: "bold",
+    },
+    disabledText: {
+        color: "#d0d0d0", // Texte grisé pour un bouton désactivé
+    },
+});
-- 
GitLab


From e0763d95336fb3a01e4881ff8018b0be8e71657f Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 09:12:07 +0100
Subject: [PATCH 084/283] feat: Generate quiz blue button can be disabled

---
 screens/PlayQuiz/PlayQuizGenerateQuiz.tsx | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
index 2cad214..b4dbe30 100644
--- a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -37,12 +37,22 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
     const [difficutlyChoose, setDifficutlyChoose] = React.useState("");
     const [categoryChoose, setCategoryChoose] = React.useState("");
     const [nbQuestions, setNbQuestions] = React.useState("");
+    const [buttonIsDisabled, setButtonIsDisabled] = React.useState(true);
     const {generateQuiz} = useQuizService();
 
+    useEffect(() => {
+        if(nbQuestions === "" || difficutlyChoose === "" || categoryChoose === "")
+        {
+            setButtonIsDisabled(true);
+        }
+        else
+        {
+            setButtonIsDisabled(false);
+        }
 
-    const handlePlayButtonPress = async () => {
-        if (nbQuestions === "" && difficutlyChoose === "" && categoryChoose === "") return;
+    }, [difficutlyChoose,categoryChoose,nbQuestions]);
 
+    const handlePlayButtonPress = async () => {
         const quizGenerated = await generateQuiz(parseInt(nbQuestions), getIdOfCategory(categoryChoose), difficutlyChoose);
         navigation.reset({
             index: 0,
@@ -64,7 +74,7 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
                     <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} />
                 </View>
                 <View style={styles.buttonPlayContainer}>
-                    <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} />
+                    <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} isDisabled={buttonIsDisabled}/>
                 </View>
             </View>
         </View>
-- 
GitLab


From 20291a803e61d79b357d080ac5b57cfdb05d375c Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 09:15:59 +0100
Subject: [PATCH 085/283] feat: Join quiz blue button can be disabled

---
 screens/PlayQuiz/PlayQuizJoinQuiz.tsx | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
index 2e1a023..a1d2523 100644
--- a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -24,6 +24,10 @@ export default function PlayQuizJoinQuiz({navigation}: Props) {
     }, [codeQuiz]);
 
     const fetchQuiz = async () => {
+        if(codeQuiz === "")
+        {
+            return;
+        }
         const quizFetched = await remainingQuiz(codeQuiz);
         if (quizFetched instanceof HttpError) {
             setError("The quiz does not exist");
@@ -34,7 +38,6 @@ export default function PlayQuizJoinQuiz({navigation}: Props) {
     };
 
     const handlePlayButtonPress = () => {
-        if(error !== "") return;
         navigation.reset({
             index: 0,
             routes: [
@@ -55,7 +58,7 @@ export default function PlayQuizJoinQuiz({navigation}: Props) {
                     <AboutAQuiz quiz={quiz} />
                 </View>
                 <View style={styles.buttonPlayContainer}>
-                    <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} />
+                    <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} isDisabled={codeQuiz==="" || error!==""}/>
                 </View>
             </View>
         </View>
-- 
GitLab


From 82f24900b531d1d58af56436d2fcb35bbc1c8cf6 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 09:21:00 +0100
Subject: [PATCH 086/283] feat: PlayingQuiz blue button can be disabled

---
 screens/PlayingQuiz/PlayingQuizBody.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index dfce563..7031a60 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -125,7 +125,7 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
                     ))}
                     {/* Ajout du PlayButton à la fin */}
                     <View style={styles.playButtonContainer}>
-                        <BlueButton onPress={handleConfirmAnswerPressed} text="Confirm" buttonStyle={{borderRadius: 50}}/>
+                        <BlueButton onPress={handleConfirmAnswerPressed} text="Confirm" buttonStyle={{borderRadius: 50}} isDisabled={selectedAnswerIndex===null}/>
                     </View>
                 </>
             ) : (
-- 
GitLab


From edb5e5ffd2b9341aaee12f89ad4c744273ff835c Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 09:32:40 +0100
Subject: [PATCH 087/283] feat: Inputs changed on login

---
 screens/Profil/ProfilModalLogin.tsx | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/ProfilModalLogin.tsx
index 3d86621..6dacfc4 100644
--- a/screens/Profil/ProfilModalLogin.tsx
+++ b/screens/Profil/ProfilModalLogin.tsx
@@ -1,7 +1,12 @@
 import { TextInput, View, StyleSheet } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
+import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import React, {useState} from "react";
 
 export default function ProfilModalLogin() {
+
+    const [email, setEmail] = useState("");
+    const [password, setPassword] = useState("");
     const handleSubmitPressed = () => {
 
     }
@@ -9,8 +14,8 @@ export default function ProfilModalLogin() {
     return (
         <View>
             <View style={styles.containerForm}>
-                <TextInput placeholder="EMAIL..." style={styles.textInput}/>
-                <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
+                <InputPlayQuiz placeholder="EMAIL..." setText={setEmail} noTitle={true}/>
+                <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true}/>
             </View>
             <DefaultButton text="LOGIN" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
         </View>
-- 
GitLab


From 2b179fc8fab56c6fc5839910ea4c6943eaeeca25 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 09:37:28 +0100
Subject: [PATCH 088/283] feat: Inputs changed on signup

---
 screens/Profil/ProfilModalSignup.tsx | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/ProfilModalSignup.tsx
index 7ced6dd..3b7b6de 100644
--- a/screens/Profil/ProfilModalSignup.tsx
+++ b/screens/Profil/ProfilModalSignup.tsx
@@ -1,7 +1,13 @@
 import { TextInput, View, StyleSheet } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
+import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import React, {useState} from "react";
 
 export default function ProfilModalSignup() {
+
+    const [email, setEmail] = useState("");
+    const [password, setPassword] = useState("");
+    const [repeatPassword, setRepeatPassword] = useState("");
     const handleSubmitPressed = () => {
 
     }
@@ -9,9 +15,9 @@ export default function ProfilModalSignup() {
     return (
         <View>
             <View style={styles.containerForm}>
-                <TextInput placeholder="EMAIL..." style={styles.textInput}/>
-                <TextInput placeholder="PASSWORD..." style={styles.textInput}/>
-                <TextInput placeholder="REPEAT PASSWORD..." style={styles.textInput}/>
+                <InputPlayQuiz placeholder="EMAIL..." setText={setEmail} noTitle={true}/>
+                <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true}/>
+                <InputPlayQuiz placeholder="REPEAT PASSWORD..." setText={setRepeatPassword} noTitle={true}/>
             </View>
             <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
         </View>
-- 
GitLab


From cc55c01fb62f96815598d08ddbc5531b1d95c36f Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 10:08:00 +0100
Subject: [PATCH 089/283] feat: getRandomQuiz service

---
 services/QuizService.ts | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index fbbf5de..6248af7 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -112,6 +112,42 @@ export const useQuizService =  () => {
             }
         }
     }
+
+    const getRandomQuiz = async () : Promise<QuizModel | HttpError> => {
+
+        // Création du corps de la requête avec les variables passées
+        const requestBody = {
+            amount: 10,
+        };
+
+        try {
+            const response = await fetch(url + "/quiz/create", {
+                method: "POST",
+                headers: {
+                    "Content-Type": "application/json",
+                },
+                body: JSON.stringify(requestBody),
+            });
+
+            if (!response.ok) {
+                throw new HttpError(response.status, "HTTP error! status: " + response.status);
+            }
+
+            // Récupération des données retournées par l'API
+            const data = await response.json();
+            const quiz = transformToQuizModel(data);
+            return quiz;
+        } catch (error) {
+            console.error("Error while generating random quiz:", error);
+
+            if (HttpError.isHttpError(error)) {
+                return error;
+            } else {
+                return new HttpError(500, "Unexpected error: " + error);
+            }
+        }
+    }
+
     return {
         generateQuiz: generateQuiz,
         getAnswerQuiz: getAnswerQuiz,
-- 
GitLab


From 40162ba1ff3f7a85e768f8e8bc7a8fabfb3d637d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 16:52:04 +0100
Subject: [PATCH 090/283] feat: splashscreen

---
 app.json          |   2 +-
 assets/icon.png   | Bin 22380 -> 59707 bytes
 package-lock.json |  13 +++++++++++++
 package.json      |   1 +
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/app.json b/app.json
index 409bd9c..d7e9736 100644
--- a/app.json
+++ b/app.json
@@ -9,7 +9,7 @@
     "userInterfaceStyle": "light",
     "splash": {
       "image": "./assets/splashscreen.png",
-      "resizeMode": "contain",
+      "resizeMode": "cover",
       "backgroundColor": "#ffffff"
     },
     "ios": {
diff --git a/assets/icon.png b/assets/icon.png
index a0b1526fc7b78680fd8d733dbc6113e1af695487..faee7622c57c0e59493f8dffdf1998d64e14b981 100644
GIT binary patch
literal 59707
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

literal 22380
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

diff --git a/package-lock.json b/package-lock.json
index 2fa9495..f44f12d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,6 +14,7 @@
         "@react-navigation/native": "^6.1.18",
         "@react-navigation/native-stack": "^6.11.0",
         "expo": "^52.0.8",
+        "expo-splash-screen": "^0.29.13",
         "expo-status-bar": "~2.0.0",
         "he": "^1.2.0",
         "i18n-js": "^4.5.0",
@@ -5958,6 +5959,18 @@
         "invariant": "^2.2.4"
       }
     },
+    "node_modules/expo-splash-screen": {
+      "version": "0.29.13",
+      "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.29.13.tgz",
+      "integrity": "sha512-OTaW6v2ErKTlguFDNi4PN+qrEFRA4TIEyFag4204CiFIpAB+13PqQiW4Ovt29aYlLERIjWD++PyoHeSdLSiZwg==",
+      "license": "MIT",
+      "dependencies": {
+        "@expo/prebuild-config": "^8.0.17"
+      },
+      "peerDependencies": {
+        "expo": "*"
+      }
+    },
     "node_modules/expo-status-bar": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.0.0.tgz",
diff --git a/package.json b/package.json
index a87f186..922dd69 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
     "@react-navigation/native": "^6.1.18",
     "@react-navigation/native-stack": "^6.11.0",
     "expo": "^52.0.8",
+    "expo-splash-screen": "^0.29.13",
     "expo-status-bar": "~2.0.0",
     "he": "^1.2.0",
     "i18n-js": "^4.5.0",
-- 
GitLab


From e8a990659701552482a01bb43d4b846ef23a4660 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 5 Dec 2024 17:37:07 +0100
Subject: [PATCH 091/283] feat: add initial value in form create quiz

---
 components/PlayQuiz/InputPlayQuiz.tsx | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
index 4df76b8..715165f 100644
--- a/components/PlayQuiz/InputPlayQuiz.tsx
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -21,6 +21,9 @@ export default function InputPlayQuiz({ title, setText, noTitle, placeholder, nu
                 onChangeText={(text) => {
                     setText(text);
                 }}
+                aria-valuemin={1}
+                aria-valuemax={50}
+                defaultValue="10"
             />
         </View>
     );
-- 
GitLab


From c1074efead44706d5daef58aa79d91e5e15ae0ba Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 5 Dec 2024 17:48:14 +0100
Subject: [PATCH 092/283] feat: add the file to create an apk

---
 app.json |  5 +++++
 eas.json | 21 +++++++++++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 eas.json

diff --git a/app.json b/app.json
index d7e9736..c930458 100644
--- a/app.json
+++ b/app.json
@@ -23,6 +23,11 @@
     },
     "web": {
       "favicon": "./assets/favicon.png"
+    },
+    "extra": {
+      "eas": {
+        "projectId": "8ee47c40-1e74-451c-972a-e1cc75ab11ff"
+      }
     }
   }
 }
diff --git a/eas.json b/eas.json
new file mode 100644
index 0000000..5da8fba
--- /dev/null
+++ b/eas.json
@@ -0,0 +1,21 @@
+{
+  "cli": {
+    "version": ">= 13.4.2",
+    "appVersionSource": "remote"
+  },
+  "build": {
+    "development": {
+      "developmentClient": true,
+      "distribution": "internal"
+    },
+    "preview": {
+      "distribution": "internal"
+    },
+    "production": {
+      "autoIncrement": true
+    }
+  },
+  "submit": {
+    "production": {}
+  }
+}
-- 
GitLab


From 1c92a859d1d087b878bd1aeabfafdcd443d6c797 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 22:16:16 +0100
Subject: [PATCH 093/283] feat: user services

---
 helper/UserHelper.ts    |  10 +
 models/UserModel.ts     |  11 +-
 package-lock.json       | 503 ++++++++++++++++++++--------------------
 package.json            |   8 +-
 services/UserService.ts | 119 ++++++++++
 5 files changed, 396 insertions(+), 255 deletions(-)
 create mode 100644 helper/UserHelper.ts
 create mode 100644 services/UserService.ts

diff --git a/helper/UserHelper.ts b/helper/UserHelper.ts
new file mode 100644
index 0000000..123b556
--- /dev/null
+++ b/helper/UserHelper.ts
@@ -0,0 +1,10 @@
+import UserModel from "../models/UserModel";
+
+export const transformToUserModel = (data: any): UserModel => {
+    const user: UserModel = {
+        id: data.id,
+        email: data.email,
+        username: data.username,
+    }
+    return user;
+};
\ No newline at end of file
diff --git a/models/UserModel.ts b/models/UserModel.ts
index f206e7d..66ecffe 100644
--- a/models/UserModel.ts
+++ b/models/UserModel.ts
@@ -1,12 +1,11 @@
 export default class UserModel {
     id: number;
-    name: string;
-    token: string;
-
-    constructor(id: number, name: string, token: string) {
+    username: string;
+    email: string;
+    constructor(id: number, username: string, email: string) {
         this.id = id;
-        this.name = name;
-        this.token = token;
+        this.username = username;
+        this.email = email;
     }
 }
 
diff --git a/package-lock.json b/package-lock.json
index f44f12d..f808720 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,20 +8,21 @@
       "name": "vili",
       "version": "1.0.0",
       "dependencies": {
-        "@react-native-async-storage/async-storage": "^2.1.0",
+        "@react-native-async-storage/async-storage": "1.23.1",
+        "@react-native-cookies/cookies": "^6.2.1",
         "@react-native-picker/picker": "^2.9.0",
         "@react-navigation/bottom-tabs": "^6.6.1",
         "@react-navigation/native": "^6.1.18",
         "@react-navigation/native-stack": "^6.11.0",
-        "expo": "^52.0.8",
-        "expo-splash-screen": "^0.29.13",
+        "axios": "^1.7.9",
+        "expo": "~52.0.14",
         "expo-status-bar": "~2.0.0",
         "he": "^1.2.0",
         "i18n-js": "^4.5.0",
         "i18next": "^23.16.5",
         "react": "^18.3.1",
         "react-i18next": "^15.1.1",
-        "react-native": "^0.76.2",
+        "react-native": "0.76.3",
         "react-native-dropdown-select-list": "^2.0.5",
         "react-native-safe-area-context": "^4.12.0",
         "react-native-screens": "~4.1.0",
@@ -116,13 +117,13 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.26.2",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz",
-      "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz",
+      "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==",
       "license": "MIT",
       "dependencies": {
-        "@babel/parser": "^7.26.2",
-        "@babel/types": "^7.26.0",
+        "@babel/parser": "^7.26.3",
+        "@babel/types": "^7.26.3",
         "@jridgewell/gen-mapping": "^0.3.5",
         "@jridgewell/trace-mapping": "^0.3.25",
         "jsesc": "^3.0.2"
@@ -143,20 +144,6 @@
         "node": ">=6.9.0"
       }
     },
-    "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz",
-      "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==",
-      "license": "MIT",
-      "peer": true,
-      "dependencies": {
-        "@babel/traverse": "^7.25.9",
-        "@babel/types": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
     "node_modules/@babel/helper-compilation-targets": {
       "version": "7.25.9",
       "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz",
@@ -195,13 +182,13 @@
       }
     },
     "node_modules/@babel/helper-create-regexp-features-plugin": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz",
-      "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz",
+      "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==",
       "license": "MIT",
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.25.9",
-        "regexpu-core": "^6.1.1",
+        "regexpu-core": "^6.2.0",
         "semver": "^6.3.1"
       },
       "engines": {
@@ -212,9 +199,9 @@
       }
     },
     "node_modules/@babel/helper-define-polyfill-provider": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz",
-      "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==",
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
+      "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
       "license": "MIT",
       "dependencies": {
         "@babel/helper-compilation-targets": "^7.22.6",
@@ -325,19 +312,6 @@
         "@babel/core": "^7.0.0"
       }
     },
-    "node_modules/@babel/helper-simple-access": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz",
-      "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==",
-      "license": "MIT",
-      "dependencies": {
-        "@babel/traverse": "^7.25.9",
-        "@babel/types": "^7.25.9"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
     "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
       "version": "7.25.9",
       "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
@@ -492,12 +466,12 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.26.2",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
-      "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz",
+      "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==",
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.26.0"
+        "@babel/types": "^7.26.3"
       },
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -1230,13 +1204,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-exponentiation-operator": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz",
-      "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
+      "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
       "license": "MIT",
       "peer": true,
       "dependencies": {
-        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9",
         "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
@@ -1390,14 +1363,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-commonjs": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz",
-      "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
+      "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.25.9",
-        "@babel/helper-plugin-utils": "^7.25.9",
-        "@babel/helper-simple-access": "^7.25.9"
+        "@babel/helper-module-transforms": "^7.26.0",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1876,9 +1848,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-typescript": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz",
-      "integrity": "sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz",
+      "integrity": "sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA==",
       "license": "MIT",
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.25.9",
@@ -2077,9 +2049,9 @@
       }
     },
     "node_modules/@babel/preset-react": {
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.25.9.tgz",
-      "integrity": "sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.26.3.tgz",
+      "integrity": "sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==",
       "license": "MIT",
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.25.9",
@@ -2180,16 +2152,16 @@
     },
     "node_modules/@babel/traverse--for-generate-function-map": {
       "name": "@babel/traverse",
-      "version": "7.25.9",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
-      "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.3.tgz",
+      "integrity": "sha512-yTmc8J+Sj8yLzwr4PD5Xb/WF3bOYu2C2OoSZPzbuqRm4n98XirsbzaX+GloeO376UnSYIYJ4NCanwV5/ugZkwA==",
       "license": "MIT",
       "dependencies": {
-        "@babel/code-frame": "^7.25.9",
-        "@babel/generator": "^7.25.9",
-        "@babel/parser": "^7.25.9",
+        "@babel/code-frame": "^7.26.2",
+        "@babel/generator": "^7.26.3",
+        "@babel/parser": "^7.26.3",
         "@babel/template": "^7.25.9",
-        "@babel/types": "^7.25.9",
+        "@babel/types": "^7.26.3",
         "debug": "^4.3.1",
         "globals": "^11.1.0"
       },
@@ -2198,9 +2170,9 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.26.0",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
-      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "version": "7.26.3",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz",
+      "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==",
       "license": "MIT",
       "dependencies": {
         "@babel/helper-string-parser": "^7.25.9",
@@ -2223,16 +2195,16 @@
       }
     },
     "node_modules/@expo/cli": {
-      "version": "0.21.6",
-      "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.21.6.tgz",
-      "integrity": "sha512-xGeQUK/IX5Wzg2ngXV89wL2s1tWaMJR+sxF8HgGwJqFshC0ikQSV0TRCtz4SCdDjfM7dTPkf4UvOSA45zUMXmA==",
+      "version": "0.22.1",
+      "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.22.1.tgz",
+      "integrity": "sha512-tpkFzlTYb/sNh8WqeTCa2ZVKMDkPgMggvY3tZeTfxeAO5olVXddKV+0U5zhHSd7pGM2w2fhEJNKI4Ub7IfyDmA==",
       "license": "MIT",
       "dependencies": {
         "@0no-co/graphql.web": "^1.0.8",
         "@babel/runtime": "^7.20.0",
         "@expo/code-signing-certificates": "^0.0.5",
         "@expo/config": "~10.0.4",
-        "@expo/config-plugins": "~9.0.3",
+        "@expo/config-plugins": "~9.0.10",
         "@expo/devcert": "^1.1.2",
         "@expo/env": "~0.4.0",
         "@expo/image-utils": "^0.6.0",
@@ -2241,11 +2213,11 @@
         "@expo/osascript": "^2.0.31",
         "@expo/package-manager": "^1.5.0",
         "@expo/plist": "^0.2.0",
-        "@expo/prebuild-config": "^8.0.16",
+        "@expo/prebuild-config": "^8.0.17",
         "@expo/rudder-sdk-node": "^1.1.1",
         "@expo/spawn-async": "^1.7.2",
         "@expo/xcpretty": "^4.3.0",
-        "@react-native/dev-middleware": "0.76.2",
+        "@react-native/dev-middleware": "0.76.3",
         "@urql/core": "^5.0.6",
         "@urql/exchange-retry": "^1.3.0",
         "accepts": "^1.3.8",
@@ -2371,13 +2343,13 @@
       }
     },
     "node_modules/@expo/config": {
-      "version": "10.0.4",
-      "resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.4.tgz",
-      "integrity": "sha512-pkvdPqKTaP6+Qvc8aTmDLQ9Dfwp98P1GO37MFKwsF5XormfN/9/eN8HfIRoM6d3uSIVKCcWW3X2yAEbNmOyfXw==",
+      "version": "10.0.6",
+      "resolved": "https://registry.npmjs.org/@expo/config/-/config-10.0.6.tgz",
+      "integrity": "sha512-xXkfPElrtxznkOZxFASJ7OPa6E9IHSjcZwj5BQ6XUF2dz5M7AFa2h5sXM8AalSaDU5tEBSgoUOjTh5957TlR8g==",
       "license": "MIT",
       "dependencies": {
         "@babel/code-frame": "~7.10.4",
-        "@expo/config-plugins": "~9.0.0",
+        "@expo/config-plugins": "~9.0.10",
         "@expo/config-types": "^52.0.0",
         "@expo/json-file": "^9.0.0",
         "deepmerge": "^4.3.1",
@@ -2392,9 +2364,9 @@
       }
     },
     "node_modules/@expo/config-plugins": {
-      "version": "9.0.9",
-      "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-9.0.9.tgz",
-      "integrity": "sha512-pbgbY3SwCMwkijhfe163J05BrTx4MqzeaV+nVgUMs7vRcjHY1tfM57Pdv6SPtgeDvZ8fvdXFXXzkJva+a7C9Bw==",
+      "version": "9.0.11",
+      "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-9.0.11.tgz",
+      "integrity": "sha512-zufuPQWkeEpXfMWFx2lWStoN43p6cO13p8n2KMIEK6jJMC/kkfldYyl8gYtEEYAL1nFfOf/W2pIXXPQ2sggnSw==",
       "license": "MIT",
       "dependencies": {
         "@expo/config-types": "^52.0.0",
@@ -2627,9 +2599,9 @@
       }
     },
     "node_modules/@expo/fingerprint": {
-      "version": "0.11.2",
-      "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.11.2.tgz",
-      "integrity": "sha512-WPibADqymGSKkNNnrGfw4dRipz7F8DwMSv7zb6T9oTGtdRiObrUpGmtBXmvo6z9MqWkNRprEJNxPjvkkvMvwhQ==",
+      "version": "0.11.3",
+      "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.11.3.tgz",
+      "integrity": "sha512-9lgXmcIePvZ7Wef63XtvuN3HfCUevF4E4tQPdEbH9/dUWwpOvvwQ3KT4OJ9jdh8JJ3nTdO9eDQ/8k8xr1aQ5Kg==",
       "license": "MIT",
       "dependencies": {
         "@expo/spawn-async": "^1.7.2",
@@ -2755,9 +2727,9 @@
       }
     },
     "node_modules/@expo/metro-config": {
-      "version": "0.19.4",
-      "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.4.tgz",
-      "integrity": "sha512-2SWwYN8MZvMIRawWEr+1RBYncitPwu2VMACRYig+wBycJ9fsPb6BMVmBYi+3MHDUlJHNy/Bqfw++jn1eqBFETQ==",
+      "version": "0.19.5",
+      "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-0.19.5.tgz",
+      "integrity": "sha512-wl5lVgXq4FN4kBJHNyU5U9J5hH8S8rYXrp/pgbwA+J/smQfiElYKMYomTGbHUb4LQ0VnmlX6/kI4x/zJk+mq7w==",
       "license": "MIT",
       "dependencies": {
         "@babel/core": "^7.20.0",
@@ -2911,17 +2883,17 @@
       }
     },
     "node_modules/@expo/prebuild-config": {
-      "version": "8.0.17",
-      "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.0.17.tgz",
-      "integrity": "sha512-HM+XpDox3fAZuXZXvy55VRcBbsZSDijGf8jI8i/pexgWvtsnt1ouelPXRuE1pXDicMX+lZO83QV+XkyLmBEXYQ==",
+      "version": "8.0.21",
+      "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.0.21.tgz",
+      "integrity": "sha512-PVvt7+2dLzmf1X4HaoibnTtfoxnor0YEdu396eLv1SG+KacmN5lMz81yO/2MXvv0SDA6THomgBNvA/uzWV5twA==",
       "license": "MIT",
       "dependencies": {
         "@expo/config": "~10.0.4",
-        "@expo/config-plugins": "~9.0.0",
+        "@expo/config-plugins": "~9.0.10",
         "@expo/config-types": "^52.0.0",
         "@expo/image-utils": "^0.6.0",
         "@expo/json-file": "^9.0.0",
-        "@react-native/normalize-colors": "0.76.2",
+        "@react-native/normalize-colors": "0.76.3",
         "debug": "^4.3.1",
         "fs-extra": "^9.0.0",
         "resolve-from": "^5.0.0",
@@ -3023,9 +2995,9 @@
       }
     },
     "node_modules/@expo/xcpretty": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.1.tgz",
-      "integrity": "sha512-sqXgo1SCv+j4VtYEwl/bukuOIBrVgx6euIoCat3Iyx5oeoXwEA2USCoeL0IPubflMxncA2INkqJ/Wr3NGrSgzw==",
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.2.tgz",
+      "integrity": "sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw==",
       "license": "BSD-3-Clause",
       "dependencies": {
         "@babel/code-frame": "7.10.4",
@@ -3486,15 +3458,27 @@
       }
     },
     "node_modules/@react-native-async-storage/async-storage": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.1.0.tgz",
-      "integrity": "sha512-eAGQGPTAuFNEoIQSB5j2Jh1zm5NPyBRTfjRMfCN0W1OakC5WIB5vsDyIQhUweKN9XOE2/V07lqTMGsL0dGXNkA==",
+      "version": "1.23.1",
+      "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.23.1.tgz",
+      "integrity": "sha512-Qd2kQ3yi6Y3+AcUlrHxSLlnBvpdCEMVGFlVBneVOjaFaPU61g1huc38g339ysXspwY1QZA2aNhrk/KlHGO+ewA==",
       "license": "MIT",
       "dependencies": {
         "merge-options": "^3.0.4"
       },
       "peerDependencies": {
-        "react-native": "^0.0.0-0 || >=0.65 <1.0"
+        "react-native": "^0.0.0-0 || >=0.60 <1.0"
+      }
+    },
+    "node_modules/@react-native-cookies/cookies": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@react-native-cookies/cookies/-/cookies-6.2.1.tgz",
+      "integrity": "sha512-D17wCA0DXJkGJIxkL74Qs9sZ3sA+c+kCoGmXVknW7bVw/W+Vv1m/7mWTNi9DLBZSRddhzYw8SU0aJapIaM/g5w==",
+      "license": "MIT",
+      "dependencies": {
+        "invariant": "^2.2.4"
+      },
+      "peerDependencies": {
+        "react-native": ">= 0.60.2"
       }
     },
     "node_modules/@react-native-picker/picker": {
@@ -3508,30 +3492,30 @@
       }
     },
     "node_modules/@react-native/assets-registry": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.2.tgz",
-      "integrity": "sha512-0CTWv/FqJzU1vsyx2JpCkyLSUOePU7DdKgFvtHdwOxFpOw3aBecszqZDGJADYV9WSZQlq6RV0HmIaWycGYCOMA==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.76.3.tgz",
+      "integrity": "sha512-7Fnc3lzCFFpnoyL1egua6d/qUp0KiIpeSLbfOMln4nI2g2BMzyFHdPjJnpLV2NehmS0omOOkrfRqK5u1F/MXzA==",
       "license": "MIT",
       "engines": {
         "node": ">=18"
       }
     },
     "node_modules/@react-native/babel-plugin-codegen": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.2.tgz",
-      "integrity": "sha512-a1IfRho/ZUVbvzSu3JWkxsvqyEI7IXApPQikhGWw4e24QYsIYHdlIULs3rb0840lqpO1dbbuudfO7lmkpkbkMg==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.76.3.tgz",
+      "integrity": "sha512-mZ7jmIIg4bUnxCqY3yTOkoHvvzsDyrZgfnIKiTGm5QACrsIGa5eT3pMFpMm2OpxGXRDrTMsYdPXE2rCyDX52VQ==",
       "license": "MIT",
       "dependencies": {
-        "@react-native/codegen": "0.76.2"
+        "@react-native/codegen": "0.76.3"
       },
       "engines": {
         "node": ">=18"
       }
     },
     "node_modules/@react-native/babel-preset": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.2.tgz",
-      "integrity": "sha512-/kbxZqy70mGONv23uZg7lm7ZCE4dO5dgMzVPz6QsveXIRHQBRLsSC+9w2iZEnYWpLayoWFmTbq8ZG+4W32D3bA==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.76.3.tgz",
+      "integrity": "sha512-zi2nPlQf9q2fmfPyzwWEj6DU96v8ziWtEfG7CTAX2PG/Vjfsr94vn/wWrCdhBVvLRQ6Kvd/MFAuDYpxmQwIiVQ==",
       "license": "MIT",
       "dependencies": {
         "@babel/core": "^7.25.2",
@@ -3575,7 +3559,7 @@
         "@babel/plugin-transform-typescript": "^7.25.2",
         "@babel/plugin-transform-unicode-regex": "^7.24.7",
         "@babel/template": "^7.25.0",
-        "@react-native/babel-plugin-codegen": "0.76.2",
+        "@react-native/babel-plugin-codegen": "0.76.3",
         "babel-plugin-syntax-hermes-parser": "^0.25.1",
         "babel-plugin-transform-flow-enums": "^0.0.2",
         "react-refresh": "^0.14.0"
@@ -3588,9 +3572,9 @@
       }
     },
     "node_modules/@react-native/codegen": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.2.tgz",
-      "integrity": "sha512-rIgdI5mHHnNTzAeDYH+ivKMIcv6vr04Ol+TmX77n1HjJkzMhQqSHWcX+Pq9oiu7l2zKkymadrw6OPD8VPgre8g==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.76.3.tgz",
+      "integrity": "sha512-oJCH/jbYeGmFJql8/y76gqWCCd74pyug41yzYAjREso1Z7xL88JhDyKMvxEnfhSdMOZYVl479N80xFiXPy3ZYA==",
       "license": "MIT",
       "dependencies": {
         "@babel/parser": "^7.25.3",
@@ -3610,13 +3594,13 @@
       }
     },
     "node_modules/@react-native/community-cli-plugin": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.2.tgz",
-      "integrity": "sha512-ZRL8oTGSMwXqTsVkRL9AVW8C/AZRnxCcFfhestsx//SrQt3J/hbtDOHTIGkkt5AEA0zEvb/UAAyIAN/wuN4llw==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.76.3.tgz",
+      "integrity": "sha512-vgsLixHS24jR0d0QqPykBWFaC+V8x9cM3cs4oYXw3W199jgBNGP9MWcUJLazD2vzrT/lUTVBVg0rBeB+4XR6fg==",
       "license": "MIT",
       "dependencies": {
-        "@react-native/dev-middleware": "0.76.2",
-        "@react-native/metro-babel-transformer": "0.76.2",
+        "@react-native/dev-middleware": "0.76.3",
+        "@react-native/metro-babel-transformer": "0.76.3",
         "chalk": "^4.0.0",
         "execa": "^5.1.1",
         "invariant": "^2.2.4",
@@ -3735,22 +3719,22 @@
       }
     },
     "node_modules/@react-native/debugger-frontend": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.2.tgz",
-      "integrity": "sha512-FIcz24Oya2wIO7rZD3dxVyK8t5ZD6Fojl9o7lrjnTWqMedcevRTtdSOIAf4ypksYH/x7HypovE2Zp8U65Xv0Mw==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.76.3.tgz",
+      "integrity": "sha512-pMHQ3NpPB28RxXciSvm2yD+uDx3pkhzfuWkc7VFgOduyzPSIr0zotUiOJzsAtrj8++bPbOsAraCeQhCqoOTWQw==",
       "license": "BSD-3-Clause",
       "engines": {
         "node": ">=18"
       }
     },
     "node_modules/@react-native/dev-middleware": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.2.tgz",
-      "integrity": "sha512-qiowXpxofLk0lpIZps7fyyp9NiKlqBwh0R0yVub5l4EJcqjLonjsznYAHbusnPW9kb9MQSdovGPNv5b8RadJww==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.76.3.tgz",
+      "integrity": "sha512-b+2IpW40z1/S5Jo5JKrWPmucYU/PzeGyGBZZ/SJvmRnBDaP3txb9yIqNZAII1EWsKNhedh8vyRO5PSuJ9Juqzw==",
       "license": "MIT",
       "dependencies": {
         "@isaacs/ttlcache": "^1.4.1",
-        "@react-native/debugger-frontend": "0.76.2",
+        "@react-native/debugger-frontend": "0.76.3",
         "chrome-launcher": "^0.15.2",
         "chromium-edge-launcher": "^0.2.0",
         "connect": "^3.6.5",
@@ -3790,31 +3774,31 @@
       }
     },
     "node_modules/@react-native/gradle-plugin": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.2.tgz",
-      "integrity": "sha512-KC5/uAeLoeD1dOjymx6gnNFHGGLB22xNYjrjrJNK5r0bw2O2KXp4rpB5VCT/2H5B48cVC0xPB7RIKOFrDHr5bQ==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.76.3.tgz",
+      "integrity": "sha512-t0aYZ8ND7+yc+yIm6Yp52bInneYpki6RSIFZ9/LMUzgMKvEB62ptt/7sfho9QkKHCNxE1DJSWIqLIGi/iHHkyg==",
       "license": "MIT",
       "engines": {
         "node": ">=18"
       }
     },
     "node_modules/@react-native/js-polyfills": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.2.tgz",
-      "integrity": "sha512-OXunyNn33fa7gQ6iU5rQcYZQsO7OkJIAr/TgVdoHxpOB4i+ZGsfv6df3JKriBVT1ZZm6ZTlKyIa4QpLq3p0dmw==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.76.3.tgz",
+      "integrity": "sha512-pubJFArMMrdZiytH+W95KngcSQs+LsxOBsVHkwgMnpBfRUxXPMK4fudtBwWvhnwN76Oe+WhxSq7vOS5XgoPhmw==",
       "license": "MIT",
       "engines": {
         "node": ">=18"
       }
     },
     "node_modules/@react-native/metro-babel-transformer": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.2.tgz",
-      "integrity": "sha512-OIYhmWfN+HDyQLzoEg+2P0h7OopYk4djggg0M+k5e1a+g2dFNJILO/BsDobM8uLA8hAzClAJyJLZbPo5jeqdMA==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.76.3.tgz",
+      "integrity": "sha512-b2zQPXmW7avw/7zewc9nzMULPIAjsTwN03hskhxHUJH5pzUf7pIklB3FrgYPZrRhJgzHiNl3tOPu7vqiKzBYPg==",
       "license": "MIT",
       "dependencies": {
         "@babel/core": "^7.25.2",
-        "@react-native/babel-preset": "0.76.2",
+        "@react-native/babel-preset": "0.76.3",
         "hermes-parser": "0.23.1",
         "nullthrows": "^1.1.1"
       },
@@ -3826,15 +3810,15 @@
       }
     },
     "node_modules/@react-native/normalize-colors": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.2.tgz",
-      "integrity": "sha512-ICoOpaTLPsFQjNLSM00NgQr6wal300cZZonHVSDXKntX+BfkLeuCHRtr/Mn+klTtW+/1v2/2FRm9dXjvyGf9Dw==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.3.tgz",
+      "integrity": "sha512-Yrpmrh4IDEupUUM/dqVxhAN8QW1VEUR3Qrk2lzJC1jB2s46hDe0hrMP2vs12YJqlzshteOthjwXQlY0TgIzgbg==",
       "license": "MIT"
     },
     "node_modules/@react-native/virtualized-lists": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.2.tgz",
-      "integrity": "sha512-FzXvkHgKvJGf0pSuLy6878cxJ6mxWKgZsH9s2kO4LWJocI8Bi3ViDx7IGAWYuvN+Fnue5TKaqGPhfD+4XrKtYQ==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.76.3.tgz",
+      "integrity": "sha512-wTGv9pVh3vAOWb29xFm+J9VRe9dUcUcb9FyaMLT/Hxa88W4wqa5ZMe1V9UvrrBiA1G5DKjv8/1ZcDsJhyugVKA==",
       "license": "MIT",
       "dependencies": {
         "invariant": "^2.2.4",
@@ -4363,6 +4347,31 @@
         "node": ">= 4.0.0"
       }
     },
+    "node_modules/axios": {
+      "version": "1.7.9",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
+      "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "node_modules/axios/node_modules/form-data": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+      "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+      "license": "MIT",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/babel-core": {
       "version": "7.0.0-bridge.0",
       "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
@@ -4425,13 +4434,13 @@
       }
     },
     "node_modules/babel-plugin-polyfill-corejs2": {
-      "version": "0.4.11",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz",
-      "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==",
+      "version": "0.4.12",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
+      "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
       "license": "MIT",
       "dependencies": {
         "@babel/compat-data": "^7.22.6",
-        "@babel/helper-define-polyfill-provider": "^0.6.2",
+        "@babel/helper-define-polyfill-provider": "^0.6.3",
         "semver": "^6.3.1"
       },
       "peerDependencies": {
@@ -4452,12 +4461,12 @@
       }
     },
     "node_modules/babel-plugin-polyfill-regenerator": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz",
-      "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==",
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
+      "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-define-polyfill-provider": "^0.6.2"
+        "@babel/helper-define-polyfill-provider": "^0.6.3"
       },
       "peerDependencies": {
         "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -4529,9 +4538,9 @@
       }
     },
     "node_modules/babel-preset-expo": {
-      "version": "12.0.1",
-      "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-12.0.1.tgz",
-      "integrity": "sha512-9T2o+aeKnHOtQhk/undQbibJv02bdCgfs68ZwgAdueljDBcs2oVfq41qG9XThYwa6Dn7CdfnoEUsIyFqBwjcVw==",
+      "version": "12.0.3",
+      "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-12.0.3.tgz",
+      "integrity": "sha512-1695e8y3U/HjifKx33vcNnFMSUSXwPWwhFxRlL6NRx2TENN6gySH82gPOWgxcra6gi+EJgXx52xG3PcqTjwW6w==",
       "license": "MIT",
       "dependencies": {
         "@babel/plugin-proposal-decorators": "^7.12.9",
@@ -4540,7 +4549,7 @@
         "@babel/plugin-transform-parameters": "^7.22.15",
         "@babel/preset-react": "^7.22.15",
         "@babel/preset-typescript": "^7.23.0",
-        "@react-native/babel-preset": "0.76.2",
+        "@react-native/babel-preset": "0.76.3",
         "babel-plugin-react-native-web": "~0.19.13",
         "react-refresh": "^0.14.2"
       },
@@ -5078,6 +5087,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/clone": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
     "node_modules/clone-deep": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -5422,15 +5440,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/defaults/node_modules/clone": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
-      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
     "node_modules/define-lazy-prop": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
@@ -5782,26 +5791,26 @@
       }
     },
     "node_modules/expo": {
-      "version": "52.0.8",
-      "resolved": "https://registry.npmjs.org/expo/-/expo-52.0.8.tgz",
-      "integrity": "sha512-EQwJFRS2UUTGTe++bcLN3b7TeSpSWhQzIPt4jIh+0iannbYxgXLE6oKApTJhh0dsMWDnZzU5a8DIdadJY8VZJA==",
+      "version": "52.0.15",
+      "resolved": "https://registry.npmjs.org/expo/-/expo-52.0.15.tgz",
+      "integrity": "sha512-7eGv8y/aslaHvKH8XVvx0XpvJIQiJZ63kBHcdjtAmy+7KCMQp4lwmrnCzYhVdROe1i/GmHF2UwYfHXIYgC1WEw==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.20.0",
-        "@expo/cli": "0.21.6",
-        "@expo/config": "~10.0.4",
-        "@expo/config-plugins": "9.0.9",
-        "@expo/fingerprint": "0.11.2",
-        "@expo/metro-config": "0.19.4",
+        "@expo/cli": "0.22.1",
+        "@expo/config": "~10.0.6",
+        "@expo/config-plugins": "~9.0.11",
+        "@expo/fingerprint": "0.11.3",
+        "@expo/metro-config": "0.19.5",
         "@expo/vector-icons": "^14.0.0",
-        "babel-preset-expo": "~12.0.1",
+        "babel-preset-expo": "~12.0.3",
         "expo-asset": "~11.0.1",
         "expo-constants": "~17.0.3",
         "expo-file-system": "~18.0.4",
         "expo-font": "~13.0.1",
         "expo-keep-awake": "~14.0.1",
-        "expo-modules-autolinking": "2.0.2",
-        "expo-modules-core": "2.0.4",
+        "expo-modules-autolinking": "2.0.3",
+        "expo-modules-core": "2.1.1",
         "fbemitter": "^3.0.0",
         "web-streams-polyfill": "^3.3.2",
         "whatwg-url-without-unicode": "8.0.0-3"
@@ -5896,9 +5905,9 @@
       }
     },
     "node_modules/expo-modules-autolinking": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.0.2.tgz",
-      "integrity": "sha512-n3jC7VoJLfOLGk8NWhEAvM5zSjbLh1kMUSo76nJupx5/vASxDdzihppYebrKrNXPHq5mcw8Jr+r7YB+8xHx7QQ==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-2.0.3.tgz",
+      "integrity": "sha512-Q/ALJ54eS7Cr7cmbP+unEDTkHFQivQerWWrqZxuXOrSFYGCYU22+/xAZXaJOpZwseOVsP74zSkoRY/wBimVs7w==",
       "license": "MIT",
       "dependencies": {
         "@expo/spawn-async": "^1.7.2",
@@ -5951,26 +5960,14 @@
       }
     },
     "node_modules/expo-modules-core": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.0.4.tgz",
-      "integrity": "sha512-nNS40KYh1d7tWXCcEKBrSigIKCVfJwkPLhR/mniAoPzqevUDLVJNJjIgKfQL6kPlsViC3hwwgrUpKSlmWv2DFg==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-2.1.1.tgz",
+      "integrity": "sha512-yQzYCLR2mre4BNMXuqkeJ0oSNgmGEMI6BcmIzeNZbC2NFEjiaDpKvlV9bclYCtyVhUEVNbJcEPYMr6c1Y4eR4w==",
       "license": "MIT",
       "dependencies": {
         "invariant": "^2.2.4"
       }
     },
-    "node_modules/expo-splash-screen": {
-      "version": "0.29.13",
-      "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.29.13.tgz",
-      "integrity": "sha512-OTaW6v2ErKTlguFDNi4PN+qrEFRA4TIEyFag4204CiFIpAB+13PqQiW4Ovt29aYlLERIjWD++PyoHeSdLSiZwg==",
-      "license": "MIT",
-      "dependencies": {
-        "@expo/prebuild-config": "^8.0.17"
-      },
-      "peerDependencies": {
-        "expo": "*"
-      }
-    },
     "node_modules/expo-status-bar": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.0.0.tgz",
@@ -6160,14 +6157,34 @@
       "license": "MIT"
     },
     "node_modules/flow-parser": {
-      "version": "0.252.0",
-      "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.252.0.tgz",
-      "integrity": "sha512-z8hKPUjZ33VLn4HVntifqmEhmolUMopysnMNzazoDqo1GLUkBsreLNsxETlKJMPotUWStQnen6SGvUNe1j4Hlg==",
+      "version": "0.255.0",
+      "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.255.0.tgz",
+      "integrity": "sha512-7QHV2m2mIMh6yIMaAPOVbyNEW77IARwO69d4DgvfDCjuORiykdMLf7XBjF7Zeov7Cpe1OXJ8sB6/aaCE3xuRBw==",
       "license": "MIT",
       "engines": {
         "node": ">=0.4.0"
       }
     },
+    "node_modules/follow-redirects": {
+      "version": "1.15.9",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/fontfaceobserver": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
@@ -8125,6 +8142,18 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "license": "MIT",
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/mime-db": {
       "version": "1.52.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -9116,6 +9145,12 @@
         "react-is": "^16.13.1"
       }
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "license": "MIT"
+    },
     "node_modules/pump": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
@@ -9298,19 +9333,19 @@
       "license": "MIT"
     },
     "node_modules/react-native": {
-      "version": "0.76.2",
-      "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.2.tgz",
-      "integrity": "sha512-mkEBKGOmJxhfq8IOsvmk0QuTzlBt9vS+uo0gwbqfUmEDqoC359v80zhUf94WimYBrBkpRQWFbEu5iqMDHrYzlQ==",
+      "version": "0.76.3",
+      "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.3.tgz",
+      "integrity": "sha512-0TUhgmlouRNf6yuDIIAdbQl0g1VsONgCMsLs7Et64hjj5VLMCA7np+4dMrZvGZ3wRNqzgeyT9oWJsUm49AcwSQ==",
       "license": "MIT",
       "dependencies": {
         "@jest/create-cache-key-function": "^29.6.3",
-        "@react-native/assets-registry": "0.76.2",
-        "@react-native/codegen": "0.76.2",
-        "@react-native/community-cli-plugin": "0.76.2",
-        "@react-native/gradle-plugin": "0.76.2",
-        "@react-native/js-polyfills": "0.76.2",
-        "@react-native/normalize-colors": "0.76.2",
-        "@react-native/virtualized-lists": "0.76.2",
+        "@react-native/assets-registry": "0.76.3",
+        "@react-native/codegen": "0.76.3",
+        "@react-native/community-cli-plugin": "0.76.3",
+        "@react-native/gradle-plugin": "0.76.3",
+        "@react-native/js-polyfills": "0.76.3",
+        "@react-native/normalize-colors": "0.76.3",
+        "@react-native/virtualized-lists": "0.76.3",
         "abort-controller": "^3.0.0",
         "anser": "^1.4.9",
         "ansi-regex": "^5.0.0",
@@ -9602,15 +9637,15 @@
       }
     },
     "node_modules/regexpu-core": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz",
-      "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==",
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+      "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
       "license": "MIT",
       "dependencies": {
         "regenerate": "^1.4.2",
         "regenerate-unicode-properties": "^10.2.0",
         "regjsgen": "^0.8.0",
-        "regjsparser": "^0.11.0",
+        "regjsparser": "^0.12.0",
         "unicode-match-property-ecmascript": "^2.0.0",
         "unicode-match-property-value-ecmascript": "^2.1.0"
       },
@@ -9625,9 +9660,9 @@
       "license": "MIT"
     },
     "node_modules/regjsparser": {
-      "version": "0.11.2",
-      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz",
-      "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==",
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+      "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
       "license": "BSD-2-Clause",
       "dependencies": {
         "jsesc": "~3.0.2"
@@ -9715,9 +9750,9 @@
       "license": "MIT"
     },
     "node_modules/resolve.exports": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
-      "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz",
+      "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==",
       "license": "MIT",
       "engines": {
         "node": ">=10"
@@ -9890,18 +9925,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/send/node_modules/mime": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-      "license": "MIT",
-      "bin": {
-        "mime": "cli.js"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/send/node_modules/on-finished": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -9971,18 +9994,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/serve-static/node_modules/mime": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-      "license": "MIT",
-      "bin": {
-        "mime": "cli.js"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/serve-static/node_modules/on-finished": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -10752,9 +10763,9 @@
       }
     },
     "node_modules/terser": {
-      "version": "5.36.0",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz",
-      "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==",
+      "version": "5.37.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz",
+      "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
       "license": "BSD-2-Clause",
       "dependencies": {
         "@jridgewell/source-map": "^0.3.3",
diff --git a/package.json b/package.json
index 922dd69..0b14e67 100644
--- a/package.json
+++ b/package.json
@@ -9,12 +9,14 @@
     "web": "expo start --web"
   },
   "dependencies": {
-    "@react-native-async-storage/async-storage": "^2.1.0",
+    "@react-native-async-storage/async-storage": "1.23.1",
+    "@react-native-cookies/cookies": "^6.2.1",
     "@react-native-picker/picker": "^2.9.0",
     "@react-navigation/bottom-tabs": "^6.6.1",
     "@react-navigation/native": "^6.1.18",
     "@react-navigation/native-stack": "^6.11.0",
-    "expo": "^52.0.8",
+    "axios": "^1.7.9",
+    "expo": "~52.0.14",
     "expo-splash-screen": "^0.29.13",
     "expo-status-bar": "~2.0.0",
     "he": "^1.2.0",
@@ -22,7 +24,7 @@
     "i18next": "^23.16.5",
     "react": "^18.3.1",
     "react-i18next": "^15.1.1",
-    "react-native": "^0.76.2",
+    "react-native": "0.76.3",
     "react-native-dropdown-select-list": "^2.0.5",
     "react-native-safe-area-context": "^4.12.0",
     "react-native-screens": "~4.1.0",
diff --git a/services/UserService.ts b/services/UserService.ts
new file mode 100644
index 0000000..756189d
--- /dev/null
+++ b/services/UserService.ts
@@ -0,0 +1,119 @@
+import HttpError from "./HttpError";
+import UserModel from "../models/UserModel";
+import axios from "axios";
+import {transformToUserModel} from "../helper/UserHelper";
+
+export const useUserService =  () => {
+    const url = "https://klebert-host.com:33037";
+
+
+    const loginUser = async (login: string, password: string): Promise<boolean | HttpError> => {
+        try {
+            const requestBody = {
+                login: login,
+                password: password,
+            };
+
+            await axios.post(`${url}/auth/login`, requestBody, {
+                withCredentials: true, // Autorise Axios à inclure les cookies
+            });
+
+            return true;
+        } catch (error: any) {
+
+            if (error.response) {
+                // Si le mot de passe ou le login est incorrect
+                if (error.response.status === 401) {
+                    return new HttpError(401, "Invalid login or password");
+                }
+
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                // Erreur réseau ou autre
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    };
+
+    const getInformationsUser = async (): Promise<UserModel | HttpError> => {
+        try {
+            const response = await axios.get(`${url}/user/me`, {
+                withCredentials: true, // Inclut les cookies dans la requête
+            });
+
+            const user = transformToUserModel(response.data);
+
+            return user;
+        } catch (error: any) {
+            if (error.response.status === 401) {
+                return new HttpError(401, "No user logged in");
+            }
+
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    };
+
+    const logoutUser = async (): Promise<boolean | HttpError> => {
+        try {
+            await axios.post(`${url}/auth/logout`, null, {
+                withCredentials: true, // Inclut les cookies dans la requête
+            });
+            return true;
+        } catch (error: any) {
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
+
+    const registerUser = async (
+        username: string,
+        password: string,
+        email: string
+    ): Promise<boolean | HttpError> => {
+        try {
+            const requestBody = {
+                username: username,
+                email: email,
+                password: password,
+            };
+
+            // Enregistrement de l'utilisateur
+            await axios.post(`${url}/user`, requestBody, {
+                withCredentials: true,
+            });
+
+
+            // Connexion après enregistrement
+            const loginResult = await loginUser(username, password);
+
+            if (loginResult instanceof HttpError) {
+                return loginResult; // Retourne l'erreur de connexion si échec
+            }
+
+            return true; // Succès
+        } catch (error: any) {
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message);
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    };
+
+
+
+
+    return {
+        loginUser: loginUser,
+        getInformationsUser: getInformationsUser,
+        logoutUser: logoutUser,
+        registerUser: registerUser
+    };
+}
-- 
GitLab


From 8db14d0418711346295fa5f020cf75a9fd5fa286 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 5 Dec 2024 23:08:33 +0100
Subject: [PATCH 094/283] fix: initial value input

---
 components/PlayQuiz/InputPlayQuiz.tsx     | 7 +++----
 screens/PlayQuiz/PlayQuizGenerateQuiz.tsx | 4 ++--
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
index 715165f..720f523 100644
--- a/components/PlayQuiz/InputPlayQuiz.tsx
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -7,9 +7,10 @@ interface Props {
     noTitle?: boolean;
     placeholder?: string;
     numeric?: boolean;
+    defaultValue?: string;
 }
 
-export default function InputPlayQuiz({ title, setText, noTitle, placeholder, numeric }: Props) {
+export default function InputPlayQuiz({ title, setText, noTitle, placeholder, numeric, defaultValue }: Props) {
     return (
         <View style={styles.container}>
             {!noTitle && title && <Text style={styles.title}>{title}</Text>}
@@ -21,9 +22,7 @@ export default function InputPlayQuiz({ title, setText, noTitle, placeholder, nu
                 onChangeText={(text) => {
                     setText(text);
                 }}
-                aria-valuemin={1}
-                aria-valuemax={50}
-                defaultValue="10"
+                defaultValue={defaultValue}
             />
         </View>
     );
diff --git a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
index b4dbe30..4b9bc60 100644
--- a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -36,7 +36,7 @@ interface Props {
 export default function PlayQuizGenerateQuiz({navigation}: Props) {
     const [difficutlyChoose, setDifficutlyChoose] = React.useState("");
     const [categoryChoose, setCategoryChoose] = React.useState("");
-    const [nbQuestions, setNbQuestions] = React.useState("");
+    const [nbQuestions, setNbQuestions] = React.useState("10");
     const [buttonIsDisabled, setButtonIsDisabled] = React.useState(true);
     const {generateQuiz} = useQuizService();
 
@@ -71,7 +71,7 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
                 <View style={styles.fieldContainer}>
                     <SelectListBox title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
                     <SelectListBox title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
-                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} />
+                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} defaultValue={nbQuestions}/>
                 </View>
                 <View style={styles.buttonPlayContainer}>
                     <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} isDisabled={buttonIsDisabled}/>
-- 
GitLab


From b27bc0f60e2cd0bb773d7df13817ace11e675ef0 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 5 Dec 2024 23:15:43 +0100
Subject: [PATCH 095/283] feat: Community service

---
 screens/Community/Community.tsx | 23 +++++++++++++++++++++--
 services/QuizService.ts         | 22 +++++++++++++++++++++-
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index ec8bfa5..7addc7d 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -1,13 +1,18 @@
 import {View, Text} from "react-native";
 import TemplateQuizList from "../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
-import {useState} from "react";
+import {useEffect, useState} from "react";
 import QuizModel from "../../models/QuizModel";
+import {useQuizService} from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
 
 interface Props {
     navigation: NavigationProp<any>
 }
 export default function Community({navigation}: Props) {
+    const  {getQuizzesCommunity} = useQuizService();
+    const [input, setInput] = useState<string>("")
+
     const [quizList, setQuizList] = useState<QuizModel[] | null>([
         {
             code: "QUIZ123",
@@ -34,7 +39,21 @@ export default function Community({navigation}: Props) {
             score: 0,
         },
     ])
-    const [input, setInput] = useState<string>("")
+
+    useEffect(  () => {
+        console.log("useEffect");
+        getQuizzesCommunity().then((quizzes) => {
+            if(quizzes instanceof HttpError){
+                console.log(quizzes);
+                return;
+            }
+            if(quizzes instanceof Array) {
+                console.log("array");
+                setQuizList(quizzes)
+            }
+        });
+
+    }, [])
 
 
     return (
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 6248af7..c5fbe58 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -3,6 +3,7 @@ import {transformToAnswerModel, transformToQuizModel} from "../helper/QuizHelper
 import AnswerModel from "../models/AnswerModel";
 import HttpError from "./HttpError";
 import QuizModel from "../models/QuizModel";
+import axios from "axios";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -148,9 +149,28 @@ export const useQuizService =  () => {
         }
     }
 
+    const getQuizzesCommunity = async () : Promise<QuizModel[] | HttpError> => {
+        try {
+            // await axios.post(`${url}/quiz/community`, null, {
+            //     withCredentials: true, // Inclut les cookies dans la requête
+            // });
+            return [];
+        } catch (error: any) {
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
+
+
+
     return {
         generateQuiz: generateQuiz,
         getAnswerQuiz: getAnswerQuiz,
-        remainingQuiz: remainingQuiz
+        remainingQuiz: remainingQuiz,
+        getQuizzesCommunity: getQuizzesCommunity
+
     }
 }
\ No newline at end of file
-- 
GitLab


From d95a1460c43def737dde629a914c280a1ebf2cb0 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 5 Dec 2024 23:40:48 +0100
Subject: [PATCH 096/283] feat: prepare end quiz set with quiz value

---
 screens/EndQuiz/EndQuizChild.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index b811860..d7c072f 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -40,8 +40,8 @@ export default function EndQuizChild({ navigation/* , route */}: Props) {
                 <Image source={require('../../assets/TitleApp.png')}/>
             </View>
             <View style={styles.containerBody}>
-                <Text style={styles.TextBodyTitle}>CONGRATS !</Text>
-                <Text style={styles.TextBody}>you finish the test with a score of 12/20 ! </Text>
+                <Text style={styles.TextBodyTitle}>{/*((quiz.score/quiz.nbQuestions)*100 > 50 ) ? 'Victory' : 'Defeat'*/'Victory'}</Text>
+                <Text style={styles.TextBody}>you finish the test with a score of {/*`${quiz.score}/${quiz.nbQuestions}`*/'12/20'} ! </Text>
                 <Image source={require('../../assets/uWin.png')} />
                 <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
-- 
GitLab


From 12fc6d9e2c41b3d4f751ac943cadabf6808ff708 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 5 Dec 2024 23:42:59 +0100
Subject: [PATCH 097/283] feat: end quiz with quiz value

---
 screens/EndQuiz/EndQuizChild.tsx | 45 ++++++++++++++++----------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index d7c072f..936e00d 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -1,33 +1,34 @@
 import { View, Image, Text, StyleSheet } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
-import { NavigationProp } from "@react-navigation/native";
+import { NavigationProp, RouteProp } from "@react-navigation/native";
+import QuizModel from "../../models/QuizModel";
 
-// type RoutePropsType = {
-//     EndQuiz: {
-//         quiz: QuizModel;
-//     };
-// };
+type RoutePropsType = {
+    EndQuiz: {
+        quiz: QuizModel;
+    };
+};
 
 interface Props {
     navigation: NavigationProp<any>;
-    // route: RouteProp<RoutePropsType, "EndQuiz">;
+    route: RouteProp<RoutePropsType, "EndQuiz">;
 }
 
-export default function EndQuizChild({ navigation/* , route */}: Props) {
-    // const { quiz } = route.params;
+export default function EndQuizChild({ navigation, route }: Props) {
+    const { quiz } = route.params;
 
     const handleRestartPress = () => {
-        // quiz.nbActualQuestion = 1;
-        // quiz.score = 0;
-        // navigation.reset({
-        //     index: 0,
-        //     routes: [
-        //         {
-        //             name: "PlayingQuiz",
-        //             params: {quiz: quiz},
-        //         },
-        //     ]
-        // });
+        quiz.nbActualQuestion = 1;
+        quiz.score = 0;
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quiz: quiz},
+                },
+            ]
+        });
     };
 
     const handleBackToMenu = () => {
@@ -40,8 +41,8 @@ export default function EndQuizChild({ navigation/* , route */}: Props) {
                 <Image source={require('../../assets/TitleApp.png')}/>
             </View>
             <View style={styles.containerBody}>
-                <Text style={styles.TextBodyTitle}>{/*((quiz.score/quiz.nbQuestions)*100 > 50 ) ? 'Victory' : 'Defeat'*/'Victory'}</Text>
-                <Text style={styles.TextBody}>you finish the test with a score of {/*`${quiz.score}/${quiz.nbQuestions}`*/'12/20'} ! </Text>
+                <Text style={styles.TextBodyTitle}>{((quiz.score/quiz.nbQuestions)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
+                <Text style={styles.TextBody}>you finish the test with a score of {`${quiz.score}/${quiz.nbQuestions}`} ! </Text>
                 <Image source={require('../../assets/uWin.png')} />
                 <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
-- 
GitLab


From 37b9bfa9ab33f53d62c74b806ca4b7d06c9ee304 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 00:24:41 +0100
Subject: [PATCH 098/283] feat: login and signup with error message

---
 screens/Profil/ProfilChild.tsx       |  2 +-
 screens/Profil/ProfilModal.tsx       | 11 ++++-
 screens/Profil/ProfilModalLogin.tsx  | 60 +++++++++++++++++++++-------
 screens/Profil/ProfilModalSignup.tsx | 49 ++++++++++++++++++++---
 4 files changed, 98 insertions(+), 24 deletions(-)

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 17911d9..53b0460 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -27,7 +27,7 @@ export default function ProfilChild({navigation}: Props) {
             </View>
 
             <ProfilHeaderAccount setModalVisible={setModalVisible} setMode={setMode}/>
-            <ProfilModal modalVisible={modalVisible} setModalVisible={setModalVisible} mode={mode} setMode={setMode}/>
+            <ProfilModal modalVisible={modalVisible} setModalVisible={setModalVisible} mode={mode} setMode={setMode} navigation={navigation}/>
         </View>
     )
 }
diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/ProfilModal.tsx
index bec04df..f0227d7 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/ProfilModal.tsx
@@ -13,12 +13,14 @@ import { ProfilSelectModeType } from "../../models/SelectModeType";
 import ProfilModalLogin from "./ProfilModalLogin";
 import ProfilModalSignup from "./ProfilModalSignup";
 import Icon from "react-native-vector-icons/MaterialIcons";
+import {NavigationProp} from "@react-navigation/native";
 
 interface Props {
     modalVisible: boolean;
     setModalVisible: (visible: boolean) => void;
     mode: ProfilSelectModeType;
     setMode: (mode: ProfilSelectModeType) => void;
+    navigation: NavigationProp<any>;
 }
 
 export default function ProfilModal({
@@ -26,7 +28,12 @@ export default function ProfilModal({
         setModalVisible,
         mode,
         setMode,
+        navigation
     }: Props) {
+    const closeModal = () => {
+        setModalVisible(false);
+    }
+
     return (
         <Modal
             animationType="slide"
@@ -48,9 +55,9 @@ export default function ProfilModal({
                     <View style={styles.containerModal}>
                         <ProfilSelectMode mode={mode} setMode={setMode} />
                         {mode === "login" ? (
-                            <ProfilModalLogin />
+                            <ProfilModalLogin navigation={navigation} closeModal={closeModal}/>
                         ) : (
-                            <ProfilModalSignup />
+                            <ProfilModalSignup navigation={navigation} closeModal={closeModal}/>
                         )}
                     </View>
                 </View>
diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/ProfilModalLogin.tsx
index 6dacfc4..7a2e74c 100644
--- a/screens/Profil/ProfilModalLogin.tsx
+++ b/screens/Profil/ProfilModalLogin.tsx
@@ -1,25 +1,46 @@
-import { TextInput, View, StyleSheet } from "react-native";
+import { TextInput, View, StyleSheet, Text } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import React, {useState} from "react";
-
-export default function ProfilModalLogin() {
+import React, { useState } from "react";
+import {useUserService} from "../../services/UserService";
+import HttpError from "../../services/HttpError";
+import {NavigationProp} from "@react-navigation/native";
 
+interface Props {
+    navigation: NavigationProp<any>;
+    closeModal: () => void;
+}
+export default function ProfilModalLogin({navigation, closeModal}: Props) {
     const [email, setEmail] = useState("");
     const [password, setPassword] = useState("");
-    const handleSubmitPressed = () => {
+    const [error, setError] = useState<string | null>(null);
+    const { loginUser } = useUserService();
 
-    }
+    const handleSubmitPressed = async () => {
+        if (email === "" || password === "") {
+            setError("Please fill in all fields");
+            return;
+        }
+        const login = await loginUser(email, password);
+        if(login instanceof HttpError){
+            setError(login.message);
+            return;
+        }
+        setError(null);
+        navigation.navigate("Home");
+        closeModal();
+    };
 
     return (
-        <View>
+        <View style={styles.container}>
+            {error && <Text style={styles.errorText}>{error}</Text>}
             <View style={styles.containerForm}>
-                <InputPlayQuiz placeholder="EMAIL..." setText={setEmail} noTitle={true}/>
-                <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true}/>
+                <InputPlayQuiz placeholder="EMAIL..." setText={setEmail} noTitle={true} />
+                <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true} />
             </View>
-            <DefaultButton text="LOGIN" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
+            <DefaultButton text="LOGIN" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText} />
         </View>
-    )
+    );
 }
 
 const styles = StyleSheet.create({
@@ -29,8 +50,11 @@ const styles = StyleSheet.create({
         display: 'flex',
         flexDirection: 'column',
         justifyContent: 'flex-start',
-        rowGap: '10%',
-        marginTop: 50,
+        rowGap: '7%',
+        marginTop: "3%",
+    },
+    container:{
+        paddingTop: '5%',
     },
     textInput: {
         height: '20%',
@@ -40,7 +64,7 @@ const styles = StyleSheet.create({
         borderColor: '#1fa9ff',
         borderRadius: 10,
         color: '#DFDFDF',
-        fontWeight: 'bold'
+        fontWeight: 'bold',
     },
     SubmitButton: {
         height: '15%',
@@ -53,4 +77,10 @@ const styles = StyleSheet.create({
         fontWeight: 'bold',
         color: '#FFFFFF',
     },
-});
\ No newline at end of file
+    errorText: {
+        color: 'red',
+        fontSize: 16,
+        marginBottom: 10, // Espacement entre le texte d'erreur et les inputs
+        textAlign: 'center', // Centrer le message d'erreur
+    },
+});
diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/ProfilModalSignup.tsx
index 3b7b6de..e4becb4 100644
--- a/screens/Profil/ProfilModalSignup.tsx
+++ b/screens/Profil/ProfilModalSignup.tsx
@@ -1,20 +1,48 @@
-import { TextInput, View, StyleSheet } from "react-native";
+import {TextInput, View, StyleSheet, Text} from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
 import React, {useState} from "react";
+import {useUserService} from "../../services/UserService";
+import HttpError from "../../services/HttpError";
+import {NavigationProp} from "@react-navigation/native";
 
-export default function ProfilModalSignup() {
+interface Props {
+    navigation: NavigationProp<any>;
+    closeModal: () => void;
+}
+export default function ProfilModalSignup({navigation, closeModal}: Props) {
 
     const [email, setEmail] = useState("");
+    const [username, setUsername] = useState("");
     const [password, setPassword] = useState("");
     const [repeatPassword, setRepeatPassword] = useState("");
-    const handleSubmitPressed = () => {
+    const [error, setError] = useState<string | null>(null);
+    const { registerUser } = useUserService();
 
+    const handleSubmitPressed = () => {
+        if (email === "" || username === "" || password === "" || repeatPassword === "") {
+            setError("Please fill in all fields");
+            return;
+        }
+        if(password !== repeatPassword){
+            setError("Passwords do not match");
+            return;
+        }
+        const register = registerUser(username, password, email);
+        if(register instanceof HttpError){
+            setError(register.message);
+            return;
+        }
+        setError(null);
+        navigation.navigate("Home");
+        closeModal();
     }
 
     return (
-        <View>
+        <View style={styles.container}>
+            {error && <Text style={styles.errorText}>{error}</Text>}
             <View style={styles.containerForm}>
+                <InputPlayQuiz placeholder="USERNAME..." setText={setUsername} noTitle={true}/>
                 <InputPlayQuiz placeholder="EMAIL..." setText={setEmail} noTitle={true}/>
                 <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true}/>
                 <InputPlayQuiz placeholder="REPEAT PASSWORD..." setText={setRepeatPassword} noTitle={true}/>
@@ -31,8 +59,11 @@ const styles = StyleSheet.create({
         display: 'flex',
         flexDirection: 'column',
         justifyContent: 'flex-start',
-        rowGap: '10%',
-        marginTop: 50
+        rowGap: '7%',
+        marginTop: "3%",
+    },
+    container:{
+        paddingTop: '5%',
     },
     textInput: {
         height: '20%',
@@ -55,4 +86,10 @@ const styles = StyleSheet.create({
         fontWeight: 'bold',
         color: '#FFFFFF',
     },
+    errorText: {
+        color: 'red',
+        fontSize: 16,
+        marginBottom: 10, // Espacement entre le texte d'erreur et les inputs
+        textAlign: 'center', // Centrer le message d'erreur
+    },
 });
\ No newline at end of file
-- 
GitLab


From 425c54fe4b55246b62bce6abf9fe87b54290f8d1 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 6 Dec 2024 00:27:18 +0100
Subject: [PATCH 099/283] feat: correct function getRandomQuiz

---
 services/QuizService.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index c5fbe58..548dbf7 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -170,6 +170,7 @@ export const useQuizService =  () => {
         generateQuiz: generateQuiz,
         getAnswerQuiz: getAnswerQuiz,
         remainingQuiz: remainingQuiz,
+        getRandomQuiz: getRandomQuiz,
         getQuizzesCommunity: getQuizzesCommunity
 
     }
-- 
GitLab


From 6e7c53acadc85e1d39a71980778b0f4f4225762e Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 6 Dec 2024 00:27:37 +0100
Subject: [PATCH 100/283] feat: set route for quick game

---
 screens/Home/HomeChild.tsx | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index cc792b7..dfe0df0 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -6,6 +6,7 @@ import { TextsStyles } from "../../styles/TextsStyles";
 import ModalJoinQuiz from "../../components/ModalJoinQuiz";
 import MenuButton from "../../components/buttons/MenuButton";
 import {NavigationProp} from "@react-navigation/native";
+import {useQuizService} from "../../services/QuizService";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -18,9 +19,19 @@ interface Props {
 export default function HomeChild({navigation}: Props) {
     const [modalVisible, setModalVisible] = useState(false);
     const {t} = useTranslation();
+    const {getRandomQuiz} = useQuizService();
 
-    const handleButtonQuickGamePressed = () => {
-        navigation.navigate("GenerateQuiz");
+    const handleButtonQuickGamePressed = async () => {
+        const quizData = await getRandomQuiz()
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quizRecovered: quizData},
+                },
+            ]
+        });
     }
     const handleButtonMyQuizzesPressed = () => {
         navigation.navigate("MyQuizzes");
-- 
GitLab


From 5db3818451834147259c98bd31cad37022eb3ca9 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 01:19:37 +0100
Subject: [PATCH 101/283] feat: user name can we see in the profil

---
 screens/Profil/ProfilChild.tsx       | 27 +++++++++++++++++++++------
 screens/Profil/ProfilModalLogin.tsx  |  4 +++-
 screens/Profil/ProfilModalSignup.tsx |  4 +++-
 services/UserService.ts              |  2 +-
 4 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 53b0460..555f2de 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -1,9 +1,13 @@
 import { NavigationProp } from "@react-navigation/native";
 import { View, StyleSheet, Image, Text, Modal, Button, TouchableOpacity } from "react-native";
 import ProfilModal from "./ProfilModal";
-import React, { useState } from "react";
+import React, {useEffect, useState} from "react";
 import ProfilHeaderAccount from "./ProfilHeaderAccount";
 import { ProfilSelectModeType } from "../../models/SelectModeType";
+import UserModel from "../../models/UserModel";
+import {useUserService} from "../../services/UserService";
+import HttpError from "../../services/HttpError";
+import BlueButton from "../../components/PlayQuiz/BlueButton";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -12,21 +16,32 @@ interface Props {
 export default function ProfilChild({navigation}: Props) {
     const [modalVisible, setModalVisible] = useState(false);
     const [mode, setMode] = useState<ProfilSelectModeType>("login");
+    const [user, setUser] = useState<UserModel | null>(null);
+    const {getInformationsUser, logoutUser} = useUserService();
+
+    useEffect(() => {
+        getInformationsUser().then((user: UserModel | HttpError) => {
+            console.log(user);
+            if(user instanceof HttpError){
+                return
+            }
+            setUser(user);
+            return
+        });
+    }, []);
 
     return (
         <View style={styles.containerGlobal}>
             <View style={styles.containerPlayerInfos}>
                 <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage}/>
                 <Image source={require('../../assets/ProfilBaseImage.png')} style={styles.profilImage}/>
-                <Text style={styles.pseudoText}>_Pseudo_</Text>
+                <Text style={styles.pseudoText}>{user ? user.username : "?"}</Text>
             </View>
             <View style={styles.containerPlayerStats}>
-                <Text style={styles.statsText}>Played quiz : _123_</Text>
-                <Text style={styles.statsText}>right answer rate : _43%_</Text>
-                <Text style={styles.statsText}>Favorit category : _HISTORY AND CULTURE_</Text>
+                {/*<Text style={styles.statsText}>Played quiz : _123_</Text>*/}
             </View>
 
-            <ProfilHeaderAccount setModalVisible={setModalVisible} setMode={setMode}/>
+            {!user && <ProfilHeaderAccount setModalVisible={setModalVisible} setMode={setMode}/>}
             <ProfilModal modalVisible={modalVisible} setModalVisible={setModalVisible} mode={mode} setMode={setMode} navigation={navigation}/>
         </View>
     )
diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/ProfilModalLogin.tsx
index 7a2e74c..aada3c7 100644
--- a/screens/Profil/ProfilModalLogin.tsx
+++ b/screens/Profil/ProfilModalLogin.tsx
@@ -27,8 +27,10 @@ export default function ProfilModalLogin({navigation, closeModal}: Props) {
             return;
         }
         setError(null);
-        navigation.navigate("Home");
         closeModal();
+        navigation.reset({
+            routes: [{name: "TabNavigator"}],
+        });
     };
 
     return (
diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/ProfilModalSignup.tsx
index e4becb4..8ebcc91 100644
--- a/screens/Profil/ProfilModalSignup.tsx
+++ b/screens/Profil/ProfilModalSignup.tsx
@@ -34,8 +34,10 @@ export default function ProfilModalSignup({navigation, closeModal}: Props) {
             return;
         }
         setError(null);
-        navigation.navigate("Home");
         closeModal();
+        navigation.reset({
+            routes: [{name: "TabNavigator"}],
+        });
     }
 
     return (
diff --git a/services/UserService.ts b/services/UserService.ts
index 756189d..398feff 100644
--- a/services/UserService.ts
+++ b/services/UserService.ts
@@ -88,7 +88,7 @@ export const useUserService =  () => {
             await axios.post(`${url}/user`, requestBody, {
                 withCredentials: true,
             });
-
+            console.log("User registered");
 
             // Connexion après enregistrement
             const loginResult = await loginUser(username, password);
-- 
GitLab


From 474e45cb44499352559a121aa9b5e3f09cd67a71 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 6 Dec 2024 01:20:15 +0100
Subject: [PATCH 102/283] =?UTF-8?q?feat:=20upgrade=20du=20style=20password?=
 =?UTF-8?q?=20=C3=A0=20l'input?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/PlayQuiz/InputPlayQuiz.tsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/components/PlayQuiz/InputPlayQuiz.tsx b/components/PlayQuiz/InputPlayQuiz.tsx
index 720f523..4a4d5cf 100644
--- a/components/PlayQuiz/InputPlayQuiz.tsx
+++ b/components/PlayQuiz/InputPlayQuiz.tsx
@@ -8,9 +8,10 @@ interface Props {
     placeholder?: string;
     numeric?: boolean;
     defaultValue?: string;
+    isSecure?: boolean;
 }
 
-export default function InputPlayQuiz({ title, setText, noTitle, placeholder, numeric, defaultValue }: Props) {
+export default function InputPlayQuiz({ title, setText, noTitle, placeholder, numeric, defaultValue, isSecure=false }: Props) {
     return (
         <View style={styles.container}>
             {!noTitle && title && <Text style={styles.title}>{title}</Text>}
@@ -23,6 +24,7 @@ export default function InputPlayQuiz({ title, setText, noTitle, placeholder, nu
                     setText(text);
                 }}
                 defaultValue={defaultValue}
+                secureTextEntry={isSecure}
             />
         </View>
     );
-- 
GitLab


From e030495d04b6f9caec5740405af5cc36ca5d5cb0 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 6 Dec 2024 01:22:07 +0100
Subject: [PATCH 103/283] feat: add style on the great input

---
 screens/Profil/ProfilModalLogin.tsx  | 2 +-
 screens/Profil/ProfilModalSignup.tsx | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/ProfilModalLogin.tsx
index 7a2e74c..4f58806 100644
--- a/screens/Profil/ProfilModalLogin.tsx
+++ b/screens/Profil/ProfilModalLogin.tsx
@@ -36,7 +36,7 @@ export default function ProfilModalLogin({navigation, closeModal}: Props) {
             {error && <Text style={styles.errorText}>{error}</Text>}
             <View style={styles.containerForm}>
                 <InputPlayQuiz placeholder="EMAIL..." setText={setEmail} noTitle={true} />
-                <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true} />
+                <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true} isSecure={true}/>
             </View>
             <DefaultButton text="LOGIN" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText} />
         </View>
diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/ProfilModalSignup.tsx
index e4becb4..f9e00fc 100644
--- a/screens/Profil/ProfilModalSignup.tsx
+++ b/screens/Profil/ProfilModalSignup.tsx
@@ -44,8 +44,8 @@ export default function ProfilModalSignup({navigation, closeModal}: Props) {
             <View style={styles.containerForm}>
                 <InputPlayQuiz placeholder="USERNAME..." setText={setUsername} noTitle={true}/>
                 <InputPlayQuiz placeholder="EMAIL..." setText={setEmail} noTitle={true}/>
-                <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true}/>
-                <InputPlayQuiz placeholder="REPEAT PASSWORD..." setText={setRepeatPassword} noTitle={true}/>
+                <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true} isSecure={true}/>
+                <InputPlayQuiz placeholder="REPEAT PASSWORD..." setText={setRepeatPassword} noTitle={true} isSecure={true}/>
             </View>
             <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
         </View>
-- 
GitLab


From 0a5b2eeed4e7b8456f77db170cefafa71635b035 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 01:26:51 +0100
Subject: [PATCH 104/283] feat: button logout

---
 screens/Profil/ProfilChild.tsx | 99 ++++++++++++++++++++++------------
 1 file changed, 66 insertions(+), 33 deletions(-)

diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 555f2de..8357747 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -1,85 +1,118 @@
 import { NavigationProp } from "@react-navigation/native";
-import { View, StyleSheet, Image, Text, Modal, Button, TouchableOpacity } from "react-native";
+import { View, StyleSheet, Image, Text, TouchableOpacity } from "react-native";
 import ProfilModal from "./ProfilModal";
-import React, {useEffect, useState} from "react";
+import React, { useEffect, useState } from "react";
 import ProfilHeaderAccount from "./ProfilHeaderAccount";
 import { ProfilSelectModeType } from "../../models/SelectModeType";
 import UserModel from "../../models/UserModel";
-import {useUserService} from "../../services/UserService";
+import { useUserService } from "../../services/UserService";
 import HttpError from "../../services/HttpError";
-import BlueButton from "../../components/PlayQuiz/BlueButton";
+import Icon from "react-native-vector-icons/MaterialIcons";
 
 interface Props {
     navigation: NavigationProp<any>;
 }
 
-export default function ProfilChild({navigation}: Props) {
+export default function ProfilChild({ navigation }: Props) {
     const [modalVisible, setModalVisible] = useState(false);
     const [mode, setMode] = useState<ProfilSelectModeType>("login");
     const [user, setUser] = useState<UserModel | null>(null);
-    const {getInformationsUser, logoutUser} = useUserService();
+    const { getInformationsUser, logoutUser } = useUserService();
 
     useEffect(() => {
         getInformationsUser().then((user: UserModel | HttpError) => {
             console.log(user);
-            if(user instanceof HttpError){
-                return
+            if (user instanceof HttpError) {
+                return;
             }
             setUser(user);
-            return
+            return;
         });
     }, []);
 
+    const handleLogout = async () => {
+        const result = await logoutUser();
+        if (!(result instanceof HttpError)) {
+            setUser(null); // Réinitialise l'utilisateur après la déconnexion
+        }
+    };
+
     return (
         <View style={styles.containerGlobal}>
             <View style={styles.containerPlayerInfos}>
-                <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage}/>
-                <Image source={require('../../assets/ProfilBaseImage.png')} style={styles.profilImage}/>
+                <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage} />
+                <Image source={require('../../assets/ProfilBaseImage.png')} style={styles.profilImage} />
                 <Text style={styles.pseudoText}>{user ? user.username : "?"}</Text>
             </View>
             <View style={styles.containerPlayerStats}>
                 {/*<Text style={styles.statsText}>Played quiz : _123_</Text>*/}
             </View>
 
-            {!user && <ProfilHeaderAccount setModalVisible={setModalVisible} setMode={setMode}/>}
-            <ProfilModal modalVisible={modalVisible} setModalVisible={setModalVisible} mode={mode} setMode={setMode} navigation={navigation}/>
+            {!user && (
+                <ProfilHeaderAccount setModalVisible={setModalVisible} setMode={setMode} />
+            )}
+            <ProfilModal
+                modalVisible={modalVisible}
+                setModalVisible={setModalVisible}
+                mode={mode}
+                setMode={setMode}
+                navigation={navigation}
+            />
+
+            {user && (
+                <TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
+                    <Icon name="logout" size={40} color="#FF0000" />
+                </TouchableOpacity>
+            )}
         </View>
-    )
+    );
 }
 
 const styles = StyleSheet.create({
     containerGlobal: {
-        display: 'flex',
-        width: '100%',
-        height: '100%',
-        justifyContent: 'flex-start',
-        alignItems: 'center',
+        display: "flex",
+        width: "100%",
+        height: "100%",
+        justifyContent: "flex-start",
+        alignItems: "center",
     },
     containerPlayerInfos: {
-        width: '100%',
-        display: 'flex',
-        alignItems: 'center',   
+        width: "100%",
+        display: "flex",
+        alignItems: "center",
     },
     titleImage: {
-        width: '45%',
-        resizeMode: 'contain',
+        width: "45%",
+        resizeMode: "contain",
     },
     profilImage: {
-        width: '45%',
-        aspectRatio: 1
+        width: "45%",
+        aspectRatio: 1,
     },
     pseudoText: {
         fontSize: 35,
-        fontWeight: 'bold',
-        color: '#00B3F4',
+        fontWeight: "bold",
+        color: "#00B3F4",
     },
     containerPlayerStats: {
-        width: '100%',
-        padding: '5%',
+        width: "100%",
+        padding: "5%",
     },
     statsText: {
         fontSize: 17,
-        fontWeight: 'bold',
+        fontWeight: "bold",
+    },
+    logoutButton: {
+        position: "absolute",
+        bottom: 20,
+        right: 20,
+        backgroundColor: "#FFF",
+        borderRadius: 50,
+        padding: 10,
+        elevation: 5, // Ombre pour Android
+        shadowColor: "#000", // Ombre pour iOS
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.2,
+        shadowRadius: 2,
     },
-    
-});
\ No newline at end of file
+});
-- 
GitLab


From 737edb07904946e52fe42d1e48988308e0751442 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 01:39:33 +0100
Subject: [PATCH 105/283] fix: pass quiz to endQuiz

---
 screens/EndQuiz/EndQuiz.tsx      | 14 +++++++++++---
 screens/EndQuiz/EndQuizChild.tsx | 11 +++--------
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/screens/EndQuiz/EndQuiz.tsx b/screens/EndQuiz/EndQuiz.tsx
index cb13d78..678fc88 100644
--- a/screens/EndQuiz/EndQuiz.tsx
+++ b/screens/EndQuiz/EndQuiz.tsx
@@ -1,18 +1,26 @@
-import { NavigationProp } from "@react-navigation/native";
+import {NavigationProp, RouteProp} from "@react-navigation/native";
 import { View, StyleSheet, Image, Text } from "react-native";
 import EndQuizChild from "./EndQuizChild";
 import TemplateMenu from "../../templates/TemplateMenu";
+import QuizModel from "../../models/QuizModel";
 
+type RoutePropsType = {
+    EndQuizChild: {
+        quiz: QuizModel;
+    };
+};
 interface Props {
+    route: RouteProp<RoutePropsType, "EndQuizChild">;
     navigation: NavigationProp<any>;
 }
 
-export default function EndQuiz({navigation}: Props) {
+export default function EndQuiz({route,navigation}: Props) {
+    const { quiz } = route.params;
     return (
         <View style={styles.containerGlobal}>
             <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}>
                 <View>
-                    <EndQuizChild navigation={navigation}/>
+                    <EndQuizChild navigation={navigation} quiz={quiz}/>
                 </View>
             </TemplateMenu>
         </View>
diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index 936e00d..b284250 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -3,19 +3,14 @@ import DefaultButton from "../../components/DefaultButton";
 import { NavigationProp, RouteProp } from "@react-navigation/native";
 import QuizModel from "../../models/QuizModel";
 
-type RoutePropsType = {
-    EndQuiz: {
-        quiz: QuizModel;
-    };
-};
+
 
 interface Props {
     navigation: NavigationProp<any>;
-    route: RouteProp<RoutePropsType, "EndQuiz">;
+    quiz: QuizModel;
 }
 
-export default function EndQuizChild({ navigation, route }: Props) {
-    const { quiz } = route.params;
+export default function EndQuizChild({ navigation, quiz }: Props) {
 
     const handleRestartPress = () => {
         quiz.nbActualQuestion = 1;
-- 
GitLab


From 653e7ab6c41930a1e829eec6df3b221e82935bfc Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 01:57:10 +0100
Subject: [PATCH 106/283] fix: go tabnavigation from playingquiz

---
 screens/PlayingQuiz/PlayingQuizBody.tsx   | 2 +-
 screens/PlayingQuiz/PlayingQuizHeader.tsx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 7031a60..b3057b1 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -47,7 +47,7 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
         const answers = await getAnswerQuiz(quiz.code, currentQuestion.id, currentQuestion.answers[selectedAnswerIndex].id);
 
         if (HttpError.isHttpError(answers)) {
-            navigation.navigate("Home");
+            navigation.navigate("TabNavigator");
             return;
         }
 
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index fa1747f..cb14415 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -22,7 +22,7 @@ export default function PlayingQuizHeader({navigation, quiz}: Props) {
             index: 0,
             routes: [
                 {
-                    name: "Home",
+                    name: "TabNavigator",
                 },
             ]
         });
-- 
GitLab


From 48874518de291ace2389afc2b322c5dad7291002 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 02:07:49 +0100
Subject: [PATCH 107/283] fix: go tabnavigation from endquiz

---
 screens/EndQuiz/EndQuizChild.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index b284250..2f85f5a 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -27,7 +27,7 @@ export default function EndQuizChild({ navigation, quiz }: Props) {
     };
 
     const handleBackToMenu = () => {
-        navigation.navigate('Home');
+        navigation.navigate('TabNavigator');
     };
 
     return (
-- 
GitLab


From 0f79a0c1de3962b0887a2afb53dd344ea3a0ec63 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 09:20:03 +0100
Subject: [PATCH 108/283] feat: fetching all quiz for community

---
 components/lists/QuizList.tsx   |  2 +-
 screens/Community/Community.tsx | 47 +++++++--------------------------
 services/QuizService.ts         | 24 ++++++++++++++++-
 templates/TemplateQuizList.tsx  |  6 ++---
 4 files changed, 37 insertions(+), 42 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 13cc1e4..2f04155 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -51,7 +51,7 @@ const quizzes: QuizModel[] = [
  */
 interface Props{
     navigation: NavigationProp<any>;
-    quizList: QuizModel[] | null
+    quizList: QuizModel[] | null | undefined
 }
 export default function QuizList({navigation,quizList}: Props) {
     const onQuizPressed = (quiz: QuizModel) => {
diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index 7addc7d..0483528 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -10,48 +10,21 @@ interface Props {
     navigation: NavigationProp<any>
 }
 export default function Community({navigation}: Props) {
-    const  {getQuizzesCommunity} = useQuizService();
+    const  {getAllQuizzes} = useQuizService();
     const [input, setInput] = useState<string>("")
+    const [loading, setLoading] = useState<boolean>(false)
 
-    const [quizList, setQuizList] = useState<QuizModel[] | null>([
-        {
-            code: "QUIZ123",
-            category: "General Knowledge",
-            questions: [],
-            nbQuestions: 3,
-            nbActualQuestion: 1,
-            score: 0,
-        },
-        {
-            code: "QUIZ456",
-            category: "Science",
-            questions: [],
-            nbQuestions: 5,
-            nbActualQuestion: 1,
-            score: 0,
-        },
-        {
-            code: "QUIZ789",
-            category: "Entertainment",
-            questions: [],
-            nbQuestions: 10,
-            nbActualQuestion: 1,
-            score: 0,
-        },
-    ])
+    const [quizList, setQuizList] = useState<QuizModel[] | null>()
 
     useEffect(  () => {
-        console.log("useEffect");
-        getQuizzesCommunity().then((quizzes) => {
-            if(quizzes instanceof HttpError){
-                console.log(quizzes);
-                return;
-            }
-            if(quizzes instanceof Array) {
-                console.log("array");
-                setQuizList(quizzes)
+
+        getAllQuizzes().then((quizzes: QuizModel[] | HttpError) => {
+            if (quizzes instanceof HttpError) {
+                console.log("Error while fetching quizzes:", quizzes);
+            } else {
+                setQuizList(quizzes);
             }
-        });
+        })
 
     }, [])
 
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 548dbf7..7877768 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -164,6 +164,27 @@ export const useQuizService =  () => {
         }
     }
 
+    const getAllQuizzes = async (): Promise<QuizModel[] | HttpError> => {
+        try {
+            // Effectuer une requête GET pour récupérer les quizzes
+            const response = await axios.get(`${url}/quiz/all`, {
+                withCredentials: true, // Inclut les cookies pour une session authentifiée
+            });
+
+            // Transformation des données de chaque quiz en modèle QuizModel
+            const quizzes: QuizModel[] = response.data.map((quiz: any) => transformToQuizModel(quiz));
+
+            return quizzes;
+        } catch (error: any) {
+            console.error("Error while fetching all quizzes:", error);
+
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    };
 
 
     return {
@@ -171,7 +192,8 @@ export const useQuizService =  () => {
         getAnswerQuiz: getAnswerQuiz,
         remainingQuiz: remainingQuiz,
         getRandomQuiz: getRandomQuiz,
-        getQuizzesCommunity: getQuizzesCommunity
+        getQuizzesCommunity: getQuizzesCommunity,
+        getAllQuizzes: getAllQuizzes
 
     }
 }
\ No newline at end of file
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 5abce9e..3f719f4 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -10,7 +10,7 @@ interface Props {
     navigation: NavigationProp<any>
     title: string
     setTextInInput: (text: string) => void
-    quizList: QuizModel[] | null
+    quizList: QuizModel[] | null | undefined
     buttonGoBack: boolean
 }
 
@@ -30,8 +30,8 @@ export default function TemplateQuizList({navigation, title, setTextInInput, qui
             <View style={styles.globalContainer}>
                 <Text style={styles.title}>{title}</Text>
                 <View style={styles.contentContainer}>
-                    <InputPlayQuiz setText={setTextInInput} noTitle={true} />
-                    <QuizList  quizList={quizList} navigation={navigation}/>
+                    {/*<InputPlayQuiz setText={setTextInInput} noTitle={true} />*/}
+                    <QuizList quizList={quizList} navigation={navigation}/>
                 </View>
             </View>
         </TemplateMenu>
-- 
GitLab


From bc6a82c33d2dc79df92672bdcb054a157367ba9d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 09:43:19 +0100
Subject: [PATCH 109/283] fix: register work

---
 screens/Profil/ProfilModalSignup.tsx | 4 ++--
 services/UserService.ts              | 4 +++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/ProfilModalSignup.tsx
index 91434d4..3179c0c 100644
--- a/screens/Profil/ProfilModalSignup.tsx
+++ b/screens/Profil/ProfilModalSignup.tsx
@@ -19,7 +19,7 @@ export default function ProfilModalSignup({navigation, closeModal}: Props) {
     const [error, setError] = useState<string | null>(null);
     const { registerUser } = useUserService();
 
-    const handleSubmitPressed = () => {
+    const handleSubmitPressed = async () => {
         if (email === "" || username === "" || password === "" || repeatPassword === "") {
             setError("Please fill in all fields");
             return;
@@ -28,7 +28,7 @@ export default function ProfilModalSignup({navigation, closeModal}: Props) {
             setError("Passwords do not match");
             return;
         }
-        const register = registerUser(username, password, email);
+        const register = await registerUser(username, password, email);
         if(register instanceof HttpError){
             setError(register.message);
             return;
diff --git a/services/UserService.ts b/services/UserService.ts
index 398feff..08399a9 100644
--- a/services/UserService.ts
+++ b/services/UserService.ts
@@ -88,7 +88,6 @@ export const useUserService =  () => {
             await axios.post(`${url}/user`, requestBody, {
                 withCredentials: true,
             });
-            console.log("User registered");
 
             // Connexion après enregistrement
             const loginResult = await loginUser(username, password);
@@ -99,6 +98,9 @@ export const useUserService =  () => {
 
             return true; // Succès
         } catch (error: any) {
+            if(error.response.status === 400) {
+                return new HttpError(400, "User already exists");
+            }
             if (error.response) {
                 return new HttpError(error.response.status, error.response.data?.message);
             } else {
-- 
GitLab


From 70d40251b47a602d6cc5f48aaf33246dea90e567 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 09:56:11 +0100
Subject: [PATCH 110/283] feat: loading icon in community screen

---
 components/lists/QuizList.tsx   | 81 +++++++++++----------------------
 screens/Community/Community.tsx |  5 +-
 templates/TemplateQuizList.tsx  |  5 +-
 3 files changed, 33 insertions(+), 58 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 2f04155..ef92c52 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -1,62 +1,19 @@
 import React from "react";
-import { FlatList, View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import { FlatList, View, Text, StyleSheet, TouchableOpacity, ActivityIndicator } from "react-native";
 import QuizModel from "../../models/QuizModel";
-import {NavigationProp} from "@react-navigation/native";
+import { NavigationProp } from "@react-navigation/native";
 
-const quizzes: QuizModel[] = [
-    {
-        code: "QUIZ123",
-        category: "General Knowledge",
-        questions: [],
-        nbQuestions: 3,
-        nbActualQuestion: 1,
-        score: 0,
-    },
-    {
-        code: "QUIZ456",
-        category: "Science",
-        questions: [],
-        nbQuestions: 5,
-        nbActualQuestion: 1,
-        score: 0,
-    },
-    {
-        code: "QUIZ789",
-        category: "Entertainment",
-        questions: [],
-        nbQuestions: 10,
-        nbActualQuestion: 1,
-        score: 0,
-    },
-];
-
-/**
- * QuizList : Un composant affichant une liste de quiz avec leur titre, nombre de questions et catégorie.
- *
- * @component
- *
- * @example
- * // Exemple d'utilisation :
- * <QuizList />
- *
- * @description
- * - Ce composant utilise un `FlatList` pour afficher les quiz.
- * - Chaque élément de la liste contient :
- *    - Le code du quiz comme titre.
- *    - Le nombre total de questions.
- *    - La catégorie du quiz, en majuscules.
- * - Les quiz sont définis dans une liste statique en haut du fichier pour cet exemple.
- *
- * @returns Un composant React contenant une liste interactive de quiz.
- */
-interface Props{
+interface Props {
     navigation: NavigationProp<any>;
-    quizList: QuizModel[] | null | undefined
+    quizList: QuizModel[] | null | undefined;
+    isLoadingData: boolean;
 }
-export default function QuizList({navigation,quizList}: Props) {
+
+export default function QuizList({ navigation, quizList, isLoadingData }: Props) {
     const onQuizPressed = (quiz: QuizModel) => {
-        navigation.navigate('InformationsOfQuiz', {quiz: quiz});
+        navigation.navigate("InformationsOfQuiz", { quiz: quiz });
     };
+
     const renderQuizItem = ({ item }: { item: QuizModel }) => (
         <TouchableOpacity style={styles.quizItem} onPress={() => onQuizPressed(item)}>
             <Text style={styles.quizTitle}>{item.code}</Text>
@@ -68,7 +25,12 @@ export default function QuizList({navigation,quizList}: Props) {
 
     return (
         <View style={styles.container}>
-            {quizList && quizList.length > 0 ? (
+            {isLoadingData ? (
+                <View style={styles.loadingContainer}>
+                    <ActivityIndicator size="large" color="#2b73fe" />
+                    <Text style={styles.loadingText}>Loading quizzes...</Text>
+                </View>
+            ) : quizList && quizList.length > 0 ? (
                 <FlatList
                     data={quizList}
                     renderItem={renderQuizItem}
@@ -77,7 +39,7 @@ export default function QuizList({navigation,quizList}: Props) {
                     contentContainerStyle={styles.listContent}
                 />
             ) : (
-                <Text style={styles.emptyMessage}>No quizzes available.</Text> // Message si la liste est vide
+                <Text style={styles.emptyMessage}>No quizzes available.</Text>
             )}
         </View>
     );
@@ -132,4 +94,15 @@ const styles = StyleSheet.create({
         textAlign: "center",
         marginTop: 20,
     },
+    loadingContainer: {
+        flex: 1,
+        justifyContent: "center",
+        alignItems: "center",
+    },
+    loadingText: {
+        fontSize: 16,
+        color: "#555",
+        marginTop: 10,
+        textAlign: "center",
+    },
 });
diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index 0483528..cee2a88 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -17,19 +17,20 @@ export default function Community({navigation}: Props) {
     const [quizList, setQuizList] = useState<QuizModel[] | null>()
 
     useEffect(  () => {
-
+        setLoading(true)
         getAllQuizzes().then((quizzes: QuizModel[] | HttpError) => {
             if (quizzes instanceof HttpError) {
                 console.log("Error while fetching quizzes:", quizzes);
             } else {
                 setQuizList(quizzes);
             }
+            setLoading(false)
         })
 
     }, [])
 
 
     return (
-        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={quizList} navigation={navigation} buttonGoBack={false}/>
+        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={quizList} navigation={navigation} buttonGoBack={false} isLoadingData={loading}/>
     );
 }
\ No newline at end of file
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 3f719f4..c204506 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -12,6 +12,7 @@ interface Props {
     setTextInInput: (text: string) => void
     quizList: QuizModel[] | null | undefined
     buttonGoBack: boolean
+    isLoadingData: boolean
 }
 
 /**
@@ -24,14 +25,14 @@ interface Props {
  * @param quizList - La liste des quiz à afficher
  * @param buttonGoBack - boolean qui dit si le bouton de retour doit être affiché
  */
-export default function TemplateQuizList({navigation, title, setTextInInput, quizList, buttonGoBack}: Props) {
+export default function TemplateQuizList({navigation, title, setTextInInput, quizList, buttonGoBack, isLoadingData}: Props) {
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={buttonGoBack}>
             <View style={styles.globalContainer}>
                 <Text style={styles.title}>{title}</Text>
                 <View style={styles.contentContainer}>
                     {/*<InputPlayQuiz setText={setTextInInput} noTitle={true} />*/}
-                    <QuizList quizList={quizList} navigation={navigation}/>
+                    <QuizList quizList={quizList} navigation={navigation} isLoadingData={isLoadingData}/>
                 </View>
             </View>
         </TemplateMenu>
-- 
GitLab


From 5a299f1c4cf341588121c3e296f8dcc3a556b54d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 09:57:12 +0100
Subject: [PATCH 111/283] feat: loading icon in My Quizzes

---
 screens/MyQuizzes/MyQuizzes.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/MyQuizzes/MyQuizzes.tsx b/screens/MyQuizzes/MyQuizzes.tsx
index 7419d53..d7916f2 100644
--- a/screens/MyQuizzes/MyQuizzes.tsx
+++ b/screens/MyQuizzes/MyQuizzes.tsx
@@ -38,6 +38,6 @@ export default function MyQuizzes({navigation}: Props) {
 
 
     return (
-        <TemplateQuizList title={"My quizzes"} setTextInInput={setInput} quizList={quizList} navigation={navigation} buttonGoBack={true}/>
+        <TemplateQuizList title={"My quizzes"} setTextInInput={setInput} quizList={quizList} navigation={navigation} buttonGoBack={true} isLoadingData={false}/>
     );
 }
\ No newline at end of file
-- 
GitLab


From 09812fabd6f406ce9205c71be41a5c5b2543d73c Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 10:00:37 +0100
Subject: [PATCH 112/283] style: comment

---
 components/lists/QuizList.tsx | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index ef92c52..4185602 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -9,6 +9,36 @@ interface Props {
     isLoadingData: boolean;
 }
 
+/**
+ * QuizList : Un composant affichant une liste de quiz avec leur titre, nombre de questions, et catégorie.
+ *
+ * @component
+ *
+ * @param navigation - Propriété de navigation utilisée pour naviguer vers l'écran "InformationsOfQuiz".
+ * @param quizList - Liste des quiz à afficher. Peut être null ou undefined.
+ * @param isLoadingData - Boolean indiquant si les données sont en cours de chargement.
+ *
+ * @example
+ * <QuizList
+ *     navigation={navigation}
+ *     quizList={quizzes}
+ *     isLoadingData={isLoading}
+ * />
+ *
+ * @description
+ * - Ce composant gère trois états :
+ *   1. Chargement : Affiche un spinner si `isLoadingData` est true.
+ *   2. Liste des quiz : Affiche une liste interactive des quiz si `quizList` contient des éléments.
+ *   3. Liste vide : Affiche un message si `quizList` est vide.
+ *
+ * - Chaque quiz affiche :
+ *   - Son code en tant que titre.
+ *   - Son nombre total de questions.
+ *   - Sa catégorie, affichée en majuscules.
+ *
+ * @returns Un composant React contenant une liste interactive de quiz ou des messages en fonction de l'état.
+ */
+
 export default function QuizList({ navigation, quizList, isLoadingData }: Props) {
     const onQuizPressed = (quiz: QuizModel) => {
         navigation.navigate("InformationsOfQuiz", { quiz: quiz });
-- 
GitLab


From 2eb6221a6f5a776053a7d8f6835eaa8c2a161a08 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 14:54:38 +0100
Subject: [PATCH 113/283] fix: fix bug in playing quiz

---
 screens/PlayingQuiz/PlayingQuizBody.tsx | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index b3057b1..87b8ce4 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -24,9 +24,20 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
     const [isCorrect, setIsCorrect] = useState<boolean | null>(null);
     const [correctAnswer, setCorrectAnswer] = useState<AnswerModel | null>(null);
     const [isAnswered, setIsAnswered] = useState<boolean>(false);
+    const [isDisabled, setIsDisabled] = useState<boolean>(true);
 
     const { getAnswerQuiz } = useQuizService();
 
+    useEffect(() => {
+        if(selectedAnswerIndex !== null) {
+            setIsDisabled(false);
+        }
+        if(selectedAnswerIndex === null) {
+            setIsDisabled(true);
+        }
+
+    }, [selectedAnswerIndex]);
+
     useEffect(() => {
         if (quiz) {
             setSelectedAnswerIndex(null);
@@ -42,6 +53,7 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
 
     const handleConfirmAnswerPressed = async () => {
         if(selectedAnswerIndex === null) return;
+        setIsDisabled(true);
         setIsAnswered(true);
 
         const answers = await getAnswerQuiz(quiz.code, currentQuestion.id, currentQuestion.answers[selectedAnswerIndex].id);
@@ -125,7 +137,7 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
                     ))}
                     {/* Ajout du PlayButton à la fin */}
                     <View style={styles.playButtonContainer}>
-                        <BlueButton onPress={handleConfirmAnswerPressed} text="Confirm" buttonStyle={{borderRadius: 50}} isDisabled={selectedAnswerIndex===null}/>
+                        <BlueButton onPress={handleConfirmAnswerPressed} text="Confirm" buttonStyle={{borderRadius: 50}} isDisabled={isDisabled}/>
                     </View>
                 </>
             ) : (
-- 
GitLab


From 46dc1c0d7621783339e25c669361aa494dcea757 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 15:04:33 +0100
Subject: [PATCH 114/283] style: overlay removed

---
 components/PlayingQuiz/ComfirmModal.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/PlayingQuiz/ComfirmModal.tsx b/components/PlayingQuiz/ComfirmModal.tsx
index f31241c..81af836 100644
--- a/components/PlayingQuiz/ComfirmModal.tsx
+++ b/components/PlayingQuiz/ComfirmModal.tsx
@@ -25,7 +25,7 @@ export default function ConfirmModal({ visible, onClose, onConfirm }: Props) {
             onRequestClose={onClose} // Ferme la modal en cas d'interaction système
         >
             <TouchableWithoutFeedback onPress={onClose}>
-                <View style={styles.overlay} />
+                <View/>
             </TouchableWithoutFeedback>
             <View style={styles.modalContainer}>
                 <TouchableOpacity style={styles.closeButton} onPress={onClose}>
@@ -34,7 +34,7 @@ export default function ConfirmModal({ visible, onClose, onConfirm }: Props) {
                 <Text style={styles.title}>WOULD YOU LIKE TO RETURN TO THE MENU ?</Text>
                 <View style={styles.separator} />
                 <View style={styles.buttonContainer}>
-                    <BlueButton text={"CONFIRM"} onPress={onConfirm}/>
+                    <BlueButton text={"CONFIRM"} onPress={onConfirm} isDisabled={false}/>
                 </View>
             </View>
         </Modal>
-- 
GitLab


From 68fbbc7af9c45861fb64cb64d691a3489320d24f Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 15:15:05 +0100
Subject: [PATCH 115/283] fix: button my quizzes removed

---
 screens/Home/HomeChild.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index dfe0df0..6e0460d 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -49,7 +49,7 @@ export default function HomeChild({navigation}: Props) {
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
                 <MenuButton text={"PLAY A QUIZ"} handleButtonPressed={handleButtonGeneratePressed}/>
-                <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
+                {/*<MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>*/}
             </View>
              <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
         </View>
-- 
GitLab


From dbe47065014c8d0da22251989be0e69bb19a548c Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 15:20:16 +0100
Subject: [PATCH 116/283] fix: font size question

---
 styles/TextsStyles.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/styles/TextsStyles.ts b/styles/TextsStyles.ts
index 1f80ebd..1ec37f0 100644
--- a/styles/TextsStyles.ts
+++ b/styles/TextsStyles.ts
@@ -13,7 +13,7 @@ export const TextsStyles = StyleSheet.create( {
         fontWeight: "bold",
     },
     subtitleText: {
-        fontSize: 24,
+        fontSize: 21,
     },
     infoQuizText: {
         fontSize: 18,
-- 
GitLab


From 50ac745ed282af4b9ad4d7275f048836d074f30e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 15:51:11 +0100
Subject: [PATCH 117/283] fix: Go playing quiz from community

---
 screens/InformationsOfQuiz/InformationsOfQuiz.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
index 2fdfb96..ba5c5d0 100644
--- a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -18,7 +18,7 @@ export default function InformationsOfQuiz({ navigation, route }: Props) {
     const { quiz } = route.params;
 
     const onPlay = () => {
-        // navigation.navigate('PlayQuiz', {quiz: quiz});
+        navigation.navigate('PlayingQuiz', {quizRecovered: quiz});
     }
 
     return (
-- 
GitLab


From 04c1e10399d276076ed671cab8921aaf0224e5f7 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Fri, 6 Dec 2024 15:55:08 +0100
Subject: [PATCH 118/283] fix: button restart removed in endQuiz

---
 screens/EndQuiz/EndQuizChild.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index 2f85f5a..cdda848 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -39,7 +39,7 @@ export default function EndQuizChild({ navigation, quiz }: Props) {
                 <Text style={styles.TextBodyTitle}>{((quiz.score/quiz.nbQuestions)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
                 <Text style={styles.TextBody}>you finish the test with a score of {`${quiz.score}/${quiz.nbQuestions}`} ! </Text>
                 <Image source={require('../../assets/uWin.png')} />
-                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
+                {/*<DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>*/}
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
             </View>
         </View>
-- 
GitLab


From 72b847c11bc47b8f3e4182f5f0e081cd6f3b66a3 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 8 Dec 2024 16:16:27 +0100
Subject: [PATCH 119/283] feat: generateQuiz with axios

---
 services/QuizService.ts | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index 7877768..2891048 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -9,7 +9,6 @@ export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
 
     const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<QuizModel | HttpError> => {
-
         // Création du corps de la requête avec les variables passées
         const requestBody = {
             amount,
@@ -18,29 +17,24 @@ export const useQuizService =  () => {
         };
 
         try {
-            const response = await fetch(url + "/quiz/create", {
-                method: "POST",
+            const response = await axios.post(`${url}/quiz/create`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
-                body: JSON.stringify(requestBody),
             });
 
-            if (!response.ok) {
-                throw new HttpError(response.status, "HTTP error! status: " + response.status);
-            }
-
             // Récupération des données retournées par l'API
-            const data = await response.json();
-            const quiz = transformToQuizModel(data);
+            const quiz = transformToQuizModel(response.data);
             return quiz;
-        } catch (error) {
+        } catch (error: any) {
             console.error("Error while generating quiz:", error);
 
-            if (HttpError.isHttpError(error)) {
-                return error;
+            if (error.response) {
+                // Gestion des erreurs HTTP
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
             } else {
-                return new HttpError(500, "Unexpected error: " + error);
+                // Gestion des erreurs réseau ou autres
+                return new HttpError(500, "Unexpected error: " + error.message);
             }
         }
     }
-- 
GitLab


From d4e58f0f6355ed778bcf0534baa3627d744d8669 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 8 Dec 2024 16:17:53 +0100
Subject: [PATCH 120/283] feat: remainingQuiz with axios

---
 services/QuizService.ts | 32 ++++++++++++--------------------
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index 2891048..de7d451 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -9,11 +9,10 @@ export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
 
     const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<QuizModel | HttpError> => {
-        // Création du corps de la requête avec les variables passées
         const requestBody = {
             amount,
             category,
-            difficulty: difficulty.toLowerCase(), // Si EDifficulty est en uppercase et l'API attend lowercase
+            difficulty: difficulty.toLowerCase(),
         };
 
         try {
@@ -39,40 +38,33 @@ export const useQuizService =  () => {
         }
     }
 
-    const remainingQuiz = async (id: string) : Promise<QuizModel | HttpError> => {
-
-        // Création du corps de la requête avec les variables passées
+    const remainingQuiz = async (id: string): Promise<QuizModel | HttpError> => {
         const requestBody = {
-            id
+            id,
         };
 
         try {
-            const response = await fetch(url + "/quiz/remaining", {
-                method: "POST",
+            const response = await axios.post(`${url}/quiz/remaining`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
-                body: JSON.stringify(requestBody),
             });
 
-            if (!response.ok) {
-                throw new HttpError(response.status, "HTTP error! status: " + response.status);
-            }
-
             // Récupération des données retournées par l'API
-            const data = await response.json();
-            const quiz = transformToQuizModel(data);
+            const quiz = transformToQuizModel(response.data);
             return quiz;
-        } catch (error) {
+        } catch (error: any) {
             console.log("Error while remaining quiz:", error);
 
-            if (HttpError.isHttpError(error)) {
-                return error;
+            if (error.response) {
+                // Gestion des erreurs HTTP
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
             } else {
-                return new HttpError(500, "Unexpected error: " + error);
+                // Gestion des erreurs réseau ou autres
+                return new HttpError(500, "Unexpected error: " + error.message);
             }
         }
-    }
+    };
 
     const getAnswerQuiz = async (codeQuiz: string, questionID: number, answerID: number) : Promise<AnswerModel[] | HttpError> => {
         try {
-- 
GitLab


From 99c715d53fd0b0dfc5423115266934b8129e88d8 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 8 Dec 2024 16:31:54 +0100
Subject: [PATCH 121/283] feat: getAnswerQuiz with axios

---
 services/QuizService.ts | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index de7d451..e7be26a 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -66,39 +66,39 @@ export const useQuizService =  () => {
         }
     };
 
-    const getAnswerQuiz = async (codeQuiz: string, questionID: number, answerID: number) : Promise<AnswerModel[] | HttpError> => {
+    const getAnswerQuiz = async (
+        codeQuiz: string,
+        questionID: number,
+        answerID: number
+    ): Promise<AnswerModel[] | HttpError> => {
         try {
             const requestBody = {
                 id: codeQuiz,
                 questionID: questionID,
-                answerID: answerID
+                answerID: answerID,
             };
 
-            const response = await fetch(url + "/quiz/answer", {
-                method: "POST",
+            const response = await axios.post(`${url}/quiz/answer`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
-                body: JSON.stringify(requestBody),
             });
 
-            if (!response.ok) {
-                throw new HttpError(response.status, "HTTP error! status: " + response.status);
-            }
-
-            const data = await response.json();
-            const answers = transformToAnswerModel(data);
+            // Récupération des données retournées par l'API
+            const answers = transformToAnswerModel(response.data);
             return answers;
-        } catch (error) {
+        } catch (error: any) {
             console.log("Error while fetching answers:", error);
 
-            if (HttpError.isHttpError(error)) {
-                return error;
+            if (error.response) {
+                // Gestion des erreurs HTTP
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
             } else {
-                return new HttpError(500, "Unexpected error: " + error);
+                // Gestion des erreurs réseau ou autres
+                return new HttpError(500, "Unexpected error: " + error.message);
             }
         }
-    }
+    };
 
     const getRandomQuiz = async () : Promise<QuizModel | HttpError> => {
 
-- 
GitLab


From 3b13926c39a086c49bf0fc70d164f24d70bce107 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 8 Dec 2024 16:34:08 +0100
Subject: [PATCH 122/283] feat: getRandomQuiz with axios

---
 services/QuizService.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index e7be26a..e4d8675 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -54,7 +54,7 @@ export const useQuizService =  () => {
             const quiz = transformToQuizModel(response.data);
             return quiz;
         } catch (error: any) {
-            console.log("Error while remaining quiz:", error);
+            console.error("Error while remaining quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -88,7 +88,7 @@ export const useQuizService =  () => {
             const answers = transformToAnswerModel(response.data);
             return answers;
         } catch (error: any) {
-            console.log("Error while fetching answers:", error);
+            console.error("Error while fetching answers:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
-- 
GitLab


From 5e0bb0fe33296f38c344f8be466767e4954cc3c3 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 8 Dec 2024 16:36:15 +0100
Subject: [PATCH 123/283] feat: getRandomQuiz with axios

---
 services/QuizService.ts | 36 +++++++++++++++---------------------
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index e4d8675..bf63bbf 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -100,40 +100,34 @@ export const useQuizService =  () => {
         }
     };
 
-    const getRandomQuiz = async () : Promise<QuizModel | HttpError> => {
-
-        // Création du corps de la requête avec les variables passées
-        const requestBody = {
-            amount: 10,
-        };
-
+    const getRandomQuiz = async (): Promise<QuizModel | HttpError> => {
         try {
-            const response = await fetch(url + "/quiz/create", {
-                method: "POST",
+            const requestBody = {
+                amount: 10,
+            };
+
+            const response = await axios.post(`${url}/quiz/create`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
-                body: JSON.stringify(requestBody),
             });
 
-            if (!response.ok) {
-                throw new HttpError(response.status, "HTTP error! status: " + response.status);
-            }
-
             // Récupération des données retournées par l'API
-            const data = await response.json();
-            const quiz = transformToQuizModel(data);
+            const quiz = transformToQuizModel(response.data);
             return quiz;
-        } catch (error) {
+        } catch (error: any) {
             console.error("Error while generating random quiz:", error);
 
-            if (HttpError.isHttpError(error)) {
-                return error;
+            if (error.response) {
+                // Gestion des erreurs HTTP
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
             } else {
-                return new HttpError(500, "Unexpected error: " + error);
+                // Gestion des erreurs réseau ou autres
+                return new HttpError(500, "Unexpected error: " + error.message);
             }
         }
-    }
+    };
+
 
     const getQuizzesCommunity = async () : Promise<QuizModel[] | HttpError> => {
         try {
-- 
GitLab


From f1cbd27d051e557c1d9b5e88211f3539c7836ef8 Mon Sep 17 00:00:00 2001
From: HUSS THEOPHILE <theophile.huss@etu.unistra.fr>
Date: Thu, 12 Dec 2024 09:51:57 +0000
Subject: [PATCH 124/283] feat: Add .gitlab-ci.yml in project instead of
 another repository

---
 .gitlab-ci.yml | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 .gitlab-ci.yml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..139742d
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,53 @@
+image: node:latest
+
+stages:
+  - build
+  - test
+  - deploy
+
+build-job:
+  stage: build
+  script:
+    - echo "Building application..."
+#     - npm install -g eas-cli
+#     - npm ci
+#     - EXPO_TOKEN=$EAS_TOKEN eas build --platform android --platform ios --profile production --non-interactive
+    - echo "Application successfully built."
+
+test-job:
+  stage: test
+  script:
+    - echo "Running unit tests..."
+    - echo "Unit tests complete"
+
+deploy-job:
+  stage: deploy
+  environment: production
+  script:
+    - echo "Deploying application..."
+#     - curl -o builds/my-app.apk "$(eas build:status --json | jq -r '.artifacts.buildUrl')"
+    - echo "Application successfully deployed."
+#   artifacts:
+#     paths:
+#       - builds/my-app.apk
+  rules:
+    - if: '$CI_COMMIT_BRANCH == "main"'
+  dependencies:
+    - build-job
+
+
+# # à supprimer à l'avenir
+# # deploy-job-test:
+# #   stage: deploy
+# #   environment: production
+# #   script:
+# #     - echo "Deploying application..."
+# #     - curl -o builds/my-app.apk "$(eas build:status --json | jq -r '.artifacts.buildUrl')"
+# #     - echo "Application successfully deployed."
+# #   artifacts:
+# #     paths:
+# #       - builds/my-app.apk
+# #   rules:
+# #     - if: '$CI_COMMIT_BRANCH == "develop"'
+# #   dependencies:
+# #     - build-job
\ No newline at end of file
-- 
GitLab


From 4d3d696430260a33fda0030eacac847c8225d33c Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 16 Dec 2024 22:08:17 +0100
Subject: [PATCH 125/283] feat: technical overhaul of playing quiz

---
 screens/PlayingQuiz/PlayingQuizBody.tsx | 198 ++++++++++++++----------
 1 file changed, 114 insertions(+), 84 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 87b8ce4..d319ab7 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -19,108 +19,116 @@ interface Props {
     navigation: NavigationProp<any>;
 }
 
-export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsAlreadyPlayed, navigation }: Props) {
-    const [selectedAnswerIndex, setSelectedAnswerIndex] = useState<number | null>(null);
-    const [isCorrect, setIsCorrect] = useState<boolean | null>(null);
-    const [correctAnswer, setCorrectAnswer] = useState<AnswerModel | null>(null);
-    const [isAnswered, setIsAnswered] = useState<boolean>(false);
-    const [isDisabled, setIsDisabled] = useState<boolean>(true);
-
-    const { getAnswerQuiz } = useQuizService();
+enum QuizState {
+    ANSWERING= "Answering",
+    LOADING= "Loading",
+    SHOWING_RESULTS= "ShowingResults",
+}
 
-    useEffect(() => {
-        if(selectedAnswerIndex !== null) {
-            setIsDisabled(false);
-        }
-        if(selectedAnswerIndex === null) {
-            setIsDisabled(true);
-        }
+const getStyleOfAnswerButtonText = (answerId: number, selectedAnswerIndex: number | null, correctAnswerId: number | null, quizState: QuizState) => {
+    if(quizState === QuizState.LOADING)
+    {
+        return styles.loadingText;
+    }
+    if(quizState === QuizState.ANSWERING)
+    {
+        return styles.answerText;
 
-    }, [selectedAnswerIndex]);
+    }
+    if(quizState === QuizState.SHOWING_RESULTS)
+    {
+        if(answerId === correctAnswerId) return styles.correctText;
+        if(answerId !== correctAnswerId && selectedAnswerIndex === answerId) return styles.incorrectText;
+    }
+    return styles.answerText;
+}
 
-    useEffect(() => {
-        if (quiz) {
-            setSelectedAnswerIndex(null);
-            setIsCorrect(null);
-            setCorrectAnswer(null);
-            setIsAnswered(false);
-        }
-    }, [quiz?.nbActualQuestion]);
+const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number | null, correctAnswerId: number | null, quizState: QuizState) => {
+    if(quizState === QuizState.LOADING)
+    {
+        return styles.loadingAnswer;
+    }
+    if(quizState === QuizState.ANSWERING)
+    {
+        if(selectedAnswerIndex === null) return styles.answerButton;
+        if(selectedAnswerIndex === answerId) return styles.selectedAnswer;
 
-    if (!quiz) return null;
+    }
+    if(quizState === QuizState.SHOWING_RESULTS)
+    {
+        if(answerId === correctAnswerId) return styles.correctAnswer;
+        if(answerId !== correctAnswerId && selectedAnswerIndex === answerId) return styles.incorrectAnswer;
+    }
+    return styles.answerButton;
+}
 
-    const currentQuestion: QuestionModel = quiz.questions[quiz.nbActualQuestion - 1];
+export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsAlreadyPlayed, navigation }: Props) {
+    const [currentQuestion, setCurrentQuestion] = useState<QuestionModel>(quiz.questions[quiz.nbActualQuestion - 1]);
+    const [questionIsFinished, setQuestionIsFinished] = useState(false);
+    const [selectedAnswerId, setSelectedAnswerId] = useState<number | null>(null);
+    const [validationButtonIsDisabled, setValidationButtonIsDisabled] = useState(true);
+    const [quizState, setQuizState] = useState(QuizState.ANSWERING);
+    const [correctAnswerId, setCorrectAnswerId] = useState<number | null>(null);
 
-    const handleConfirmAnswerPressed = async () => {
-        if(selectedAnswerIndex === null) return;
-        setIsDisabled(true);
-        setIsAnswered(true);
+    const {getAnswerQuiz} = useQuizService();
 
-        const answers = await getAnswerQuiz(quiz.code, currentQuestion.id, currentQuestion.answers[selectedAnswerIndex].id);
+    useEffect(() => {
+        setCurrentQuestion(quiz.questions[quiz.nbActualQuestion - 1]);
+        setSelectedAnswerId(null); // Réinitialise la sélection
+        setQuestionIsFinished(false); // Réinitialise l'état de la question
+        setCorrectAnswerId(null); // Réinitialise l'id de la bonne réponse
+        setQuizState(QuizState.ANSWERING)
+    }, [quiz.nbActualQuestion]);
 
+    const getCorrectAnswer = (answers: AnswerModel[]): AnswerModel => {
+        const correctAnswer = answers.find((answer) => answer.isCorrect);
+        if (!correctAnswer) throw new Error("No correct answer found");
+        return correctAnswer;
+    };
+    const onValidation = async () => {
+        setQuizState(QuizState.LOADING);
+        const answerId = currentQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
+        if(!answerId) return;
+        const answers = await getAnswerQuiz(quiz.code, currentQuestion.id, answerId);
         if (HttpError.isHttpError(answers)) {
-            navigation.navigate("TabNavigator");
             return;
         }
+        setQuizState(QuizState.SHOWING_RESULTS);
+        const correctAnswerIdFetched = getCorrectAnswer(answers).id;
+        if(selectedAnswerId === correctAnswerIdFetched)
+            setQuiz((prevQuiz) => ({
+                ...prevQuiz,
+                score: prevQuiz.score + 1,
+            }));
+        setCorrectAnswerId(correctAnswerIdFetched);
 
-        const correctAnswer = getCorrectAnswer(answers);
-        const isAnswerCorrect = currentQuestion.answers[selectedAnswerIndex].id === correctAnswer.id;
-
-        setSelectedAnswerIndex(selectedAnswerIndex);
-        setIsCorrect(isAnswerCorrect);
-        setCorrectAnswer(correctAnswer);
-
-        await new Promise((resolve) => setTimeout(resolve, 2000));
+    };
 
+    const onContinue = () => {
         if (quiz.nbActualQuestion === quiz.questions.length) {
             navigation.navigate("EndQuiz", {quiz: quiz});
+            return;
         }
-
         setQuiz((prevQuiz) => ({
             ...prevQuiz,
             nbActualQuestion: prevQuiz.nbActualQuestion + 1,
-            score: isAnswerCorrect ? prevQuiz.score + 1 : prevQuiz.score
         }));
     }
 
-    const handleAnswerPress = async (index: number) => {
-        if (isAnswered) return
-        setSelectedAnswerIndex(index);
-    };
-
-    const getCorrectAnswer = (answers: AnswerModel[]): AnswerModel => {
-        const correctAnswer = answers.find((answer) => answer.isCorrect);
-        if (!correctAnswer) throw new Error("No correct answer found");
-        return correctAnswer;
-    };
-
-    const getButtonStyle = (index: number) => {
-        if (selectedAnswerIndex === null) return ButtonsStyles.answerButton;
-
-        if(!isAnswered && index === selectedAnswerIndex && !isCorrect) return styles.selectedAnswer;
-
-        if (index === selectedAnswerIndex && isCorrect !== null) {
-            return isCorrect ? styles.correctAnswer : styles.incorrectAnswer;
-        }
-        if (currentQuestion.answers[index].id === correctAnswer?.id) {
-            return styles.correctAnswer;
+    useEffect(() => {
+        if(selectedAnswerId !== null) {
+            setValidationButtonIsDisabled(false)
+            return;
         }
-        return ButtonsStyles.answerButton;
-    };
-
-    const getTextStyle = (index: number) => {
-        if (selectedAnswerIndex === null || !isAnswered && index === selectedAnswerIndex) return TextsStyles.defaultText;
-
+        setValidationButtonIsDisabled(true)
+    }, [selectedAnswerId]);
 
-
-        if (index === selectedAnswerIndex && isCorrect !== null) {
-            return isCorrect ? styles.correctText : styles.incorrectText;
-        }
-        if (currentQuestion.answers[index].id === correctAnswer?.id) {
-            return styles.correctText;
+    const onAnsweredButtonClicked = (answerId: number) => {
+        if(quizState === QuizState.SHOWING_RESULTS || quizState === QuizState.LOADING) {
+            return;
         }
-        return TextsStyles.defaultText;
-    };
+        setSelectedAnswerId(answerId);
+    }
 
     return (
         <View style={styles.buttonContainer}>
@@ -130,14 +138,14 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
                         <DefaultButton
                             key={index}
                             text={answer.text}
-                            handleButtonPressed={() => handleAnswerPress(index)}
-                            buttonStyle={getButtonStyle(index)}
-                            buttonText={getTextStyle(index)}
+                            handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
+                            buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                            buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
                         />
                     ))}
                     {/* Ajout du PlayButton à la fin */}
                     <View style={styles.playButtonContainer}>
-                        <BlueButton onPress={handleConfirmAnswerPressed} text="Confirm" buttonStyle={{borderRadius: 50}} isDisabled={isDisabled}/>
+                        <BlueButton onPress={() => quizState === QuizState.ANSWERING ? onValidation() : onContinue()} text={quizState === QuizState.ANSWERING ? "CONFIRM" : "CONTINUE"} buttonStyle={{borderRadius: 50}} isDisabled={false}/>
                     </View>
                 </>
             ) : (
@@ -147,6 +155,7 @@ export default function PlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsA
     );
 
 }
+
 const styles = StyleSheet.create({
     buttonContainer: {
         display: 'flex',
@@ -171,11 +180,20 @@ const styles = StyleSheet.create({
         borderColor: 'red',
         borderWidth: 2,
     },
+    loadingAnswer: {
+        ...ButtonsStyles.answerButton,
+        backgroundColor: 'grey',
+        borderWidth: 2,
+    },
     selectedAnswer: {
         ...ButtonsStyles.answerButton,
-        borderColor: '#45128c',
+        borderColor: 'grey',
         borderWidth: 2,
     },
+    answerText: {
+        color: 'black',
+        textAlign: 'center',
+    },
     correctText: {
         fontWeight: 'bold',
         color: 'green',
@@ -185,9 +203,21 @@ const styles = StyleSheet.create({
         color: 'red',
     },
     loadingText: {
-        fontSize: 18,
-        color: 'gray',
+        color: 'black',
         textAlign: 'center',
     },
+    answerButton: {
+        backgroundColor: "#F3F3F3",
+        height: '15%',
+        alignItems: 'center',
+        width: '80%',
+        marginVertical: '3%',
+        justifyContent: "center",
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.5,
+        elevation: 5,
+    },
 });
 
-- 
GitLab


From f76cd4bf39dadaef4ac5f3762eb7b91d179fbc76 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 16 Dec 2024 22:21:28 +0100
Subject: [PATCH 126/283] style: loading button style

---
 screens/PlayingQuiz/PlayingQuizBody.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index d319ab7..fff9677 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -182,7 +182,7 @@ const styles = StyleSheet.create({
     },
     loadingAnswer: {
         ...ButtonsStyles.answerButton,
-        backgroundColor: 'grey',
+        backgroundColor: '#4F6367',
         borderWidth: 2,
     },
     selectedAnswer: {
-- 
GitLab


From 52657e8f807c28bbf8be772fe2742e3b67aa8f36 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 17 Dec 2024 21:11:38 +0100
Subject: [PATCH 127/283] feat: added community quiz service

---
 components/loading/LoadingIndicator.tsx | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 components/loading/LoadingIndicator.tsx

diff --git a/components/loading/LoadingIndicator.tsx b/components/loading/LoadingIndicator.tsx
new file mode 100644
index 0000000..e69de29
-- 
GitLab


From fcc0500b3ef27f8511535d363b35a7ad9b40fc8b Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 17 Dec 2024 21:17:22 +0100
Subject: [PATCH 128/283] feat: added service for community quiz

---
 components/loading/LoadingIndicator.tsx | 22 +++++++++++++++++
 screens/Home/HomeChild.tsx              |  5 ++++
 services/QuizService.ts                 | 32 +++++++++++++------------
 3 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/components/loading/LoadingIndicator.tsx b/components/loading/LoadingIndicator.tsx
index e69de29..2520955 100644
--- a/components/loading/LoadingIndicator.tsx
+++ b/components/loading/LoadingIndicator.tsx
@@ -0,0 +1,22 @@
+import React from "react";
+import { View, StyleSheet, ActivityIndicator } from "react-native";
+
+export default function LoadingIndicator() {
+    return (
+        <View style={styles.container}>
+            <ActivityIndicator size="large" color="#2b73fe" />
+        </View>
+    );
+}
+
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex", // Change le type de flex pour que la vue soit centrée
+        width: "100%", // Prend toute la largeur de l'écran
+        height: "100%", // Prend toute la hauteur de l'écran
+        ...StyleSheet.absoluteFillObject, // Prend toute la surface de l'écran
+        justifyContent: "center", // Centre verticalement
+        alignItems: "center", // Centre horizontalement
+    },
+});
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 6e0460d..780947f 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -7,6 +7,7 @@ import ModalJoinQuiz from "../../components/ModalJoinQuiz";
 import MenuButton from "../../components/buttons/MenuButton";
 import {NavigationProp} from "@react-navigation/native";
 import {useQuizService} from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -23,6 +24,10 @@ export default function HomeChild({navigation}: Props) {
 
     const handleButtonQuickGamePressed = async () => {
         const quizData = await getRandomQuiz()
+        if (quizData instanceof HttpError) {
+            console.error("Error while fetching random quiz:", quizData);
+            return;
+        }
         navigation.reset({
             index: 0,
             routes: [
diff --git a/services/QuizService.ts b/services/QuizService.ts
index bf63bbf..2c77eb5 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -128,32 +128,35 @@ export const useQuizService =  () => {
         }
     };
 
-
-    const getQuizzesCommunity = async () : Promise<QuizModel[] | HttpError> => {
+    const getAllQuizzes = async (): Promise<QuizModel[] | HttpError> => {
         try {
-            // await axios.post(`${url}/quiz/community`, null, {
-            //     withCredentials: true, // Inclut les cookies dans la requête
-            // });
-            return [];
+            // Effectuer une requête GET pour récupérer les quizzes
+            const response = await axios.get(`${url}/quiz/all`, {
+                withCredentials: true, // Inclut les cookies pour une session authentifiée
+            });
+
+            // Transformation des données de chaque quiz en modèle QuizModel
+            const quizzes: QuizModel[] = response.data.map((quiz: any) => transformToQuizModel(quiz));
+
+            return quizzes;
         } catch (error: any) {
+            console.error("Error while fetching all quizzes:", error);
+
             if (error.response) {
                 return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
             } else {
                 return new HttpError(500, "Unexpected error: " + error.message);
             }
         }
-    }
+    };
 
-    const getAllQuizzes = async (): Promise<QuizModel[] | HttpError> => {
+    const getCommunityQuiz = async (skip: number, take: number) => {
         try {
-            // Effectuer une requête GET pour récupérer les quizzes
-            const response = await axios.get(`${url}/quiz/all`, {
+            const response = await axios.get(`${url}/quiz/paginated?skip=${skip}&take=${take}`, {
                 withCredentials: true, // Inclut les cookies pour une session authentifiée
             });
 
-            // Transformation des données de chaque quiz en modèle QuizModel
             const quizzes: QuizModel[] = response.data.map((quiz: any) => transformToQuizModel(quiz));
-
             return quizzes;
         } catch (error: any) {
             console.error("Error while fetching all quizzes:", error);
@@ -172,8 +175,7 @@ export const useQuizService =  () => {
         getAnswerQuiz: getAnswerQuiz,
         remainingQuiz: remainingQuiz,
         getRandomQuiz: getRandomQuiz,
-        getQuizzesCommunity: getQuizzesCommunity,
-        getAllQuizzes: getAllQuizzes
-
+        getAllQuizzes: getAllQuizzes,
+        getCommunityQuiz: getCommunityQuiz
     }
 }
\ No newline at end of file
-- 
GitLab


From 7fae578aa8129d3387378294f5a4884ec39f7a2a Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 17 Dec 2024 22:47:56 +0100
Subject: [PATCH 129/283] chore: added package for infinite scroll

---
 package-lock.json | 186 ++++++++++++++++++++++++++++++++++++++++++++--
 package.json      |   5 +-
 2 files changed, 185 insertions(+), 6 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index f808720..34cf915 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,8 +14,11 @@
         "@react-navigation/bottom-tabs": "^6.6.1",
         "@react-navigation/native": "^6.1.18",
         "@react-navigation/native-stack": "^6.11.0",
+        "@tanstack/react-query": "^5.62.8",
+        "@tanstack/react-query-devtools": "^5.62.8",
         "axios": "^1.7.9",
         "expo": "~52.0.14",
+        "expo-splash-screen": "^0.29.13",
         "expo-status-bar": "~2.0.0",
         "he": "^1.2.0",
         "i18n-js": "^4.5.0",
@@ -26,7 +29,8 @@
         "react-native-dropdown-select-list": "^2.0.5",
         "react-native-safe-area-context": "^4.12.0",
         "react-native-screens": "~4.1.0",
-        "react-native-vector-icons": "^10.2.0"
+        "react-native-vector-icons": "^10.2.0",
+        "react-query": "^3.39.3"
       },
       "devDependencies": {
         "@babel/core": "^7.20.0",
@@ -2883,9 +2887,9 @@
       }
     },
     "node_modules/@expo/prebuild-config": {
-      "version": "8.0.21",
-      "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.0.21.tgz",
-      "integrity": "sha512-PVvt7+2dLzmf1X4HaoibnTtfoxnor0YEdu396eLv1SG+KacmN5lMz81yO/2MXvv0SDA6THomgBNvA/uzWV5twA==",
+      "version": "8.0.23",
+      "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-8.0.23.tgz",
+      "integrity": "sha512-Zf01kFiN2PISmLb0DhIAJh76v3J2oYUKSjiAtGZLOH0HUz59by/qdyU4mGHWdeyRdCCrLUA21Rct2MBykvRMsg==",
       "license": "MIT",
       "dependencies": {
         "@expo/config": "~10.0.4",
@@ -2893,7 +2897,7 @@
         "@expo/config-types": "^52.0.0",
         "@expo/image-utils": "^0.6.0",
         "@expo/json-file": "^9.0.0",
-        "@react-native/normalize-colors": "0.76.3",
+        "@react-native/normalize-colors": "0.76.5",
         "debug": "^4.3.1",
         "fs-extra": "^9.0.0",
         "resolve-from": "^5.0.0",
@@ -2901,6 +2905,12 @@
         "xml2js": "0.6.0"
       }
     },
+    "node_modules/@expo/prebuild-config/node_modules/@react-native/normalize-colors": {
+      "version": "0.76.5",
+      "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.76.5.tgz",
+      "integrity": "sha512-6QRLEok1r55gLqj+94mEWUENuU5A6wsr2OoXpyq/CgQ7THWowbHtru/kRGRr6o3AQXrVnZheR60JNgFcpNYIug==",
+      "license": "MIT"
+    },
     "node_modules/@expo/prebuild-config/node_modules/fs-extra": {
       "version": "9.1.0",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
@@ -3960,6 +3970,59 @@
         "@sinonjs/commons": "^3.0.0"
       }
     },
+    "node_modules/@tanstack/query-core": {
+      "version": "5.62.8",
+      "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.8.tgz",
+      "integrity": "sha512-4fV31vDsUyvNGrKIOUNPrZztoyL187bThnoQOvAXEVlZbSiuPONpfx53634MKKdvsDir5NyOGm80ShFaoHS/mw==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/tannerlinsley"
+      }
+    },
+    "node_modules/@tanstack/query-devtools": {
+      "version": "5.61.4",
+      "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.61.4.tgz",
+      "integrity": "sha512-21Tw+u8E3IJJj4A/Bct4H0uBaDTEu7zBrR79FeSyY+mS2gx5/m316oDtJiKkILc819VSTYt+sFzODoJNcpPqZQ==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/tannerlinsley"
+      }
+    },
+    "node_modules/@tanstack/react-query": {
+      "version": "5.62.8",
+      "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.62.8.tgz",
+      "integrity": "sha512-8TUstKxF/fysHonZsWg/hnlDVgasTdHx6Q+f1/s/oPKJBJbKUWPZEHwLTMOZgrZuroLMiqYKJ9w69Abm8mWP0Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@tanstack/query-core": "5.62.8"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/tannerlinsley"
+      },
+      "peerDependencies": {
+        "react": "^18 || ^19"
+      }
+    },
+    "node_modules/@tanstack/react-query-devtools": {
+      "version": "5.62.8",
+      "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.62.8.tgz",
+      "integrity": "sha512-SwjXjQTRONd9WPeKVQQ9framG7YNqPV8PS+EGNVNXAyz2XThulMRCvZnh2+3DggnjcYM7YcpnuoZ4RH7q13p0g==",
+      "license": "MIT",
+      "dependencies": {
+        "@tanstack/query-devtools": "5.61.4"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/tannerlinsley"
+      },
+      "peerDependencies": {
+        "@tanstack/react-query": "^5.62.8",
+        "react": "^18 || ^19"
+      }
+    },
     "node_modules/@types/babel__core": {
       "version": "7.20.5",
       "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -4698,6 +4761,22 @@
         "node": ">=8"
       }
     },
+    "node_modules/broadcast-channel": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
+      "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.7.2",
+        "detect-node": "^2.1.0",
+        "js-sha3": "0.8.0",
+        "microseconds": "0.2.0",
+        "nano-time": "1.0.0",
+        "oblivious-set": "1.0.0",
+        "rimraf": "3.0.2",
+        "unload": "2.2.0"
+      }
+    },
     "node_modules/browserslist": {
       "version": "4.24.2",
       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz",
@@ -5517,6 +5596,12 @@
         "node": ">=0.10"
       }
     },
+    "node_modules/detect-node": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+      "license": "MIT"
+    },
     "node_modules/dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -5968,6 +6053,18 @@
         "invariant": "^2.2.4"
       }
     },
+    "node_modules/expo-splash-screen": {
+      "version": "0.29.18",
+      "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-0.29.18.tgz",
+      "integrity": "sha512-bTBY+LF6YtYen2j60yGNh2SX/tG4UXZAyBCMMriOSiZZ7LSCs3ARyEufaSiWk+ckWShTeMqItOnaAN/CAF8MJA==",
+      "license": "MIT",
+      "dependencies": {
+        "@expo/prebuild-config": "^8.0.23"
+      },
+      "peerDependencies": {
+        "expo": "*"
+      }
+    },
     "node_modules/expo-status-bar": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.0.0.tgz",
@@ -7114,6 +7211,12 @@
       "integrity": "sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ==",
       "license": "MIT"
     },
+    "node_modules/js-sha3": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
+      "license": "MIT"
+    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -7683,6 +7786,16 @@
       "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==",
       "license": "Apache-2.0"
     },
+    "node_modules/match-sorter": {
+      "version": "6.3.4",
+      "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz",
+      "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.23.8",
+        "remove-accents": "0.5.0"
+      }
+    },
     "node_modules/md5": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
@@ -8142,6 +8255,12 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
+    "node_modules/microseconds": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
+      "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==",
+      "license": "MIT"
+    },
     "node_modules/mime": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -8346,6 +8465,15 @@
         "thenify-all": "^1.0.0"
       }
     },
+    "node_modules/nano-time": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
+      "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==",
+      "license": "ISC",
+      "dependencies": {
+        "big-integer": "^1.6.16"
+      }
+    },
     "node_modules/nanoid": {
       "version": "3.3.7",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@@ -8534,6 +8662,12 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/oblivious-set": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
+      "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==",
+      "license": "MIT"
+    },
     "node_modules/on-finished": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@@ -9543,6 +9677,32 @@
         "async-limiter": "~1.0.0"
       }
     },
+    "node_modules/react-query": {
+      "version": "3.39.3",
+      "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz",
+      "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.5.5",
+        "broadcast-channel": "^3.4.1",
+        "match-sorter": "^6.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/tannerlinsley"
+      },
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/react-refresh": {
       "version": "0.14.2",
       "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
@@ -9671,6 +9831,12 @@
         "regjsparser": "bin/parser"
       }
     },
+    "node_modules/remove-accents": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
+      "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==",
+      "license": "MIT"
+    },
     "node_modules/remove-trailing-slash": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz",
@@ -11061,6 +11227,16 @@
         "node": ">= 4.0.0"
       }
     },
+    "node_modules/unload": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz",
+      "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime": "^7.6.2",
+        "detect-node": "^2.0.4"
+      }
+    },
     "node_modules/unpipe": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
diff --git a/package.json b/package.json
index 0b14e67..b58c2ac 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,8 @@
     "@react-navigation/bottom-tabs": "^6.6.1",
     "@react-navigation/native": "^6.1.18",
     "@react-navigation/native-stack": "^6.11.0",
+    "@tanstack/react-query": "^5.62.8",
+    "@tanstack/react-query-devtools": "^5.62.8",
     "axios": "^1.7.9",
     "expo": "~52.0.14",
     "expo-splash-screen": "^0.29.13",
@@ -28,7 +30,8 @@
     "react-native-dropdown-select-list": "^2.0.5",
     "react-native-safe-area-context": "^4.12.0",
     "react-native-screens": "~4.1.0",
-    "react-native-vector-icons": "^10.2.0"
+    "react-native-vector-icons": "^10.2.0",
+    "react-query": "^3.39.3"
   },
   "devDependencies": {
     "@babel/core": "^7.20.0",
-- 
GitLab


From e314acd592e719db02e2ecb3bdb4081c35abaae5 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 17 Dec 2024 22:48:18 +0100
Subject: [PATCH 130/283] chore: added QueryClientProvider in app.tsx

---
 App.tsx | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/App.tsx b/App.tsx
index 41a0a91..4b3b1c0 100644
--- a/App.tsx
+++ b/App.tsx
@@ -5,6 +5,8 @@ import { SafeAreaProvider } from "react-native-safe-area-context";
 import StackNavigator from "./routes/StackNavigator";
 import { useEffect } from 'react';
 import * as SplashScreen from 'expo-splash-screen';
+import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
+const queryClient = new QueryClient();
 
 export default function App() {
     // LogBox.ignoreAllLogs(true);
@@ -26,11 +28,13 @@ export default function App() {
 
   const { t } = useTranslation();
   return (
-    <SafeAreaProvider>
-        <I18nextProvider i18n={i18n}>
-            <StackNavigator/>
-        </I18nextProvider>
-    </SafeAreaProvider>
+    <QueryClientProvider client={queryClient}>
+      <SafeAreaProvider>
+          <I18nextProvider i18n={i18n}>
+              <StackNavigator/>
+          </I18nextProvider>
+      </SafeAreaProvider>
+    </QueryClientProvider>
   );
 }
 
-- 
GitLab


From 8c110da1edefe984e5128388c91949333616dd91 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 17 Dec 2024 22:56:05 +0100
Subject: [PATCH 131/283] refactor: added props

---
 templates/TemplateQuizList.tsx | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index c204506..7782d71 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -25,14 +25,24 @@ interface Props {
  * @param quizList - La liste des quiz à afficher
  * @param buttonGoBack - boolean qui dit si le bouton de retour doit être affiché
  */
-export default function TemplateQuizList({navigation, title, setTextInInput, quizList, buttonGoBack, isLoadingData}: Props) {
+
+interface Props {
+    navigation: NavigationProp<any>
+    title: string
+    setTextInInput: (text: string) => void
+    quizList: QuizModel[] | null | undefined
+    buttonGoBack: boolean
+    isLoadingData: boolean
+    nextPage?: () => void;
+}
+export default function TemplateQuizList({navigation, title, setTextInInput, quizList, buttonGoBack, isLoadingData, nextPage}: Props) {
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={buttonGoBack}>
             <View style={styles.globalContainer}>
                 <Text style={styles.title}>{title}</Text>
                 <View style={styles.contentContainer}>
                     {/*<InputPlayQuiz setText={setTextInInput} noTitle={true} />*/}
-                    <QuizList quizList={quizList} navigation={navigation} isLoadingData={isLoadingData}/>
+                    <QuizList quizList={quizList} navigation={navigation} isLoadingData={isLoadingData} nextPage={nextPage}/>
                 </View>
             </View>
         </TemplateMenu>
-- 
GitLab


From 7a5e6ef6a342064ee08509d43360e5639444bd7c Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 17 Dec 2024 22:56:25 +0100
Subject: [PATCH 132/283] feat: added infinite scroll

---
 components/lists/QuizList.tsx   | 15 ++++++++++---
 screens/Community/Community.tsx | 39 +++++++++++++++++++++------------
 services/QuizService.ts         |  2 +-
 3 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 4185602..57146b9 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -7,6 +7,7 @@ interface Props {
     navigation: NavigationProp<any>;
     quizList: QuizModel[] | null | undefined;
     isLoadingData: boolean;
+    nextPage?: () => void;
 }
 
 /**
@@ -39,7 +40,7 @@ interface Props {
  * @returns Un composant React contenant une liste interactive de quiz ou des messages en fonction de l'état.
  */
 
-export default function QuizList({ navigation, quizList, isLoadingData }: Props) {
+export default function QuizList({ navigation, quizList, isLoadingData, nextPage }: Props) {
     const onQuizPressed = (quiz: QuizModel) => {
         navigation.navigate("InformationsOfQuiz", { quiz: quiz });
     };
@@ -48,7 +49,7 @@ export default function QuizList({ navigation, quizList, isLoadingData }: Props)
         <TouchableOpacity style={styles.quizItem} onPress={() => onQuizPressed(item)}>
             <Text style={styles.quizTitle}>{item.code}</Text>
             <Text style={styles.quizDetails}>
-                {item.nbQuestions} QUESTIONS | {item.category.toUpperCase()}
+                {item.nbQuestions} QUESTIONS | {item.category ? item.category.toUpperCase() : ""}
             </Text>
         </TouchableOpacity>
     );
@@ -67,6 +68,15 @@ export default function QuizList({ navigation, quizList, isLoadingData }: Props)
                     keyExtractor={(item) => item.code}
                     showsVerticalScrollIndicator={true}
                     contentContainerStyle={styles.listContent}
+                    onEndReached={() => {
+                        console.log("onEndReached triggered");
+                        if (nextPage) {
+                            console.log("Calling nextPage...");
+                            nextPage();
+                        }
+                    }}
+
+                    onEndReachedThreshold={0.5}
                 />
             ) : (
                 <Text style={styles.emptyMessage}>No quizzes available.</Text>
@@ -91,7 +101,6 @@ const styles = StyleSheet.create({
         width: "100%", // Assurez-vous que le conteneur occupe toute la largeur
     },
     listContent: {
-        paddingVertical: 10,
     },
     quizItem: {
         backgroundColor: "#f3f3f3",
diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index cee2a88..f9ece3c 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -5,32 +5,43 @@ import {useEffect, useState} from "react";
 import QuizModel from "../../models/QuizModel";
 import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
+import {useInfiniteQuery} from "@tanstack/react-query";
 
 interface Props {
     navigation: NavigationProp<any>
 }
 export default function Community({navigation}: Props) {
-    const  {getAllQuizzes} = useQuizService();
+    const  {getCommunityQuiz} = useQuizService();
     const [input, setInput] = useState<string>("")
     const [loading, setLoading] = useState<boolean>(false)
 
-    const [quizList, setQuizList] = useState<QuizModel[] | null>()
+    const fetchCommunityQuizzes = async ({pageParam = 1}) => {
+        console.log("fetchCommunityQuizzes");
+        const quizzes = await getCommunityQuiz(pageParam,7);
+        if (HttpError.isHttpError(quizzes)) {
+            console.error("Error while fetching community quizzes:", quizzes);
+            return [];
+        }
+        return quizzes;
+    }
 
-    useEffect(  () => {
-        setLoading(true)
-        getAllQuizzes().then((quizzes: QuizModel[] | HttpError) => {
-            if (quizzes instanceof HttpError) {
-                console.log("Error while fetching quizzes:", quizzes);
-            } else {
-                setQuizList(quizzes);
-            }
-            setLoading(false)
-        })
 
-    }, [])
+    const {
+        data,
+        fetchNextPage,
+    } = useInfiniteQuery({
+        queryKey: ["communityQuizzes"],
+        queryFn: fetchCommunityQuizzes,
+        initialPageParam: 0,
+        getNextPageParam: (lastPage, allPages) => {
+            // Si la dernière page a moins de 7 quizzes, il n'y a plus de page suivante
+            if (lastPage.length < 7) return undefined;
 
+            // On augmente skip de 7 pour la prochaine requête
+            return allPages.length * 7;
+        }});
 
     return (
-        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={quizList} navigation={navigation} buttonGoBack={false} isLoadingData={loading}/>
+        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage}/>
     );
 }
\ No newline at end of file
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 2c77eb5..499ba54 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -156,10 +156,10 @@ export const useQuizService =  () => {
                 withCredentials: true, // Inclut les cookies pour une session authentifiée
             });
 
+
             const quizzes: QuizModel[] = response.data.map((quiz: any) => transformToQuizModel(quiz));
             return quizzes;
         } catch (error: any) {
-            console.error("Error while fetching all quizzes:", error);
 
             if (error.response) {
                 return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
-- 
GitLab


From 7e1098e77b87151d44fab453859d4c36d796bc25 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 17 Dec 2024 22:58:27 +0100
Subject: [PATCH 133/283] refactor: removed console.log

---
 components/lists/QuizList.tsx   | 2 --
 hooks/UseUser.ts                | 2 --
 screens/Community/Community.tsx | 1 -
 screens/Profil/ProfilChild.tsx  | 1 -
 4 files changed, 6 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 57146b9..decffdc 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -69,9 +69,7 @@ export default function QuizList({ navigation, quizList, isLoadingData, nextPage
                     showsVerticalScrollIndicator={true}
                     contentContainerStyle={styles.listContent}
                     onEndReached={() => {
-                        console.log("onEndReached triggered");
                         if (nextPage) {
-                            console.log("Calling nextPage...");
                             nextPage();
                         }
                     }}
diff --git a/hooks/UseUser.ts b/hooks/UseUser.ts
index 810fc17..7d30040 100644
--- a/hooks/UseUser.ts
+++ b/hooks/UseUser.ts
@@ -6,7 +6,6 @@ export const useUser = () => {
             if (!item) {
                 return undefined;
             }
-            console.log("User informations loaded");
             return JSON.parse(item);
         } catch (error) {
             console.error("Erreur lors de la récupération de la donnée des informations utilisateur", error);
@@ -17,7 +16,6 @@ export const useUser = () => {
     const setUser = async <T>(key: string, newValue: T) => {
         try {
             await AsyncStorage.setItem(key, JSON.stringify(newValue));
-            console.log("User informations saved");
         } catch (error) {
             console.error("Erreur lors de l'enregistrement de la donnée", error);
         }
diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index f9ece3c..4b3e111 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -16,7 +16,6 @@ export default function Community({navigation}: Props) {
     const [loading, setLoading] = useState<boolean>(false)
 
     const fetchCommunityQuizzes = async ({pageParam = 1}) => {
-        console.log("fetchCommunityQuizzes");
         const quizzes = await getCommunityQuiz(pageParam,7);
         if (HttpError.isHttpError(quizzes)) {
             console.error("Error while fetching community quizzes:", quizzes);
diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 8357747..b3dee69 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -21,7 +21,6 @@ export default function ProfilChild({ navigation }: Props) {
 
     useEffect(() => {
         getInformationsUser().then((user: UserModel | HttpError) => {
-            console.log(user);
             if (user instanceof HttpError) {
                 return;
             }
-- 
GitLab


From f4cb0e2b603107a614ea1dd9a578a7d15d618c66 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 17 Dec 2024 23:46:29 +0100
Subject: [PATCH 134/283] refactor: changing structure of models

---
 components/lists/QuizList.tsx   | 26 +++++++++----------
 helper/QuizHelper.ts            |  8 +++---
 models/QuestionModel.ts         |  2 +-
 models/QuizModel.ts             | 44 +++++++++++++++++++++++++++++++--
 screens/Community/Community.tsx |  2 +-
 services/QuizService.ts         | 12 ++++++---
 templates/TemplateQuizList.tsx  |  6 ++---
 7 files changed, 73 insertions(+), 27 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index decffdc..45ff335 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -1,14 +1,9 @@
 import React from "react";
 import { FlatList, View, Text, StyleSheet, TouchableOpacity, ActivityIndicator } from "react-native";
-import QuizModel from "../../models/QuizModel";
+import {QuizModel, Quiz} from "../../models/QuizModel";
 import { NavigationProp } from "@react-navigation/native";
 
-interface Props {
-    navigation: NavigationProp<any>;
-    quizList: QuizModel[] | null | undefined;
-    isLoadingData: boolean;
-    nextPage?: () => void;
-}
+
 
 /**
  * QuizList : Un composant affichant une liste de quiz avec leur titre, nombre de questions, et catégorie.
@@ -39,17 +34,22 @@ interface Props {
  *
  * @returns Un composant React contenant une liste interactive de quiz ou des messages en fonction de l'état.
  */
-
+interface Props {
+    navigation: NavigationProp<any>;
+    quizList: Quiz[] | null | undefined;
+    isLoadingData: boolean;
+    nextPage?: () => void;
+}
 export default function QuizList({ navigation, quizList, isLoadingData, nextPage }: Props) {
-    const onQuizPressed = (quiz: QuizModel) => {
+    const onQuizPressed = (quiz: Quiz) => {
         navigation.navigate("InformationsOfQuiz", { quiz: quiz });
     };
 
-    const renderQuizItem = ({ item }: { item: QuizModel }) => (
+    const renderQuizItem = ({ item }: { item: Quiz }) => (
         <TouchableOpacity style={styles.quizItem} onPress={() => onQuizPressed(item)}>
-            <Text style={styles.quizTitle}>{item.code}</Text>
+            <Text style={styles.quizTitle}>{item.id}</Text>
             <Text style={styles.quizDetails}>
-                {item.nbQuestions} QUESTIONS | {item.category ? item.category.toUpperCase() : ""}
+                {item.questionCount} QUESTIONS | {item.category ? item.category.name.toUpperCase() : ""}
             </Text>
         </TouchableOpacity>
     );
@@ -65,7 +65,7 @@ export default function QuizList({ navigation, quizList, isLoadingData, nextPage
                 <FlatList
                     data={quizList}
                     renderItem={renderQuizItem}
-                    keyExtractor={(item) => item.code}
+                    keyExtractor={(item) => item.id}
                     showsVerticalScrollIndicator={true}
                     contentContainerStyle={styles.listContent}
                     onEndReached={() => {
diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index 6456903..e201c6f 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -1,6 +1,6 @@
 
 // Fonction utilitaire pour mélanger les réponses
-import QuizModel from "../models/QuizModel";
+import {QuizModel} from "../models/QuizModel";
 import QuestionModel from "../models/QuestionModel";
 import AnswerModel from "../models/AnswerModel";
 
@@ -55,7 +55,8 @@ export const transformToQuizModel = (data: any): QuizModel => {
         return {
             id: question.id,
             question: question.text, // Texte de la question
-            category: question.category.name,
+            category: "aa",
+            // category: question.category.name ? question.category.name : "Community Quizz", // Extraction du nom de la catégorie
             answers: answers, // Réponses associées
             multiple: question.type === "multiple", // Détermine si c'est une question multiple
             nbOfTheQuestion: question.order, // Numéro de la question
@@ -65,7 +66,8 @@ export const transformToQuizModel = (data: any): QuizModel => {
     // Création de l'objet QuizModel
     const quiz: QuizModel = {
         code: data.id, // Mapping de codeQuiz vers code
-        category: data.category.name, // Extraction du nom de la catégorie
+        category: "aa",
+        // category: data.category.name ? data.category.name : "Community Quizz", // Extraction du nom de la catégorie
         questions: questions, // Questions transformées
         nbQuestions: data.questionCount, // Nombre total de questions
         nbActualQuestion: data.questionIndex, // Index actuel de la question
diff --git a/models/QuestionModel.ts b/models/QuestionModel.ts
index 527e1fc..a823f5b 100644
--- a/models/QuestionModel.ts
+++ b/models/QuestionModel.ts
@@ -3,7 +3,7 @@ import AnswerModel from "./AnswerModel";
 export default interface QuestionModel {
     id: number;
     question: string;
-    category: string;
+    category?: string;
     answers: AnswerModel[];
     multiple: boolean;
     nbOfTheQuestion: number;
diff --git a/models/QuizModel.ts b/models/QuizModel.ts
index 6e1cbb9..38d6cda 100644
--- a/models/QuizModel.ts
+++ b/models/QuizModel.ts
@@ -1,10 +1,50 @@
 import QuestionModel from "./QuestionModel";
 
-export default interface QuizModel {
+export interface QuizModel {
     code: string;
-    category: string;
+    category?: string;
     questions: QuestionModel[];
     nbQuestions: number;
     nbActualQuestion: number;
     score: number;
 }
+
+interface Difficulty {
+    id: number;
+    name: string;
+}
+
+interface Category {
+    id: number;
+    name: string;
+}
+
+export interface Answer {
+    id: number;
+    text: string;
+    isCorrect?: boolean;
+    questionId: number;
+}
+
+export interface Question {
+    id: number;
+    text: string;
+    categoryId: number;
+    quizId: string;
+    order: number;
+    answers: Answer[];
+}
+export interface Quiz {
+    id: string;
+    name: string;
+    description: string;
+    score: number;
+    questionIndex: number;
+    questionCount: number;
+    categoryId: number;
+    difficultyId: number;
+    authorId: number,
+    category?: Category,
+    difficulty: Difficulty,
+    questions: Question[],
+}
\ No newline at end of file
diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index 4b3e111..772faf2 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -2,7 +2,7 @@ import {View, Text} from "react-native";
 import TemplateQuizList from "../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import {useEffect, useState} from "react";
-import QuizModel from "../../models/QuizModel";
+import {QuizModel} from "../../models/QuizModel";
 import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 499ba54..f83ab83 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -2,8 +2,9 @@ import {EDifficulty} from "../models/EDifficulty";
 import {transformToAnswerModel, transformToQuizModel} from "../helper/QuizHelper";
 import AnswerModel from "../models/AnswerModel";
 import HttpError from "./HttpError";
-import QuizModel from "../models/QuizModel";
+import {Quiz, QuizModel} from "../models/QuizModel";
 import axios from "axios";
+import QuestionModel from "../models/QuestionModel";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -150,15 +151,18 @@ export const useQuizService =  () => {
         }
     };
 
+
+
+
+
     const getCommunityQuiz = async (skip: number, take: number) => {
         try {
-            const response = await axios.get(`${url}/quiz/paginated?skip=${skip}&take=${take}`, {
+            const response = await axios.get<Quiz[]>(`${url}/quiz/paginated?skip=${skip}&take=${take}`, {
                 withCredentials: true, // Inclut les cookies pour une session authentifiée
             });
 
 
-            const quizzes: QuizModel[] = response.data.map((quiz: any) => transformToQuizModel(quiz));
-            return quizzes;
+            return response.data;
         } catch (error: any) {
 
             if (error.response) {
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 7782d71..1ec5fec 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -4,13 +4,13 @@ import TemplateMenu from "./TemplateMenu";
 import {NavigationProp} from "@react-navigation/native";
 import InputPlayQuiz from "../components/PlayQuiz/InputPlayQuiz";
 import QuizList from "../components/lists/QuizList";
-import QuizModel from "../models/QuizModel";
+import {QuizModel,Quiz} from "../models/QuizModel";
 
 interface Props {
     navigation: NavigationProp<any>
     title: string
     setTextInInput: (text: string) => void
-    quizList: QuizModel[] | null | undefined
+    quizList: Quiz[] | null | undefined
     buttonGoBack: boolean
     isLoadingData: boolean
 }
@@ -30,7 +30,7 @@ interface Props {
     navigation: NavigationProp<any>
     title: string
     setTextInInput: (text: string) => void
-    quizList: QuizModel[] | null | undefined
+    quizList: Quiz[] | null | undefined
     buttonGoBack: boolean
     isLoadingData: boolean
     nextPage?: () => void;
-- 
GitLab


From 1526a4acd7c8aba20d5293a7bfbd8e5147d0bcc5 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 18 Dec 2024 00:09:15 +0100
Subject: [PATCH 135/283] refactor: changing structure of models

---
 components/PlayQuiz/AboutAQuiz.tsx        |  8 +++---
 screens/EndQuiz/EndQuizChild.tsx          | 10 +++----
 screens/PlayQuiz/PlayQuizJoinQuiz.tsx     |  4 +--
 screens/PlayingQuiz/PlayingQuiz.tsx       |  6 ++---
 screens/PlayingQuiz/PlayingQuizBody.tsx   | 18 ++++++-------
 screens/PlayingQuiz/PlayingQuizHeader.tsx | 14 +++++-----
 services/QuizService.ts                   | 32 +++++++++--------------
 7 files changed, 43 insertions(+), 49 deletions(-)

diff --git a/components/PlayQuiz/AboutAQuiz.tsx b/components/PlayQuiz/AboutAQuiz.tsx
index 1e2249a..e396031 100644
--- a/components/PlayQuiz/AboutAQuiz.tsx
+++ b/components/PlayQuiz/AboutAQuiz.tsx
@@ -1,9 +1,9 @@
 import React from "react";
 import { View, Text, StyleSheet } from "react-native";
-import QuizModel from "../../models/QuizModel";
+import  {Quiz} from "../../models/QuizModel";
 
 interface Props {
-    quiz?: QuizModel;
+    quiz?: Quiz;
 }
 export default function AboutAQuiz({quiz} : Props) {
     return (
@@ -11,8 +11,8 @@ export default function AboutAQuiz({quiz} : Props) {
             <Text style={styles.title}>About this quiz</Text>
             <View style={styles.separator} />
             <View style={styles.infoContainer}>
-                <Text style={styles.text}>Category : {quiz ? quiz.category : "?"}</Text>
-                <Text style={styles.text}>Question : {quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
+                <Text style={styles.text}>Category : {quiz ? quiz.category?.name : "?"}</Text>
+                <Text style={styles.text}>Question : {quiz ? quiz.questionIndex : "?"}/{quiz ? quiz.questionCount : "?"}</Text>
                 <Text style={styles.text}>Score : {quiz ? quiz.score : "?"}</Text>
             </View>
 
diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index cdda848..39eb6ad 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -1,19 +1,19 @@
 import { View, Image, Text, StyleSheet } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { NavigationProp, RouteProp } from "@react-navigation/native";
-import QuizModel from "../../models/QuizModel";
+import {Quiz} from "../../models/QuizModel";
 
 
 
 interface Props {
     navigation: NavigationProp<any>;
-    quiz: QuizModel;
+    quiz: Quiz;
 }
 
 export default function EndQuizChild({ navigation, quiz }: Props) {
 
     const handleRestartPress = () => {
-        quiz.nbActualQuestion = 1;
+        quiz.questionIndex = 1;
         quiz.score = 0;
         navigation.reset({
             index: 0,
@@ -36,8 +36,8 @@ export default function EndQuizChild({ navigation, quiz }: Props) {
                 <Image source={require('../../assets/TitleApp.png')}/>
             </View>
             <View style={styles.containerBody}>
-                <Text style={styles.TextBodyTitle}>{((quiz.score/quiz.nbQuestions)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
-                <Text style={styles.TextBody}>you finish the test with a score of {`${quiz.score}/${quiz.nbQuestions}`} ! </Text>
+                <Text style={styles.TextBodyTitle}>{((quiz.score/quiz.questionCount)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
+                <Text style={styles.TextBody}>you finish the test with a score of {`${quiz.score}/${quiz.questionCount}`} ! </Text>
                 <Image source={require('../../assets/uWin.png')} />
                 {/*<DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>*/}
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
diff --git a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
index a1d2523..eaa763f 100644
--- a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -3,7 +3,7 @@ import AboutAQuiz from "../../components/PlayQuiz/AboutAQuiz";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
 import React, { useEffect } from "react";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import QuizModel from "../../models/QuizModel";
+import {Quiz} from "../../models/QuizModel";
 import { useQuizService } from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
 import {getIdOfCategory} from "../../helper/QuizHelper";
@@ -14,7 +14,7 @@ interface Props {
 }
 export default function PlayQuizJoinQuiz({navigation}: Props) {
     const [codeQuiz, setCodeQuiz] = React.useState("");
-    const [quiz, setQuiz] = React.useState<QuizModel>();
+    const [quiz, setQuiz] = React.useState<Quiz>();
     const [error, setError] = React.useState<string>("");
 
     const { remainingQuiz } = useQuizService();
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index e16dd84..7f413d9 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -3,7 +3,7 @@ import PlayingQuizHeader from "./PlayingQuizHeader";
 import {useEffect, useState} from "react";
 import TemplateDuo from "../../templates/TemplateDuo";
 import QuestionModel from "../../models/QuestionModel";
-import QuizModel from "../../models/QuizModel";
+import {Quiz} from "../../models/QuizModel";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
 import ConfirmModal from "../../components/PlayingQuiz/ComfirmModal";
 
@@ -25,7 +25,7 @@ const optionsTheme = [
 
 type RoutePropsType = {
     PlayingQuiz: {
-        quizRecovered: QuizModel;
+        quizRecovered: Quiz;
     };
 };
 
@@ -37,7 +37,7 @@ interface Props {
 export default function PlayingQuiz({route, navigation}:Props) {
     const {quizRecovered} = route.params;
     const [isAlreadyPlayed, setIsAlreadyPlayed] = useState(false);
-    const [quiz, setQuiz] = useState<QuizModel>(quizRecovered);
+    const [quiz, setQuiz] = useState<Quiz>(quizRecovered);
 
     return (
         <TemplateDuo
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index fff9677..fa256d4 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -2,7 +2,7 @@ import { View, StyleSheet, Text } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
 import { TextsStyles } from "../../styles/TextsStyles";
-import QuizModel from "../../models/QuizModel";
+import {Question, Quiz} from "../../models/QuizModel";
 import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
 import { useQuizService } from "../../services/QuizService";
 import QuestionModel from "../../models/QuestionModel";
@@ -12,8 +12,8 @@ import HttpError from "../../services/HttpError";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
 
 interface Props {
-    quiz: QuizModel;
-    setQuiz: Dispatch<SetStateAction<QuizModel>>;
+    quiz: Quiz;
+    setQuiz: Dispatch<SetStateAction<Quiz>>;
     isAlreadyPlayed: boolean;
     setIsAlreadyPlayed: (isAlreadyPlayed: boolean) => void;
     navigation: NavigationProp<any>;
@@ -63,7 +63,7 @@ const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number |
 }
 
 export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsAlreadyPlayed, navigation }: Props) {
-    const [currentQuestion, setCurrentQuestion] = useState<QuestionModel>(quiz.questions[quiz.nbActualQuestion - 1]);
+    const [currentQuestion, setCurrentQuestion] = useState<Question>(quiz.questions[quiz.questionIndex - 1]);
     const [questionIsFinished, setQuestionIsFinished] = useState(false);
     const [selectedAnswerId, setSelectedAnswerId] = useState<number | null>(null);
     const [validationButtonIsDisabled, setValidationButtonIsDisabled] = useState(true);
@@ -73,12 +73,12 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
     const {getAnswerQuiz} = useQuizService();
 
     useEffect(() => {
-        setCurrentQuestion(quiz.questions[quiz.nbActualQuestion - 1]);
+        setCurrentQuestion(quiz.questions[quiz.questionIndex - 1]);
         setSelectedAnswerId(null); // Réinitialise la sélection
         setQuestionIsFinished(false); // Réinitialise l'état de la question
         setCorrectAnswerId(null); // Réinitialise l'id de la bonne réponse
         setQuizState(QuizState.ANSWERING)
-    }, [quiz.nbActualQuestion]);
+    }, [quiz.questionIndex]);
 
     const getCorrectAnswer = (answers: AnswerModel[]): AnswerModel => {
         const correctAnswer = answers.find((answer) => answer.isCorrect);
@@ -89,7 +89,7 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
         setQuizState(QuizState.LOADING);
         const answerId = currentQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
         if(!answerId) return;
-        const answers = await getAnswerQuiz(quiz.code, currentQuestion.id, answerId);
+        const answers = await getAnswerQuiz(quiz.id, currentQuestion.id, answerId);
         if (HttpError.isHttpError(answers)) {
             return;
         }
@@ -105,13 +105,13 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
     };
 
     const onContinue = () => {
-        if (quiz.nbActualQuestion === quiz.questions.length) {
+        if (quiz.questionIndex === quiz.questions.length) {
             navigation.navigate("EndQuiz", {quiz: quiz});
             return;
         }
         setQuiz((prevQuiz) => ({
             ...prevQuiz,
-            nbActualQuestion: prevQuiz.nbActualQuestion + 1,
+            questionIndex: prevQuiz.questionIndex + 1,
         }));
     }
 
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index cb14415..581c895 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -1,6 +1,6 @@
 import { View, StyleSheet, Text } from "react-native";
 import { TextsStyles } from "../../styles/TextsStyles";
-import QuizModel from "../../models/QuizModel";
+import  {Quiz} from "../../models/QuizModel";
 import {useTranslation} from "react-i18next";
 import DefaultButton from "../../components/DefaultButton";
 import GoHomeButton from "../../components/PlayingQuiz/GoHomeButton";
@@ -10,7 +10,7 @@ import {useState} from "react";
 
 interface Props {
     navigation: NavigationProp<any>
-    quiz: QuizModel;
+    quiz: Quiz;
 }
 
 export default function PlayingQuizHeader({navigation, quiz}: Props) {
@@ -28,26 +28,26 @@ export default function PlayingQuizHeader({navigation, quiz}: Props) {
         });
     }
 
-    if (quiz.nbQuestions <= quiz.nbActualQuestion - 1) return;
+    if (quiz.questionCount <= quiz.questionIndex - 1) return;
 
     return (
             <View style={styles.container}>
                 <View style={styles.header}>
                     <GoHomeButton navigation={navigation} onPress={setIsConfirmModalVisible}/>
-                    <Text style={styles.codeQuizText}>ID QUIZZ : {quiz ? quiz.code : "?"}</Text>
+                    <Text style={styles.codeQuizText}>ID QUIZZ : {quiz ? quiz.id : "?"}</Text>
                 </View>
                 <View style={styles.questionAndScoreContainer}>
                     <View style={styles.InformationsContainer}>
                         <Text style={TextsStyles.titleText}>{t("app.screens.question.question")}</Text>
-                        <Text style={TextsStyles.titleText}>{quiz ? quiz.nbActualQuestion : "?"}/{quiz ? quiz.nbQuestions : "?"}</Text>
+                        <Text style={TextsStyles.titleText}>{quiz ? quiz.questionIndex : "?"}/{quiz ? quiz.questionCount : "?"}</Text>
                     </View>
                     <View style={styles.InformationsContainer}>
                         <Text style={TextsStyles.titleText}>{t("app.screens.question.score")}</Text>
-                        <Text style={TextsStyles.titleText}>{quiz ? quiz.score : 0}/{quiz ? quiz.nbQuestions : "?"}</Text>
+                        <Text style={TextsStyles.titleText}>{quiz ? quiz.score : 0}/{quiz ? quiz.questionCount : "?"}</Text>
                     </View>
                 </View>
                 <View style={styles.QuizQuestionContainer}>
-                    <Text style={TextsStyles.subtitleText}>{quiz.questions[quiz.nbActualQuestion-1].question ? quiz.questions[quiz.nbActualQuestion-1].question : "Loading..."}</Text>
+                    <Text style={TextsStyles.subtitleText}>{quiz.questions[quiz.questionIndex-1].text ? quiz.questions[quiz.questionIndex-1].text : "Loading..."}</Text>
                 </View>
                 <ConfirmModal visible={isConfirmModalVisible} onClose={()=>setIsConfirmModalVisible(false)} onConfirm={handleConfirmModalConfirm}/>
 
diff --git a/services/QuizService.ts b/services/QuizService.ts
index f83ab83..10405c1 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -2,14 +2,14 @@ import {EDifficulty} from "../models/EDifficulty";
 import {transformToAnswerModel, transformToQuizModel} from "../helper/QuizHelper";
 import AnswerModel from "../models/AnswerModel";
 import HttpError from "./HttpError";
-import {Quiz, QuizModel} from "../models/QuizModel";
+import {Answer, Quiz, QuizModel} from "../models/QuizModel";
 import axios from "axios";
 import QuestionModel from "../models/QuestionModel";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
 
-    const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<QuizModel | HttpError> => {
+    const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<Quiz | HttpError> => {
         const requestBody = {
             amount,
             category,
@@ -17,15 +17,14 @@ export const useQuizService =  () => {
         };
 
         try {
-            const response = await axios.post(`${url}/quiz/create`, requestBody, {
+            const response = await axios.post<Quiz>(`${url}/quiz/create`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
 
             // Récupération des données retournées par l'API
-            const quiz = transformToQuizModel(response.data);
-            return quiz;
+            return response.data;
         } catch (error: any) {
             console.error("Error while generating quiz:", error);
 
@@ -39,21 +38,20 @@ export const useQuizService =  () => {
         }
     }
 
-    const remainingQuiz = async (id: string): Promise<QuizModel | HttpError> => {
+    const remainingQuiz = async (id: string): Promise<Quiz | HttpError> => {
         const requestBody = {
             id,
         };
 
         try {
-            const response = await axios.post(`${url}/quiz/remaining`, requestBody, {
+            const response = await axios.post<Quiz>(`${url}/quiz/remaining`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
 
             // Récupération des données retournées par l'API
-            const quiz = transformToQuizModel(response.data);
-            return quiz;
+            return response.data;
         } catch (error: any) {
             console.error("Error while remaining quiz:", error);
 
@@ -71,7 +69,7 @@ export const useQuizService =  () => {
         codeQuiz: string,
         questionID: number,
         answerID: number
-    ): Promise<AnswerModel[] | HttpError> => {
+    ): Promise<Answer[] | HttpError> => {
         try {
             const requestBody = {
                 id: codeQuiz,
@@ -79,15 +77,13 @@ export const useQuizService =  () => {
                 answerID: answerID,
             };
 
-            const response = await axios.post(`${url}/quiz/answer`, requestBody, {
+            const response = await axios.post<Answer[]>(`${url}/quiz/answer`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
 
-            // Récupération des données retournées par l'API
-            const answers = transformToAnswerModel(response.data);
-            return answers;
+            return response.data;
         } catch (error: any) {
             console.error("Error while fetching answers:", error);
 
@@ -101,21 +97,19 @@ export const useQuizService =  () => {
         }
     };
 
-    const getRandomQuiz = async (): Promise<QuizModel | HttpError> => {
+    const getRandomQuiz = async (): Promise<Quiz | HttpError> => {
         try {
             const requestBody = {
                 amount: 10,
             };
 
-            const response = await axios.post(`${url}/quiz/create`, requestBody, {
+            const response = await axios.post<Quiz>(`${url}/quiz/create`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
 
-            // Récupération des données retournées par l'API
-            const quiz = transformToQuizModel(response.data);
-            return quiz;
+            return response.data;
         } catch (error: any) {
             console.error("Error while generating random quiz:", error);
 
-- 
GitLab


From d871734991b0dc36e45ebb45db0f34978f57cf74 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 18 Dec 2024 00:19:56 +0100
Subject: [PATCH 136/283] refactor: changing structure of models

---
 components/lists/QuizList.tsx                 |  2 +-
 screens/Community/Community.tsx               |  1 -
 screens/EndQuiz/EndQuiz.tsx                   |  4 +--
 .../InformationsOfQuiz/InformationsOfQuiz.tsx | 10 +++---
 screens/MyQuizzes/MyQuizzes.tsx               | 30 ++---------------
 screens/PlayingQuiz/PlayingQuiz.tsx           |  4 +--
 screens/PlayingQuiz/PlayingQuizBody.tsx       |  7 ++--
 services/QuizService.ts                       | 33 +------------------
 templates/TemplateQuizList.tsx                |  2 +-
 9 files changed, 15 insertions(+), 78 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 45ff335..66743eb 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -1,6 +1,6 @@
 import React from "react";
 import { FlatList, View, Text, StyleSheet, TouchableOpacity, ActivityIndicator } from "react-native";
-import {QuizModel, Quiz} from "../../models/QuizModel";
+import {Quiz} from "../../models/QuizModel";
 import { NavigationProp } from "@react-navigation/native";
 
 
diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index 772faf2..152b7f3 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -2,7 +2,6 @@ import {View, Text} from "react-native";
 import TemplateQuizList from "../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import {useEffect, useState} from "react";
-import {QuizModel} from "../../models/QuizModel";
 import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
diff --git a/screens/EndQuiz/EndQuiz.tsx b/screens/EndQuiz/EndQuiz.tsx
index 678fc88..6f997e3 100644
--- a/screens/EndQuiz/EndQuiz.tsx
+++ b/screens/EndQuiz/EndQuiz.tsx
@@ -2,11 +2,11 @@ import {NavigationProp, RouteProp} from "@react-navigation/native";
 import { View, StyleSheet, Image, Text } from "react-native";
 import EndQuizChild from "./EndQuizChild";
 import TemplateMenu from "../../templates/TemplateMenu";
-import QuizModel from "../../models/QuizModel";
+import {Quiz} from "../../models/QuizModel";
 
 type RoutePropsType = {
     EndQuizChild: {
-        quiz: QuizModel;
+        quiz: Quiz;
     };
 };
 interface Props {
diff --git a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
index ba5c5d0..faa6e90 100644
--- a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -2,11 +2,11 @@ import React from "react";
 import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
 import TemplateMenu from "../../templates/TemplateMenu";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
-import QuizModel from "../../models/QuizModel";
+import {Quiz} from "../../models/QuizModel";
 
 type RoutePropsType = {
     InformationsOfQuiz: {
-        quiz: QuizModel;
+        quiz: Quiz;
     };
 };
 interface Props {
@@ -24,12 +24,12 @@ export default function InformationsOfQuiz({ navigation, route }: Props) {
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
             <View style={styles.container}>
-                <Text style={styles.quizTitle}>{quiz.category}</Text>
-                <Text style={styles.quizDescription}>{quiz.category}</Text>
+                <Text style={styles.quizTitle}>{quiz.name}</Text>
+                <Text style={styles.quizDescription}>{quiz.category?.name}</Text>
 
                 <View style={styles.aboutContainer}>
                     <Text style={styles.aboutTitle}>About this quiz :</Text>
-                    <Text style={styles.aboutDetails}>{quiz.nbQuestions} questions</Text>
+                    <Text style={styles.aboutDetails}>{quiz.questionCount} questions</Text>
                     <Text style={styles.aboutDetails}>By : Unknown</Text>
                 </View>
 
diff --git a/screens/MyQuizzes/MyQuizzes.tsx b/screens/MyQuizzes/MyQuizzes.tsx
index d7916f2..02612ee 100644
--- a/screens/MyQuizzes/MyQuizzes.tsx
+++ b/screens/MyQuizzes/MyQuizzes.tsx
@@ -1,39 +1,13 @@
-import {View, Text} from "react-native";
 import TemplateQuizList from "../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import {useState} from "react";
-import QuizModel from "../../models/QuizModel";
+import {Quiz} from "../../models/QuizModel";
 
 interface Props {
     navigation: NavigationProp<any>
 }
 export default function MyQuizzes({navigation}: Props) {
-    const [quizList, setQuizList] = useState<QuizModel[] | null>([
-        {
-            code: "QUIZ123",
-            category: "General Knowledge",
-            questions: [],
-            nbQuestions: 3,
-            nbActualQuestion: 1,
-            score: 0,
-        },
-        {
-            code: "QUIZ456",
-            category: "Science",
-            questions: [],
-            nbQuestions: 5,
-            nbActualQuestion: 1,
-            score: 0,
-        },
-        {
-            code: "QUIZ789",
-            category: "Entertainment",
-            questions: [],
-            nbQuestions: 10,
-            nbActualQuestion: 1,
-            score: 0,
-        },
-    ])
+    const [quizList, setQuizList] = useState<Quiz[] | null>([]);
     const [input, setInput] = useState<string>("")
 
 
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 7f413d9..5749ba1 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -1,11 +1,9 @@
 import PlayingQuizBody from "./PlayingQuizBody";
 import PlayingQuizHeader from "./PlayingQuizHeader";
-import {useEffect, useState} from "react";
+import {useState} from "react";
 import TemplateDuo from "../../templates/TemplateDuo";
-import QuestionModel from "../../models/QuestionModel";
 import {Quiz} from "../../models/QuizModel";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
-import ConfirmModal from "../../components/PlayingQuiz/ComfirmModal";
 
 const optionsTheme = [
     "General Knowledge",
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index fa256d4..b65ac63 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -1,12 +1,9 @@
 import { View, StyleSheet, Text } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
-import { TextsStyles } from "../../styles/TextsStyles";
-import {Question, Quiz} from "../../models/QuizModel";
+import {Answer, Question, Quiz} from "../../models/QuizModel";
 import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
 import { useQuizService } from "../../services/QuizService";
-import QuestionModel from "../../models/QuestionModel";
-import AnswerModel from "../../models/AnswerModel";
 import {NavigationProp} from "@react-navigation/native";
 import HttpError from "../../services/HttpError";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
@@ -80,7 +77,7 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
         setQuizState(QuizState.ANSWERING)
     }, [quiz.questionIndex]);
 
-    const getCorrectAnswer = (answers: AnswerModel[]): AnswerModel => {
+    const getCorrectAnswer = (answers: Answer[]): Answer => {
         const correctAnswer = answers.find((answer) => answer.isCorrect);
         if (!correctAnswer) throw new Error("No correct answer found");
         return correctAnswer;
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 10405c1..37e1110 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -1,10 +1,6 @@
-import {EDifficulty} from "../models/EDifficulty";
-import {transformToAnswerModel, transformToQuizModel} from "../helper/QuizHelper";
-import AnswerModel from "../models/AnswerModel";
 import HttpError from "./HttpError";
-import {Answer, Quiz, QuizModel} from "../models/QuizModel";
+import {Answer, Quiz} from "../models/QuizModel";
 import axios from "axios";
-import QuestionModel from "../models/QuestionModel";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -123,32 +119,6 @@ export const useQuizService =  () => {
         }
     };
 
-    const getAllQuizzes = async (): Promise<QuizModel[] | HttpError> => {
-        try {
-            // Effectuer une requête GET pour récupérer les quizzes
-            const response = await axios.get(`${url}/quiz/all`, {
-                withCredentials: true, // Inclut les cookies pour une session authentifiée
-            });
-
-            // Transformation des données de chaque quiz en modèle QuizModel
-            const quizzes: QuizModel[] = response.data.map((quiz: any) => transformToQuizModel(quiz));
-
-            return quizzes;
-        } catch (error: any) {
-            console.error("Error while fetching all quizzes:", error);
-
-            if (error.response) {
-                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
-            } else {
-                return new HttpError(500, "Unexpected error: " + error.message);
-            }
-        }
-    };
-
-
-
-
-
     const getCommunityQuiz = async (skip: number, take: number) => {
         try {
             const response = await axios.get<Quiz[]>(`${url}/quiz/paginated?skip=${skip}&take=${take}`, {
@@ -173,7 +143,6 @@ export const useQuizService =  () => {
         getAnswerQuiz: getAnswerQuiz,
         remainingQuiz: remainingQuiz,
         getRandomQuiz: getRandomQuiz,
-        getAllQuizzes: getAllQuizzes,
         getCommunityQuiz: getCommunityQuiz
     }
 }
\ No newline at end of file
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 1ec5fec..a96db4c 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -4,7 +4,7 @@ import TemplateMenu from "./TemplateMenu";
 import {NavigationProp} from "@react-navigation/native";
 import InputPlayQuiz from "../components/PlayQuiz/InputPlayQuiz";
 import QuizList from "../components/lists/QuizList";
-import {QuizModel,Quiz} from "../models/QuizModel";
+import {Quiz} from "../models/QuizModel";
 
 interface Props {
     navigation: NavigationProp<any>
-- 
GitLab


From 74b67abed3a93c3b7e02b963dd8fb5bc6969c3c8 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 18 Dec 2024 00:25:22 +0100
Subject: [PATCH 137/283] refactor: rename models

---
 components/PlayQuiz/AboutAQuiz.tsx            |  2 +-
 components/lists/QuizList.tsx                 |  2 +-
 helper/QuizHelper.ts                          |  2 +-
 models/Answer.ts                              |  6 +++
 models/AnswerModel.ts                         |  6 ---
 models/Question.ts                            | 10 ++++
 models/QuestionModel.ts                       | 10 ----
 models/Quiz.ts                                | 26 ++++++++++
 models/QuizModel.ts                           | 50 -------------------
 screens/EndQuiz/EndQuiz.tsx                   |  2 +-
 screens/EndQuiz/EndQuizChild.tsx              |  2 +-
 .../InformationsOfQuiz/InformationsOfQuiz.tsx |  2 +-
 screens/MyQuizzes/MyQuizzes.tsx               |  2 +-
 screens/PlayQuiz/PlayQuizJoinQuiz.tsx         |  2 +-
 screens/PlayingQuiz/PlayingQuiz.tsx           |  2 +-
 screens/PlayingQuiz/PlayingQuizBody.tsx       |  4 +-
 screens/PlayingQuiz/PlayingQuizHeader.tsx     |  2 +-
 services/QuizService.ts                       |  2 +-
 templates/TemplateQuizList.tsx                |  2 +-
 19 files changed, 57 insertions(+), 79 deletions(-)
 create mode 100644 models/Answer.ts
 delete mode 100644 models/AnswerModel.ts
 create mode 100644 models/Question.ts
 delete mode 100644 models/QuestionModel.ts
 create mode 100644 models/Quiz.ts
 delete mode 100644 models/QuizModel.ts

diff --git a/components/PlayQuiz/AboutAQuiz.tsx b/components/PlayQuiz/AboutAQuiz.tsx
index e396031..94ae96e 100644
--- a/components/PlayQuiz/AboutAQuiz.tsx
+++ b/components/PlayQuiz/AboutAQuiz.tsx
@@ -1,6 +1,6 @@
 import React from "react";
 import { View, Text, StyleSheet } from "react-native";
-import  {Quiz} from "../../models/QuizModel";
+import  {Quiz} from "../../models/Quiz";
 
 interface Props {
     quiz?: Quiz;
diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 66743eb..5f5502b 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -1,6 +1,6 @@
 import React from "react";
 import { FlatList, View, Text, StyleSheet, TouchableOpacity, ActivityIndicator } from "react-native";
-import {Quiz} from "../../models/QuizModel";
+import {Quiz} from "../../models/Quiz";
 import { NavigationProp } from "@react-navigation/native";
 
 
diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index e201c6f..9285f26 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -1,6 +1,6 @@
 
 // Fonction utilitaire pour mélanger les réponses
-import {QuizModel} from "../models/QuizModel";
+import {QuizModel} from "../models/Quiz";
 import QuestionModel from "../models/QuestionModel";
 import AnswerModel from "../models/AnswerModel";
 
diff --git a/models/Answer.ts b/models/Answer.ts
new file mode 100644
index 0000000..9bc373e
--- /dev/null
+++ b/models/Answer.ts
@@ -0,0 +1,6 @@
+export interface Answer {
+    id: number;
+    text: string;
+    isCorrect?: boolean;
+    questionId: number;
+}
\ No newline at end of file
diff --git a/models/AnswerModel.ts b/models/AnswerModel.ts
deleted file mode 100644
index 4e66a15..0000000
--- a/models/AnswerModel.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export default interface AnswerModel {
-    id: number;
-    text: string;
-    isCorrect?: boolean;
-    questionId?: number;
-}
\ No newline at end of file
diff --git a/models/Question.ts b/models/Question.ts
new file mode 100644
index 0000000..a474b8a
--- /dev/null
+++ b/models/Question.ts
@@ -0,0 +1,10 @@
+import {Answer} from "./Answer";
+
+export interface Question {
+    id: number;
+    text: string;
+    categoryId: number;
+    quizId: string;
+    order: number;
+    answers: Answer[];
+}
\ No newline at end of file
diff --git a/models/QuestionModel.ts b/models/QuestionModel.ts
deleted file mode 100644
index a823f5b..0000000
--- a/models/QuestionModel.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import AnswerModel from "./AnswerModel";
-
-export default interface QuestionModel {
-    id: number;
-    question: string;
-    category?: string;
-    answers: AnswerModel[];
-    multiple: boolean;
-    nbOfTheQuestion: number;
-}
\ No newline at end of file
diff --git a/models/Quiz.ts b/models/Quiz.ts
new file mode 100644
index 0000000..d02f93a
--- /dev/null
+++ b/models/Quiz.ts
@@ -0,0 +1,26 @@
+import {Question} from "./Question";
+
+interface Difficulty {
+    id: number;
+    name: string;
+}
+
+interface Category {
+    id: number;
+    name: string;
+}
+
+export interface Quiz {
+    id: string;
+    name: string;
+    description: string;
+    score: number;
+    questionIndex: number;
+    questionCount: number;
+    categoryId: number;
+    difficultyId: number;
+    authorId: number,
+    category?: Category,
+    difficulty: Difficulty,
+    questions: Question[],
+}
\ No newline at end of file
diff --git a/models/QuizModel.ts b/models/QuizModel.ts
deleted file mode 100644
index 38d6cda..0000000
--- a/models/QuizModel.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import QuestionModel from "./QuestionModel";
-
-export interface QuizModel {
-    code: string;
-    category?: string;
-    questions: QuestionModel[];
-    nbQuestions: number;
-    nbActualQuestion: number;
-    score: number;
-}
-
-interface Difficulty {
-    id: number;
-    name: string;
-}
-
-interface Category {
-    id: number;
-    name: string;
-}
-
-export interface Answer {
-    id: number;
-    text: string;
-    isCorrect?: boolean;
-    questionId: number;
-}
-
-export interface Question {
-    id: number;
-    text: string;
-    categoryId: number;
-    quizId: string;
-    order: number;
-    answers: Answer[];
-}
-export interface Quiz {
-    id: string;
-    name: string;
-    description: string;
-    score: number;
-    questionIndex: number;
-    questionCount: number;
-    categoryId: number;
-    difficultyId: number;
-    authorId: number,
-    category?: Category,
-    difficulty: Difficulty,
-    questions: Question[],
-}
\ No newline at end of file
diff --git a/screens/EndQuiz/EndQuiz.tsx b/screens/EndQuiz/EndQuiz.tsx
index 6f997e3..ee5c5c5 100644
--- a/screens/EndQuiz/EndQuiz.tsx
+++ b/screens/EndQuiz/EndQuiz.tsx
@@ -2,7 +2,7 @@ import {NavigationProp, RouteProp} from "@react-navigation/native";
 import { View, StyleSheet, Image, Text } from "react-native";
 import EndQuizChild from "./EndQuizChild";
 import TemplateMenu from "../../templates/TemplateMenu";
-import {Quiz} from "../../models/QuizModel";
+import {Quiz} from "../../models/Quiz";
 
 type RoutePropsType = {
     EndQuizChild: {
diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index 39eb6ad..a1450a0 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -1,7 +1,7 @@
 import { View, Image, Text, StyleSheet } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { NavigationProp, RouteProp } from "@react-navigation/native";
-import {Quiz} from "../../models/QuizModel";
+import {Quiz} from "../../models/Quiz";
 
 
 
diff --git a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
index faa6e90..442776a 100644
--- a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -2,7 +2,7 @@ import React from "react";
 import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
 import TemplateMenu from "../../templates/TemplateMenu";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
-import {Quiz} from "../../models/QuizModel";
+import {Quiz} from "../../models/Quiz";
 
 type RoutePropsType = {
     InformationsOfQuiz: {
diff --git a/screens/MyQuizzes/MyQuizzes.tsx b/screens/MyQuizzes/MyQuizzes.tsx
index 02612ee..eb61204 100644
--- a/screens/MyQuizzes/MyQuizzes.tsx
+++ b/screens/MyQuizzes/MyQuizzes.tsx
@@ -1,7 +1,7 @@
 import TemplateQuizList from "../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import {useState} from "react";
-import {Quiz} from "../../models/QuizModel";
+import {Quiz} from "../../models/Quiz";
 
 interface Props {
     navigation: NavigationProp<any>
diff --git a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
index eaa763f..4493ce4 100644
--- a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
+++ b/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -3,7 +3,7 @@ import AboutAQuiz from "../../components/PlayQuiz/AboutAQuiz";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
 import React, { useEffect } from "react";
 import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import {Quiz} from "../../models/QuizModel";
+import {Quiz} from "../../models/Quiz";
 import { useQuizService } from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
 import {getIdOfCategory} from "../../helper/QuizHelper";
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 5749ba1..bcfe263 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -2,7 +2,7 @@ import PlayingQuizBody from "./PlayingQuizBody";
 import PlayingQuizHeader from "./PlayingQuizHeader";
 import {useState} from "react";
 import TemplateDuo from "../../templates/TemplateDuo";
-import {Quiz} from "../../models/QuizModel";
+import {Quiz} from "../../models/Quiz";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
 
 const optionsTheme = [
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index b65ac63..4d3a8d9 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -1,12 +1,14 @@
 import { View, StyleSheet, Text } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
-import {Answer, Question, Quiz} from "../../models/QuizModel";
 import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
 import { useQuizService } from "../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
 import HttpError from "../../services/HttpError";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
+import {Question} from "../../models/Question";
+import {Answer} from "../../models/Answer";
+import {Quiz} from "../../models/Quiz";
 
 interface Props {
     quiz: Quiz;
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 581c895..e2c5634 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -1,6 +1,6 @@
 import { View, StyleSheet, Text } from "react-native";
 import { TextsStyles } from "../../styles/TextsStyles";
-import  {Quiz} from "../../models/QuizModel";
+import  {Quiz} from "../../models/Quiz";
 import {useTranslation} from "react-i18next";
 import DefaultButton from "../../components/DefaultButton";
 import GoHomeButton from "../../components/PlayingQuiz/GoHomeButton";
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 37e1110..11c81f8 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -1,5 +1,5 @@
 import HttpError from "./HttpError";
-import {Answer, Quiz} from "../models/QuizModel";
+import {Answer, Quiz} from "../models/Quiz";
 import axios from "axios";
 
 export const useQuizService =  () => {
diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index a96db4c..61f2d8f 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -4,7 +4,7 @@ import TemplateMenu from "./TemplateMenu";
 import {NavigationProp} from "@react-navigation/native";
 import InputPlayQuiz from "../components/PlayQuiz/InputPlayQuiz";
 import QuizList from "../components/lists/QuizList";
-import {Quiz} from "../models/QuizModel";
+import {Quiz} from "../models/Quiz";
 
 interface Props {
     navigation: NavigationProp<any>
-- 
GitLab


From 2fea68ad9a265591921d0b6d6e6b542ab88b4114 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 18 Dec 2024 17:15:37 +0100
Subject: [PATCH 138/283] fix: answering question

---
 screens/PlayingQuiz/PlayingQuizBody.tsx |  1 +
 services/QuizService.ts                 | 14 +++++++++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 4d3a8d9..ad504db 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -85,6 +85,7 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
         return correctAnswer;
     };
     const onValidation = async () => {
+        if(selectedAnswerId === null) return;
         setQuizState(QuizState.LOADING);
         const answerId = currentQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
         if(!answerId) return;
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 11c81f8..34beecd 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -1,6 +1,7 @@
 import HttpError from "./HttpError";
-import {Answer, Quiz} from "../models/Quiz";
+import {Quiz} from "../models/Quiz";
 import axios from "axios";
+import {Answer} from "../models/Answer";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -73,13 +74,20 @@ export const useQuizService =  () => {
                 answerID: answerID,
             };
 
-            const response = await axios.post<Answer[]>(`${url}/quiz/answer`, requestBody, {
+            const response = await axios.post(`${url}/quiz/answer`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
 
-            return response.data;
+            const answers: Answer[] = response.data.answers.map((answer: any) => ({
+                id: answer.id,
+                text: answer.text,
+                isCorrect: answer.isCorrect,
+                questionId: answer.questionId,
+            }));
+
+            return answers;
         } catch (error: any) {
             console.error("Error while fetching answers:", error);
 
-- 
GitLab


From 5f4012e3c963535c3860342a9d2ade6395ca4b23 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 18 Dec 2024 22:58:59 +0100
Subject: [PATCH 139/283] feat: restart quiz in end quiz screen

---
 screens/EndQuiz/EndQuizChild.tsx | 26 +++++++++++++++++++++-----
 services/QuizService.ts          | 26 ++++++++++++++++++++++++--
 2 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/EndQuiz/EndQuizChild.tsx
index a1450a0..9d31713 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/EndQuiz/EndQuizChild.tsx
@@ -2,6 +2,8 @@ import { View, Image, Text, StyleSheet } from "react-native";
 import DefaultButton from "../../components/DefaultButton";
 import { NavigationProp, RouteProp } from "@react-navigation/native";
 import {Quiz} from "../../models/Quiz";
+import {useQuizService} from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
 
 
 
@@ -12,15 +14,29 @@ interface Props {
 
 export default function EndQuizChild({ navigation, quiz }: Props) {
 
-    const handleRestartPress = () => {
-        quiz.questionIndex = 1;
-        quiz.score = 0;
+    const {restartQuiz, remainingQuiz} = useQuizService()
+
+    const handleRestartPress = async () => {
+        const isRestarted = await restartQuiz(quiz.id);
+        if(HttpError.isHttpError(isRestarted)){
+            console.log(isRestarted.message);
+            return
+        }
+        if(!isRestarted) {
+            return;
+        }
+        const quizRestarted = await remainingQuiz(quiz.id);
+        if(HttpError.isHttpError(quizRestarted)){
+            console.log(quizRestarted.message);
+            return
+        }
+
         navigation.reset({
             index: 0,
             routes: [
                 {
                     name: "PlayingQuiz",
-                    params: {quiz: quiz},
+                    params: {quizRecovered: quizRestarted},
                 },
             ]
         });
@@ -39,7 +55,7 @@ export default function EndQuizChild({ navigation, quiz }: Props) {
                 <Text style={styles.TextBodyTitle}>{((quiz.score/quiz.questionCount)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
                 <Text style={styles.TextBody}>you finish the test with a score of {`${quiz.score}/${quiz.questionCount}`} ! </Text>
                 <Image source={require('../../assets/uWin.png')} />
-                {/*<DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>*/}
+                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
             </View>
         </View>
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 11c81f8..f7aa4a2 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -1,6 +1,7 @@
 import HttpError from "./HttpError";
-import {Answer, Quiz} from "../models/Quiz";
+import {Quiz} from "../models/Quiz";
 import axios from "axios";
+import {Answer} from "../models/Answer";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -137,12 +138,33 @@ export const useQuizService =  () => {
         }
     };
 
+    const restartQuiz = async (id: string) : Promise<boolean | HttpError> => {
+        try {
+            const requestBody = {
+                id
+            };
+
+            await axios.patch(`${url}/quiz/restart`, requestBody, {
+                withCredentials: true,
+            });
+
+            return true;
+        } catch (error: any) {
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message);
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
+
 
     return {
         generateQuiz: generateQuiz,
         getAnswerQuiz: getAnswerQuiz,
         remainingQuiz: remainingQuiz,
         getRandomQuiz: getRandomQuiz,
-        getCommunityQuiz: getCommunityQuiz
+        getCommunityQuiz: getCommunityQuiz,
+        restartQuiz: restartQuiz
     }
 }
\ No newline at end of file
-- 
GitLab


From c1ffdee65390f9e8af49c6a677c07dd0a4abd69a Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 19 Dec 2024 14:51:29 +0100
Subject: [PATCH 140/283] feat: restart quiz in end quiz screen

---
 helper/QuizHelper.ts    | 103 +++++++---------------------------------
 services/QuizService.ts |   7 +--
 2 files changed, 22 insertions(+), 88 deletions(-)

diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index 9285f26..e2ee3aa 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -1,88 +1,21 @@
-
-// Fonction utilitaire pour mélanger les réponses
-import {QuizModel} from "../models/Quiz";
-import QuestionModel from "../models/QuestionModel";
-import AnswerModel from "../models/AnswerModel";
-
-const optionsTheme = [
-    "General Knowledge",
-    "Entertainment: Books",
-    "Entertainment: Film",
-    "Entertainment: Music",
-    "Entertainment: Musicals & Theatres",
-    "Entertainment: Television",
-    "Entertainment: Video Games",
-    "Entertainment: Board Games",
-    "Science & Nature",
-    "Science: Computers",
-    "Science: Mathematics",
-    "Mythology",
-    "Sports",
-    "Geography"]
-
-const shuffleAnswers = (answers: string[]): string[] => {
-    for (let i = answers.length - 1; i > 0; i--) {
-        const j = Math.floor(Math.random() * (i + 1));
-        [answers[i], answers[j]] = [answers[j], answers[i]];
-    }
-    return answers;
-};
-
-// Cette méthode est utilisée quand on récupère les réponses d'une question
-export const transformToAnswerModel = (data: any): AnswerModel[] => {
-    const answers: AnswerModel[] = data.answers.map((answer: any) => {
-        return {
-            id: answer.id,
-            text: answer.text,
-            isCorrect: answer.isCorrect,
-            questionId: answer.questionId,
-        };
-    });
-    return answers;
-};
-
-export const transformToQuizModel = (data: any): QuizModel => {
-    // Transformation des questions
-    const questions: QuestionModel[] = data.questions.map((question: any) => {
-        // Transformation des réponses pour cette question
-        const answers: AnswerModel[] = question.answers.map((answer: any) => {
-            return {
-                id: answer.id,
-                text: answer.text,
-            };
-        });
-
-        return {
-            id: question.id,
-            question: question.text, // Texte de la question
-            category: "aa",
-            // category: question.category.name ? question.category.name : "Community Quizz", // Extraction du nom de la catégorie
-            answers: answers, // Réponses associées
-            multiple: question.type === "multiple", // Détermine si c'est une question multiple
-            nbOfTheQuestion: question.order, // Numéro de la question
-        };
-    });
-
-    // Création de l'objet QuizModel
-    const quiz: QuizModel = {
-        code: data.id, // Mapping de codeQuiz vers code
-        category: "aa",
-        // category: data.category.name ? data.category.name : "Community Quizz", // Extraction du nom de la catégorie
-        questions: questions, // Questions transformées
-        nbQuestions: data.questionCount, // Nombre total de questions
-        nbActualQuestion: data.questionIndex, // Index actuel de la question
-        score: data.score, // Score actuel
+import {Quiz} from "../models/Quiz";
+export const shuffleAnswersOfQuiz = (quiz: Quiz): Quiz => {
+    // Clone le quiz pour éviter de modifier l'original
+    const shuffledQuiz: Quiz = {
+        ...quiz,
+        questions: quiz.questions.map((question) => ({
+            ...question,
+            answers: [...question.answers], // Clone les réponses pour éviter de modifier l'original
+        })),
     };
 
-    return quiz;
-};
-
-
-export const getIdOfCategory = (category: string) => {
-    for (let i = 0; i < optionsTheme.length; i++) {
-        if (optionsTheme[i] === category) {
-            return i;
+    // Mélange les réponses de chaque question
+    shuffledQuiz.questions.forEach((question) => {
+        for (let i = question.answers.length - 1; i > 0; i--) {
+            const j = Math.floor(Math.random() * (i + 1));
+            [question.answers[i], question.answers[j]] = [question.answers[j], question.answers[i]];
         }
-    }
-    return 0;
-}
+    });
+
+    return shuffledQuiz;
+};
\ No newline at end of file
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 85573fd..17a2475 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -2,6 +2,7 @@ import HttpError from "./HttpError";
 import {Quiz} from "../models/Quiz";
 import axios from "axios";
 import {Answer} from "../models/Answer";
+import {shuffleAnswersOfQuiz} from "../helper/QuizHelper";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -21,7 +22,7 @@ export const useQuizService =  () => {
             });
 
             // Récupération des données retournées par l'API
-            return response.data;
+            return shuffleAnswersOfQuiz(response.data);
         } catch (error: any) {
             console.error("Error while generating quiz:", error);
 
@@ -48,7 +49,7 @@ export const useQuizService =  () => {
             });
 
             // Récupération des données retournées par l'API
-            return response.data;
+            return shuffleAnswersOfQuiz(response.data);
         } catch (error: any) {
             console.error("Error while remaining quiz:", error);
 
@@ -113,7 +114,7 @@ export const useQuizService =  () => {
                 },
             });
 
-            return response.data;
+            return shuffleAnswersOfQuiz(response.data);
         } catch (error: any) {
             console.error("Error while generating random quiz:", error);
 
-- 
GitLab


From 63dbab457c318f23df5311f2bc4d78e49bb6cdb3 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 19:12:29 +0100
Subject: [PATCH 141/283] feat: add multiplayer to tab nav

---
 routes/TabNavigation.tsx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index 834245c..65ddcdc 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -4,6 +4,7 @@ import Home from "../screens/Home/Home";
 import Icon from "react-native-vector-icons/MaterialIcons";
 import Profil from "../screens/Profil/Profil";
 import Community from "../screens/Community/Community";
+import Multiplayer from "../screens/Multiplayer/Multiplayer";
 
 const Tab = createBottomTabNavigator();
 
@@ -36,6 +37,9 @@ export default function TabNavigator() {
                     } else if (route.name === "Community") {
                         iconName = "people";
                     }
+                    else if (route.name === "Multiplayer") {
+                        iconName = "diversity-2";
+                    }
                     return <Icon name={iconName} size={64} color={color} />;
                 },
             })}
@@ -48,7 +52,10 @@ export default function TabNavigator() {
                 name="Community"
                 component={Community}
             />
-
+            <Tab.Screen
+                name="Multiplayer"
+                component={Multiplayer}
+            />
             <Tab.Screen
                 name="Profil"
                 component={Profil}
-- 
GitLab


From b6e0b2b26f1edf083b9a8fd10c3aeb521bbedd68 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 19:14:27 +0100
Subject: [PATCH 142/283] fix: error with name property of icon

---
 routes/TabNavigation.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index 65ddcdc..332a6cb 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -40,7 +40,7 @@ export default function TabNavigator() {
                     else if (route.name === "Multiplayer") {
                         iconName = "diversity-2";
                     }
-                    return <Icon name={iconName} size={64} color={color} />;
+                    return <Icon name={iconName ?? ''} size={64} color={color} />;
                 },
             })}
         >
-- 
GitLab


From 5aa2121f54193a2615379ddab54e364249432c23 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 19:24:42 +0100
Subject: [PATCH 143/283] feat: add multiplayer to stack nav

---
 routes/StackNavigator.tsx | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index cbfdc43..3c3c037 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -8,6 +8,7 @@ import TabNavigator from "./TabNavigation";
 import PlayQuiz from "../screens/PlayQuiz/PlayQuiz";
 import MyQuizzes from "../screens/MyQuizzes/MyQuizzes";
 import InformationsOfQuiz from "../screens/InformationsOfQuiz/InformationsOfQuiz";
+import Multiplayer from "../screens/Multiplayer/Multiplayer";
 
 const Stack = createNativeStackNavigator();
 
@@ -23,6 +24,8 @@ export default function StackNavigator() {
                 <Stack.Screen name="EndQuiz" component={EndQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="MyQuizzes" component={MyQuizzes} options={{ headerShown: false }}/>
                 <Stack.Screen name="InformationsOfQuiz" component={InformationsOfQuiz} options={{ headerShown: false }}/>
+
+                <Stack.Screen name="Multiplayer" component={Multiplayer} options={{ headerShown: false }}/>
             </Stack.Navigator>
         </NavigationContainer>
     );
-- 
GitLab


From 6fa822cb6514a4f56cfc7a3b96265479343658a5 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 19:41:59 +0100
Subject: [PATCH 144/283] feat: multiplayer screen

---
 screens/Multiplayer/Multiplayer.tsx      | 29 +++++++++
 screens/Multiplayer/MultiplayerChild.tsx | 79 ++++++++++++++++++++++++
 2 files changed, 108 insertions(+)
 create mode 100644 screens/Multiplayer/Multiplayer.tsx
 create mode 100644 screens/Multiplayer/MultiplayerChild.tsx

diff --git a/screens/Multiplayer/Multiplayer.tsx b/screens/Multiplayer/Multiplayer.tsx
new file mode 100644
index 0000000..4b40687
--- /dev/null
+++ b/screens/Multiplayer/Multiplayer.tsx
@@ -0,0 +1,29 @@
+import { NavigationProp } from "@react-navigation/native";
+import { View, StyleSheet } from "react-native";
+import TemplateMenu from "../../templates/TemplateMenu";
+import MultiplayerChild from "./MultiplayerChild";
+
+interface Props {
+    navigation: NavigationProp<any>;
+}
+
+export default function Home({navigation}: Props) {
+    return (
+        <View style={styles.containerGlobal}>
+                <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}>
+                    <View>
+                        <MultiplayerChild navigation={navigation}/>
+                    </View>
+                </TemplateMenu>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        flexDirection: 'column',
+    },
+});
\ No newline at end of file
diff --git a/screens/Multiplayer/MultiplayerChild.tsx b/screens/Multiplayer/MultiplayerChild.tsx
new file mode 100644
index 0000000..be9843a
--- /dev/null
+++ b/screens/Multiplayer/MultiplayerChild.tsx
@@ -0,0 +1,79 @@
+import { View, StyleSheet, Image, Modal, TextInput } from "react-native";
+import DefaultButton from "../../components/DefaultButton";
+import {useTranslation} from "react-i18next";
+import { useState } from "react";
+import { TextsStyles } from "../../styles/TextsStyles";
+import ModalJoinQuiz from "../../components/ModalJoinQuiz";
+import MenuButton from "../../components/buttons/MenuButton";
+import {NavigationProp} from "@react-navigation/native";
+import {useQuizService} from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
+
+interface Props {
+    navigation: NavigationProp<any>;
+}
+
+/**
+ * HomeChild : Enfant de l'écran Home, il contient le menu principal
+ * @param navigation - navigation
+ */
+export default function MultiplayerChild({navigation}: Props) {
+    const [modalVisible, setModalVisible] = useState(false);
+    const {t} = useTranslation();
+
+    const handleButtonCommunityPressed = async () => {
+        navigation.navigate("MultiplayerCommunity");
+    }
+    
+    const handleOnlineQuizPressed = () => {
+        navigation.navigate("OnlineQuiz");
+    }
+
+    const handleButtonOngoingQuizzesPressed = () => {
+        navigation.navigate("OngoingQuizzes");
+    }
+
+    return (
+        <View style={styles.containerGlobal}>
+            <View style={styles.imageContainer}>
+                <Image source={require('../../assets/TitleApp.png')} style={styles.image} />
+            </View>
+            <View style={styles.buttonContainer}>
+                <MenuButton text={"COMMUNITY"} handleButtonPressed={handleButtonCommunityPressed}/>
+                <MenuButton text={"PLAY AN ONLINE QUIZ"} handleButtonPressed={handleOnlineQuizPressed}/>
+                <MenuButton text={"ONGOING QUIZZES"} handleButtonPressed={handleButtonOngoingQuizzesPressed}/>
+            </View>
+             <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        justifyContent: 'flex-start',
+        alignItems: 'center',
+    },
+    image: {
+    },
+    button: {
+        borderRadius: 40,
+        height: '35%',
+        marginTop: '5%'
+    },
+    imageContainer: {
+        display: 'flex',
+        alignItems: 'center',
+        marginTop: '15%',
+        marginBottom: '25%',
+    },
+    buttonContainer: {
+        width: '100%',
+        display: 'flex',
+        flexDirection: 'column',
+        paddingLeft: '8%',
+        gap: '9%',
+    }
+});
\ No newline at end of file
-- 
GitLab


From 65560ce941027d62c949afd46baf3d4d461a31e6 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 20:05:48 +0100
Subject: [PATCH 145/283] feat: add multiplayer community to stack nav

---
 routes/StackNavigator.tsx                       |  7 +++++++
 .../MultiplayerCommunity.tsx                    | 17 +++++++++++++++++
 2 files changed, 24 insertions(+)
 create mode 100644 screens/MultiplayerCommunity/MultiplayerCommunity.tsx

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 3c3c037..bb4c2a2 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -9,6 +9,9 @@ import PlayQuiz from "../screens/PlayQuiz/PlayQuiz";
 import MyQuizzes from "../screens/MyQuizzes/MyQuizzes";
 import InformationsOfQuiz from "../screens/InformationsOfQuiz/InformationsOfQuiz";
 import Multiplayer from "../screens/Multiplayer/Multiplayer";
+import MultiplayerCommunity from "../screens/MultiplayerCommunity/MultiplayerCommunity";
+import OnlineQuiz from "../screens/OnlineQuiz/OnlineQuiz";
+import OngoingQuizzes from "../screens/OngoingQuizzes/OngoingQuizzes";
 
 const Stack = createNativeStackNavigator();
 
@@ -26,6 +29,10 @@ export default function StackNavigator() {
                 <Stack.Screen name="InformationsOfQuiz" component={InformationsOfQuiz} options={{ headerShown: false }}/>
 
                 <Stack.Screen name="Multiplayer" component={Multiplayer} options={{ headerShown: false }}/>
+                <Stack.Screen name="MultiplayerCommunity" component={MultiplayerCommunity} options={{ headerShown: false }}/>
+                <Stack.Screen name="OnlineQuiz" component={OnlineQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="OngoingQuizzes" component={OngoingQuizzes} options={{ headerShown: false }}/>
+                
             </Stack.Navigator>
         </NavigationContainer>
     );
diff --git a/screens/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
new file mode 100644
index 0000000..21d8772
--- /dev/null
+++ b/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -0,0 +1,17 @@
+import { View, Text, StyleSheet } from "react-native";
+
+export default function MultiplayerCommunity() {
+    return (
+        <View style={styles.container}>
+            <Text>MultiplayerCommunity</Text>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        justifyContent: 'center',
+        alignItems: 'center',
+    }
+});
\ No newline at end of file
-- 
GitLab


From 0b49513a7491ef35d922c269d1105a32fb442509 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 20:06:19 +0100
Subject: [PATCH 146/283] feat: add onlinequiz to staack nav

---
 routes/StackNavigator.tsx         |  1 -
 screens/OnlineQuiz/OnlineQuiz.tsx | 17 +++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 screens/OnlineQuiz/OnlineQuiz.tsx

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index bb4c2a2..6531506 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -31,7 +31,6 @@ export default function StackNavigator() {
                 <Stack.Screen name="Multiplayer" component={Multiplayer} options={{ headerShown: false }}/>
                 <Stack.Screen name="MultiplayerCommunity" component={MultiplayerCommunity} options={{ headerShown: false }}/>
                 <Stack.Screen name="OnlineQuiz" component={OnlineQuiz} options={{ headerShown: false }}/>
-                <Stack.Screen name="OngoingQuizzes" component={OngoingQuizzes} options={{ headerShown: false }}/>
                 
             </Stack.Navigator>
         </NavigationContainer>
diff --git a/screens/OnlineQuiz/OnlineQuiz.tsx b/screens/OnlineQuiz/OnlineQuiz.tsx
new file mode 100644
index 0000000..cd2dab7
--- /dev/null
+++ b/screens/OnlineQuiz/OnlineQuiz.tsx
@@ -0,0 +1,17 @@
+import { View, Text, StyleSheet } from "react-native";
+
+export default function OnlineQuiz() {
+    return (
+        <View style={styles.container}>
+            <Text>OnlineQuiz</Text>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        justifyContent: 'center',
+        alignItems: 'center',
+    }
+});
\ No newline at end of file
-- 
GitLab


From 3fabb386c3f8cde1ea818d2cfa0d6c9a3ecfe39b Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 20:06:38 +0100
Subject: [PATCH 147/283] feat: add ongoingquizzes to nav

---
 routes/StackNavigator.tsx                 |  1 +
 screens/OngoingQuizzes/OngoingQuizzes.tsx | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 screens/OngoingQuizzes/OngoingQuizzes.tsx

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 6531506..bb4c2a2 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -31,6 +31,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="Multiplayer" component={Multiplayer} options={{ headerShown: false }}/>
                 <Stack.Screen name="MultiplayerCommunity" component={MultiplayerCommunity} options={{ headerShown: false }}/>
                 <Stack.Screen name="OnlineQuiz" component={OnlineQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="OngoingQuizzes" component={OngoingQuizzes} options={{ headerShown: false }}/>
                 
             </Stack.Navigator>
         </NavigationContainer>
diff --git a/screens/OngoingQuizzes/OngoingQuizzes.tsx b/screens/OngoingQuizzes/OngoingQuizzes.tsx
new file mode 100644
index 0000000..191ae5f
--- /dev/null
+++ b/screens/OngoingQuizzes/OngoingQuizzes.tsx
@@ -0,0 +1,17 @@
+import { View, StyleSheet, Text } from "react-native";
+
+export default function OngoingQuizzes() {
+    return (
+        <View style={styles.container}>
+            <Text>OngoingQuizzes</Text>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        justifyContent: 'center',
+        alignItems: 'center',
+    }
+});
\ No newline at end of file
-- 
GitLab


From b6007e12aade976a2eec833be83eec671b12ade2 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 21:08:32 +0100
Subject: [PATCH 148/283] feat: modify onlineQuiz to use templateMenu

---
 screens/OnlineQuiz/OnlineQuiz.tsx | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/screens/OnlineQuiz/OnlineQuiz.tsx b/screens/OnlineQuiz/OnlineQuiz.tsx
index cd2dab7..76c45c3 100644
--- a/screens/OnlineQuiz/OnlineQuiz.tsx
+++ b/screens/OnlineQuiz/OnlineQuiz.tsx
@@ -1,17 +1,28 @@
-import { View, Text, StyleSheet } from "react-native";
+import { NavigationProp } from "@react-navigation/native";
+import { View, StyleSheet } from "react-native";
+import TemplateMenu from "../../templates/TemplateMenu";
+import OnlineQuizChild from "./OnlineQuizChild";
 
-export default function OnlineQuiz() {
+interface Props{
+    navigation: NavigationProp<any>
+}
+export default function OnlineQuiz({navigation}: Props) {
     return (
-        <View style={styles.container}>
-            <Text>OnlineQuiz</Text>
+        <View style={styles.containerGlobal}>
+            <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
+                <View>
+                    <OnlineQuizChild navigation={navigation}/>
+                </View>
+            </TemplateMenu>
         </View>
-    );
+    )
 }
 
 const styles = StyleSheet.create({
-    container: {
-        flex: 1,
-        justifyContent: 'center',
-        alignItems: 'center',
-    }
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        flexDirection: 'column',
+    },
 });
\ No newline at end of file
-- 
GitLab


From 8f65af87d283da5a3c7df5613e4e34b3deeb492c Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Fri, 27 Dec 2024 21:25:42 +0100
Subject: [PATCH 149/283] feat:  create onlineQuizChild in copy of
 PlayQuizChild

---
 screens/OnlineQuiz/OnlineQuizChild.tsx | 44 ++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 screens/OnlineQuiz/OnlineQuizChild.tsx

diff --git a/screens/OnlineQuiz/OnlineQuizChild.tsx b/screens/OnlineQuiz/OnlineQuizChild.tsx
new file mode 100644
index 0000000..d131af2
--- /dev/null
+++ b/screens/OnlineQuiz/OnlineQuizChild.tsx
@@ -0,0 +1,44 @@
+import { NavigationProp } from "@react-navigation/native";
+import { useState } from "react";
+import { SelectModeType } from "../../models/SelectModeType";
+import { TouchableWithoutFeedback, View, StyleSheet, Keyboard } from "react-native";
+import SelectMode from "../../components/PlayQuiz/SelectMode";
+import PlayQuizGenerateQuiz from "../PlayQuiz/PlayQuizGenerateQuiz";
+import PlayQuizJoinQuiz from "../PlayQuiz/PlayQuizJoinQuiz";
+
+interface Props {
+    navigation: NavigationProp<any>
+}
+
+export default function OnlineQuizChild({navigation}: Props){
+ const [mode, setMode] = useState<SelectModeType>("play");
+
+    return (
+        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
+            <View style={styles.containerGlobal}>
+                <View style={styles.contentContainer}>
+                    <SelectMode mode={mode} setMode={setMode}/>
+                    {mode === "play" ? (
+                        <PlayQuizGenerateQuiz navigation={navigation}/>
+                    ) : (
+                        <PlayQuizJoinQuiz navigation={navigation}/>
+                    )}
+                </View>
+            </View>
+        </TouchableWithoutFeedback>
+    )
+}
+const styles = StyleSheet.create({
+    containerGlobal: {
+        width: '100%',
+        height: '100%',
+        alignItems: 'center',
+        justifyContent: 'center',
+    },
+    contentContainer: {
+        display: 'flex',
+        width: '95%',
+        height: '100%',
+        flexDirection: 'column',
+    },
+});
\ No newline at end of file
-- 
GitLab


From c00baa1e60a371a21e446088da2742c8dd0588cf Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 28 Dec 2024 18:21:35 +0100
Subject: [PATCH 150/283] feat: add onlineSelectMode

---
 models/SelectModeType.ts                |  3 +-
 screens/OnlineQuiz/OnlineSelectMode.tsx | 74 +++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 screens/OnlineQuiz/OnlineSelectMode.tsx

diff --git a/models/SelectModeType.ts b/models/SelectModeType.ts
index 8c155fa..826e0b8 100644
--- a/models/SelectModeType.ts
+++ b/models/SelectModeType.ts
@@ -1,2 +1,3 @@
 export type SelectModeType = "play" | "join";
-export type ProfilSelectModeType = "login" | "signup";
\ No newline at end of file
+export type ProfilSelectModeType = "login" | "signup";
+export type OnlineSelectModeType = "create" | "join";
\ No newline at end of file
diff --git a/screens/OnlineQuiz/OnlineSelectMode.tsx b/screens/OnlineQuiz/OnlineSelectMode.tsx
new file mode 100644
index 0000000..8275f69
--- /dev/null
+++ b/screens/OnlineQuiz/OnlineSelectMode.tsx
@@ -0,0 +1,74 @@
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import { OnlineSelectModeType } from "../../models/SelectModeType";
+
+interface Props {
+    mode: OnlineSelectModeType;
+    setMode: (mode: OnlineSelectModeType) => void;
+}
+
+export default function OnlineSelectMode({ mode, setMode }: Props) {
+    return (
+        <View style={styles.container}>
+            <View style={styles.buttonContainer}>
+                <TouchableOpacity onPress={() => setMode("create")} style={{marginLeft: '10%'}}>
+                    <Text style={[styles.text, mode === "create" && styles.activeText]}>CREATE A LOBBY</Text>
+                </TouchableOpacity>
+                <View style={[styles.bar, mode === "create" ? styles.activeBar : styles.inactiveBar]} />
+            </View>
+
+            <View style={styles.buttonContainer}>
+                <TouchableOpacity onPress={() => setMode("join")} style={{marginRight: '10%'}}>
+                    <Text style={[styles.text, mode === "join" && styles.activeText]}>JOIN A QUIZ</Text>
+                </TouchableOpacity>
+                <View style={[styles.bar, mode === "join" ? styles.activeBar : styles.inactiveBar]} />
+            </View>
+
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: 'flex',
+        width: '100%',
+        height: '15%',
+        flexDirection: 'row',
+        backgroundColor: '#f3f3f3',
+        borderRadius: 10,
+        justifyContent: 'space-around',
+        alignItems: 'center',
+        // Ombre pour Android
+        elevation: 5,
+        // Ombre pour iOS
+        shadowColor: '#000',
+        shadowOffset: { width: 0, height: 4 }, // Décalage de l'ombre en bas
+        shadowOpacity: 0.25, // Opacité de l'ombre
+        shadowRadius: 3.84, // Flou de l'ombre
+    },
+    buttonContainer: {
+        display: 'flex',
+        flexDirection: 'column',
+        width: '40%',
+        alignItems: 'center',
+        gap: "5%",
+    },
+    text: {
+        fontSize: 25,
+        color: '#bebebe',
+    },
+    activeText: {
+        color: '#2b73fe',
+    },
+    bar: {
+        width: '100%',
+        height: '4%',
+        marginTop: '4%',
+        borderRadius: 10,
+    },
+    activeBar: {
+        backgroundColor: '#2b73fe', // Couleur pour le bouton actif
+    },
+    inactiveBar: {
+        backgroundColor: '#bebebe', // Couleur grise pour les boutons inactifs
+    },
+});
-- 
GitLab


From e1103c2abfa4f9d37993d6be860fb3df96f215d5 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 28 Dec 2024 18:22:05 +0100
Subject: [PATCH 151/283] feat: add select mode and onlineCreateLobby

---
 screens/OnlineQuiz/OnlineCreateLobby.tsx | 107 +++++++++++++++++++++++
 screens/OnlineQuiz/OnlineQuizChild.tsx   |  14 +--
 2 files changed, 114 insertions(+), 7 deletions(-)
 create mode 100644 screens/OnlineQuiz/OnlineCreateLobby.tsx

diff --git a/screens/OnlineQuiz/OnlineCreateLobby.tsx b/screens/OnlineQuiz/OnlineCreateLobby.tsx
new file mode 100644
index 0000000..95f7a94
--- /dev/null
+++ b/screens/OnlineQuiz/OnlineCreateLobby.tsx
@@ -0,0 +1,107 @@
+import { Text,View, StyleSheet } from "react-native";
+import SelectListBox from "../../components/PlayQuiz/SelectListBox";
+import React, {useEffect} from "react";
+import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import BlueButton from "../../components/PlayQuiz/BlueButton";
+import {getIdOfCategory} from "../../helper/QuizHelper";
+import {useQuizService} from "../../services/QuizService";
+import {NavigationProp} from "@react-navigation/native";
+
+const difficulty = [
+    { key: "easy", value: "easy" },
+    { key: "medium", value: "medium" },
+    { key: "hard", value: "hard" },
+];
+
+const categories = [
+    { key: "9", value: "General Knowledge"},
+    { key: "10", value: "Entertainment: Books" },
+    { key: "11", value: "Entertainment: Film" },
+    { key: "12", value: "Entertainment: Music"},
+    { key: "13", value: "Entertainment: Musicals & Theatres" },
+    { key: "14", value: "Entertainment: Television" },
+    { key: "15", value: "Entertainment: Video Games" },
+    { key: "16", value: "Entertainment: Board Games" },
+    { key: "17", value: "Science & Nature" },
+    { key: "18", value: "Science: Computers" },
+    { key: "19", value: "Science: Mathematics" },
+    { key: "20", value: "Mythology" },
+    { key: "21", value: "Sports" },
+    { key: "22", value: "Geography" },
+];
+interface Props {
+    navigation: NavigationProp<any>;
+}
+
+export default function OnlineCreateLobby({navigation}: Props) {
+    const [difficutlyChoose, setDifficutlyChoose] = React.useState("");
+    const [categoryChoose, setCategoryChoose] = React.useState("");
+    const [nbQuestions, setNbQuestions] = React.useState("10");
+    const [buttonIsDisabled, setButtonIsDisabled] = React.useState(true);
+    const {generateQuiz} = useQuizService();
+
+    useEffect(() => {
+        if(nbQuestions === "" || difficutlyChoose === "" || categoryChoose === "")
+        {
+            setButtonIsDisabled(true);
+        }
+        else
+        {
+            setButtonIsDisabled(false);
+        }
+
+    }, [difficutlyChoose,categoryChoose,nbQuestions]);
+
+    const handlePlayButtonPress = async () => {
+        const quizGenerated = await generateQuiz(parseInt(nbQuestions), getIdOfCategory(categoryChoose), difficutlyChoose);
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quizRecovered: quizGenerated},
+                },
+            ]
+        });
+    };
+
+    return (
+        <View style={styles.container}>
+            <View style={styles.contentContainer}>
+                <View style={styles.fieldContainer}>
+                    <SelectListBox title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
+                    <SelectListBox title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
+                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} defaultValue={nbQuestions}/>
+                </View>
+                <View style={styles.buttonPlayContainer}>
+                    <BlueButton onPress={handlePlayButtonPress} text={"CREATE LOBBY"} isDisabled={buttonIsDisabled}/>
+                </View>
+            </View>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        width: "100%",
+        height: "75%",
+        justifyContent: "space-between",
+    },
+    contentContainer: {
+        flex: 1, // Prend toute la hauteur disponible
+        flexDirection: "column",
+        justifyContent: "space-between",
+    },
+    fieldContainer: {
+        width: "100%",
+        flexDirection: "column",
+        justifyContent: "space-between",
+        marginTop: 20,
+        gap: 20,
+    },
+    buttonPlayContainer: {
+        alignItems: "center",
+        paddingVertical: 20,
+    },
+});
diff --git a/screens/OnlineQuiz/OnlineQuizChild.tsx b/screens/OnlineQuiz/OnlineQuizChild.tsx
index d131af2..f77ad6d 100644
--- a/screens/OnlineQuiz/OnlineQuizChild.tsx
+++ b/screens/OnlineQuiz/OnlineQuizChild.tsx
@@ -1,25 +1,25 @@
 import { NavigationProp } from "@react-navigation/native";
 import { useState } from "react";
-import { SelectModeType } from "../../models/SelectModeType";
+import { OnlineSelectModeType, SelectModeType } from "../../models/SelectModeType";
 import { TouchableWithoutFeedback, View, StyleSheet, Keyboard } from "react-native";
-import SelectMode from "../../components/PlayQuiz/SelectMode";
-import PlayQuizGenerateQuiz from "../PlayQuiz/PlayQuizGenerateQuiz";
 import PlayQuizJoinQuiz from "../PlayQuiz/PlayQuizJoinQuiz";
+import OnlineSelectMode from "./OnlineSelectMode";
+import OnlineCreateLobby from "./OnlineCreateLobby";
 
 interface Props {
     navigation: NavigationProp<any>
 }
 
 export default function OnlineQuizChild({navigation}: Props){
- const [mode, setMode] = useState<SelectModeType>("play");
+ const [mode, setMode] = useState<OnlineSelectModeType>("create");
 
     return (
         <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
             <View style={styles.containerGlobal}>
                 <View style={styles.contentContainer}>
-                    <SelectMode mode={mode} setMode={setMode}/>
-                    {mode === "play" ? (
-                        <PlayQuizGenerateQuiz navigation={navigation}/>
+                    <OnlineSelectMode mode={mode} setMode={setMode}/>
+                    {mode === "create" ? (
+                        <OnlineCreateLobby navigation={navigation}/>
                     ) : (
                         <PlayQuizJoinQuiz navigation={navigation}/>
                     )}
-- 
GitLab


From 6af1638a00b41c065e4d5c08d6242ffa49f00962 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 28 Dec 2024 18:27:35 +0100
Subject: [PATCH 152/283] feat: add online play quiz

---
 screens/OnlineQuiz/OnlinePlayQuiz.tsx  | 97 ++++++++++++++++++++++++++
 screens/OnlineQuiz/OnlineQuizChild.tsx |  4 +-
 2 files changed, 99 insertions(+), 2 deletions(-)
 create mode 100644 screens/OnlineQuiz/OnlinePlayQuiz.tsx

diff --git a/screens/OnlineQuiz/OnlinePlayQuiz.tsx b/screens/OnlineQuiz/OnlinePlayQuiz.tsx
new file mode 100644
index 0000000..48f212f
--- /dev/null
+++ b/screens/OnlineQuiz/OnlinePlayQuiz.tsx
@@ -0,0 +1,97 @@
+import { StyleSheet, View, Text } from "react-native";
+import AboutAQuiz from "../../components/PlayQuiz/AboutAQuiz";
+import BlueButton from "../../components/PlayQuiz/BlueButton";
+import React, { useEffect } from "react";
+import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import {Quiz} from "../../models/Quiz";
+import { useQuizService } from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
+import {getIdOfCategory} from "../../helper/QuizHelper";
+import {NavigationProp} from "@react-navigation/native";
+
+interface Props {
+    navigation: NavigationProp<any>;
+}
+export default function OnlinePlayQuiz({navigation}: Props) {
+    const [codeQuiz, setCodeQuiz] = React.useState("");
+    const [quiz, setQuiz] = React.useState<Quiz>();
+    const [error, setError] = React.useState<string>("");
+
+    const { remainingQuiz } = useQuizService();
+
+    useEffect(() => {
+        fetchQuiz();
+    }, [codeQuiz]);
+
+    const fetchQuiz = async () => {
+        if(codeQuiz === "")
+        {
+            return;
+        }
+        const quizFetched = await remainingQuiz(codeQuiz);
+        if (quizFetched instanceof HttpError) {
+            setError("The quiz does not exist");
+            return;
+        }
+        setError("");
+        setQuiz(quizFetched);
+    };
+
+    const handlePlayButtonPress = () => {
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quizRecovered: quiz},
+                },
+            ]
+        });
+    };
+
+    return (
+        <View style={styles.container}>
+            <View style={styles.contentContainer}>
+                <View style={styles.fieldContainer}>
+                    {error ? <Text style={styles.errorText}>{error}</Text> : null}
+                    <InputPlayQuiz placeholder={"Enter quiz ID"} setText={setCodeQuiz} noTitle={true} />
+                    <AboutAQuiz quiz={quiz} />
+                </View>
+                <View style={styles.buttonPlayContainer}>
+                    <BlueButton onPress={handlePlayButtonPress} text={"JOIN"} isDisabled={codeQuiz==="" || error!==""}/>
+                </View>
+            </View>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        width: "100%",
+        height: "75%",
+        justifyContent: "space-between",
+    },
+    contentContainer: {
+        flex: 1, // Prend toute la hauteur disponible
+        flexDirection: "column",
+        justifyContent: "space-between",
+    },
+    fieldContainer: {
+        width: "100%",
+        flexDirection: "column",
+        justifyContent: "space-between",
+        marginTop: 20,
+        gap: 20,
+    },
+    buttonPlayContainer: {
+        alignItems: "center",
+        paddingVertical: 20,
+    },
+    errorText: {
+        color: "red",
+        fontSize: 16,
+        marginBottom: 5,
+        textAlign: "left", // Aligne le texte à gauche
+    },
+});
diff --git a/screens/OnlineQuiz/OnlineQuizChild.tsx b/screens/OnlineQuiz/OnlineQuizChild.tsx
index f77ad6d..15c561b 100644
--- a/screens/OnlineQuiz/OnlineQuizChild.tsx
+++ b/screens/OnlineQuiz/OnlineQuizChild.tsx
@@ -2,9 +2,9 @@ import { NavigationProp } from "@react-navigation/native";
 import { useState } from "react";
 import { OnlineSelectModeType, SelectModeType } from "../../models/SelectModeType";
 import { TouchableWithoutFeedback, View, StyleSheet, Keyboard } from "react-native";
-import PlayQuizJoinQuiz from "../PlayQuiz/PlayQuizJoinQuiz";
 import OnlineSelectMode from "./OnlineSelectMode";
 import OnlineCreateLobby from "./OnlineCreateLobby";
+import OnlinePlayQuiz from "./OnlinePlayQuiz";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -21,7 +21,7 @@ export default function OnlineQuizChild({navigation}: Props){
                     {mode === "create" ? (
                         <OnlineCreateLobby navigation={navigation}/>
                     ) : (
-                        <PlayQuizJoinQuiz navigation={navigation}/>
+                        <OnlinePlayQuiz navigation={navigation}/>
                     )}
                 </View>
             </View>
-- 
GitLab


From 2e3fdc7a0059561df6bccabf31440c0d0bdaa9de Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 5 Jan 2025 16:23:00 +0100
Subject: [PATCH 153/283] feat: add action when click on quiz in to the param

---
 components/lists/QuizList.tsx | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 5f5502b..6cb9f80 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -35,16 +35,12 @@ import { NavigationProp } from "@react-navigation/native";
  * @returns Un composant React contenant une liste interactive de quiz ou des messages en fonction de l'état.
  */
 interface Props {
-    navigation: NavigationProp<any>;
     quizList: Quiz[] | null | undefined;
     isLoadingData: boolean;
     nextPage?: () => void;
+    onQuizPressed:(quiz: Quiz) => void;
 }
-export default function QuizList({ navigation, quizList, isLoadingData, nextPage }: Props) {
-    const onQuizPressed = (quiz: Quiz) => {
-        navigation.navigate("InformationsOfQuiz", { quiz: quiz });
-    };
-
+export default function QuizList({ quizList, isLoadingData, nextPage, onQuizPressed }: Props) {
     const renderQuizItem = ({ item }: { item: Quiz }) => (
         <TouchableOpacity style={styles.quizItem} onPress={() => onQuizPressed(item)}>
             <Text style={styles.quizTitle}>{item.id}</Text>
-- 
GitLab


From d692d25bb048638479effe5702a505bc4aeda89d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 5 Jan 2025 16:24:45 +0100
Subject: [PATCH 154/283] feat: add the action when quiz is clicked to the
 param

---
 templates/TemplateQuizList.tsx | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/templates/TemplateQuizList.tsx b/templates/TemplateQuizList.tsx
index 61f2d8f..3b07229 100644
--- a/templates/TemplateQuizList.tsx
+++ b/templates/TemplateQuizList.tsx
@@ -34,15 +34,17 @@ interface Props {
     buttonGoBack: boolean
     isLoadingData: boolean
     nextPage?: () => void;
+    onQuizPressed:(quiz: Quiz) => void;
 }
-export default function TemplateQuizList({navigation, title, setTextInInput, quizList, buttonGoBack, isLoadingData, nextPage}: Props) {
+
+export default function TemplateQuizList({navigation, title, setTextInInput, quizList, buttonGoBack, isLoadingData, nextPage, onQuizPressed }: Props) {
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={buttonGoBack}>
             <View style={styles.globalContainer}>
                 <Text style={styles.title}>{title}</Text>
                 <View style={styles.contentContainer}>
-                    {/*<InputPlayQuiz setText={setTextInInput} noTitle={true} />*/}
-                    <QuizList quizList={quizList} navigation={navigation} isLoadingData={isLoadingData} nextPage={nextPage}/>
+                    <InputPlayQuiz setText={setTextInInput} noTitle={true} />
+                    <QuizList quizList={quizList} isLoadingData={isLoadingData} nextPage={nextPage} onQuizPressed={onQuizPressed}/>
                 </View>
             </View>
         </TemplateMenu>
-- 
GitLab


From 5b6de82a278ae21c930b3f0262b80e5742210251 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 5 Jan 2025 16:28:20 +0100
Subject: [PATCH 155/283] feat: add the action when quiz is clicked

---
 screens/Community/Community.tsx | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/screens/Community/Community.tsx b/screens/Community/Community.tsx
index 152b7f3..73afe99 100644
--- a/screens/Community/Community.tsx
+++ b/screens/Community/Community.tsx
@@ -5,6 +5,7 @@ import {useEffect, useState} from "react";
 import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
+import { Quiz } from "../../models/Quiz";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -23,6 +24,10 @@ export default function Community({navigation}: Props) {
         return quizzes;
     }
 
+    const onQuizPressed = (quiz: Quiz) => {
+        navigation.navigate("InformationsOfQuiz", { quiz: quiz });
+    };
+
 
     const {
         data,
@@ -40,6 +45,6 @@ export default function Community({navigation}: Props) {
         }});
 
     return (
-        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage}/>
+        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
     );
 }
\ No newline at end of file
-- 
GitLab


From b02f5dc670cb0f3cbfcda8b569c2c5f7ba4096c4 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 5 Jan 2025 16:29:38 +0100
Subject: [PATCH 156/283] feat: add the same action when a quiz is clicked than
 the community screen

---
 .../MultiplayerCommunity.tsx                  | 58 ++++++++++++++-----
 1 file changed, 45 insertions(+), 13 deletions(-)

diff --git a/screens/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
index 21d8772..01bec0b 100644
--- a/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -1,17 +1,49 @@
-import { View, Text, StyleSheet } from "react-native";
+import {View, Text} from "react-native";
+import TemplateQuizList from "../../templates/TemplateQuizList";
+import {NavigationProp} from "@react-navigation/native";
+import {useEffect, useState} from "react";
+import {useQuizService} from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
+import {useInfiniteQuery} from "@tanstack/react-query";
+import { Quiz } from "../../models/Quiz";
 
-export default function MultiplayerCommunity() {
-    return (
-        <View style={styles.container}>
-            <Text>MultiplayerCommunity</Text>
-        </View>
-    );
+interface Props {
+    navigation: NavigationProp<any>
 }
+export default function MultiplayerCommunity({navigation}: Props) {
+    const  {getCommunityQuiz} = useQuizService();
+    const [input, setInput] = useState<string>("")
+    const [loading, setLoading] = useState<boolean>(false)
 
-const styles = StyleSheet.create({
-    container: {
-        flex: 1,
-        justifyContent: 'center',
-        alignItems: 'center',
+    const fetchCommunityQuizzes = async ({pageParam = 1}) => {
+        const quizzes = await getCommunityQuiz(pageParam,7);
+        if (HttpError.isHttpError(quizzes)) {
+            console.error("Error while fetching community quizzes:", quizzes);
+            return [];
+        }
+        return quizzes;
     }
-});
\ No newline at end of file
+
+    const onQuizPressed = (quiz: Quiz) => {
+            navigation.navigate("InformationsOfQuiz", { quiz: quiz });
+    };
+
+    const {
+        data,
+        fetchNextPage,
+    } = useInfiniteQuery({
+        queryKey: ["communityQuizzes"],
+        queryFn: fetchCommunityQuizzes,
+        initialPageParam: 0,
+        getNextPageParam: (lastPage, allPages) => {
+            // Si la dernière page a moins de 7 quizzes, il n'y a plus de page suivante
+            if (lastPage.length < 7) return undefined;
+
+            // On augmente skip de 7 pour la prochaine requête
+            return allPages.length * 7;
+        }});
+
+    return (
+        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+    );
+}
\ No newline at end of file
-- 
GitLab


From ae53e4311fc052646ac083b5900221584f084e11 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 5 Jan 2025 16:46:15 +0100
Subject: [PATCH 157/283] feat: add modal to create a lobby

---
 .../MultiplayerCommunity.tsx                  | 47 +++++++++++++++++--
 1 file changed, 42 insertions(+), 5 deletions(-)

diff --git a/screens/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
index 01bec0b..cb9dcc8 100644
--- a/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -1,19 +1,21 @@
-import {View, Text} from "react-native";
+import {View, Text, Modal, TextInput} from "react-native";
 import TemplateQuizList from "../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
-import {useEffect, useState} from "react";
+import React, {useState} from "react";
 import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
 import { Quiz } from "../../models/Quiz";
+import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
     navigation: NavigationProp<any>
 }
 export default function MultiplayerCommunity({navigation}: Props) {
-    const  {getCommunityQuiz} = useQuizService();
+    const  {getCommunityQuiz, getRandomQuiz} = useQuizService();
     const [input, setInput] = useState<string>("")
     const [loading, setLoading] = useState<boolean>(false)
+    const [showModal, setShowModal] = useState<boolean>(false);
 
     const fetchCommunityQuizzes = async ({pageParam = 1}) => {
         const quizzes = await getCommunityQuiz(pageParam,7);
@@ -25,7 +27,29 @@ export default function MultiplayerCommunity({navigation}: Props) {
     }
 
     const onQuizPressed = (quiz: Quiz) => {
-            navigation.navigate("InformationsOfQuiz", { quiz: quiz });
+        setShowModal(true);
+    };
+
+    const onClosePressed = () => {
+        setShowModal(false);
+    };
+
+    const onPlayPressed = async () => {
+        setShowModal(false);
+        const quizData = await getRandomQuiz() //TODO: change the quiz who's getting played
+        if (quizData instanceof HttpError) {
+            console.error("Error while fetching random quiz:", quizData);
+            return;
+        }
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quizRecovered: quizData},
+                },
+            ]
+        });
     };
 
     const {
@@ -44,6 +68,19 @@ export default function MultiplayerCommunity({navigation}: Props) {
         }});
 
     return (
-        <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+        <View>
+            <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+            <Modal visible={showModal}>
+                <View>
+                    <View>
+                        <Text>CREATE A LOBBY</Text>
+                        <Text>NUMBER OF PLAYER</Text>
+                        <TextInput></TextInput>
+                        <DefaultButton text="CLOSE" handleButtonPressed={onClosePressed}/>
+                        <DefaultButton text="PLAY" handleButtonPressed={onPlayPressed}/>
+                    </View>
+                </View>
+            </Modal>
+        </View>
     );
 }
\ No newline at end of file
-- 
GitLab


From 3ef5087e8950ae0dd3d0449a3b4d291f9a4a9213 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 5 Jan 2025 16:58:22 +0100
Subject: [PATCH 158/283] feat: add ongoingQuizzes

---
 screens/OngoingQuizzes/OngoingQuizzes.tsx | 68 ++++++++++++++++++-----
 1 file changed, 55 insertions(+), 13 deletions(-)

diff --git a/screens/OngoingQuizzes/OngoingQuizzes.tsx b/screens/OngoingQuizzes/OngoingQuizzes.tsx
index 191ae5f..64502b9 100644
--- a/screens/OngoingQuizzes/OngoingQuizzes.tsx
+++ b/screens/OngoingQuizzes/OngoingQuizzes.tsx
@@ -1,17 +1,59 @@
-import { View, StyleSheet, Text } from "react-native";
+import {View, Text} from "react-native";
+import TemplateQuizList from "../../templates/TemplateQuizList";
+import {NavigationProp} from "@react-navigation/native";
+import {useEffect, useState} from "react";
+import {useQuizService} from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
+import {useInfiniteQuery} from "@tanstack/react-query";
+import { Quiz } from "../../models/Quiz";
+import DefaultButton from "../../components/DefaultButton";
 
-export default function OngoingQuizzes() {
-    return (
-        <View style={styles.container}>
-            <Text>OngoingQuizzes</Text>
-        </View>
-    );
+interface Props {
+    navigation: NavigationProp<any>
 }
+export default function Community({navigation}: Props) {
+    const  {getCommunityQuiz} = useQuizService();
+    const [input, setInput] = useState<string>("")
+    const [loading, setLoading] = useState<boolean>(false)
+    const [CurrentQuiz, setCurrentQuiz] = useState<Quiz | null>(null);
 
-const styles = StyleSheet.create({
-    container: {
-        flex: 1,
-        justifyContent: 'center',
-        alignItems: 'center',
+    const fetchCommunityQuizzes = async ({pageParam = 1}) => {
+        const quizzes = await getCommunityQuiz(pageParam,7);
+        if (HttpError.isHttpError(quizzes)) {
+            console.error("Error while fetching community quizzes:", quizzes);
+            return [];
+        }
+        return quizzes;
     }
-});
\ No newline at end of file
+
+    const onQuizPressed = (quiz: Quiz) => {
+        setCurrentQuiz(quiz);
+    };
+
+    const onJoinPressed = () => {
+        navigation.goBack();
+    };
+
+
+    const {
+        data,
+        fetchNextPage,
+    } = useInfiniteQuery({
+        queryKey: ["communityQuizzes"],
+        queryFn: fetchCommunityQuizzes,
+        initialPageParam: 0,
+        getNextPageParam: (lastPage, allPages) => {
+            // Si la dernière page a moins de 7 quizzes, il n'y a plus de page suivante
+            if (lastPage.length < 7) return undefined;
+
+            // On augmente skip de 7 pour la prochaine requête
+            return allPages.length * 7;
+        }});
+
+    return (
+        <View>
+            <TemplateQuizList title={"Ongoing Quizzes"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+            <DefaultButton text="JOIN" handleButtonPressed={onJoinPressed}/>
+        </View>
+    );
+}
\ No newline at end of file
-- 
GitLab


From 5ff525c04a48b4d29b68662889a9bf043633e2c0 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 5 Jan 2025 17:06:33 +0100
Subject: [PATCH 159/283] feat: add lobby to the stack Navigation

---
 routes/StackNavigator.tsx |  3 ++-
 screens/Lobby/Lobby.tsx   | 22 ++++++++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 screens/Lobby/Lobby.tsx

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index bb4c2a2..ad94af9 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -12,6 +12,7 @@ import Multiplayer from "../screens/Multiplayer/Multiplayer";
 import MultiplayerCommunity from "../screens/MultiplayerCommunity/MultiplayerCommunity";
 import OnlineQuiz from "../screens/OnlineQuiz/OnlineQuiz";
 import OngoingQuizzes from "../screens/OngoingQuizzes/OngoingQuizzes";
+import Lobby from "../screens/Lobby/Lobby";
 
 const Stack = createNativeStackNavigator();
 
@@ -32,7 +33,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="MultiplayerCommunity" component={MultiplayerCommunity} options={{ headerShown: false }}/>
                 <Stack.Screen name="OnlineQuiz" component={OnlineQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="OngoingQuizzes" component={OngoingQuizzes} options={{ headerShown: false }}/>
-                
+                <Stack.Screen name="Lobby" component={Lobby} options={{ headerShown: false }}/>
             </Stack.Navigator>
         </NavigationContainer>
     );
diff --git a/screens/Lobby/Lobby.tsx b/screens/Lobby/Lobby.tsx
new file mode 100644
index 0000000..541bd56
--- /dev/null
+++ b/screens/Lobby/Lobby.tsx
@@ -0,0 +1,22 @@
+import { View, Text, StyleSheet } from "react-native";
+
+export default function Lobby() {
+    return (
+        <View style={styles.container}>
+            <Text style={styles.title}>Lobby</Text>
+        </View>
+    )
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        height: "100%",
+        width: "100%",
+        justifyContent: "center",
+        alignItems: "center",
+    },
+    title: {
+        fontSize: 40,
+    }
+});
\ No newline at end of file
-- 
GitLab


From 5421df6d29ccb21bb2979e28cbf9e0d6afa22fc1 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 17:40:43 +0100
Subject: [PATCH 160/283] refactor: removed useless hook

---
 hooks/UseUser.ts | 58 ------------------------------------------------
 1 file changed, 58 deletions(-)
 delete mode 100644 hooks/UseUser.ts

diff --git a/hooks/UseUser.ts b/hooks/UseUser.ts
deleted file mode 100644
index 7d30040..0000000
--- a/hooks/UseUser.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import AsyncStorage from "@react-native-async-storage/async-storage";
-export const useUser = () => {
-    const getUser = async <T>(key: string): Promise<T | undefined> => {
-        try {
-            const item = await AsyncStorage.getItem(key);
-            if (!item) {
-                return undefined;
-            }
-            return JSON.parse(item);
-        } catch (error) {
-            console.error("Erreur lors de la récupération de la donnée des informations utilisateur", error);
-            return undefined;
-        }
-    };
-
-    const setUser = async <T>(key: string, newValue: T) => {
-        try {
-            await AsyncStorage.setItem(key, JSON.stringify(newValue));
-        } catch (error) {
-            console.error("Erreur lors de l'enregistrement de la donnée", error);
-        }
-    };
-
-    const getAnonymousUser = async <T>(): Promise<T | undefined> => {
-        return getUser("anonymousUser");
-    }
-
-    const setAnonymousUser = async <T>(newValue: T) => {
-        return setUser("anonymousUser", newValue);
-    }
-
-    const getRealUser = async <T>(): Promise<T | undefined> => {
-        return getUser("realUser");
-    }
-
-    const setRealUser = async <T>(newValue: T) => {
-        return setUser("realUser", newValue);
-    }
-
-    const connectUser = async <T>(user: T) => {
-        // TODO: Implement
-    }
-
-    const logOutUser = async () => {
-        // TODO: Implement
-    }
-
-    return {
-        getAnonymousUser: getAnonymousUser,
-        setAnonymousUser: setAnonymousUser,
-        getRealUser: getRealUser,
-        setRealUser: setRealUser,
-        connectUser: connectUser,
-        logOutUser: logOutUser,
-    };
-}
-
-
-- 
GitLab


From 8d8af2b0bb46bbc1b61ec109f5e9344c6f181cd1 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 17:53:15 +0100
Subject: [PATCH 161/283] refactor(files archi): moved GenerateQuiz

---
 screens/GenerateQuiz/GenerateQuizHeader.tsx            |  0
 .../{ => Home/PlayQuiz}/GenerateQuiz/GenerateQuiz.tsx  |  2 +-
 .../PlayQuiz}/GenerateQuiz/GenerateQuizBody.tsx        | 10 +++++-----
 3 files changed, 6 insertions(+), 6 deletions(-)
 delete mode 100644 screens/GenerateQuiz/GenerateQuizHeader.tsx
 rename screens/{ => Home/PlayQuiz}/GenerateQuiz/GenerateQuiz.tsx (78%)
 rename screens/{ => Home/PlayQuiz}/GenerateQuiz/GenerateQuizBody.tsx (89%)

diff --git a/screens/GenerateQuiz/GenerateQuizHeader.tsx b/screens/GenerateQuiz/GenerateQuizHeader.tsx
deleted file mode 100644
index e69de29..0000000
diff --git a/screens/GenerateQuiz/GenerateQuiz.tsx b/screens/Home/PlayQuiz/GenerateQuiz/GenerateQuiz.tsx
similarity index 78%
rename from screens/GenerateQuiz/GenerateQuiz.tsx
rename to screens/Home/PlayQuiz/GenerateQuiz/GenerateQuiz.tsx
index 014f469..0d95d50 100644
--- a/screens/GenerateQuiz/GenerateQuiz.tsx
+++ b/screens/Home/PlayQuiz/GenerateQuiz/GenerateQuiz.tsx
@@ -1,4 +1,4 @@
-import TemplateScreen from "../../templates/TemplateScreen";
+import TemplateScreen from "../../../../templates/TemplateScreen";
 import GenerateQuizBody from "./GenerateQuizBody";
 
 export default function GenerateQuiz({navigation}: any) {
diff --git a/screens/GenerateQuiz/GenerateQuizBody.tsx b/screens/Home/PlayQuiz/GenerateQuiz/GenerateQuizBody.tsx
similarity index 89%
rename from screens/GenerateQuiz/GenerateQuizBody.tsx
rename to screens/Home/PlayQuiz/GenerateQuiz/GenerateQuizBody.tsx
index 198f438..854806a 100644
--- a/screens/GenerateQuiz/GenerateQuizBody.tsx
+++ b/screens/Home/PlayQuiz/GenerateQuiz/GenerateQuizBody.tsx
@@ -1,11 +1,11 @@
-import ComboBox from "../../components/comboBox/ComboBox";
-import DefaultButton from "../../components/DefaultButton";
+import ComboBox from "../../../../components/comboBox/ComboBox";
+import DefaultButton from "../../../../components/DefaultButton";
 import {StyleSheet, View} from "react-native";
 import {useState} from "react";
 import {useTranslation} from "react-i18next";
-import {useQuizService} from "../../services/QuizService";
-import {EDifficulty} from "../../models/EDifficulty";
-import {getIdOfCategory} from "../../helper/QuizHelper";
+import {useQuizService} from "../../../../services/QuizService";
+import {EDifficulty} from "../../../../models/EDifficulty";
+import {getIdOfCategory} from "../../../../helper/QuizHelper";
 
 const optionsDifficulty = [ 'easy', 'medium', 'hard'];
 const optionsQuestions = ['1', '50'];
-- 
GitLab


From c4e36b136b7db6523225d0f3551c18ad7fd06e3e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 17:53:46 +0100
Subject: [PATCH 162/283] refactor(files archi): moved Profile screen and
 componenents

---
 screens/Profil/{ => Modals}/ProfilModal.tsx       | 4 ++--
 screens/Profil/{ => Modals}/ProfilModalLogin.tsx  | 8 ++++----
 screens/Profil/{ => Modals}/ProfilModalSignup.tsx | 8 ++++----
 screens/Profil/ProfilChild.tsx                    | 2 +-
 4 files changed, 11 insertions(+), 11 deletions(-)
 rename screens/Profil/{ => Modals}/ProfilModal.tsx (95%)
 rename screens/Profil/{ => Modals}/ProfilModalLogin.tsx (91%)
 rename screens/Profil/{ => Modals}/ProfilModalSignup.tsx (92%)

diff --git a/screens/Profil/ProfilModal.tsx b/screens/Profil/Modals/ProfilModal.tsx
similarity index 95%
rename from screens/Profil/ProfilModal.tsx
rename to screens/Profil/Modals/ProfilModal.tsx
index f0227d7..fb5afbd 100644
--- a/screens/Profil/ProfilModal.tsx
+++ b/screens/Profil/Modals/ProfilModal.tsx
@@ -8,8 +8,8 @@ import {
     Keyboard,
     TouchableWithoutFeedback,
 } from "react-native";
-import ProfilSelectMode from "./ProfilSelectMode";
-import { ProfilSelectModeType } from "../../models/SelectModeType";
+import ProfilSelectMode from "../ProfilSelectMode";
+import { ProfilSelectModeType } from "../../../models/SelectModeType";
 import ProfilModalLogin from "./ProfilModalLogin";
 import ProfilModalSignup from "./ProfilModalSignup";
 import Icon from "react-native-vector-icons/MaterialIcons";
diff --git a/screens/Profil/ProfilModalLogin.tsx b/screens/Profil/Modals/ProfilModalLogin.tsx
similarity index 91%
rename from screens/Profil/ProfilModalLogin.tsx
rename to screens/Profil/Modals/ProfilModalLogin.tsx
index 0d0a373..48b38b2 100644
--- a/screens/Profil/ProfilModalLogin.tsx
+++ b/screens/Profil/Modals/ProfilModalLogin.tsx
@@ -1,9 +1,9 @@
 import { TextInput, View, StyleSheet, Text } from "react-native";
-import DefaultButton from "../../components/DefaultButton";
-import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import DefaultButton from "../../../components/DefaultButton";
+import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import React, { useState } from "react";
-import {useUserService} from "../../services/UserService";
-import HttpError from "../../services/HttpError";
+import {useUserService} from "../../../services/UserService";
+import HttpError from "../../../services/HttpError";
 import {NavigationProp} from "@react-navigation/native";
 
 interface Props {
diff --git a/screens/Profil/ProfilModalSignup.tsx b/screens/Profil/Modals/ProfilModalSignup.tsx
similarity index 92%
rename from screens/Profil/ProfilModalSignup.tsx
rename to screens/Profil/Modals/ProfilModalSignup.tsx
index 3179c0c..db63d11 100644
--- a/screens/Profil/ProfilModalSignup.tsx
+++ b/screens/Profil/Modals/ProfilModalSignup.tsx
@@ -1,9 +1,9 @@
 import {TextInput, View, StyleSheet, Text} from "react-native";
-import DefaultButton from "../../components/DefaultButton";
-import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import DefaultButton from "../../../components/DefaultButton";
+import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import React, {useState} from "react";
-import {useUserService} from "../../services/UserService";
-import HttpError from "../../services/HttpError";
+import {useUserService} from "../../../services/UserService";
+import HttpError from "../../../services/HttpError";
 import {NavigationProp} from "@react-navigation/native";
 
 interface Props {
diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index b3dee69..81208fc 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -1,6 +1,6 @@
 import { NavigationProp } from "@react-navigation/native";
 import { View, StyleSheet, Image, Text, TouchableOpacity } from "react-native";
-import ProfilModal from "./ProfilModal";
+import ProfilModal from "./Modals/ProfilModal";
 import React, { useEffect, useState } from "react";
 import ProfilHeaderAccount from "./ProfilHeaderAccount";
 import { ProfilSelectModeType } from "../../models/SelectModeType";
-- 
GitLab


From e6382a98db24cbb923ee225b1c02935a51173a92 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 17:54:23 +0100
Subject: [PATCH 163/283] refactor(files archi): moved PlayQuiz screen and
 components

---
 screens/{ => Home}/PlayQuiz/PlayQuiz.tsx           |  4 ++--
 screens/{ => Home}/PlayQuiz/PlayQuizChild.tsx      |  4 ++--
 .../{ => Home}/PlayQuiz/PlayQuizGenerateQuiz.tsx   | 10 +++++-----
 screens/{ => Home}/PlayQuiz/PlayQuizJoinQuiz.tsx   | 14 +++++++-------
 4 files changed, 16 insertions(+), 16 deletions(-)
 rename screens/{ => Home}/PlayQuiz/PlayQuiz.tsx (88%)
 rename screens/{ => Home}/PlayQuiz/PlayQuizChild.tsx (91%)
 rename screens/{ => Home}/PlayQuiz/PlayQuizGenerateQuiz.tsx (91%)
 rename screens/{ => Home}/PlayQuiz/PlayQuizJoinQuiz.tsx (85%)

diff --git a/screens/PlayQuiz/PlayQuiz.tsx b/screens/Home/PlayQuiz/PlayQuiz.tsx
similarity index 88%
rename from screens/PlayQuiz/PlayQuiz.tsx
rename to screens/Home/PlayQuiz/PlayQuiz.tsx
index 991c6ba..02c949f 100644
--- a/screens/PlayQuiz/PlayQuiz.tsx
+++ b/screens/Home/PlayQuiz/PlayQuiz.tsx
@@ -1,7 +1,7 @@
 import {NavigationProp} from "@react-navigation/native";
-import TemplateMenu from "../../templates/TemplateMenu";
+import TemplateMenu from "../../../templates/TemplateMenu";
 import {StyleSheet, View} from "react-native";
-import HomeChild from "../Home/HomeChild";
+import HomeChild from "../HomeChild";
 import React from "react";
 import PlayQuizChild from "./PlayQuizChild";
 
diff --git a/screens/PlayQuiz/PlayQuizChild.tsx b/screens/Home/PlayQuiz/PlayQuizChild.tsx
similarity index 91%
rename from screens/PlayQuiz/PlayQuizChild.tsx
rename to screens/Home/PlayQuiz/PlayQuizChild.tsx
index ad6e515..4c982b3 100644
--- a/screens/PlayQuiz/PlayQuizChild.tsx
+++ b/screens/Home/PlayQuiz/PlayQuizChild.tsx
@@ -1,8 +1,8 @@
 import {Text, View, StyleSheet, TouchableWithoutFeedback, Keyboard} from "react-native";
 import {NavigationProp} from "@react-navigation/native";
-import SelectMode from "../../components/PlayQuiz/SelectMode";
+import SelectMode from "../../../components/PlayQuiz/SelectMode";
 import React, {useState} from "react";
-import {SelectModeType} from "../../models/SelectModeType";
+import {SelectModeType} from "../../../models/SelectModeType";
 import PlayQuizGenerateQuiz from "./PlayQuizGenerateQuiz";
 import PlayQuizJoinQuiz from "./PlayQuizJoinQuiz";
 
diff --git a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
similarity index 91%
rename from screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
rename to screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
index 4b9bc60..bfcb144 100644
--- a/screens/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -1,10 +1,10 @@
 import { Text,View, StyleSheet } from "react-native";
-import SelectListBox from "../../components/PlayQuiz/SelectListBox";
+import SelectListBox from "../../../components/PlayQuiz/SelectListBox";
 import React, {useEffect} from "react";
-import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import BlueButton from "../../components/PlayQuiz/BlueButton";
-import {getIdOfCategory} from "../../helper/QuizHelper";
-import {useQuizService} from "../../services/QuizService";
+import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
+import BlueButton from "../../../components/PlayQuiz/BlueButton";
+import {getIdOfCategory} from "../../../helper/QuizHelper";
+import {useQuizService} from "../../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
 
 const difficulty = [
diff --git a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
similarity index 85%
rename from screens/PlayQuiz/PlayQuizJoinQuiz.tsx
rename to screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
index 4493ce4..264ad60 100644
--- a/screens/PlayQuiz/PlayQuizJoinQuiz.tsx
+++ b/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -1,12 +1,12 @@
 import { StyleSheet, View, Text } from "react-native";
-import AboutAQuiz from "../../components/PlayQuiz/AboutAQuiz";
-import BlueButton from "../../components/PlayQuiz/BlueButton";
+import AboutAQuiz from "../../../components/PlayQuiz/AboutAQuiz";
+import BlueButton from "../../../components/PlayQuiz/BlueButton";
 import React, { useEffect } from "react";
-import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import {Quiz} from "../../models/Quiz";
-import { useQuizService } from "../../services/QuizService";
-import HttpError from "../../services/HttpError";
-import {getIdOfCategory} from "../../helper/QuizHelper";
+import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
+import {Quiz} from "../../../models/Quiz";
+import { useQuizService } from "../../../services/QuizService";
+import HttpError from "../../../services/HttpError";
+import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {NavigationProp} from "@react-navigation/native";
 
 interface Props {
-- 
GitLab


From be15756c2f10d56bef706f1d2e6f90c2adfbe31e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 17:55:12 +0100
Subject: [PATCH 164/283] refactor(files archi): moved InformationsOfQuiz

---
 .../{ => Community}/InformationsOfQuiz/InformationsOfQuiz.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
 rename screens/{ => Community}/InformationsOfQuiz/InformationsOfQuiz.tsx (96%)

diff --git a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
similarity index 96%
rename from screens/InformationsOfQuiz/InformationsOfQuiz.tsx
rename to screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
index 442776a..a65b874 100644
--- a/screens/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -1,8 +1,8 @@
 import React from "react";
 import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
-import TemplateMenu from "../../templates/TemplateMenu";
+import TemplateMenu from "../../../templates/TemplateMenu";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
-import {Quiz} from "../../models/Quiz";
+import {Quiz} from "../../../models/Quiz";
 
 type RoutePropsType = {
     InformationsOfQuiz: {
-- 
GitLab


From cafc0d33108206b3362cd1e1f63be9c640087719 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 18:03:37 +0100
Subject: [PATCH 165/283] refactor(files archi): moved endQuiz

---
 screens/{ => PlayingQuiz}/EndQuiz/EndQuiz.tsx      |  4 ++--
 screens/{ => PlayingQuiz}/EndQuiz/EndQuizChild.tsx | 12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)
 rename screens/{ => PlayingQuiz}/EndQuiz/EndQuiz.tsx (97%)
 rename screens/{ => PlayingQuiz}/EndQuiz/EndQuizChild.tsx (90%)

diff --git a/screens/EndQuiz/EndQuiz.tsx b/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
similarity index 97%
rename from screens/EndQuiz/EndQuiz.tsx
rename to screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
index ee5c5c5..8297ee0 100644
--- a/screens/EndQuiz/EndQuiz.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
@@ -1,8 +1,8 @@
 import {NavigationProp, RouteProp} from "@react-navigation/native";
 import { View, StyleSheet, Image, Text } from "react-native";
 import EndQuizChild from "./EndQuizChild";
-import TemplateMenu from "../../templates/TemplateMenu";
-import {Quiz} from "../../models/Quiz";
+import TemplateMenu from "../../../templates/TemplateMenu";
+import {Quiz} from "../../../models/Quiz";
 
 type RoutePropsType = {
     EndQuizChild: {
diff --git a/screens/EndQuiz/EndQuizChild.tsx b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
similarity index 90%
rename from screens/EndQuiz/EndQuizChild.tsx
rename to screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
index 9d31713..2a8dc49 100644
--- a/screens/EndQuiz/EndQuizChild.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
@@ -1,9 +1,9 @@
 import { View, Image, Text, StyleSheet } from "react-native";
-import DefaultButton from "../../components/DefaultButton";
+import DefaultButton from "../../../components/DefaultButton";
 import { NavigationProp, RouteProp } from "@react-navigation/native";
-import {Quiz} from "../../models/Quiz";
-import {useQuizService} from "../../services/QuizService";
-import HttpError from "../../services/HttpError";
+import {Quiz} from "../../../models/Quiz";
+import {useQuizService} from "../../../services/QuizService";
+import HttpError from "../../../services/HttpError";
 
 
 
@@ -49,12 +49,12 @@ export default function EndQuizChild({ navigation, quiz }: Props) {
     return (
         <View style={styles.container}>
             <View style={styles.containerHeader}>
-                <Image source={require('../../assets/TitleApp.png')}/>
+                <Image source={require('../../../assets/TitleApp.png')}/>
             </View>
             <View style={styles.containerBody}>
                 <Text style={styles.TextBodyTitle}>{((quiz.score/quiz.questionCount)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
                 <Text style={styles.TextBody}>you finish the test with a score of {`${quiz.score}/${quiz.questionCount}`} ! </Text>
-                <Image source={require('../../assets/uWin.png')} />
+                <Image source={require('../../../assets/uWin.png')} />
                 <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
             </View>
-- 
GitLab


From 5ee8a1996f19dd6772e18dca952fff3d51a20c3d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 18:40:52 +0100
Subject: [PATCH 166/283] refactor(files archi): moved Home

---
 {screens/Home => components/navigation}/HeaderNavigation.tsx | 2 +-
 screens/Home/HomeChild.tsx                                   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
 rename {screens/Home => components/navigation}/HeaderNavigation.tsx (96%)

diff --git a/screens/Home/HeaderNavigation.tsx b/components/navigation/HeaderNavigation.tsx
similarity index 96%
rename from screens/Home/HeaderNavigation.tsx
rename to components/navigation/HeaderNavigation.tsx
index 03370bb..1b17e9c 100644
--- a/screens/Home/HeaderNavigation.tsx
+++ b/components/navigation/HeaderNavigation.tsx
@@ -1,6 +1,6 @@
 import { View, StyleSheet, Image, TouchableOpacity } from "react-native";
 import { NavigationProp } from "@react-navigation/native";
-import ConfirmModal from "../../components/PlayingQuiz/ComfirmModal";
+import ConfirmModal from "../PlayingQuiz/ComfirmModal";
 
 interface Props {
     navigation: NavigationProp<any>;
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 780947f..1df4cb5 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -53,7 +53,7 @@ export default function HomeChild({navigation}: Props) {
             </View>
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
-                <MenuButton text={"PLAY A QUIZ"} handleButtonPressed={handleButtonGeneratePressed}/>
+                <MenuButton text={"PLAY"} handleButtonPressed={handleButtonGeneratePressed}/>
                 {/*<MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>*/}
             </View>
              <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
-- 
GitLab


From 1757ed0a3680e30e529f0d87624335845cb0a834 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 18:41:08 +0100
Subject: [PATCH 167/283] refactor(files archi): moved rest

---
 routes/StackNavigator.tsx                  | 10 +++++-----
 screens/{ => Home}/MyQuizzes/MyQuizzes.tsx |  4 ++--
 templates/TemplateMenu.tsx                 |  2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)
 rename screens/{ => Home}/MyQuizzes/MyQuizzes.tsx (81%)

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index cbfdc43..7f91326 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -1,13 +1,13 @@
 import {createNativeStackNavigator} from "@react-navigation/native-stack";
 import {NavigationContainer} from "@react-navigation/native";
 import Home from "../screens/Home/Home";
-import GenerateQuiz from "../screens/GenerateQuiz/GenerateQuiz";
-import EndQuiz from "../screens/EndQuiz/EndQuiz";
+import GenerateQuiz from "../screens/Home/PlayQuiz/GenerateQuiz/GenerateQuiz";
+import EndQuiz from "../screens/PlayingQuiz/EndQuiz/EndQuiz";
 import PlayingQuiz from "../screens/PlayingQuiz/PlayingQuiz";
 import TabNavigator from "./TabNavigation";
-import PlayQuiz from "../screens/PlayQuiz/PlayQuiz";
-import MyQuizzes from "../screens/MyQuizzes/MyQuizzes";
-import InformationsOfQuiz from "../screens/InformationsOfQuiz/InformationsOfQuiz";
+import PlayQuiz from "../screens/Home/PlayQuiz/PlayQuiz";
+import MyQuizzes from "../screens/Home/MyQuizzes/MyQuizzes";
+import InformationsOfQuiz from "../screens/Community/InformationsOfQuiz/InformationsOfQuiz";
 
 const Stack = createNativeStackNavigator();
 
diff --git a/screens/MyQuizzes/MyQuizzes.tsx b/screens/Home/MyQuizzes/MyQuizzes.tsx
similarity index 81%
rename from screens/MyQuizzes/MyQuizzes.tsx
rename to screens/Home/MyQuizzes/MyQuizzes.tsx
index eb61204..66004ca 100644
--- a/screens/MyQuizzes/MyQuizzes.tsx
+++ b/screens/Home/MyQuizzes/MyQuizzes.tsx
@@ -1,7 +1,7 @@
-import TemplateQuizList from "../../templates/TemplateQuizList";
+import TemplateQuizList from "../../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import {useState} from "react";
-import {Quiz} from "../../models/Quiz";
+import {Quiz} from "../../../models/Quiz";
 
 interface Props {
     navigation: NavigationProp<any>
diff --git a/templates/TemplateMenu.tsx b/templates/TemplateMenu.tsx
index 6be8186..d58ffa2 100644
--- a/templates/TemplateMenu.tsx
+++ b/templates/TemplateMenu.tsx
@@ -1,5 +1,5 @@
 import {ImageBackground, Text, View, StyleSheet, SafeAreaView} from "react-native";
-import HeaderNavigation from "../screens/Home/HeaderNavigation";
+import HeaderNavigation from "../components/navigation/HeaderNavigation";
 import {NavigationProp} from "@react-navigation/native";
 
 interface Props{
-- 
GitLab


From 2a10ec4617f4bc87f57c9517e1dc41ccd5676e14 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 18:54:22 +0100
Subject: [PATCH 168/283] refactor(files archi): moved defaultButton

---
 components/ModalJoinQuiz.tsx                            | 2 +-
 components/{ => buttons}/DefaultButton.tsx              | 4 ++--
 components/comboBox/ComboBox.tsx                        | 2 +-
 screens/Home/HomeChild.tsx                              | 2 +-
 screens/Home/PlayQuiz/GenerateQuiz/GenerateQuizBody.tsx | 2 +-
 screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx            | 2 +-
 screens/PlayingQuiz/PlayingQuizBody.tsx                 | 2 +-
 screens/PlayingQuiz/PlayingQuizHeader.tsx               | 2 +-
 screens/Profil/Modals/ProfilModalLogin.tsx              | 2 +-
 screens/Profil/Modals/ProfilModalSignup.tsx             | 2 +-
 10 files changed, 11 insertions(+), 11 deletions(-)
 rename components/{ => buttons}/DefaultButton.tsx (88%)

diff --git a/components/ModalJoinQuiz.tsx b/components/ModalJoinQuiz.tsx
index 77320ad..be899d2 100644
--- a/components/ModalJoinQuiz.tsx
+++ b/components/ModalJoinQuiz.tsx
@@ -1,5 +1,5 @@
 import { Modal, View, Text, StyleSheet, TextInput } from "react-native";
-import DefaultButton from "./DefaultButton";
+import DefaultButton from "./buttons/DefaultButton";
 import {useState} from "react";
 import {useQuizService} from "../services/QuizService";
 import HttpError from "../services/HttpError";
diff --git a/components/DefaultButton.tsx b/components/buttons/DefaultButton.tsx
similarity index 88%
rename from components/DefaultButton.tsx
rename to components/buttons/DefaultButton.tsx
index d4aaa4f..cd0fe2a 100644
--- a/components/DefaultButton.tsx
+++ b/components/buttons/DefaultButton.tsx
@@ -1,6 +1,6 @@
 import {TouchableOpacity, Text} from "react-native";
-import {ButtonsStyles} from "../styles/ButtonsStyles";
-import {TextsStyles} from "../styles/TextsStyles";
+import {ButtonsStyles} from "../../styles/ButtonsStyles";
+import {TextsStyles} from "../../styles/TextsStyles";
 
 interface Props{
     text: string;
diff --git a/components/comboBox/ComboBox.tsx b/components/comboBox/ComboBox.tsx
index d89f425..12ed9f3 100644
--- a/components/comboBox/ComboBox.tsx
+++ b/components/comboBox/ComboBox.tsx
@@ -1,7 +1,7 @@
 import React, { useState } from 'react';
 import { View, Text, StyleSheet, Modal, TouchableOpacity, TextInput, Platform } from 'react-native';
 import { Picker } from '@react-native-picker/picker';
-import DefaultButton from "../DefaultButton";
+import DefaultButton from "../buttons/DefaultButton";
 
 interface Props {
     options: string[];
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 1df4cb5..fd9c7da 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -1,5 +1,5 @@
 import { View, StyleSheet, Image, Modal, TextInput } from "react-native";
-import DefaultButton from "../../components/DefaultButton";
+import DefaultButton from "../../components/buttons/DefaultButton";
 import {useTranslation} from "react-i18next";
 import { useState } from "react";
 import { TextsStyles } from "../../styles/TextsStyles";
diff --git a/screens/Home/PlayQuiz/GenerateQuiz/GenerateQuizBody.tsx b/screens/Home/PlayQuiz/GenerateQuiz/GenerateQuizBody.tsx
index 854806a..a50e17d 100644
--- a/screens/Home/PlayQuiz/GenerateQuiz/GenerateQuizBody.tsx
+++ b/screens/Home/PlayQuiz/GenerateQuiz/GenerateQuizBody.tsx
@@ -1,5 +1,5 @@
 import ComboBox from "../../../../components/comboBox/ComboBox";
-import DefaultButton from "../../../../components/DefaultButton";
+import DefaultButton from "../../../../components/buttons/DefaultButton";
 import {StyleSheet, View} from "react-native";
 import {useState} from "react";
 import {useTranslation} from "react-i18next";
diff --git a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
index 2a8dc49..2d8bafc 100644
--- a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
@@ -1,5 +1,5 @@
 import { View, Image, Text, StyleSheet } from "react-native";
-import DefaultButton from "../../../components/DefaultButton";
+import DefaultButton from "../../../components/buttons/DefaultButton";
 import { NavigationProp, RouteProp } from "@react-navigation/native";
 import {Quiz} from "../../../models/Quiz";
 import {useQuizService} from "../../../services/QuizService";
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index ad504db..3393f06 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -1,5 +1,5 @@
 import { View, StyleSheet, Text } from "react-native";
-import DefaultButton from "../../components/DefaultButton";
+import DefaultButton from "../../components/buttons/DefaultButton";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
 import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
 import { useQuizService } from "../../services/QuizService";
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index e2c5634..9da0130 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -2,7 +2,7 @@ import { View, StyleSheet, Text } from "react-native";
 import { TextsStyles } from "../../styles/TextsStyles";
 import  {Quiz} from "../../models/Quiz";
 import {useTranslation} from "react-i18next";
-import DefaultButton from "../../components/DefaultButton";
+import DefaultButton from "../../components/buttons/DefaultButton";
 import GoHomeButton from "../../components/PlayingQuiz/GoHomeButton";
 import {NavigationProp} from "@react-navigation/native";
 import ConfirmModal from "../../components/PlayingQuiz/ComfirmModal";
diff --git a/screens/Profil/Modals/ProfilModalLogin.tsx b/screens/Profil/Modals/ProfilModalLogin.tsx
index 48b38b2..2f651da 100644
--- a/screens/Profil/Modals/ProfilModalLogin.tsx
+++ b/screens/Profil/Modals/ProfilModalLogin.tsx
@@ -1,5 +1,5 @@
 import { TextInput, View, StyleSheet, Text } from "react-native";
-import DefaultButton from "../../../components/DefaultButton";
+import DefaultButton from "../../../components/buttons/DefaultButton";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import React, { useState } from "react";
 import {useUserService} from "../../../services/UserService";
diff --git a/screens/Profil/Modals/ProfilModalSignup.tsx b/screens/Profil/Modals/ProfilModalSignup.tsx
index db63d11..a673efa 100644
--- a/screens/Profil/Modals/ProfilModalSignup.tsx
+++ b/screens/Profil/Modals/ProfilModalSignup.tsx
@@ -1,5 +1,5 @@
 import {TextInput, View, StyleSheet, Text} from "react-native";
-import DefaultButton from "../../../components/DefaultButton";
+import DefaultButton from "../../../components/buttons/DefaultButton";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import React, {useState} from "react";
 import {useUserService} from "../../../services/UserService";
-- 
GitLab


From d49c3e898addc6d2151126841d837b83d6929102 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 19:06:34 +0100
Subject: [PATCH 169/283] refactor(files archi): moved Blue Button

---
 components/PlayingQuiz/ComfirmModal.tsx         | 2 +-
 components/{PlayQuiz => buttons}/BlueButton.tsx | 0
 screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx  | 2 +-
 screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx      | 2 +-
 screens/PlayingQuiz/PlayingQuizBody.tsx         | 2 +-
 styles/ButtonsStyles.ts                         | 7 +++++++
 styles/TextsStyles.ts                           | 4 ++++
 7 files changed, 15 insertions(+), 4 deletions(-)
 rename components/{PlayQuiz => buttons}/BlueButton.tsx (100%)

diff --git a/components/PlayingQuiz/ComfirmModal.tsx b/components/PlayingQuiz/ComfirmModal.tsx
index 81af836..4b91e82 100644
--- a/components/PlayingQuiz/ComfirmModal.tsx
+++ b/components/PlayingQuiz/ComfirmModal.tsx
@@ -8,7 +8,7 @@ import {
     TouchableWithoutFeedback,
 } from "react-native";
 import Icon from "react-native-vector-icons/MaterialIcons";
-import BlueButton from "../PlayQuiz/BlueButton"; // Pour l'icône de fermeture
+import BlueButton from "../buttons/BlueButton"; // Pour l'icône de fermeture
 
 interface Props {
     visible: boolean;
diff --git a/components/PlayQuiz/BlueButton.tsx b/components/buttons/BlueButton.tsx
similarity index 100%
rename from components/PlayQuiz/BlueButton.tsx
rename to components/buttons/BlueButton.tsx
diff --git a/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
index bfcb144..481b82f 100644
--- a/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -2,7 +2,7 @@ import { Text,View, StyleSheet } from "react-native";
 import SelectListBox from "../../../components/PlayQuiz/SelectListBox";
 import React, {useEffect} from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
-import BlueButton from "../../../components/PlayQuiz/BlueButton";
+import BlueButton from "../../../components/buttons/BlueButton";
 import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {useQuizService} from "../../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
diff --git a/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
index 264ad60..9f856f9 100644
--- a/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
+++ b/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -1,6 +1,6 @@
 import { StyleSheet, View, Text } from "react-native";
 import AboutAQuiz from "../../../components/PlayQuiz/AboutAQuiz";
-import BlueButton from "../../../components/PlayQuiz/BlueButton";
+import BlueButton from "../../../components/buttons/BlueButton";
 import React, { useEffect } from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import {Quiz} from "../../../models/Quiz";
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 3393f06..da6f1f6 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -5,7 +5,7 @@ import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
 import { useQuizService } from "../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
 import HttpError from "../../services/HttpError";
-import BlueButton from "../../components/PlayQuiz/BlueButton";
+import BlueButton from "../../components/buttons/BlueButton";
 import {Question} from "../../models/Question";
 import {Answer} from "../../models/Answer";
 import {Quiz} from "../../models/Quiz";
diff --git a/styles/ButtonsStyles.ts b/styles/ButtonsStyles.ts
index 4f56435..5d33ddb 100644
--- a/styles/ButtonsStyles.ts
+++ b/styles/ButtonsStyles.ts
@@ -7,6 +7,13 @@ export const ButtonsStyles = StyleSheet.create( {
         justifyContent: 'center',
         borderRadius: 10,
     },
+    whiteButton: {
+        backgroundColor: "#45128C",
+        padding: 10,
+        alignItems: "center",
+        justifyContent: 'center',
+        borderRadius: 10,
+    },
     answerButton: {
         backgroundColor: "#F3F3F3",
         height: '15%',
diff --git a/styles/TextsStyles.ts b/styles/TextsStyles.ts
index 1ec37f0..84e6ba3 100644
--- a/styles/TextsStyles.ts
+++ b/styles/TextsStyles.ts
@@ -8,6 +8,10 @@ export const TextsStyles = StyleSheet.create( {
         color: "white",
         fontSize: 17,
     },
+    whiteButtonText: {
+        color: "white",
+        fontSize: 17,
+    },
     titleText: {
         fontSize: 24,
         fontWeight: "bold",
-- 
GitLab


From 5e8f377f4318cf80766afbc6d2464b8f92e265d6 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 19:11:48 +0100
Subject: [PATCH 170/283] feat: white button

---
 components/buttons/WhiteButton.tsx | 50 ++++++++++++++++++++++++++++++
 screens/Home/HomeChild.tsx         |  4 +++
 2 files changed, 54 insertions(+)
 create mode 100644 components/buttons/WhiteButton.tsx

diff --git a/components/buttons/WhiteButton.tsx b/components/buttons/WhiteButton.tsx
new file mode 100644
index 0000000..a702557
--- /dev/null
+++ b/components/buttons/WhiteButton.tsx
@@ -0,0 +1,50 @@
+import { View, Text, StyleSheet, TouchableOpacity, GestureResponderEvent } from "react-native";
+
+interface Props {
+    onPress: ((event: GestureResponderEvent) => void) | undefined;
+    text: string;
+    buttonStyle?: any;
+    isDisabled: boolean;
+}
+
+export default function WhiteButton({ onPress, text, buttonStyle, isDisabled }: Props) {
+    return (
+        <TouchableOpacity
+            style={[
+                styles.container,
+                isDisabled ? styles.disabledContainer : styles.enabledContainer,
+                buttonStyle,
+            ]}
+            onPress={onPress}
+            disabled={isDisabled}
+        >
+            <Text style={[styles.text, isDisabled && styles.disabledText]}>{text}</Text>
+        </TouchableOpacity>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        width: "100%",
+        height: 70,
+        alignItems: "center",
+        justifyContent: "center",
+        borderRadius: 10,
+        borderWidth: 5,
+        borderColor: "#508bff",
+    },
+    enabledContainer: {
+        backgroundColor: "white", // Couleur bleue par défaut
+    },
+    disabledContainer: {
+        backgroundColor: "#b0b0b0", // Gris désactivé
+    },
+    text: {
+        fontSize: 28,
+        color: "#508bff",
+        fontWeight: "bold",
+    },
+    disabledText: {
+        color: "#d0d0d0", // Texte grisé pour un bouton désactivé
+    },
+});
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index fd9c7da..da7d22d 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -8,6 +8,8 @@ import MenuButton from "../../components/buttons/MenuButton";
 import {NavigationProp} from "@react-navigation/native";
 import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
+import BlueButton from "../../components/buttons/BlueButton";
+import WhiteButton from "../../components/buttons/WhiteButton";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -54,6 +56,8 @@ export default function HomeChild({navigation}: Props) {
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
                 <MenuButton text={"PLAY"} handleButtonPressed={handleButtonGeneratePressed}/>
+                <BlueButton onPress={()=>{}} text={"test"} isDisabled={false}/>
+                <WhiteButton onPress={()=>{}} text={"test"} isDisabled={false}/>
                 {/*<MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>*/}
             </View>
              <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
-- 
GitLab


From af8c68a46567228b5b97889d00d906d64f075208 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 19:12:39 +0100
Subject: [PATCH 171/283] feat: testing compononents pushed

---
 screens/Home/HomeChild.tsx | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index da7d22d..fd9c7da 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -8,8 +8,6 @@ import MenuButton from "../../components/buttons/MenuButton";
 import {NavigationProp} from "@react-navigation/native";
 import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
-import BlueButton from "../../components/buttons/BlueButton";
-import WhiteButton from "../../components/buttons/WhiteButton";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -56,8 +54,6 @@ export default function HomeChild({navigation}: Props) {
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
                 <MenuButton text={"PLAY"} handleButtonPressed={handleButtonGeneratePressed}/>
-                <BlueButton onPress={()=>{}} text={"test"} isDisabled={false}/>
-                <WhiteButton onPress={()=>{}} text={"test"} isDisabled={false}/>
                 {/*<MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>*/}
             </View>
              <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
-- 
GitLab


From bc9ee8b8263a4b97ebfcbc46f65dc0b8d0ec07f0 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 20:49:44 +0100
Subject: [PATCH 172/283] feat: indicator on answer button

---
 components/buttons/AnswerButton.tsx     | 58 +++++++++++++++++++++++++
 screens/PlayingQuiz/PlayingQuizBody.tsx |  4 +-
 2 files changed, 61 insertions(+), 1 deletion(-)
 create mode 100644 components/buttons/AnswerButton.tsx

diff --git a/components/buttons/AnswerButton.tsx b/components/buttons/AnswerButton.tsx
new file mode 100644
index 0000000..2cc1fb6
--- /dev/null
+++ b/components/buttons/AnswerButton.tsx
@@ -0,0 +1,58 @@
+import {TouchableOpacity, Text, StyleSheet, View} from "react-native";
+import {ButtonsStyles} from "../../styles/ButtonsStyles";
+import {TextsStyles} from "../../styles/TextsStyles";
+
+interface Props{
+    text: string;
+    handleButtonPressed:() => void;
+    buttonStyle?: any;
+    buttonText?: any;
+    indicator?: number | undefined;
+}
+
+/**
+ * AnswerButton : Un bouton par défaut, il possède déjà un style mais on peut le surcharger grâce à la propriété buttonStyle
+ * @param text - Texte du bouton
+ * @param handleButtonPressed - Fonction qui sera exécutée lorsque le bouton sera pressé
+ * @param buttonStyle - Surcharge du style du bouton
+ * @param buttonText - Surcharge du style du texte du bouton
+ */
+export default function AnswerButton({text, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
+    return(
+        <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
+            {indicator !== undefined && (
+                <View style={styles.indicator}>
+                    <Text style={styles.indicatorText}>{indicator}</Text>
+                </View>
+            )}
+            <Text style={[TextsStyles.defaultButtonText, buttonText]}>{text}</Text>
+        </TouchableOpacity>
+    )
+}
+
+const styles = StyleSheet.create({
+    defaultButton: {
+        backgroundColor: "#45128C",
+        padding: 10,
+        alignItems: "center",
+        justifyContent: 'center',
+        borderRadius: 10,
+    },
+    indicator: {
+        position: "absolute",
+        top: "-16%",
+        left: "5%",
+        width: 25,
+        height: 25,
+        borderRadius: 15,
+        backgroundColor: "#D3D3D3",
+        justifyContent: "center",
+        alignItems: "center",
+        zIndex: 1,
+    },
+    indicatorText: {
+        color: "#000",
+        fontWeight: "bold",
+        fontSize: 14,
+    },
+})
\ No newline at end of file
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index da6f1f6..ea8adb4 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -9,6 +9,7 @@ import BlueButton from "../../components/buttons/BlueButton";
 import {Question} from "../../models/Question";
 import {Answer} from "../../models/Answer";
 import {Quiz} from "../../models/Quiz";
+import AnswerButton from "../../components/buttons/AnswerButton";
 
 interface Props {
     quiz: Quiz;
@@ -135,12 +136,13 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
             {currentQuestion ? (
                 <>
                     {currentQuestion.answers.map((answer, index) => (
-                        <DefaultButton
+                        <AnswerButton
                             key={index}
                             text={answer.text}
                             handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
                             buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
                             buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                            indicator={3}
                         />
                     ))}
                     {/* Ajout du PlayButton à la fin */}
-- 
GitLab


From ecc8d09827a0d909e82392dca7d9b3f22d144f2b Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 21:20:23 +0100
Subject: [PATCH 173/283] feat: testing code was pushed

---
 screens/PlayingQuiz/PlayingQuizBody.tsx | 1 -
 1 file changed, 1 deletion(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index ea8adb4..5e96e78 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -142,7 +142,6 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
                             handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
                             buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
                             buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
-                            indicator={3}
                         />
                     ))}
                     {/* Ajout du PlayButton à la fin */}
-- 
GitLab


From 34dcf3dbc68a78c23961cc8060b14aad424c1914 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 5 Jan 2025 21:31:30 +0100
Subject: [PATCH 174/283] feat: progress bar

---
 components/progressBar/ProgressBar.tsx | 46 ++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 components/progressBar/ProgressBar.tsx

diff --git a/components/progressBar/ProgressBar.tsx b/components/progressBar/ProgressBar.tsx
new file mode 100644
index 0000000..2908587
--- /dev/null
+++ b/components/progressBar/ProgressBar.tsx
@@ -0,0 +1,46 @@
+import React from "react";
+import { View, StyleSheet, Animated } from "react-native";
+
+interface Props {
+    progress: number; // Valeur entre 0 et 1 représentant la progression
+}
+
+export default function ProgressBar({ progress }: Props) {
+    // Limite la progression entre 0 et 1
+    const clampedProgress = Math.min(Math.max(progress, 0), 1);
+
+    // Calcul de la couleur en fonction de la progression
+    const interpolateColor = () => {
+        const red = Math.floor(255 * clampedProgress);
+        const blue = Math.floor(255 * (1 - clampedProgress));
+        return `rgb(${red}, 0, ${blue})`;
+    };
+
+    return (
+        <View style={styles.container}>
+            <Animated.View
+                style={[
+                    styles.progressBar,
+                    {
+                        width: `${clampedProgress * 100}%`,
+                        backgroundColor: interpolateColor(),
+                    },
+                ]}
+            />
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        height: 30, // Épaisseur de la barre
+        width: "100%",
+        backgroundColor: "#e0e0e0", // Couleur de fond
+        borderRadius: 15, // Bords arrondis
+        overflow: "hidden", // Empêche le débordement
+    },
+    progressBar: {
+        height: "100%",
+        borderRadius: 15,
+    },
+});
-- 
GitLab


From 243f9bcd7a7200ca72fedefde8e72e038dd577ad Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 6 Jan 2025 20:23:46 +0100
Subject: [PATCH 175/283] feat: progress bar color

---
 components/progressBar/ProgressBar.tsx |  39 +++---
 package-lock.json                      | 182 +++++++++++++++++++++++++
 package.json                           |   1 +
 3 files changed, 202 insertions(+), 20 deletions(-)

diff --git a/components/progressBar/ProgressBar.tsx b/components/progressBar/ProgressBar.tsx
index 2908587..38ad361 100644
--- a/components/progressBar/ProgressBar.tsx
+++ b/components/progressBar/ProgressBar.tsx
@@ -1,5 +1,6 @@
 import React from "react";
-import { View, StyleSheet, Animated } from "react-native";
+import { View, StyleSheet } from "react-native";
+import * as Progress from "react-native-progress";
 
 interface Props {
     progress: number; // Valeur entre 0 et 1 représentant la progression
@@ -11,21 +12,26 @@ export default function ProgressBar({ progress }: Props) {
 
     // Calcul de la couleur en fonction de la progression
     const interpolateColor = () => {
-        const red = Math.floor(255 * clampedProgress);
-        const blue = Math.floor(255 * (1 - clampedProgress));
-        return `rgb(${red}, 0, ${blue})`;
+        const startColor = { r: 43, g: 115, b: 254 }; // #45128C (bleu-violet)
+        const endColor = { r: 255, g: 0, b: 0 }; // Rouge
+
+        const r = Math.floor(startColor.r + (endColor.r - startColor.r) * clampedProgress);
+        const g = Math.floor(startColor.g + (endColor.g - startColor.g) * clampedProgress);
+        const b = Math.floor(startColor.b + (endColor.b - startColor.b) * clampedProgress);
+
+        return `rgb(${r}, ${g}, ${b})`;
     };
 
     return (
         <View style={styles.container}>
-            <Animated.View
-                style={[
-                    styles.progressBar,
-                    {
-                        width: `${clampedProgress * 100}%`,
-                        backgroundColor: interpolateColor(),
-                    },
-                ]}
+            <Progress.Bar
+                progress={clampedProgress}
+                width={null} // Occupe toute la largeur disponible
+                height={30} // Épaisseur de la barre
+                color={interpolateColor()} // Couleur dynamique
+                borderRadius={15} // Bords arrondis
+                unfilledColor="#e0e0e0" // Couleur de fond
+                borderWidth={0} // Supprime la bordure
             />
         </View>
     );
@@ -33,14 +39,7 @@ export default function ProgressBar({ progress }: Props) {
 
 const styles = StyleSheet.create({
     container: {
-        height: 30, // Épaisseur de la barre
         width: "100%",
-        backgroundColor: "#e0e0e0", // Couleur de fond
-        borderRadius: 15, // Bords arrondis
-        overflow: "hidden", // Empêche le débordement
-    },
-    progressBar: {
-        height: "100%",
-        borderRadius: 15,
+        padding: 10, // Ajoute un espace autour de la barre
     },
 });
diff --git a/package-lock.json b/package-lock.json
index 34cf915..74090c7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
         "react-i18next": "^15.1.1",
         "react-native": "0.76.3",
         "react-native-dropdown-select-list": "^2.0.5",
+        "react-native-progress": "^5.0.1",
         "react-native-safe-area-context": "^4.12.0",
         "react-native-screens": "~4.1.0",
         "react-native-vector-icons": "^10.2.0",
@@ -4718,6 +4719,13 @@
         "node": "*"
       }
     },
+    "node_modules/boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+      "license": "ISC",
+      "peer": true
+    },
     "node_modules/bplist-creator": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz",
@@ -5443,6 +5451,60 @@
         "node": ">=8"
       }
     },
+    "node_modules/css-select": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+      "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+      "license": "BSD-2-Clause",
+      "peer": true,
+      "dependencies": {
+        "boolbase": "^1.0.0",
+        "css-what": "^6.1.0",
+        "domhandler": "^5.0.2",
+        "domutils": "^3.0.1",
+        "nth-check": "^2.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/css-tree": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+      "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "mdn-data": "2.0.14",
+        "source-map": "^0.6.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/css-tree/node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "license": "BSD-3-Clause",
+      "peer": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/css-what": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+      "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+      "license": "BSD-2-Clause",
+      "peer": true,
+      "engines": {
+        "node": ">= 6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
     "node_modules/csstype": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@@ -5614,6 +5676,65 @@
         "node": ">=8"
       }
     },
+    "node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause",
+      "peer": true
+    },
+    "node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "license": "BSD-2-Clause",
+      "peer": true,
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/domutils": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.1.tgz",
+      "integrity": "sha512-xWXmuRnN9OMP6ptPd2+H0cCbcYBULa5YDTbMm/2lvkWvNA3O4wcW+GvzooqBuNM8yy6pl3VIAeJTUUWUbfI5Fw==",
+      "license": "BSD-2-Clause",
+      "peer": true,
+      "dependencies": {
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
     "node_modules/dotenv": {
       "version": "16.4.5",
       "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
@@ -5683,6 +5804,19 @@
         "once": "^1.4.0"
       }
     },
+    "node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "license": "BSD-2-Clause",
+      "peer": true,
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
     "node_modules/env-editor": {
       "version": "0.4.2",
       "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz",
@@ -7822,6 +7956,13 @@
         "node": ">=0.10"
       }
     },
+    "node_modules/mdn-data": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+      "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+      "license": "CC0-1.0",
+      "peer": true
+    },
     "node_modules/memoize-one": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@@ -8635,6 +8776,19 @@
         "node": ">=4"
       }
     },
+    "node_modules/nth-check": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+      "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+      "license": "BSD-2-Clause",
+      "peer": true,
+      "dependencies": {
+        "boolbase": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/nth-check?sponsor=1"
+      }
+    },
     "node_modules/nullthrows": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
@@ -9533,6 +9687,18 @@
       "integrity": "sha512-TepbcagQVUMB6nLuIlVU2ghRpQHAECOeZWe8K04ymW6NqbKbxuczZSDFfdCiABiiQ2dFD+8Dz65y4K7/uUEqGg==",
       "license": "MIT"
     },
+    "node_modules/react-native-progress": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/react-native-progress/-/react-native-progress-5.0.1.tgz",
+      "integrity": "sha512-TYfJ4auAe5vubDma2yfFvt7ktSI+UCfysqJnkdHEcLXqAitRFOozgF/cLgN5VNi/iLdaf3ga1ETi2RF4jVZ/+g==",
+      "license": "MIT",
+      "dependencies": {
+        "prop-types": "^15.7.2"
+      },
+      "peerDependencies": {
+        "react-native-svg": "*"
+      }
+    },
     "node_modules/react-native-safe-area-context": {
       "version": "4.12.0",
       "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.12.0.tgz",
@@ -9557,6 +9723,22 @@
         "react-native": "*"
       }
     },
+    "node_modules/react-native-svg": {
+      "version": "15.10.1",
+      "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.10.1.tgz",
+      "integrity": "sha512-Hqz/doQciVFK/Df2v+wsW96oY5jxlta7rZ31KQYo78dlgvAHEaGr6paEOAMvlIruw7EHNQ0Vc1ZmJPJF2kfIPQ==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "css-select": "^5.1.0",
+        "css-tree": "^1.1.3",
+        "warn-once": "0.1.1"
+      },
+      "peerDependencies": {
+        "react": "*",
+        "react-native": "*"
+      }
+    },
     "node_modules/react-native-vector-icons": {
       "version": "10.2.0",
       "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-10.2.0.tgz",
diff --git a/package.json b/package.json
index b58c2ac..c2f6b34 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
     "react-i18next": "^15.1.1",
     "react-native": "0.76.3",
     "react-native-dropdown-select-list": "^2.0.5",
+    "react-native-progress": "^5.0.1",
     "react-native-safe-area-context": "^4.12.0",
     "react-native-screens": "~4.1.0",
     "react-native-vector-icons": "^10.2.0",
-- 
GitLab


From 93f7c95c8e8bd421d9a400b9548892effa197315 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 6 Jan 2025 20:25:17 +0100
Subject: [PATCH 176/283] feat: progress bar height

---
 components/progressBar/ProgressBar.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/progressBar/ProgressBar.tsx b/components/progressBar/ProgressBar.tsx
index 38ad361..fbf4cb5 100644
--- a/components/progressBar/ProgressBar.tsx
+++ b/components/progressBar/ProgressBar.tsx
@@ -27,7 +27,7 @@ export default function ProgressBar({ progress }: Props) {
             <Progress.Bar
                 progress={clampedProgress}
                 width={null} // Occupe toute la largeur disponible
-                height={30} // Épaisseur de la barre
+                height={25} // Épaisseur de la barre
                 color={interpolateColor()} // Couleur dynamique
                 borderRadius={15} // Bords arrondis
                 unfilledColor="#e0e0e0" // Couleur de fond
-- 
GitLab


From 628883db40447f451e7275d998492650124da855 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 20:41:19 +0100
Subject: [PATCH 177/283] refactor: sort multiplayer file like the global
 refactor

---
 routes/StackNavigator.tsx                            |  8 ++++----
 screens/{ => Multiplayer}/Lobby/Lobby.tsx            |  0
 .../MultiplayerCommunity/MultiplayerCommunity.tsx    |  8 ++++----
 .../OngoingQuizzes/OngoingQuizzes.tsx                |  8 ++++----
 .../OnlineQuiz/OnlineCreateLobby.tsx                 |  8 ++++----
 .../{ => Multiplayer}/OnlineQuiz/OnlinePlayQuiz.tsx  | 12 ++++++------
 screens/{ => Multiplayer}/OnlineQuiz/OnlineQuiz.tsx  |  2 +-
 .../{ => Multiplayer}/OnlineQuiz/OnlineQuizChild.tsx |  2 +-
 .../OnlineQuiz/OnlineSelectMode.tsx                  |  2 +-
 9 files changed, 25 insertions(+), 25 deletions(-)
 rename screens/{ => Multiplayer}/Lobby/Lobby.tsx (100%)
 rename screens/{ => Multiplayer}/MultiplayerCommunity/MultiplayerCommunity.tsx (92%)
 rename screens/{ => Multiplayer}/OngoingQuizzes/OngoingQuizzes.tsx (89%)
 rename screens/{ => Multiplayer}/OnlineQuiz/OnlineCreateLobby.tsx (93%)
 rename screens/{ => Multiplayer}/OnlineQuiz/OnlinePlayQuiz.tsx (88%)
 rename screens/{ => Multiplayer}/OnlineQuiz/OnlineQuiz.tsx (92%)
 rename screens/{ => Multiplayer}/OnlineQuiz/OnlineQuizChild.tsx (94%)
 rename screens/{ => Multiplayer}/OnlineQuiz/OnlineSelectMode.tsx (97%)

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index f81935e..2fbc28e 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -6,10 +6,10 @@ import EndQuiz from "../screens/PlayingQuiz/EndQuiz/EndQuiz";
 import PlayingQuiz from "../screens/PlayingQuiz/PlayingQuiz";
 import TabNavigator from "./TabNavigation";
 import Multiplayer from "../screens/Multiplayer/Multiplayer";
-import MultiplayerCommunity from "../screens/MultiplayerCommunity/MultiplayerCommunity";
-import OnlineQuiz from "../screens/OnlineQuiz/OnlineQuiz";
-import OngoingQuizzes from "../screens/OngoingQuizzes/OngoingQuizzes";
-import Lobby from "../screens/Lobby/Lobby";
+import MultiplayerCommunity from "../screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity";
+import OnlineQuiz from "../screens/Multiplayer/OnlineQuiz/OnlineQuiz";
+import OngoingQuizzes from "../screens/Multiplayer/OngoingQuizzes/OngoingQuizzes";
+import Lobby from "../screens/Multiplayer/Lobby/Lobby";
 import PlayQuiz from "../screens/Home/PlayQuiz/PlayQuiz";
 import MyQuizzes from "../screens/Home/MyQuizzes/MyQuizzes";
 import InformationsOfQuiz from "../screens/Community/InformationsOfQuiz/InformationsOfQuiz";
diff --git a/screens/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
similarity index 100%
rename from screens/Lobby/Lobby.tsx
rename to screens/Multiplayer/Lobby/Lobby.tsx
diff --git a/screens/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
similarity index 92%
rename from screens/MultiplayerCommunity/MultiplayerCommunity.tsx
rename to screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index cb9dcc8..8da6d0c 100644
--- a/screens/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -1,11 +1,11 @@
 import {View, Text, Modal, TextInput} from "react-native";
-import TemplateQuizList from "../../templates/TemplateQuizList";
+import TemplateQuizList from "../../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import React, {useState} from "react";
-import {useQuizService} from "../../services/QuizService";
-import HttpError from "../../services/HttpError";
+import {useQuizService} from "../../../services/QuizService";
+import HttpError from "../../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
-import { Quiz } from "../../models/Quiz";
+import { Quiz } from "../../../models/Quiz";
 import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
diff --git a/screens/OngoingQuizzes/OngoingQuizzes.tsx b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
similarity index 89%
rename from screens/OngoingQuizzes/OngoingQuizzes.tsx
rename to screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
index 64502b9..ca24520 100644
--- a/screens/OngoingQuizzes/OngoingQuizzes.tsx
+++ b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
@@ -1,11 +1,11 @@
 import {View, Text} from "react-native";
-import TemplateQuizList from "../../templates/TemplateQuizList";
+import TemplateQuizList from "../../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import {useEffect, useState} from "react";
-import {useQuizService} from "../../services/QuizService";
-import HttpError from "../../services/HttpError";
+import {useQuizService} from "../../../services/QuizService";
+import HttpError from "../../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
-import { Quiz } from "../../models/Quiz";
+import { Quiz } from "../../../models/Quiz";
 import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
diff --git a/screens/OnlineQuiz/OnlineCreateLobby.tsx b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
similarity index 93%
rename from screens/OnlineQuiz/OnlineCreateLobby.tsx
rename to screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
index 95f7a94..62756f5 100644
--- a/screens/OnlineQuiz/OnlineCreateLobby.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
@@ -1,10 +1,10 @@
 import { Text,View, StyleSheet } from "react-native";
-import SelectListBox from "../../components/PlayQuiz/SelectListBox";
+import SelectListBox from "../../../components/PlayQuiz/SelectListBox";
 import React, {useEffect} from "react";
-import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
+import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
-import {getIdOfCategory} from "../../helper/QuizHelper";
-import {useQuizService} from "../../services/QuizService";
+import {getIdOfCategory} from "../../../helper/QuizHelper";
+import {useQuizService} from "../../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
 
 const difficulty = [
diff --git a/screens/OnlineQuiz/OnlinePlayQuiz.tsx b/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
similarity index 88%
rename from screens/OnlineQuiz/OnlinePlayQuiz.tsx
rename to screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
index 48f212f..958dd33 100644
--- a/screens/OnlineQuiz/OnlinePlayQuiz.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
@@ -1,12 +1,12 @@
 import { StyleSheet, View, Text } from "react-native";
-import AboutAQuiz from "../../components/PlayQuiz/AboutAQuiz";
+import AboutAQuiz from "../../../components/PlayQuiz/AboutAQuiz";
 import BlueButton from "../../components/PlayQuiz/BlueButton";
 import React, { useEffect } from "react";
-import InputPlayQuiz from "../../components/PlayQuiz/InputPlayQuiz";
-import {Quiz} from "../../models/Quiz";
-import { useQuizService } from "../../services/QuizService";
-import HttpError from "../../services/HttpError";
-import {getIdOfCategory} from "../../helper/QuizHelper";
+import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
+import {Quiz} from "../../../models/Quiz";
+import { useQuizService } from "../../../services/QuizService";
+import HttpError from "../../../services/HttpError";
+import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {NavigationProp} from "@react-navigation/native";
 
 interface Props {
diff --git a/screens/OnlineQuiz/OnlineQuiz.tsx b/screens/Multiplayer/OnlineQuiz/OnlineQuiz.tsx
similarity index 92%
rename from screens/OnlineQuiz/OnlineQuiz.tsx
rename to screens/Multiplayer/OnlineQuiz/OnlineQuiz.tsx
index 76c45c3..7b3ce82 100644
--- a/screens/OnlineQuiz/OnlineQuiz.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineQuiz.tsx
@@ -1,6 +1,6 @@
 import { NavigationProp } from "@react-navigation/native";
 import { View, StyleSheet } from "react-native";
-import TemplateMenu from "../../templates/TemplateMenu";
+import TemplateMenu from "../../../templates/TemplateMenu";
 import OnlineQuizChild from "./OnlineQuizChild";
 
 interface Props{
diff --git a/screens/OnlineQuiz/OnlineQuizChild.tsx b/screens/Multiplayer/OnlineQuiz/OnlineQuizChild.tsx
similarity index 94%
rename from screens/OnlineQuiz/OnlineQuizChild.tsx
rename to screens/Multiplayer/OnlineQuiz/OnlineQuizChild.tsx
index 15c561b..ce6258b 100644
--- a/screens/OnlineQuiz/OnlineQuizChild.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineQuizChild.tsx
@@ -1,6 +1,6 @@
 import { NavigationProp } from "@react-navigation/native";
 import { useState } from "react";
-import { OnlineSelectModeType, SelectModeType } from "../../models/SelectModeType";
+import { OnlineSelectModeType, SelectModeType } from "../../../models/SelectModeType";
 import { TouchableWithoutFeedback, View, StyleSheet, Keyboard } from "react-native";
 import OnlineSelectMode from "./OnlineSelectMode";
 import OnlineCreateLobby from "./OnlineCreateLobby";
diff --git a/screens/OnlineQuiz/OnlineSelectMode.tsx b/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
similarity index 97%
rename from screens/OnlineQuiz/OnlineSelectMode.tsx
rename to screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
index 8275f69..0f27af3 100644
--- a/screens/OnlineQuiz/OnlineSelectMode.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
@@ -1,5 +1,5 @@
 import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
-import { OnlineSelectModeType } from "../../models/SelectModeType";
+import { OnlineSelectModeType } from "../../../models/SelectModeType";
 
 interface Props {
     mode: OnlineSelectModeType;
-- 
GitLab


From 60a434d99111f1dbeed10b45fa870dc74f3bb9b4 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 20:47:10 +0100
Subject: [PATCH 178/283] refactor: replace default button by Blue/white Button

---
 .../MultiplayerCommunity/MultiplayerCommunity.tsx      | 10 ++++++----
 screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx  |  5 +++--
 screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx   |  2 +-
 screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx      |  4 ++--
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index 8da6d0c..555dadb 100644
--- a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -6,7 +6,9 @@ import {useQuizService} from "../../../services/QuizService";
 import HttpError from "../../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
 import { Quiz } from "../../../models/Quiz";
-import DefaultButton from "../../components/DefaultButton";
+import WhiteButton from "../../../components/buttons/WhiteButton";
+import BlueButton from "../../../components/buttons/BlueButton";
+// import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -75,9 +77,9 @@ export default function MultiplayerCommunity({navigation}: Props) {
                     <View>
                         <Text>CREATE A LOBBY</Text>
                         <Text>NUMBER OF PLAYER</Text>
-                        <TextInput></TextInput>
-                        <DefaultButton text="CLOSE" handleButtonPressed={onClosePressed}/>
-                        <DefaultButton text="PLAY" handleButtonPressed={onPlayPressed}/>
+                        <TextInput/>
+                        <WhiteButton text="CLOSE" onPress={onClosePressed} isDisabled={false}/>
+                        <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
                     </View>
                 </View>
             </Modal>
diff --git a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
index ca24520..89dee2a 100644
--- a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
+++ b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
@@ -6,7 +6,8 @@ import {useQuizService} from "../../../services/QuizService";
 import HttpError from "../../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
 import { Quiz } from "../../../models/Quiz";
-import DefaultButton from "../../components/DefaultButton";
+import BlueButton from "../../../components/buttons/BlueButton";
+// import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -53,7 +54,7 @@ export default function Community({navigation}: Props) {
     return (
         <View>
             <TemplateQuizList title={"Ongoing Quizzes"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
-            <DefaultButton text="JOIN" handleButtonPressed={onJoinPressed}/>
+            <BlueButton text="JOIN" onPress={onJoinPressed} isDisabled={false}/>
         </View>
     );
 }
\ No newline at end of file
diff --git a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
index 62756f5..b59c626 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
@@ -2,10 +2,10 @@ import { Text,View, StyleSheet } from "react-native";
 import SelectListBox from "../../../components/PlayQuiz/SelectListBox";
 import React, {useEffect} from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
-import BlueButton from "../../components/PlayQuiz/BlueButton";
 import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {useQuizService} from "../../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
+import BlueButton from "../../../components/buttons/BlueButton";
 
 const difficulty = [
     { key: "easy", value: "easy" },
diff --git a/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx b/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
index 958dd33..d298d8c 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
@@ -1,13 +1,13 @@
 import { StyleSheet, View, Text } from "react-native";
 import AboutAQuiz from "../../../components/PlayQuiz/AboutAQuiz";
-import BlueButton from "../../components/PlayQuiz/BlueButton";
 import React, { useEffect } from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import {Quiz} from "../../../models/Quiz";
 import { useQuizService } from "../../../services/QuizService";
 import HttpError from "../../../services/HttpError";
-import {getIdOfCategory} from "../../../helper/QuizHelper";
+// import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {NavigationProp} from "@react-navigation/native";
+import BlueButton from "../../../components/buttons/BlueButton";
 
 interface Props {
     navigation: NavigationProp<any>;
-- 
GitLab


From 9b2b2dad7c71792d92caef55bb435de300053da1 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 21:02:07 +0100
Subject: [PATCH 179/283] feat: add button on multiplayer community page

---
 .../MultiplayerCommunity.tsx                  | 35 ++++++++++++++++---
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index 555dadb..5f3a18f 100644
--- a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -1,4 +1,4 @@
-import {View, Text, Modal, TextInput} from "react-native";
+import {View, Text, Modal, TextInput, StyleSheet} from "react-native";
 import TemplateQuizList from "../../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import React, {useState} from "react";
@@ -8,7 +8,6 @@ import {useInfiniteQuery} from "@tanstack/react-query";
 import { Quiz } from "../../../models/Quiz";
 import WhiteButton from "../../../components/buttons/WhiteButton";
 import BlueButton from "../../../components/buttons/BlueButton";
-// import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -69,9 +68,18 @@ export default function MultiplayerCommunity({navigation}: Props) {
             return allPages.length * 7;
         }});
 
+    const onCreateLobbyPressed = () => {
+        setShowModal(true);
+    };
+
     return (
-        <View>
-            <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+        <View style={styles.containerGlobal}>
+            <View style={styles.templateQuizListContainer}>
+                <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+            </View>
+            <View style={styles.buttonContainer}>
+                <BlueButton text="CREATE LOBBY" onPress={onCreateLobbyPressed}  isDisabled={false}/>
+            </View>
             <Modal visible={showModal}>
                 <View>
                     <View>
@@ -85,4 +93,21 @@ export default function MultiplayerCommunity({navigation}: Props) {
             </Modal>
         </View>
     );
-}
\ No newline at end of file
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        flexDirection: 'column',
+    },
+    templateQuizListContainer: {
+        height: '90%',
+    },
+    buttonContainer: {
+        height: '10%',
+        width: '95%',
+        marginLeft: '2.5%',
+    }
+});
\ No newline at end of file
-- 
GitLab


From f9a3f877d29bdb4694f738ebfb36034b1dc8d879 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 21:05:15 +0100
Subject: [PATCH 180/283] feat: modify action when quiz is pressed

---
 .../MultiplayerCommunity/MultiplayerCommunity.tsx     | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index 5f3a18f..e890761 100644
--- a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -17,6 +17,7 @@ export default function MultiplayerCommunity({navigation}: Props) {
     const [input, setInput] = useState<string>("")
     const [loading, setLoading] = useState<boolean>(false)
     const [showModal, setShowModal] = useState<boolean>(false);
+    const [quiz, setQuiz] = useState<Quiz | null>(null);
 
     const fetchCommunityQuizzes = async ({pageParam = 1}) => {
         const quizzes = await getCommunityQuiz(pageParam,7);
@@ -27,10 +28,14 @@ export default function MultiplayerCommunity({navigation}: Props) {
         return quizzes;
     }
 
-    const onQuizPressed = (quiz: Quiz) => {
+    const onCreateLobbyPressed = () => {
         setShowModal(true);
     };
 
+    const onQuizPressed = (quiz: Quiz) => {
+        setQuiz(quiz);
+    };
+
     const onClosePressed = () => {
         setShowModal(false);
     };
@@ -68,9 +73,7 @@ export default function MultiplayerCommunity({navigation}: Props) {
             return allPages.length * 7;
         }});
 
-    const onCreateLobbyPressed = () => {
-        setShowModal(true);
-    };
+    
 
     return (
         <View style={styles.containerGlobal}>
-- 
GitLab


From d4aed3bd7449aa4c975bbba9d7c72f7aabd7bf6c Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 21:13:35 +0100
Subject: [PATCH 181/283] feat: create modal create lobby

---
 components/Multiplayer/ModalCreateLobby.tsx   | 25 +++++++++++++++++++
 .../MultiplayerCommunity.tsx                  | 13 ++--------
 2 files changed, 27 insertions(+), 11 deletions(-)
 create mode 100644 components/Multiplayer/ModalCreateLobby.tsx

diff --git a/components/Multiplayer/ModalCreateLobby.tsx b/components/Multiplayer/ModalCreateLobby.tsx
new file mode 100644
index 0000000..f55e56e
--- /dev/null
+++ b/components/Multiplayer/ModalCreateLobby.tsx
@@ -0,0 +1,25 @@
+import { Modal, View, Text, TextInput } from "react-native";
+import WhiteButton from "../buttons/WhiteButton";
+import BlueButton from "../buttons/BlueButton";
+
+interface Props {
+    showModal: boolean;
+    onClosePressed: () => void;
+    onPlayPressed: () => void;
+}
+
+export default function ModalCreateLobby({showModal, onClosePressed, onPlayPressed}: Props) {
+    return (
+        <Modal visible={showModal}>
+            <View>
+                <View>
+                    <Text>CREATE A LOBBY</Text>
+                    <Text>NUMBER OF PLAYER</Text>
+                    <TextInput/>
+                    <WhiteButton text="CLOSE" onPress={onClosePressed} isDisabled={false}/>
+                    <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
+                </View>
+            </View>
+        </Modal>
+    );
+}
\ No newline at end of file
diff --git a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index e890761..decdc8b 100644
--- a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -8,6 +8,7 @@ import {useInfiniteQuery} from "@tanstack/react-query";
 import { Quiz } from "../../../models/Quiz";
 import WhiteButton from "../../../components/buttons/WhiteButton";
 import BlueButton from "../../../components/buttons/BlueButton";
+import ModalCreateLobby from "../../../components/Multiplayer/ModalCreateLobby";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -83,17 +84,7 @@ export default function MultiplayerCommunity({navigation}: Props) {
             <View style={styles.buttonContainer}>
                 <BlueButton text="CREATE LOBBY" onPress={onCreateLobbyPressed}  isDisabled={false}/>
             </View>
-            <Modal visible={showModal}>
-                <View>
-                    <View>
-                        <Text>CREATE A LOBBY</Text>
-                        <Text>NUMBER OF PLAYER</Text>
-                        <TextInput/>
-                        <WhiteButton text="CLOSE" onPress={onClosePressed} isDisabled={false}/>
-                        <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
-                    </View>
-                </View>
-            </Modal>
+            <ModalCreateLobby onClosePressed={onClosePressed} onPlayPressed={onPlayPressed} showModal={showModal}/>
         </View>
     );
 }
-- 
GitLab


From ab06b58c8f21e61fb79b9661ab09fbc436415117 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 21:48:52 +0100
Subject: [PATCH 182/283] style: add style for modal create lobby

---
 components/Multiplayer/ModalCreateLobby.tsx | 92 ++++++++++++++++++---
 1 file changed, 82 insertions(+), 10 deletions(-)

diff --git a/components/Multiplayer/ModalCreateLobby.tsx b/components/Multiplayer/ModalCreateLobby.tsx
index f55e56e..7b084a1 100644
--- a/components/Multiplayer/ModalCreateLobby.tsx
+++ b/components/Multiplayer/ModalCreateLobby.tsx
@@ -1,6 +1,8 @@
-import { Modal, View, Text, TextInput } from "react-native";
+import { Modal, View, Text, TextInput, StyleSheet } from "react-native";
 import WhiteButton from "../buttons/WhiteButton";
 import BlueButton from "../buttons/BlueButton";
+import babelConfig from "../../babel.config";
+import DefaultButton from "../buttons/DefaultButton";
 
 interface Props {
     showModal: boolean;
@@ -10,16 +12,86 @@ interface Props {
 
 export default function ModalCreateLobby({showModal, onClosePressed, onPlayPressed}: Props) {
     return (
-        <Modal visible={showModal}>
-            <View>
-                <View>
-                    <Text>CREATE A LOBBY</Text>
-                    <Text>NUMBER OF PLAYER</Text>
-                    <TextInput/>
-                    <WhiteButton text="CLOSE" onPress={onClosePressed} isDisabled={false}/>
-                    <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
+        <Modal visible={showModal} animationType="slide" transparent={true}>
+            <View style={styles.centeredView}>
+                <View style={styles.modalView}>
+                    <Text style={styles.title}>CREATE A LOBBY</Text>
+                    <View style={styles.inputGroup}>
+                        <Text>NUMBER OF PLAYER</Text>
+                        <TextInput style={styles.input}/>
+                    </View>
+                    <View style={styles.buttonGroup}>
+                        <View style={styles.button}>
+                            <WhiteButton text="CLOSE" onPress={onClosePressed} isDisabled={false}/>
+                        </View>   
+                        <View style={styles.button}>
+                            <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
+                        </View>
+                    </View>
                 </View>
             </View>
         </Modal>
     );
-}
\ No newline at end of file
+}
+
+const styles = StyleSheet.create({
+    centeredView: {
+        flex: 1,
+        justifyContent: 'center',
+        alignItems: 'center',
+        backgroundColor: 'rgba(0, 0, 0, 0.5)'
+    },
+    modalView: {
+        display: 'flex',
+        justifyContent: 'space-between',
+        height: '50%',
+        width: '90%',
+        margin: '10%',
+        padding: '5%',
+        backgroundColor: 'white',
+        borderRadius: 20,
+        alignItems: 'center',
+        shadowColor: '#000',
+        shadowOffset: {
+            width: 0,
+            height: 2,
+        },
+        shadowOpacity: 0.25,
+        shadowRadius: 4,
+        elevation: 5,
+    },
+    buttonGroup: {
+        flexDirection: 'row',
+        justifyContent: 'space-between',
+        width: '100%',
+    },
+    button: {
+        width: '45%',
+    },
+    title: {
+        fontSize: 40,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+        alignSelf: "center", // Centre uniquement le titre
+        textAlign: 'center',
+    },
+    inputGroup: {
+        width: '100%',
+        marginBottom: 20,
+    },
+    input: {
+        width: "100%",
+        height: 70,
+        backgroundColor: "white",
+        borderColor: "#2ec7ff",
+        borderWidth: 3,
+        borderRadius: 8,
+        paddingLeft: 10,
+        elevation: 5,
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 4 },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.84,
+    },
+});
\ No newline at end of file
-- 
GitLab


From c55978fd13cc60b4d027eef4e69a6f01a77c072d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 22:03:13 +0100
Subject: [PATCH 183/283] feat: action on play pressed

---
 components/Multiplayer/ModalCreateLobby.tsx   | 10 +++++-----
 .../MultiplayerCommunity.tsx                  | 20 ++++---------------
 2 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/components/Multiplayer/ModalCreateLobby.tsx b/components/Multiplayer/ModalCreateLobby.tsx
index 7b084a1..f87b518 100644
--- a/components/Multiplayer/ModalCreateLobby.tsx
+++ b/components/Multiplayer/ModalCreateLobby.tsx
@@ -1,16 +1,16 @@
 import { Modal, View, Text, TextInput, StyleSheet } from "react-native";
 import WhiteButton from "../buttons/WhiteButton";
 import BlueButton from "../buttons/BlueButton";
-import babelConfig from "../../babel.config";
-import DefaultButton from "../buttons/DefaultButton";
+import { useState } from "react";
 
 interface Props {
     showModal: boolean;
     onClosePressed: () => void;
-    onPlayPressed: () => void;
+    onPlayPressed: (nbPlayer: number) => void;
 }
 
 export default function ModalCreateLobby({showModal, onClosePressed, onPlayPressed}: Props) {
+    const [nbPlayer, setNbPlayer] = useState<number>(1);
     return (
         <Modal visible={showModal} animationType="slide" transparent={true}>
             <View style={styles.centeredView}>
@@ -18,14 +18,14 @@ export default function ModalCreateLobby({showModal, onClosePressed, onPlayPress
                     <Text style={styles.title}>CREATE A LOBBY</Text>
                     <View style={styles.inputGroup}>
                         <Text>NUMBER OF PLAYER</Text>
-                        <TextInput style={styles.input}/>
+                        <TextInput style={styles.input} defaultValue={nbPlayer.toString()} onChangeText={(text) => setNbPlayer(Number(text))}/>
                     </View>
                     <View style={styles.buttonGroup}>
                         <View style={styles.button}>
                             <WhiteButton text="CLOSE" onPress={onClosePressed} isDisabled={false}/>
                         </View>   
                         <View style={styles.button}>
-                            <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
+                            <BlueButton text="PLAY" onPress={() => onPlayPressed(nbPlayer)} isDisabled={false}/>
                         </View>
                     </View>
                 </View>
diff --git a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index decdc8b..8d7723a 100644
--- a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -21,7 +21,7 @@ export default function MultiplayerCommunity({navigation}: Props) {
     const [quiz, setQuiz] = useState<Quiz | null>(null);
 
     const fetchCommunityQuizzes = async ({pageParam = 1}) => {
-        const quizzes = await getCommunityQuiz(pageParam,7);
+        const quizzes = await getCommunityQuiz(pageParam,7);//TODO: changer pour get les quiz community public
         if (HttpError.isHttpError(quizzes)) {
             console.error("Error while fetching community quizzes:", quizzes);
             return [];
@@ -41,24 +41,12 @@ export default function MultiplayerCommunity({navigation}: Props) {
         setShowModal(false);
     };
 
-    const onPlayPressed = async () => {
+    const onPlayPressed = async (nbPlayer: number) => {
         setShowModal(false);
-        const quizData = await getRandomQuiz() //TODO: change the quiz who's getting played
-        if (quizData instanceof HttpError) {
-            console.error("Error while fetching random quiz:", quizData);
-            return;
-        }
-        navigation.reset({
-            index: 0,
-            routes: [
-                {
-                    name: "PlayingQuiz",
-                    params: {quizRecovered: quizData},
-                },
-            ]
-        });
+        navigation.navigate("Lobby", {quiz: quiz, nbPlayer: nbPlayer});
     };
 
+
     const {
         data,
         fetchNextPage,
-- 
GitLab


From 53ca5bc3c17940b919f7af39494ee65282916fc6 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 22:07:13 +0100
Subject: [PATCH 184/283] style: change color of active page

---
 screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx b/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
index 0f27af3..59ec2c2 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
@@ -57,7 +57,7 @@ const styles = StyleSheet.create({
         color: '#bebebe',
     },
     activeText: {
-        color: '#2b73fe',
+        color: '#2ec7ff',
     },
     bar: {
         width: '100%',
@@ -66,7 +66,7 @@ const styles = StyleSheet.create({
         borderRadius: 10,
     },
     activeBar: {
-        backgroundColor: '#2b73fe', // Couleur pour le bouton actif
+        backgroundColor: '#2ec7ff', // Couleur pour le bouton actif
     },
     inactiveBar: {
         backgroundColor: '#bebebe', // Couleur grise pour les boutons inactifs
-- 
GitLab


From e1a535f6ce44998434d2f19b0f1bb5af20693aaf Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 22:13:12 +0100
Subject: [PATCH 185/283] feat: add number of player to create lobby form

---
 screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
index b59c626..177d4b6 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
@@ -37,6 +37,7 @@ export default function OnlineCreateLobby({navigation}: Props) {
     const [difficutlyChoose, setDifficutlyChoose] = React.useState("");
     const [categoryChoose, setCategoryChoose] = React.useState("");
     const [nbQuestions, setNbQuestions] = React.useState("10");
+    const [nbPlayers, setNbPlayers] = React.useState("2");
     const [buttonIsDisabled, setButtonIsDisabled] = React.useState(true);
     const {generateQuiz} = useQuizService();
 
@@ -58,8 +59,8 @@ export default function OnlineCreateLobby({navigation}: Props) {
             index: 0,
             routes: [
                 {
-                    name: "PlayingQuiz",
-                    params: {quizRecovered: quizGenerated},
+                    name: "Lobby",
+                    params: {quizGenerated: quizGenerated, nbPlayers: parseInt(nbPlayers)},
                 },
             ]
         });
@@ -71,7 +72,8 @@ export default function OnlineCreateLobby({navigation}: Props) {
                 <View style={styles.fieldContainer}>
                     <SelectListBox title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
                     <SelectListBox title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
-                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} defaultValue={nbQuestions}/>
+                    <InputPlayQuiz title="NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} defaultValue={nbQuestions}/>
+                    <InputPlayQuiz title="NUMBER OF PLAYERS" setText={setNbPlayers} numeric={true} defaultValue={nbPlayers}/>
                 </View>
                 <View style={styles.buttonPlayContainer}>
                     <BlueButton onPress={handlePlayButtonPress} text={"CREATE LOBBY"} isDisabled={buttonIsDisabled}/>
-- 
GitLab


From cb22560531b9ebce0c22f7d0ed25347e555a8b42 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Mon, 6 Jan 2025 22:22:22 +0100
Subject: [PATCH 186/283] feat: add button to ongoinQuizzes

---
 .../OngoingQuizzes/OngoingQuizzes.tsx         | 32 +++++++++++++++----
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
index 89dee2a..ace408c 100644
--- a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
+++ b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
@@ -1,4 +1,4 @@
-import {View, Text} from "react-native";
+import {View, StyleSheet} from "react-native";
 import TemplateQuizList from "../../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
 import {useEffect, useState} from "react";
@@ -7,7 +7,6 @@ import HttpError from "../../../services/HttpError";
 import {useInfiniteQuery} from "@tanstack/react-query";
 import { Quiz } from "../../../models/Quiz";
 import BlueButton from "../../../components/buttons/BlueButton";
-// import DefaultButton from "../../components/DefaultButton";
 
 interface Props {
     navigation: NavigationProp<any>
@@ -35,7 +34,7 @@ export default function Community({navigation}: Props) {
         navigation.goBack();
     };
 
-
+    //TODO: changer la fonction de fetch
     const {
         data,
         fetchNextPage,
@@ -53,8 +52,29 @@ export default function Community({navigation}: Props) {
 
     return (
         <View>
-            <TemplateQuizList title={"Ongoing Quizzes"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
-            <BlueButton text="JOIN" onPress={onJoinPressed} isDisabled={false}/>
+            <View style={styles.templateQuizListContainer}>
+                <TemplateQuizList title={"Ongoing Quizzes"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+            </View>
+            <View style={styles.buttonContainer}>
+                <BlueButton text="JOIN" onPress={onJoinPressed} isDisabled={false}/>
+            </View>
         </View>
     );
-}
\ No newline at end of file
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        flexDirection: 'column',
+    },
+    templateQuizListContainer: {
+        height: '90%',
+    },
+    buttonContainer: {
+        height: '10%',
+        width: '95%',
+        marginLeft: '2.5%',
+    }
+});
\ No newline at end of file
-- 
GitLab


From 3bd1174f9dffdb739c3a8b9604a5ca578f391e42 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 7 Jan 2025 17:37:44 +0100
Subject: [PATCH 187/283] chore: rename file

---
 .../PlayQuiz/{SelectListBox.tsx => SelectListBoxString.tsx}     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename components/PlayQuiz/{SelectListBox.tsx => SelectListBoxString.tsx} (96%)

diff --git a/components/PlayQuiz/SelectListBox.tsx b/components/PlayQuiz/SelectListBoxString.tsx
similarity index 96%
rename from components/PlayQuiz/SelectListBox.tsx
rename to components/PlayQuiz/SelectListBoxString.tsx
index 12612f6..5bca1d5 100644
--- a/components/PlayQuiz/SelectListBox.tsx
+++ b/components/PlayQuiz/SelectListBoxString.tsx
@@ -9,7 +9,7 @@ interface Props {
 
 }
 
-export default function SelectListBox({data, setSelected, title} : Props) {
+export default function SelectListBoxString({data, setSelected, title} : Props) {
 
     return (
         <View style={styles.container}>
-- 
GitLab


From 961f4903b69e7ecb619ae449b08cc22f0854b2c0 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 7 Jan 2025 17:51:07 +0100
Subject: [PATCH 188/283] feat: adding service to fetch categories

---
 models/Quiz.ts          |  2 +-
 services/QuizService.ts | 20 +++++++++++++++++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/models/Quiz.ts b/models/Quiz.ts
index d02f93a..b5087c2 100644
--- a/models/Quiz.ts
+++ b/models/Quiz.ts
@@ -5,7 +5,7 @@ interface Difficulty {
     name: string;
 }
 
-interface Category {
+export interface Category {
     id: number;
     name: string;
 }
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 17a2475..28e66bb 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -166,6 +166,23 @@ export const useQuizService =  () => {
         }
     }
 
+    const getCategories = async () => {
+        try {
+            const response = await axios.get(`${url}/quiz/categories`, {
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            });
+            return response.data;
+        } catch (error: any) {
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    };
+
 
     return {
         generateQuiz: generateQuiz,
@@ -173,6 +190,7 @@ export const useQuizService =  () => {
         remainingQuiz: remainingQuiz,
         getRandomQuiz: getRandomQuiz,
         getCommunityQuiz: getCommunityQuiz,
-        restartQuiz: restartQuiz
+        restartQuiz: restartQuiz,
+        getCategories: getCategories
     }
 }
\ No newline at end of file
-- 
GitLab


From 8a2e34341bfcd742e6b266c2fc27f5692bdf189e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 7 Jan 2025 17:56:54 +0100
Subject: [PATCH 189/283] feat: adding SelectListBoxCategory

---
 components/PlayQuiz/SelectListBoxCategory.tsx | 84 +++++++++++++++++++
 .../Home/PlayQuiz/PlayQuizGenerateQuiz.tsx    | 34 ++++++--
 2 files changed, 109 insertions(+), 9 deletions(-)
 create mode 100644 components/PlayQuiz/SelectListBoxCategory.tsx

diff --git a/components/PlayQuiz/SelectListBoxCategory.tsx b/components/PlayQuiz/SelectListBoxCategory.tsx
new file mode 100644
index 0000000..95715e1
--- /dev/null
+++ b/components/PlayQuiz/SelectListBoxCategory.tsx
@@ -0,0 +1,84 @@
+import { View, StyleSheet, Text } from "react-native";
+import { SelectList } from "react-native-dropdown-select-list";
+import React from "react";
+import { Category } from "../../models/Quiz";
+
+interface Props {
+    data: Category[], // La liste des catégories
+    setSelected: (val: Category) => void, // Fonction pour gérer la sélection d'une catégorie
+    title: string, // Titre affiché au-dessus de la liste
+}
+
+export default function SelectListBoxCategory({ data, setSelected, title }: Props) {
+    // Transformer les données dans le format attendu
+    const transformedData = data.map((category) => ({
+        key: category.id.toString(), // Sauvegarde l'ID en tant que clé
+        value: category.name, // Affiche le nom
+    }));
+
+    return (
+        <View style={styles.container}>
+            <View style={styles.dropdownContainer}>
+                <Text style={styles.title}>{title}</Text>
+                <SelectList
+                    setSelected={(key: string) => {
+                        // Trouver la catégorie sélectionnée à partir de son ID
+                        const selectedCategory = data.find((category) => category.id.toString() === key);
+                        if (selectedCategory) {
+                            setSelected(selectedCategory);
+                        }
+                    }}
+                    data={transformedData} // Données transformées pour SelectList
+                    save="key" // Sauvegarde la clé (ID)
+                    dropdownStyles={styles.dropdownStyles}
+                    boxStyles={styles.boxStyles}
+                    inputStyles={styles.inputStyles}
+                />
+            </View>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        alignItems: "center",
+        width: "100%",
+    },
+    dropdownContainer: {
+        width: "100%",
+    },
+    title: {
+        fontSize: 20,
+        fontWeight: "bold",
+        marginBottom: 5,
+        color: "#333",
+        textAlign: "left",
+    },
+    dropdownStyles: {
+        position: "absolute",
+        width: "100%",
+        top: 40,
+        zIndex: 2,
+        backgroundColor: "white",
+        borderColor: "black",
+        borderWidth: 1,
+        borderRadius: 8,
+    },
+    boxStyles: {
+        backgroundColor: "white",
+        borderColor: "#bebebe",
+        borderWidth: 2,
+        borderRadius: 8,
+        height: 70,
+        alignItems: "center",
+        elevation: 5,
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 4 },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.84,
+    },
+    inputStyles: {
+        fontSize: 18,
+        color: "black",
+    },
+});
diff --git a/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
index 481b82f..c55cf39 100644
--- a/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -1,11 +1,12 @@
 import { Text,View, StyleSheet } from "react-native";
-import SelectListBox from "../../../components/PlayQuiz/SelectListBox";
-import React, {useEffect} from "react";
+import SelectListBoxString from "../../../components/PlayQuiz/SelectListBoxString";
+import React, {useEffect, useState} from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import BlueButton from "../../../components/buttons/BlueButton";
-import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {useQuizService} from "../../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
+import {Category} from "../../../models/Quiz";
+import SelectListBoxCategory from "../../../components/PlayQuiz/SelectListBoxCategory";
 
 const difficulty = [
     { key: "easy", value: "easy" },
@@ -35,13 +36,28 @@ interface Props {
 
 export default function PlayQuizGenerateQuiz({navigation}: Props) {
     const [difficutlyChoose, setDifficutlyChoose] = React.useState("");
-    const [categoryChoose, setCategoryChoose] = React.useState("");
     const [nbQuestions, setNbQuestions] = React.useState("10");
     const [buttonIsDisabled, setButtonIsDisabled] = React.useState(true);
-    const {generateQuiz} = useQuizService();
+    const [categories, setCategories] = useState<Category[]>([]);
+    const [categoryChoose, setCategoryChoose] = React.useState<Category | null>(null);
+
+    const {generateQuiz, getCategories} = useQuizService();
+    const fetchingCategories = async () => {
+        const categories = await getCategories();
+        console.log(categories);
+        let categoriesTemp: Category[] = [];
+        categories.map((category: Category) => {
+            categoriesTemp.push({'name': category.name, 'id': category.id});
+        });
+        setCategories(categoriesTemp);
+    }
+
+    useEffect(() => {
+        fetchingCategories();
+    }, []);
 
     useEffect(() => {
-        if(nbQuestions === "" || difficutlyChoose === "" || categoryChoose === "")
+        if(nbQuestions === "" || difficutlyChoose === "" || categoryChoose === null)
         {
             setButtonIsDisabled(true);
         }
@@ -53,7 +69,7 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
     }, [difficutlyChoose,categoryChoose,nbQuestions]);
 
     const handlePlayButtonPress = async () => {
-        const quizGenerated = await generateQuiz(parseInt(nbQuestions), getIdOfCategory(categoryChoose), difficutlyChoose);
+        const quizGenerated = await generateQuiz(parseInt(nbQuestions), categoryChoose ? categoryChoose.id : 10 , difficutlyChoose);
         navigation.reset({
             index: 0,
             routes: [
@@ -69,8 +85,8 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
         <View style={styles.container}>
             <View style={styles.contentContainer}>
                 <View style={styles.fieldContainer}>
-                    <SelectListBox title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
-                    <SelectListBox title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
+                    <SelectListBoxString title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
+                    <SelectListBoxCategory title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
                     <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} defaultValue={nbQuestions}/>
                 </View>
                 <View style={styles.buttonPlayContainer}>
-- 
GitLab


From fce7ded1c8dcd00070d498ce1432f76d1219b76c Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 7 Jan 2025 21:26:56 +0100
Subject: [PATCH 190/283] feat: add image for lobby

---
 assets/add.png | Bin 0 -> 1688 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 assets/add.png

diff --git a/assets/add.png b/assets/add.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ca8aad752ac7e6f52cb5fd353a3955526ea037c
GIT binary patch
literal 1688
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

literal 0
HcmV?d00001

-- 
GitLab


From 8d58a25e2f869ff086ce99393631cca4a34aad9c Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 7 Jan 2025 21:27:13 +0100
Subject: [PATCH 191/283] feat: add screen lobby

---
 screens/Multiplayer/Lobby/Lobby.tsx | 96 ++++++++++++++++++++++++++---
 1 file changed, 89 insertions(+), 7 deletions(-)

diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index 541bd56..24d9935 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -1,10 +1,60 @@
-import { View, Text, StyleSheet } from "react-native";
+import { View, Text, StyleSheet, Button, Image } from "react-native";
+import TemplateMenu from "../../../templates/TemplateMenu";
+import { NavigationProp } from "@react-navigation/native";
+import React, { useState } from "react";
+import WhiteButton from "../../../components/buttons/WhiteButton";
+import BlueButton from "../../../components/buttons/BlueButton";
+import { TouchableOpacity } from "react-native";
+
+interface Props {
+    navigation: NavigationProp<any>;
+}
+
+export default function Lobby({navigation}: Props) {
+    const [isHost, setIsHost] = useState<boolean>(true);
+
+    const onLeavePressed = () => {
+        navigation.navigate("Multiplayer");
+    };
+
+    const onPlayPressed = () => {
+        navigation.navigate("PlayingQuiz", {quizId: 1});//TODO : changer le quizId
+    }
+
+    const onCancelPressed = () => {
+        navigation.navigate("Multiplayer");
+    };
+
+    const onInvitePressed = () => {
+        //TODO : implementer l'invite
+    }
 
-export default function Lobby() {
     return (
-        <View style={styles.container}>
-            <Text style={styles.title}>Lobby</Text>
-        </View>
+        <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
+            <Text style={styles.title}>{'BMW OFFICIAL QUIZ (I’m leaking oil)'}</Text>
+            <View style={styles.containerPlayers}>
+                <View style={styles.PlayerItem}>
+                    <TouchableOpacity style={styles.buttonInvite} onPress={onInvitePressed}>
+                        <Image source={require('../../../assets/add.png')} style={styles.imagePlayer}/>
+                    </TouchableOpacity>
+                    <Text style={styles.textPlayer}>Invite</Text>
+                </View>
+            </View>
+            {isHost ?
+                <View style={styles.buttonGroup}>
+                    <View style={styles.button}>
+                        <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
+                    </View>   
+                    <View style={styles.button}>
+                        <WhiteButton text="CANCEL" onPress={onCancelPressed} isDisabled={false}/>
+                    </View>
+                </View>
+            :
+                <View style={styles.buttonGroup}>
+                    <WhiteButton text="LEAVE" onPress={onLeavePressed} isDisabled={false}/>
+                </View>
+            }
+        </TemplateMenu>
     )
 }
 
@@ -18,5 +68,37 @@ const styles = StyleSheet.create({
     },
     title: {
         fontSize: 40,
-    }
-});
\ No newline at end of file
+        textAlign: 'center',
+    },
+    containerPlayers: {
+        width: '100%',
+        height: '60%',
+        overflow: 'scroll',
+    },
+    PlayerItem: {
+        width: '30%',
+        height: 'auto',
+        display: 'flex',
+        flexDirection: 'column',
+        justifyContent: 'center',
+        alignItems: 'center',
+    },
+    buttonInvite: {
+    },
+    imagePlayer: {
+        width: 100,
+        height: 100,
+    },
+    textPlayer: {
+        fontSize: 20,
+    },
+    buttonGroup: {
+        flexDirection: 'row',
+        justifyContent: 'space-evenly',
+        width: '100%',
+    },
+    button: {
+        width: '45%',
+    },
+    
+});
-- 
GitLab


From 654d97e8817c3be5c64a66d4b89bcd1fbcc0a1d1 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 7 Jan 2025 21:28:25 +0100
Subject: [PATCH 192/283] feat: join lobby

---
 screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
index ace408c..4b251f2 100644
--- a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
+++ b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
@@ -31,7 +31,7 @@ export default function Community({navigation}: Props) {
     };
 
     const onJoinPressed = () => {
-        navigation.goBack();
+        navigation.navigate("Lobby");
     };
 
     //TODO: changer la fonction de fetch
-- 
GitLab


From f7d46b9494544d0d11afacd7e9b9ca96432ca174 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 7 Jan 2025 21:52:36 +0100
Subject: [PATCH 193/283] feat: add modal Invite Player

---
 components/Multiplayer/ModalInvitePlayer.tsx | 72 ++++++++++++++++++++
 screens/Multiplayer/Lobby/Lobby.tsx          | 57 +++++++++-------
 2 files changed, 103 insertions(+), 26 deletions(-)
 create mode 100644 components/Multiplayer/ModalInvitePlayer.tsx

diff --git a/components/Multiplayer/ModalInvitePlayer.tsx b/components/Multiplayer/ModalInvitePlayer.tsx
new file mode 100644
index 0000000..dbf2294
--- /dev/null
+++ b/components/Multiplayer/ModalInvitePlayer.tsx
@@ -0,0 +1,72 @@
+import { Modal, View, Text, StyleSheet, Image } from "react-native";
+import WhiteButton from "../buttons/WhiteButton";
+
+interface Props {
+    showModal: boolean;
+    onClosePressed: () => void;
+}
+
+export default function ModalInvitePlayer({showModal, onClosePressed,}: Props) {
+    return (
+        <Modal visible={showModal} animationType="slide" transparent={true}>
+            <View style={styles.centeredView}>
+                <View style={styles.modalView}>
+                    <Text style={styles.title}>JOIN</Text>
+                    <Image source={require('../../assets/favicon.png')}/>
+                    <Text style={styles.or}>OR</Text>
+                    <Text style={styles.link}>https://klebert-host.com/join_quiz/6975</Text>
+                    <View style={styles.buttonGroup}>
+                        <WhiteButton text="CLOSE" onPress={onClosePressed} isDisabled={false}/>
+                    </View>
+                </View>
+            </View>
+        </Modal>
+    );
+}
+
+const styles = StyleSheet.create({
+    centeredView: {
+        flex: 1,
+        justifyContent: 'center',
+        alignItems: 'center',
+        backgroundColor: 'rgba(0, 0, 0, 0.5)'
+    },
+    modalView: {
+        display: 'flex',
+        justifyContent: 'space-between',
+        height: '50%',
+        width: '90%',
+        margin: '10%',
+        padding: '5%',
+        backgroundColor: 'white',
+        borderRadius: 20,
+        alignItems: 'center',
+        shadowColor: '#000',
+        shadowOffset: {
+            width: 0,
+            height: 2,
+        },
+        shadowOpacity: 0.25,
+        shadowRadius: 4,
+        elevation: 5,
+    },
+    buttonGroup: {
+        flexDirection: 'row',
+        justifyContent: 'space-between',
+        width: '100%',
+    },
+    title: {
+        fontSize: 40,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+        alignSelf: "center",
+        textAlign: 'center',
+    },
+    or: {
+        fontSize: 32,
+    },
+    link: {
+        color: '#0000EE',
+    }
+});
\ No newline at end of file
diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index 24d9935..0a27500 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -5,6 +5,7 @@ import React, { useState } from "react";
 import WhiteButton from "../../../components/buttons/WhiteButton";
 import BlueButton from "../../../components/buttons/BlueButton";
 import { TouchableOpacity } from "react-native";
+import ModalInvitePlayer from "../../../components/Multiplayer/ModalInvitePlayer";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -12,6 +13,7 @@ interface Props {
 
 export default function Lobby({navigation}: Props) {
     const [isHost, setIsHost] = useState<boolean>(true);
+    const [showModal, setShowModal] = useState<boolean>(false);
 
     const onLeavePressed = () => {
         navigation.navigate("Multiplayer");
@@ -19,42 +21,45 @@ export default function Lobby({navigation}: Props) {
 
     const onPlayPressed = () => {
         navigation.navigate("PlayingQuiz", {quizId: 1});//TODO : changer le quizId
-    }
+    };
 
     const onCancelPressed = () => {
         navigation.navigate("Multiplayer");
     };
 
     const onInvitePressed = () => {
-        //TODO : implementer l'invite
-    }
+        setShowModal(true);
+    };
 
     return (
-        <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
-            <Text style={styles.title}>{'BMW OFFICIAL QUIZ (I’m leaking oil)'}</Text>
-            <View style={styles.containerPlayers}>
-                <View style={styles.PlayerItem}>
-                    <TouchableOpacity style={styles.buttonInvite} onPress={onInvitePressed}>
-                        <Image source={require('../../../assets/add.png')} style={styles.imagePlayer}/>
-                    </TouchableOpacity>
-                    <Text style={styles.textPlayer}>Invite</Text>
-                </View>
-            </View>
-            {isHost ?
-                <View style={styles.buttonGroup}>
-                    <View style={styles.button}>
-                        <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
-                    </View>   
-                    <View style={styles.button}>
-                        <WhiteButton text="CANCEL" onPress={onCancelPressed} isDisabled={false}/>
+        <View>
+            <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
+                <Text style={styles.title}>{'BMW OFFICIAL QUIZ (I’m leaking oil)'}</Text>
+                <View style={styles.containerPlayers}>
+                    <View style={styles.PlayerItem}>
+                        <TouchableOpacity style={styles.buttonInvite} onPress={onInvitePressed}>
+                            <Image source={require('../../../assets/add.png')} style={styles.imagePlayer}/>
+                        </TouchableOpacity>
+                        <Text style={styles.textPlayer}>Invite</Text>
                     </View>
                 </View>
-            :
-                <View style={styles.buttonGroup}>
-                    <WhiteButton text="LEAVE" onPress={onLeavePressed} isDisabled={false}/>
-                </View>
-            }
-        </TemplateMenu>
+                {isHost ?
+                    <View style={styles.buttonGroup}>
+                        <View style={styles.button}>
+                            <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
+                        </View>   
+                        <View style={styles.button}>
+                            <WhiteButton text="CANCEL" onPress={onCancelPressed} isDisabled={false}/>
+                        </View>
+                    </View>
+                :
+                    <View style={styles.buttonGroup}>
+                        <WhiteButton text="LEAVE" onPress={onLeavePressed} isDisabled={false}/>
+                    </View>
+                }
+            </TemplateMenu>
+            <ModalInvitePlayer showModal={showModal} onClosePressed={() => setShowModal(false)}/>
+        </View>
     )
 }
 
-- 
GitLab


From 3994b731af6964a78de3bbee53e6193d12d0f142 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Tue, 7 Jan 2025 22:02:55 +0100
Subject: [PATCH 194/283] style: page lobby

---
 screens/Multiplayer/Lobby/Lobby.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index 0a27500..021f173 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -72,12 +72,14 @@ const styles = StyleSheet.create({
         alignItems: "center",
     },
     title: {
-        fontSize: 40,
+        fontSize: 32,
         textAlign: 'center',
+        color: '#00B3F4',
+        marginBottom: 20,
     },
     containerPlayers: {
         width: '100%',
-        height: '60%',
+        height: '65%',
         overflow: 'scroll',
     },
     PlayerItem: {
-- 
GitLab


From 25cbb79c11a9860d6be04e53e0e12ae76e053f0e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 8 Jan 2025 10:18:52 +0100
Subject: [PATCH 195/283] chore: removed unused comments

---
 screens/PlayingQuiz/EndQuiz/EndQuiz.tsx | 75 -------------------------
 1 file changed, 75 deletions(-)

diff --git a/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx b/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
index 8297ee0..2d567b3 100644
--- a/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
@@ -35,78 +35,3 @@ const styles = StyleSheet.create({
         flexDirection: 'column',
     },
 });
-
-
-
-// import DefaultButton from "../../components/DefaultButton";
-// import { TextsStyles } from "../../styles/TextsStyles";
-// import { ButtonsStyles } from "../../styles/ButtonsStyles";
-// import {useTranslation} from "react-i18next";
-// import QuizModel from "../../models/QuizModel";
-// import {NavigationProp, RouteProp} from "@react-navigation/native";
-
-// type RoutePropsType = {
-//     EndQuiz: {
-//         quiz: QuizModel;
-//     };
-// };
-
-// interface Props {
-//     navigation: NavigationProp<any>;
-//     route: RouteProp<RoutePropsType, "EndQuiz">;
-// }
-
-// export default function EndQuiz({ navigation, route }: Props) {
-//     const { quiz } = route.params;
-//     const {t} = useTranslation();
-//     const handleButtonRePlayPressed = () => {
-//         quiz.nbActualQuestion = 1;
-//         quiz.score = 0;
-//         navigation.reset({
-//             index: 0,
-//             routes: [
-//                 {
-//                     name: "PlayingQuiz",
-//                     params: {quiz: quiz},
-//                 },
-//             ]
-//         });
-//     }
-
-//     const handleButtonHomePressed = () => {
-//         navigation.navigate('Home');
-//     }
-
-//     return (
-//         <View style={styles.container}>
-//             <Image source={require('../../assets/FondTemplate.png')} style={styles.image}/>
-//             <Text style={TextsStyles.titleText}>{t("app.screens.endQuiz.score")} : {quiz.score}</Text>
-//             <Text style={TextsStyles.subtitleText}>{((quiz.score/quiz.nbQuestions)*100 > 50 ) ? t("app.screens.endQuiz.lose") : t("app.screens.endQuiz.win")}</Text>
-//             <View style={styles.buttonContainer}>
-//                 <DefaultButton text={t("app.screens.endQuiz.replay")} handleButtonPressed={handleButtonRePlayPressed} buttonStyle={ButtonsStyles.defaultButton}></DefaultButton>
-//                 <DefaultButton text={t("app.screens.endQuiz.goHome")} handleButtonPressed={handleButtonHomePressed}></DefaultButton>
-//             </View>
-//         </View>
-//     )
-// }
-
-// const styles = StyleSheet.create({
-//     container: {
-//         display: 'flex',
-//         width: '100%',
-//         height: '100%',
-//         alignItems: 'center',
-//         justifyContent: 'center',
-//         gap: 10,  
-//     },
-//     buttonContainer: {
-//         width: '80%',
-//         margin: '10%',
-//         gap: 20
-//     },
-//     image: {
-//         width: '100%',
-//         height: '100%',
-//         position: 'absolute',
-//     },
-// });
\ No newline at end of file
-- 
GitLab


From 7557b98b9e70f03e1eea7518ba2ffd95896e33df Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 8 Jan 2025 10:19:39 +0100
Subject: [PATCH 196/283] feat: added the EndQuizMulti screen

---
 .../PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx |  41 +++++
 .../EndQuizMulti/EndQuizMultiChild.tsx        | 156 ++++++++++++++++++
 2 files changed, 197 insertions(+)
 create mode 100644 screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx
 create mode 100644 screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx

diff --git a/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx b/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx
new file mode 100644
index 0000000..1945637
--- /dev/null
+++ b/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx
@@ -0,0 +1,41 @@
+import {NavigationProp, RouteProp} from "@react-navigation/native";
+import { View, StyleSheet, Image, Text } from "react-native";
+import TemplateMenu from "../../../templates/TemplateMenu";
+import {Quiz} from "../../../models/Quiz";
+import EndQuizChild from "../EndQuiz/EndQuizChild";
+import EndQuizMultiChild from "./EndQuizMultiChild";
+
+type RoutePropsType = {
+    EndQuizChild: {
+        quiz: Quiz;
+    };
+};
+interface Props {
+    route: RouteProp<RoutePropsType, "EndQuizChild">;
+    navigation: NavigationProp<any>;
+}
+
+export default function EndQuizMulti({route,navigation}: Props) {
+    const { quiz } = route.params;
+    return (
+        <View style={styles.containerGlobal}>
+            <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}>
+                <View>
+                    <EndQuizMultiChild navigation={navigation} quiz={quiz}/>
+                </View>
+            </TemplateMenu>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    containerGlobal: {
+        display: 'flex',
+        width: '100%',
+        height: '100%',
+        flexDirection: 'column',
+    },
+});
+
+
+
diff --git a/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx b/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx
new file mode 100644
index 0000000..3ba9918
--- /dev/null
+++ b/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx
@@ -0,0 +1,156 @@
+import { View, Image, Text, StyleSheet } from "react-native";
+import DefaultButton from "../../../components/buttons/DefaultButton";
+import { NavigationProp, RouteProp } from "@react-navigation/native";
+import {Quiz} from "../../../models/Quiz";
+import {useQuizService} from "../../../services/QuizService";
+import HttpError from "../../../services/HttpError";
+import UserScore from "../../../components/PlayingQuiz/EndQuiz/UserScore";
+import UserModel from "../../../models/UserModel";
+import EndQuizListPlayer from "../../../components/PlayingQuiz/EndQuiz/EndQuizListPlayer";
+
+
+
+interface Props {
+    navigation: NavigationProp<any>;
+    quiz: Quiz;
+}
+
+export default function EndQuizMultiChild({ navigation, quiz }: Props) {
+
+    const {restartQuiz, remainingQuiz} = useQuizService()
+
+    const handleRestartPress = async () => {
+        const isRestarted = await restartQuiz(quiz.id);
+        if(HttpError.isHttpError(isRestarted)){
+            console.log(isRestarted.message);
+            return
+        }
+        if(!isRestarted) {
+            return;
+        }
+        const quizRestarted = await remainingQuiz(quiz.id);
+        if(HttpError.isHttpError(quizRestarted)){
+            console.log(quizRestarted.message);
+            return
+        }
+
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {quizRecovered: quizRestarted},
+                },
+            ]
+        });
+    };
+
+    const handleBackToMenu = () => {
+        navigation.navigate('TabNavigator');
+    };
+    const user = new UserModel(10,"Thomassss", "Thomas");
+
+    return (
+        <View style={styles.container}>
+            <View style={styles.containerHeader}>
+                <Image source={require('../../../assets/TitleApp.png')}/>
+            </View>
+            <View style={styles.containerBody}>
+                <Image
+                    source={require('../../../assets/stars.png')} // URL de l'avatar ou placeholder
+                    style={styles.stars}
+                />
+                <View style={styles.usersContainer}>
+                    <UserScore user={user} score={10} maxScore={quiz.questionCount} isFirst={false}/>
+                    <UserScore user={user} score={10} maxScore={quiz.questionCount} isFirst={true}/>
+                    <UserScore user={user} score={10} maxScore={quiz.questionCount} isFirst={false}/>
+                </View>
+                <EndQuizListPlayer users={[new UserModel(1, "user1", "user1@email.com"), new UserModel(2, "user2", "user2@email.com")]} maxScore={quiz.questionCount}/>
+
+                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
+                <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
+            </View>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        height: '100%',
+        width: '100%',
+        display: 'flex',
+        flexDirection: 'column',
+        alignItems: 'center',
+        justifyContent: 'space-around'
+    },
+    usersContainer: {
+        display: 'flex',
+        width: '100%',
+        flexDirection: 'row',
+        alignItems: 'center',
+        justifyContent: 'space-around',
+    },
+    containerHeader: {
+        height: '10%',
+        width: '100%',
+        alignItems: 'center',
+    },
+    containerBody: {
+        height: '80%',
+        width: '90%',
+        display: 'flex',
+        flexDirection: 'column',
+        alignItems: 'center',
+        justifyContent: 'space-around',
+        backgroundColor: '#F3F3F3',
+        borderRadius: 40,
+        padding: '5%',
+        shadowColor: "#000",
+        shadowOffset: {
+            width: 0,
+            height: 2,
+        },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.84,
+        elevation: 5,
+    },
+    TextBodyTitle: {
+        textAlign: 'center',
+        fontSize: 24,
+        fontWeight: 'bold',
+    },
+    TextBody: {
+        textAlign: 'center',
+        fontSize: 22,
+        fontWeight: 'bold',
+    },
+    whiteButton: {
+        height: '12%',
+        width: '80%',
+        backgroundColor: '#FFFFFF',
+        borderColor: '#2B73FE',
+        borderWidth: 4,
+        borderRadius: 10,
+        padding: 0
+    },
+    whiteButtonText: {
+        fontSize: 24,
+        fontWeight: 'bold',
+        color: '#2B73FE',
+    },
+    blueButton: {
+        height: '12%',
+        width: '80%',
+        backgroundColor: '#2B73FE',
+        borderRadius: 10,
+        padding: 0
+    },
+    blueButtonText: {
+        fontSize: 24,
+        fontWeight: 'bold',
+        color: '#FFFFFF',
+    },
+    stars: {
+        resizeMode: "cover",
+    },
+});
\ No newline at end of file
-- 
GitLab


From 26d19830c74b148e10fde84ca73ab05285ccea27 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 8 Jan 2025 10:20:04 +0100
Subject: [PATCH 197/283] feat: added the EndQuizListPlayer

---
 .../PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx | 86 +++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx

diff --git a/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx b/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx
new file mode 100644
index 0000000..a2378cb
--- /dev/null
+++ b/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx
@@ -0,0 +1,86 @@
+import React from "react";
+import { FlatList, View, Text, StyleSheet, Image } from "react-native";
+import UserModel from "../../../models/UserModel";
+
+interface Props {
+    users: UserModel[];
+    maxScore: number;
+}
+
+export default function EndQuizListPlayer({ users, maxScore }: Props) {
+    const renderUser = ({ item, index }: { item: UserModel; index: number }) => (
+        <View style={[styles.userContainer, index === 0 && styles.firstPlace]}>
+            <Image
+                source={require("../../../assets/ProfilBaseImage.png")} // Replace with actual profile picture if available
+                style={styles.avatar}
+            />
+            <View style={styles.infoContainer}>
+                <Text style={[styles.username, index === 0 && styles.firstPlaceText]}>
+                    {item.username.toUpperCase()}
+                </Text>
+                <Text style={styles.score}>
+                    {10 + index}/{maxScore} {/* Adjust score logic as needed */}
+                </Text>
+            </View>
+        </View>
+    );
+
+    return (
+        <View style={styles.container}>
+            <FlatList
+                data={users}
+                renderItem={renderUser}
+                keyExtractor={(item) => item.id.toString()}
+                showsVerticalScrollIndicator={false}
+            />
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        width: "100%",
+        padding: 20,
+        backgroundColor: "#fff",
+        borderRadius: 20,
+    },
+    userContainer: {
+        flexDirection: "row",
+        alignItems: "center",
+        backgroundColor: "#f9f9f9",
+        borderRadius: 10,
+        padding: 15,
+        marginBottom: 10,
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.1,
+        shadowRadius: 3,
+        elevation: 2,
+    },
+    firstPlace: {
+        // backgroundColor: "#ffe700",
+        // shadowColor: "#ff9900",
+        // shadowOpacity: 0.3,
+    },
+    avatar: {
+        width: 40,
+        height: 40,
+        borderRadius: 25,
+        marginRight: 15,
+    },
+    infoContainer: {
+        flex: 1,
+    },
+    username: {
+        fontSize: 18,
+        fontWeight: "bold",
+        color: "#333",
+    },
+    firstPlaceText: {
+        // color: "#ff9900",
+    },
+    score: {
+        fontSize: 16,
+        color: "#666",
+    },
+});
-- 
GitLab


From 196e7f0d60eacb4377b54e8a91e820dfdde6a5c5 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 8 Jan 2025 10:20:17 +0100
Subject: [PATCH 198/283] feat: added the UserScore

---
 components/PlayingQuiz/EndQuiz/UserScore.tsx | 79 ++++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 components/PlayingQuiz/EndQuiz/UserScore.tsx

diff --git a/components/PlayingQuiz/EndQuiz/UserScore.tsx b/components/PlayingQuiz/EndQuiz/UserScore.tsx
new file mode 100644
index 0000000..d57489c
--- /dev/null
+++ b/components/PlayingQuiz/EndQuiz/UserScore.tsx
@@ -0,0 +1,79 @@
+import UserModel from "../../../models/UserModel";
+import { View, Text, StyleSheet, Image } from "react-native";
+
+interface Props {
+    user: UserModel;
+    score: number;
+    maxScore: number;
+    isFirst: boolean;
+}
+
+export default function UserScore({ user, score, maxScore, isFirst }: Props) {
+
+    function shortenString(input: string): string {
+        if (input.length <= 5) {
+            return input; // Si la chaîne est déjà de 4 caractères ou moins, on la retourne telle quelle
+        }
+        return `${input.slice(0, 5)}...`; // Garde les 4 premiers caractères et ajoute "..."
+    }
+
+    return (
+        <View style={styles.container}>
+            <View style={[styles.avatarContainer, isFirst && styles.firstAvatar]}>
+                <Image
+                    source={require('../../../assets/ProfilBaseImage.png')} // URL de l'avatar ou placeholder
+                    style={styles.avatar}
+                />
+            </View>
+            <Text style={styles.userName}>{shortenString(user.username.toUpperCase())}</Text>
+            <Text style={styles.userScore}>
+                {score}/{maxScore}
+            </Text>
+        </View>
+    );
+}
+
+
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        flexDirection: "column",
+        alignItems: "center",
+        justifyContent: "space-around",
+        marginHorizontal: 10,
+    },
+    avatarContainer: {
+        width: 70,
+        height: 70,
+        borderRadius: 50,
+        backgroundColor: "#d9e3f0", // Fond gris clair
+        alignItems: "center",
+        justifyContent: "center",
+    },
+    firstAvatar: {
+        width: 90,
+        height: 90,
+        // borderWidth: 3, // Ajoute une bordure pour le premier utilisateur
+        // borderColor: "#FFD700", // Couleur or pour marquer le premier
+    },
+    avatar: {
+        width: "100%",
+        height: "100%",
+        resizeMode: "cover",
+    },
+    userName: {
+        fontSize: 16,
+        fontWeight: "bold",
+        color: "#000",
+        marginTop: 5,
+        textAlign: "center",
+    },
+    userScore: {
+        fontSize: 14,
+        fontWeight: "500",
+        color: "#333",
+        textAlign: "center",
+        marginTop: 5,
+    },
+});
-- 
GitLab


From 47f3e388626975e4f8e988bbfd7ca13129b4b7fa Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 8 Jan 2025 10:20:54 +0100
Subject: [PATCH 199/283] feat: added the navigation for EndQuizMulti

---
 routes/StackNavigator.tsx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 7f91326..e0b86ca 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -8,6 +8,7 @@ import TabNavigator from "./TabNavigation";
 import PlayQuiz from "../screens/Home/PlayQuiz/PlayQuiz";
 import MyQuizzes from "../screens/Home/MyQuizzes/MyQuizzes";
 import InformationsOfQuiz from "../screens/Community/InformationsOfQuiz/InformationsOfQuiz";
+import EndQuizMulti from "../screens/PlayingQuiz/EndQuizMulti/EndQuizMulti";
 
 const Stack = createNativeStackNavigator();
 
@@ -21,6 +22,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="PlayingQuiz" component={PlayingQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="PlayQuiz" component={PlayQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="EndQuiz" component={EndQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="EndQuizMulti" component={EndQuizMulti} options={{ headerShown: false }}/>
                 <Stack.Screen name="MyQuizzes" component={MyQuizzes} options={{ headerShown: false }}/>
                 <Stack.Screen name="InformationsOfQuiz" component={InformationsOfQuiz} options={{ headerShown: false }}/>
             </Stack.Navigator>
-- 
GitLab


From 09b96f1cdf1382d849a55ed7d5e8ace42a1e9811 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 8 Jan 2025 10:21:07 +0100
Subject: [PATCH 200/283] feat: added stars.png

---
 assets/stars.png | Bin 0 -> 6666 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 assets/stars.png

diff --git a/assets/stars.png b/assets/stars.png
new file mode 100644
index 0000000000000000000000000000000000000000..09c430621cb58984d1b88f1e46e5d71c2b9a3284
GIT binary patch
literal 6666
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
U!EG5~)c^nh07*qoM6N<$g1z6<u>b%7

literal 0
HcmV?d00001

-- 
GitLab


From 57198d68e6b983884b461117d381800775b8db6e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 8 Jan 2025 10:21:39 +0100
Subject: [PATCH 201/283] debug: for go into endquiz screen

---
 screens/Home/Home.tsx | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/screens/Home/Home.tsx b/screens/Home/Home.tsx
index dc3b638..1369070 100644
--- a/screens/Home/Home.tsx
+++ b/screens/Home/Home.tsx
@@ -3,12 +3,35 @@ import TemplateMono from "../../templates/TemplateMono";
 import HomeChild from "./HomeChild";
 import TemplateMenu from "../../templates/TemplateMenu";
 import {NavigationProp} from "@react-navigation/native";
+import {Quiz} from "../../models/Quiz";
 
 interface Props {
     navigation: NavigationProp<any>;
 }
 
 export default function Home({navigation}: Props) {
+    const debugQuiz: Quiz = {
+        id: "debug-quiz-001",
+        name: "Debug Quiz",
+        description: "This is a basic quiz for debugging purposes.",
+        score: 0,
+        questionIndex: 0,
+        questionCount: 0,
+        categoryId: 1,
+        difficultyId: 1,
+        authorId: 1,
+        category: {
+            id: 1,
+            name: "General Knowledge",
+        },
+        difficulty: {
+            id: 1,
+            name: "Easy",
+        },
+        questions: [], // Tableau de questions vide
+    };
+
+    navigation.navigate("EndQuizMulti", {quiz: debugQuiz});
     return (
         <View style={styles.containerGlobal}>
                 <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}>
-- 
GitLab


From 553ff5fd9222600ef6990dc756e4e43abd76fa8e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 8 Jan 2025 14:02:53 +0100
Subject: [PATCH 202/283] fix: changed port number to use prod API

---
 services/QuizService.ts | 2 +-
 services/UserService.ts | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index 28e66bb..6ceff37 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -5,7 +5,7 @@ import {Answer} from "../models/Answer";
 import {shuffleAnswersOfQuiz} from "../helper/QuizHelper";
 
 export const useQuizService =  () => {
-    const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
+    const url = "https://klebert-host.com:33036"; // Remplace par l'URL de ton endpoint API
 
     const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<Quiz | HttpError> => {
         const requestBody = {
diff --git a/services/UserService.ts b/services/UserService.ts
index 08399a9..f76e653 100644
--- a/services/UserService.ts
+++ b/services/UserService.ts
@@ -4,7 +4,7 @@ import axios from "axios";
 import {transformToUserModel} from "../helper/UserHelper";
 
 export const useUserService =  () => {
-    const url = "https://klebert-host.com:33037";
+    const url = "https://klebert-host.com:33036";
 
 
     const loginUser = async (login: string, password: string): Promise<boolean | HttpError> => {
-- 
GitLab


From 3563b3415cf4c932f8a1e93ae88b6a2a91e10bcf Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 8 Jan 2025 14:09:01 +0100
Subject: [PATCH 203/283] feat: add header go back to multi community

---
 .../Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index 8d7723a..18dba4d 100644
--- a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -67,7 +67,7 @@ export default function MultiplayerCommunity({navigation}: Props) {
     return (
         <View style={styles.containerGlobal}>
             <View style={styles.templateQuizListContainer}>
-                <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+                <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={true} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
             </View>
             <View style={styles.buttonContainer}>
                 <BlueButton text="CREATE LOBBY" onPress={onCreateLobbyPressed}  isDisabled={false}/>
-- 
GitLab


From 0605dd637f7137ba865a7e372493c889271dd2cb Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 8 Jan 2025 14:09:25 +0100
Subject: [PATCH 204/283] feat: add header go back to ongoingquizzes

---
 screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
index 4b251f2..f368297 100644
--- a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
+++ b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
@@ -53,7 +53,7 @@ export default function Community({navigation}: Props) {
     return (
         <View>
             <View style={styles.templateQuizListContainer}>
-                <TemplateQuizList title={"Ongoing Quizzes"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={false} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
+                <TemplateQuizList title={"Ongoing Quizzes"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={true} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
             </View>
             <View style={styles.buttonContainer}>
                 <BlueButton text="JOIN" onPress={onJoinPressed} isDisabled={false}/>
-- 
GitLab


From 5e823e8548c7dfd1fec2d2ffa023ed66b2514d2c Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 8 Jan 2025 20:57:04 +0100
Subject: [PATCH 205/283] feat: add player list in lobby

---
 screens/Multiplayer/Lobby/Lobby.tsx | 98 ++++++++++++++++++++---------
 1 file changed, 68 insertions(+), 30 deletions(-)

diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index 021f173..71c5a5c 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -1,4 +1,4 @@
-import { View, Text, StyleSheet, Button, Image } from "react-native";
+import { View, Text, StyleSheet, Button, Image, ScrollView, FlatList } from "react-native";
 import TemplateMenu from "../../../templates/TemplateMenu";
 import { NavigationProp } from "@react-navigation/native";
 import React, { useState } from "react";
@@ -15,6 +15,47 @@ export default function Lobby({navigation}: Props) {
     const [isHost, setIsHost] = useState<boolean>(true);
     const [showModal, setShowModal] = useState<boolean>(false);
 
+    const players = [
+        { id: 0, name: 'Invite'},
+        { id: 1, name: 'John Doe'},
+        { id: 2, name: 'John Doe'},
+        { id: 3, name: 'John Doe'},
+        { id: 4, name: 'John Doe'},
+        { id: 5, name: 'John Doe'},
+        { id: 6, name: 'John Doe'},
+        { id: 7, name: 'John Doe'},
+        { id: 8, name: 'John Doe'},
+        { id: 9, name: 'John Doe'},
+        { id: 10, name: 'John Doe'},
+        { id: 11, name: 'John Doe'},
+        { id: 12, name: 'John Doe'},
+        { id: 13, name: 'John Doe'},
+        { id: 14, name: 'John Doe'},
+        { id: 15, name: 'John Doe'},
+    ];
+
+    const item = ({item}: {item: {id: number, name: string}}) => {
+        return (
+            <>
+                {item.name === 'Invite' ? 
+                    <View style={styles.PlayerItem}>
+                        <TouchableOpacity style={styles.imagePlayer} onPress={onInvitePressed}>
+                            <Image source={require('../../../assets/add.png')}  />
+                        </TouchableOpacity>
+                        <Text style={styles.textPlayer}>Invite</Text>
+                    </View>
+                :
+                    <View style={styles.PlayerItem}>
+                        <Image source={require('../../../assets/ProfilBaseImage.png')} style={styles.imagePlayer} />
+                        <Text style={styles.textPlayer}>{item.name}</Text>
+                    </View>
+                }
+            </>
+            
+        )
+    }
+
+
     const onLeavePressed = () => {
         navigation.navigate("Multiplayer");
     };
@@ -36,12 +77,13 @@ export default function Lobby({navigation}: Props) {
             <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
                 <Text style={styles.title}>{'BMW OFFICIAL QUIZ (I’m leaking oil)'}</Text>
                 <View style={styles.containerPlayers}>
-                    <View style={styles.PlayerItem}>
-                        <TouchableOpacity style={styles.buttonInvite} onPress={onInvitePressed}>
-                            <Image source={require('../../../assets/add.png')} style={styles.imagePlayer}/>
-                        </TouchableOpacity>
-                        <Text style={styles.textPlayer}>Invite</Text>
-                    </View>
+                    <FlatList
+                        data={players}
+                        renderItem={item}
+                        numColumns={3}
+                        keyExtractor={(item) => item.id.toString()}
+                        showsVerticalScrollIndicator={true}
+                    />
                 </View>
                 {isHost ?
                     <View style={styles.buttonGroup}>
@@ -64,40 +106,37 @@ export default function Lobby({navigation}: Props) {
 }
 
 const styles = StyleSheet.create({
-    container: {
-        display: "flex",
-        height: "100%",
-        width: "100%",
-        justifyContent: "center",
-        alignItems: "center",
-    },
-    title: {
-        fontSize: 32,
-        textAlign: 'center',
-        color: '#00B3F4',
-        marginBottom: 20,
-    },
     containerPlayers: {
-        width: '100%',
         height: '65%',
-        overflow: 'scroll',
+        width: '100%',
     },
     PlayerItem: {
         width: '30%',
-        height: 'auto',
-        display: 'flex',
-        flexDirection: 'column',
+        aspectRatio: 1,
         justifyContent: 'center',
         alignItems: 'center',
-    },
-    buttonInvite: {
+        margin: 5,
     },
     imagePlayer: {
-        width: 100,
-        height: 100,
+        width: '80%',
+        height: '80%',
     },
     textPlayer: {
         fontSize: 20,
+        textAlign: 'center',
+    },
+    container: {
+        display: "flex",
+        height: "100%",
+        width: "100%",
+        justifyContent: "center",
+        alignItems: "center",
+    },
+    title: {
+        fontSize: 32,
+        textAlign: 'center',
+        color: '#00B3F4',
+        marginBottom: 20,
     },
     buttonGroup: {
         flexDirection: 'row',
@@ -107,5 +146,4 @@ const styles = StyleSheet.create({
     button: {
         width: '45%',
     },
-    
 });
-- 
GitLab


From dc38bee02a570eae0906421458ae5e99ebd352c0 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 8 Jan 2025 21:30:26 +0100
Subject: [PATCH 206/283] styles: fix styles for online selectMode

---
 screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx b/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
index 59ec2c2..bf33162 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
@@ -10,14 +10,14 @@ export default function OnlineSelectMode({ mode, setMode }: Props) {
     return (
         <View style={styles.container}>
             <View style={styles.buttonContainer}>
-                <TouchableOpacity onPress={() => setMode("create")} style={{marginLeft: '10%'}}>
+                <TouchableOpacity onPress={() => setMode("create")}>
                     <Text style={[styles.text, mode === "create" && styles.activeText]}>CREATE A LOBBY</Text>
                 </TouchableOpacity>
                 <View style={[styles.bar, mode === "create" ? styles.activeBar : styles.inactiveBar]} />
             </View>
 
             <View style={styles.buttonContainer}>
-                <TouchableOpacity onPress={() => setMode("join")} style={{marginRight: '10%'}}>
+                <TouchableOpacity onPress={() => setMode("join")}>
                     <Text style={[styles.text, mode === "join" && styles.activeText]}>JOIN A QUIZ</Text>
                 </TouchableOpacity>
                 <View style={[styles.bar, mode === "join" ? styles.activeBar : styles.inactiveBar]} />
@@ -31,7 +31,7 @@ const styles = StyleSheet.create({
     container: {
         display: 'flex',
         width: '100%',
-        height: '15%',
+        height: '12%',
         flexDirection: 'row',
         backgroundColor: '#f3f3f3',
         borderRadius: 10,
@@ -48,13 +48,14 @@ const styles = StyleSheet.create({
     buttonContainer: {
         display: 'flex',
         flexDirection: 'column',
-        width: '40%',
+        width: '45%',
         alignItems: 'center',
-        gap: "5%",
+        gap: "2%",
     },
     text: {
-        fontSize: 25,
+        fontSize: 18,
         color: '#bebebe',
+        textAlign: 'center',
     },
     activeText: {
         color: '#2ec7ff',
-- 
GitLab


From d2a62992a7ad39b63988274ad52ab383c13583ce Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 8 Jan 2025 21:36:42 +0100
Subject: [PATCH 207/283] style: fix style for lobby player list

---
 screens/Multiplayer/Lobby/Lobby.tsx | 53 ++++++++++++++++-------------
 1 file changed, 30 insertions(+), 23 deletions(-)

diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index 71c5a5c..6bc6cd4 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -75,30 +75,32 @@ export default function Lobby({navigation}: Props) {
     return (
         <View>
             <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
-                <Text style={styles.title}>{'BMW OFFICIAL QUIZ (I’m leaking oil)'}</Text>
-                <View style={styles.containerPlayers}>
-                    <FlatList
-                        data={players}
-                        renderItem={item}
-                        numColumns={3}
-                        keyExtractor={(item) => item.id.toString()}
-                        showsVerticalScrollIndicator={true}
-                    />
-                </View>
-                {isHost ?
-                    <View style={styles.buttonGroup}>
-                        <View style={styles.button}>
-                            <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
-                        </View>   
-                        <View style={styles.button}>
-                            <WhiteButton text="CANCEL" onPress={onCancelPressed} isDisabled={false}/>
-                        </View>
+                <View style={styles.containerLobby}>  
+                    <Text style={styles.title}>{'BMW OFFICIAL QUIZ (I’m leaking oil)'}</Text>
+                    <View style={styles.containerPlayers}>
+                        <FlatList
+                            data={players}
+                            renderItem={item}
+                            numColumns={3}
+                            keyExtractor={(item) => item.id.toString()}
+                            showsVerticalScrollIndicator={true}
+                        />
                     </View>
-                :
-                    <View style={styles.buttonGroup}>
-                        <WhiteButton text="LEAVE" onPress={onLeavePressed} isDisabled={false}/>
-                    </View>
-                }
+                    {isHost ?
+                        <View style={styles.buttonGroup}>
+                            <View style={styles.button}>
+                                <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
+                            </View>   
+                            <View style={styles.button}>
+                                <WhiteButton text="CANCEL" onPress={onCancelPressed} isDisabled={false}/>
+                            </View>
+                        </View>
+                    :
+                        <View style={styles.buttonGroup}>
+                            <WhiteButton text="LEAVE" onPress={onLeavePressed} isDisabled={false}/>
+                        </View>
+                    }
+                </View>
             </TemplateMenu>
             <ModalInvitePlayer showModal={showModal} onClosePressed={() => setShowModal(false)}/>
         </View>
@@ -146,4 +148,9 @@ const styles = StyleSheet.create({
     button: {
         width: '45%',
     },
+    containerLobby: {
+        height: '87%',
+        display: 'flex',
+        justifyContent: 'space-around',
+    }
 });
-- 
GitLab


From 694367bbc6bd0d9dee6e1dbc3b47a4f0df4724d2 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 8 Jan 2025 21:40:02 +0100
Subject: [PATCH 208/283] style: fix style for modal create lobby

---
 components/Multiplayer/ModalCreateLobby.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/components/Multiplayer/ModalCreateLobby.tsx b/components/Multiplayer/ModalCreateLobby.tsx
index f87b518..831538c 100644
--- a/components/Multiplayer/ModalCreateLobby.tsx
+++ b/components/Multiplayer/ModalCreateLobby.tsx
@@ -44,7 +44,7 @@ const styles = StyleSheet.create({
     modalView: {
         display: 'flex',
         justifyContent: 'space-between',
-        height: '50%',
+        height: 400,
         width: '90%',
         margin: '10%',
         padding: '5%',
-- 
GitLab


From 44969d458d5303778b98818653492f5e69155299 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Wed, 8 Jan 2025 22:10:29 +0100
Subject: [PATCH 209/283] style: modif modal

---
 screens/Profil/Modals/ProfilModal.tsx       |  2 +-
 screens/Profil/Modals/ProfilModalLogin.tsx  | 14 ++++++--------
 screens/Profil/Modals/ProfilModalSignup.tsx |  8 ++++++--
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/screens/Profil/Modals/ProfilModal.tsx b/screens/Profil/Modals/ProfilModal.tsx
index fb5afbd..c24d3fc 100644
--- a/screens/Profil/Modals/ProfilModal.tsx
+++ b/screens/Profil/Modals/ProfilModal.tsx
@@ -82,7 +82,7 @@ const styles = StyleSheet.create({
         position: "absolute",
     },
     containerModal: {
-        height: "80%",
+        height: 600,
         width: "90%",
         backgroundColor: "#D9D9D9",
         borderRadius: 40,
diff --git a/screens/Profil/Modals/ProfilModalLogin.tsx b/screens/Profil/Modals/ProfilModalLogin.tsx
index 2f651da..41c3553 100644
--- a/screens/Profil/Modals/ProfilModalLogin.tsx
+++ b/screens/Profil/Modals/ProfilModalLogin.tsx
@@ -1,10 +1,10 @@
 import { TextInput, View, StyleSheet, Text } from "react-native";
-import DefaultButton from "../../../components/buttons/DefaultButton";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import React, { useState } from "react";
 import {useUserService} from "../../../services/UserService";
 import HttpError from "../../../services/HttpError";
 import {NavigationProp} from "@react-navigation/native";
+import BlueButton from "../../../components/buttons/BlueButton";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -40,14 +40,14 @@ export default function ProfilModalLogin({navigation, closeModal}: Props) {
                 <InputPlayQuiz placeholder="EMAIL..." setText={setEmail} noTitle={true} />
                 <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true} isSecure={true}/>
             </View>
-            <DefaultButton text="LOGIN" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText} />
+            <BlueButton text="LOGIN" onPress={handleSubmitPressed} buttonStyle={styles.SubmitButton} isDisabled={false}/>
         </View>
     );
 }
 
 const styles = StyleSheet.create({
     containerForm: {
-        height: '67%',
+        height: 'auto',
         width: '100%',
         display: 'flex',
         flexDirection: 'column',
@@ -56,7 +56,10 @@ const styles = StyleSheet.create({
         marginTop: "3%",
     },
     container:{
+        height: 475,
         paddingTop: '5%',
+        display: 'flex',
+        justifyContent: 'space-between'
     },
     textInput: {
         height: '20%',
@@ -74,11 +77,6 @@ const styles = StyleSheet.create({
         backgroundColor: '#2b73fe',
         borderRadius: 10,
     },
-    SubmitText: {
-        fontSize: 20,
-        fontWeight: 'bold',
-        color: '#FFFFFF',
-    },
     errorText: {
         color: 'red',
         fontSize: 16,
diff --git a/screens/Profil/Modals/ProfilModalSignup.tsx b/screens/Profil/Modals/ProfilModalSignup.tsx
index a673efa..124a42e 100644
--- a/screens/Profil/Modals/ProfilModalSignup.tsx
+++ b/screens/Profil/Modals/ProfilModalSignup.tsx
@@ -5,6 +5,7 @@ import React, {useState} from "react";
 import {useUserService} from "../../../services/UserService";
 import HttpError from "../../../services/HttpError";
 import {NavigationProp} from "@react-navigation/native";
+import BlueButton from "../../../components/buttons/BlueButton";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -49,14 +50,14 @@ export default function ProfilModalSignup({navigation, closeModal}: Props) {
                 <InputPlayQuiz placeholder="PASSWORD..." setText={setPassword} noTitle={true} isSecure={true}/>
                 <InputPlayQuiz placeholder="REPEAT PASSWORD..." setText={setRepeatPassword} noTitle={true} isSecure={true}/>
             </View>
-            <DefaultButton text="SIGNUP" handleButtonPressed={handleSubmitPressed} buttonStyle={styles.SubmitButton} buttonText={styles.SubmitText}/>
+            <BlueButton text="SIGNUP" onPress={handleSubmitPressed} buttonStyle={styles.SubmitButton} isDisabled={false}/>
         </View>
     )
 }
 
 const styles = StyleSheet.create({
     containerForm: {
-        height: '67%',
+        height: 'auto',
         width: '100%',
         display: 'flex',
         flexDirection: 'column',
@@ -65,7 +66,10 @@ const styles = StyleSheet.create({
         marginTop: "3%",
     },
     container:{
+        height: 475,
         paddingTop: '5%',
+        isplay: 'flex',
+        justifyContent: 'space-between'
     },
     textInput: {
         height: '20%',
-- 
GitLab


From d9346c3d8eee4ff38129a6aefdd63f99612f1b1d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 9 Jan 2025 18:55:05 +0100
Subject: [PATCH 210/283] feat: added new services for playing quiz

---
 services/QuizService.ts | 119 ++++++++++++++++++++++++++++++++++------
 services/UserService.ts |   2 +-
 2 files changed, 104 insertions(+), 17 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index 6ceff37..f65804a 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -3,11 +3,16 @@ import {Quiz} from "../models/Quiz";
 import axios from "axios";
 import {Answer} from "../models/Answer";
 import {shuffleAnswersOfQuiz} from "../helper/QuizHelper";
+import {Question} from "../models/Question";
+import {AnswerResponse} from "../models/AnswerResponse";
+import {QuizInformations} from "../models/QuizInformations";
+import {QuestionResponse} from "../models/QuestionResponse";
+import {QuizGenerateAnswer} from "../models/QuizGenerateAnswer";
 
 export const useQuizService =  () => {
-    const url = "https://klebert-host.com:33036"; // Remplace par l'URL de ton endpoint API
+    const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
 
-    const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<Quiz | HttpError> => {
+    const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<string | HttpError> => {
         const requestBody = {
             amount,
             category,
@@ -15,14 +20,14 @@ export const useQuizService =  () => {
         };
 
         try {
-            const response = await axios.post<Quiz>(`${url}/quiz/create`, requestBody, {
+            const response = await axios.post(`${url}/quiz/generate`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
-
-            // Récupération des données retournées par l'API
-            return shuffleAnswersOfQuiz(response.data);
+            const runId =  response.data.id;
+            // Récupération du run ID
+            return runId;
         } catch (error: any) {
             console.error("Error while generating quiz:", error);
 
@@ -36,6 +41,82 @@ export const useQuizService =  () => {
         }
     }
 
+    const getActualQuestionOfAQuiz = async (quizId: string): Promise<Question | HttpError> => {
+        const requestBody = {
+            id: quizId,
+        };
+
+        try {
+            const response = await axios.post<QuestionResponse>(`${url}/run/question`, requestBody, {
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            });
+
+            return response.data.question;
+        } catch (error: any) {
+            console.error("Error while remaining quiz:", error);
+
+            if (error.response) {
+                // Gestion des erreurs HTTP
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                // Gestion des erreurs réseau ou autres
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
+
+    const getQuizInformations = async (quizId: string): Promise<QuizInformations | HttpError> => {
+
+        try {
+            const response = await axios.get<QuizInformations>(`${url}/quiz/info/`+quizId, {
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            });
+            return response.data;
+        } catch (error: any) {
+            console.error("Error while getQuizInformations quiz:", error);
+
+            if (error.response) {
+                // Gestion des erreurs HTTP
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                // Gestion des erreurs réseau ou autres
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
+
+    const answerQuestion = async (quizId: string, questionId: number, answerId: string): Promise<AnswerResponse | HttpError> => {
+        const requestBody = {
+            id: quizId,
+            questionID: questionId,
+            answerID: answerId,
+        };
+
+        try {
+            const response = await axios.post<AnswerResponse>(`${url}/run/answer`, requestBody, {
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            });
+
+            return response.data;
+        } catch (error: any) {
+            console.error("Error while remaining quiz:", error);
+
+            if (error.response) {
+                // Gestion des erreurs HTTP
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                // Gestion des erreurs réseau ou autres
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    };
+
     const remainingQuiz = async (id: string): Promise<Quiz | HttpError> => {
         const requestBody = {
             id,
@@ -102,21 +183,24 @@ export const useQuizService =  () => {
         }
     };
 
-    const getRandomQuiz = async (): Promise<Quiz | HttpError> => {
-        try {
-            const requestBody = {
-                amount: 10,
-            };
+    const getRandomQuiz = async (): Promise<QuizGenerateAnswer | HttpError> => {
+        const requestBody = {
+            amount: 10,
+            category: 10,
+            difficulty: "easy",
+        };
 
-            const response = await axios.post<Quiz>(`${url}/quiz/create`, requestBody, {
+        try {
+            const response = await axios.post<QuizGenerateAnswer>(`${url}/quiz/generate`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
-
-            return shuffleAnswersOfQuiz(response.data);
+            const runId =  response.data.id;
+            // Récupération du run ID
+            return {id: runId, quizId: response.data.quizId};
         } catch (error: any) {
-            console.error("Error while generating random quiz:", error);
+            console.error("Error while generating quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -191,6 +275,9 @@ export const useQuizService =  () => {
         getRandomQuiz: getRandomQuiz,
         getCommunityQuiz: getCommunityQuiz,
         restartQuiz: restartQuiz,
-        getCategories: getCategories
+        getCategories: getCategories,
+        answerQuestion: answerQuestion,
+        getActualQuestionOfAQuiz: getActualQuestionOfAQuiz,
+        getQuizInformations: getQuizInformations
     }
 }
\ No newline at end of file
diff --git a/services/UserService.ts b/services/UserService.ts
index f76e653..08399a9 100644
--- a/services/UserService.ts
+++ b/services/UserService.ts
@@ -4,7 +4,7 @@ import axios from "axios";
 import {transformToUserModel} from "../helper/UserHelper";
 
 export const useUserService =  () => {
-    const url = "https://klebert-host.com:33036";
+    const url = "https://klebert-host.com:33037";
 
 
     const loginUser = async (login: string, password: string): Promise<boolean | HttpError> => {
-- 
GitLab


From 84e42c6afb84b4ac1741573224396f9f1840e4f9 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 9 Jan 2025 18:55:41 +0100
Subject: [PATCH 211/283] feat: added new models for playing quiz and services

---
 models/AnswerResponse.ts     | 17 +++++++++++++++++
 models/Question.ts           |  3 +++
 models/QuestionResponse.ts   |  5 +++++
 models/QuizGenerateAnswer.ts |  4 ++++
 4 files changed, 29 insertions(+)
 create mode 100644 models/AnswerResponse.ts
 create mode 100644 models/QuestionResponse.ts
 create mode 100644 models/QuizGenerateAnswer.ts

diff --git a/models/AnswerResponse.ts b/models/AnswerResponse.ts
new file mode 100644
index 0000000..217cf6e
--- /dev/null
+++ b/models/AnswerResponse.ts
@@ -0,0 +1,17 @@
+import {Answer} from "./Answer";
+import {Category} from "./Quiz";
+
+export interface AnswerResponse {
+    score: number;
+    answers:{
+        id: number;
+        text: string;
+        type:string;
+        categoryId: number;
+        quizId: string;
+        order: number;
+        answers: Answer[];
+    }
+    category: Category;
+
+}
\ No newline at end of file
diff --git a/models/Question.ts b/models/Question.ts
index a474b8a..7b77932 100644
--- a/models/Question.ts
+++ b/models/Question.ts
@@ -1,10 +1,13 @@
 import {Answer} from "./Answer";
+import {Category} from "./Quiz";
 
 export interface Question {
     id: number;
     text: string;
+    type: string;
     categoryId: number;
     quizId: string;
     order: number;
     answers: Answer[];
+    category: Category;
 }
\ No newline at end of file
diff --git a/models/QuestionResponse.ts b/models/QuestionResponse.ts
new file mode 100644
index 0000000..4e1cee6
--- /dev/null
+++ b/models/QuestionResponse.ts
@@ -0,0 +1,5 @@
+import {Question} from "./Question";
+
+export interface QuestionResponse {
+    question: Question;
+}
\ No newline at end of file
diff --git a/models/QuizGenerateAnswer.ts b/models/QuizGenerateAnswer.ts
new file mode 100644
index 0000000..3992ebe
--- /dev/null
+++ b/models/QuizGenerateAnswer.ts
@@ -0,0 +1,4 @@
+export interface QuizGenerateAnswer {
+    id: string;
+    quizId: string;
+}
\ No newline at end of file
-- 
GitLab


From a55dfb910e119cc64670193864a77485e1d6cd9e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 9 Jan 2025 18:56:09 +0100
Subject: [PATCH 212/283] fix: changing for quick game

---
 screens/Home/HomeChild.tsx | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index fd9c7da..22afb5d 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -24,6 +24,7 @@ export default function HomeChild({navigation}: Props) {
 
     const handleButtonQuickGamePressed = async () => {
         const quizData = await getRandomQuiz()
+        console.log(quizData);
         if (quizData instanceof HttpError) {
             console.error("Error while fetching random quiz:", quizData);
             return;
@@ -33,7 +34,7 @@ export default function HomeChild({navigation}: Props) {
             routes: [
                 {
                     name: "PlayingQuiz",
-                    params: {quizRecovered: quizData},
+                    params: {runId: quizData.id, quizId: quizData.quizId},
                 },
             ]
         });
-- 
GitLab


From 27e1b9a4891f194ee58d8d8a32b5be2b2f96d44b Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 9 Jan 2025 18:56:53 +0100
Subject: [PATCH 213/283] refactor: changed the logic for playing game

---
 screens/PlayingQuiz/PlayingQuiz.tsx       | 63 ++++++++++++-------
 screens/PlayingQuiz/PlayingQuizBody.tsx   | 76 +++++++++--------------
 screens/PlayingQuiz/PlayingQuizHeader.tsx | 19 +++---
 3 files changed, 80 insertions(+), 78 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index bcfe263..406582e 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -1,29 +1,18 @@
-import PlayingQuizBody from "./PlayingQuizBody";
 import PlayingQuizHeader from "./PlayingQuizHeader";
-import {useState} from "react";
+import React, {useEffect, useState} from "react";
 import TemplateDuo from "../../templates/TemplateDuo";
-import {Quiz} from "../../models/Quiz";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
+import {QuizInformations} from "../../models/QuizInformations";
+import {useQuizService} from "../../services/QuizService";
+import HttpError from "../../services/HttpError";
+import {Question} from "../../models/Question";
+import PlayingQuizBody from "./PlayingQuizBody";
 
-const optionsTheme = [
-    "General Knowledge",
-    "Entertainment: Books",
-    "Entertainment: Film",
-    "Entertainment: Music",
-    "Entertainment: Musicals & Theatres",
-    "Entertainment: Television",
-    "Entertainment: Video Games",
-    "Entertainment: Board Games",
-    "Science & Nature",
-    "Science: Computers",
-    "Science: Mathematics",
-    "Mythology",
-    "Sports",
-    "Geography"]
 
 type RoutePropsType = {
     PlayingQuiz: {
-        quizRecovered: Quiz;
+        runId: string;
+        quizId: string;
     };
 };
 
@@ -33,14 +22,40 @@ interface Props {
 }
 
 export default function PlayingQuiz({route, navigation}:Props) {
-    const {quizRecovered} = route.params;
-    const [isAlreadyPlayed, setIsAlreadyPlayed] = useState(false);
-    const [quiz, setQuiz] = useState<Quiz>(quizRecovered);
+    const {runId, quizId} = route.params;
+    const { getQuizInformations, getActualQuestionOfAQuiz } = useQuizService();
+    const [quizInformations, setQuizInformations] = useState<QuizInformations | undefined>(undefined);
+    const [actualQuestion, setActualQuestion] = useState<Question | undefined>(undefined);
+    const [score, setScore] = useState(0);
+
+    const fetchQuizInformations = async () => {
+        const quizInformationsFetched = await getQuizInformations(quizId);
+        if (HttpError.isHttpError(quizInformationsFetched)) {
+            return;
+        }
+        setQuizInformations(quizInformationsFetched);
+    }
+
+    const fetchActualQuestion = async () => {
+        const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
+        if (HttpError.isHttpError(actualQuestionFetched)) {
+            return;
+        }
+        setActualQuestion(actualQuestionFetched);
+    }
+
+    useEffect(() => {
+        fetchQuizInformations();
+    }, []);
+
+    useEffect(() => {
+        fetchActualQuestion();
+    }, [quizId]);
 
     return (
         <TemplateDuo
-            childrenHeader={<PlayingQuizHeader quiz={quiz} navigation={navigation}></PlayingQuizHeader>}
-            childrenBody={<PlayingQuizBody quiz={quiz} setQuiz={setQuiz} isAlreadyPlayed={isAlreadyPlayed} setIsAlreadyPlayed={setIsAlreadyPlayed} navigation={navigation}></PlayingQuizBody>}
+            childrenHeader={<PlayingQuizHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score} navigation={navigation}></PlayingQuizHeader>}
+            childrenBody={<PlayingQuizBody quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} navigation={navigation}></PlayingQuizBody>}
         />
     );
 }
\ No newline at end of file
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 5e96e78..b8d01b0 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -10,12 +10,14 @@ import {Question} from "../../models/Question";
 import {Answer} from "../../models/Answer";
 import {Quiz} from "../../models/Quiz";
 import AnswerButton from "../../components/buttons/AnswerButton";
+import {QuizInformations} from "../../models/QuizInformations";
 
 interface Props {
-    quiz: Quiz;
-    setQuiz: Dispatch<SetStateAction<Quiz>>;
-    isAlreadyPlayed: boolean;
-    setIsAlreadyPlayed: (isAlreadyPlayed: boolean) => void;
+    quizInformations: QuizInformations;
+    runId?: string;
+    actualQuestion: Question;
+    fetchActualQuestion: () => void;
+    setScore: (score: number) => void;
     navigation: NavigationProp<any>;
 }
 
@@ -62,24 +64,13 @@ const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number |
     return styles.answerButton;
 }
 
-export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIsAlreadyPlayed, navigation }: Props) {
-    const [currentQuestion, setCurrentQuestion] = useState<Question>(quiz.questions[quiz.questionIndex - 1]);
-    const [questionIsFinished, setQuestionIsFinished] = useState(false);
+export default function PlayingQuizBody({ quizInformations, runId, actualQuestion, fetchActualQuestion, setScore, navigation }: Props) {
     const [selectedAnswerId, setSelectedAnswerId] = useState<number | null>(null);
-    const [validationButtonIsDisabled, setValidationButtonIsDisabled] = useState(true);
     const [quizState, setQuizState] = useState(QuizState.ANSWERING);
     const [correctAnswerId, setCorrectAnswerId] = useState<number | null>(null);
+    const [isLastQuestion, setIsLastQuestion] = useState(false);
 
-    const {getAnswerQuiz} = useQuizService();
-
-    useEffect(() => {
-        setCurrentQuestion(quiz.questions[quiz.questionIndex - 1]);
-        setSelectedAnswerId(null); // Réinitialise la sélection
-        setQuestionIsFinished(false); // Réinitialise l'état de la question
-        setCorrectAnswerId(null); // Réinitialise l'id de la bonne réponse
-        setQuizState(QuizState.ANSWERING)
-    }, [quiz.questionIndex]);
-
+    const {answerQuestion} = useQuizService();
     const getCorrectAnswer = (answers: Answer[]): Answer => {
         const correctAnswer = answers.find((answer) => answer.isCorrect);
         if (!correctAnswer) throw new Error("No correct answer found");
@@ -88,41 +79,35 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
     const onValidation = async () => {
         if(selectedAnswerId === null) return;
         setQuizState(QuizState.LOADING);
-        const answerId = currentQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
+        const answerId = actualQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
         if(!answerId) return;
-        const answers = await getAnswerQuiz(quiz.id, currentQuestion.id, answerId);
-        if (HttpError.isHttpError(answers)) {
+        const answereFetched = await answerQuestion(runId, actualQuestion.id, answerId);
+
+        if (HttpError.isHttpError(answereFetched)) {
             return;
         }
-        setQuizState(QuizState.SHOWING_RESULTS);
-        const correctAnswerIdFetched = getCorrectAnswer(answers).id;
-        if(selectedAnswerId === correctAnswerIdFetched)
-            setQuiz((prevQuiz) => ({
-                ...prevQuiz,
-                score: prevQuiz.score + 1,
-            }));
+        setScore(answereFetched.score);
+        const correctAnswerIdFetched = getCorrectAnswer(answereFetched.answers.answers).id;
         setCorrectAnswerId(correctAnswerIdFetched);
+        setQuizState(QuizState.SHOWING_RESULTS);
 
-    };
-
-    const onContinue = () => {
-        if (quiz.questionIndex === quiz.questions.length) {
-            navigation.navigate("EndQuiz", {quiz: quiz});
+        // Check si c'est la dernière question
+        if(answereFetched.answers.order === quizInformations.questionCount - 1) {
+            setIsLastQuestion(true);
             return;
         }
-        setQuiz((prevQuiz) => ({
-            ...prevQuiz,
-            questionIndex: prevQuiz.questionIndex + 1,
-        }));
-    }
 
-    useEffect(() => {
-        if(selectedAnswerId !== null) {
-            setValidationButtonIsDisabled(false)
+    };
+    const onContinue = () => {
+        if(isLastQuestion) {
+            console.log("go endquiz");
             return;
         }
-        setValidationButtonIsDisabled(true)
-    }, [selectedAnswerId]);
+        fetchActualQuestion();
+        setQuizState(QuizState.ANSWERING);
+        setSelectedAnswerId(null);
+        setCorrectAnswerId(null);
+    }
 
     const onAnsweredButtonClicked = (answerId: number) => {
         if(quizState === QuizState.SHOWING_RESULTS || quizState === QuizState.LOADING) {
@@ -133,9 +118,9 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
 
     return (
         <View style={styles.buttonContainer}>
-            {currentQuestion ? (
+            {actualQuestion ? (
                 <>
-                    {currentQuestion.answers.map((answer, index) => (
+                    {actualQuestion.answers.map((answer, index) => (
                         <AnswerButton
                             key={index}
                             text={answer.text}
@@ -144,7 +129,6 @@ export default function APlayingQuizBody({ quiz, setQuiz, isAlreadyPlayed, setIs
                             buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
                         />
                     ))}
-                    {/* Ajout du PlayButton à la fin */}
                     <View style={styles.playButtonContainer}>
                         <BlueButton onPress={() => quizState === QuizState.ANSWERING ? onValidation() : onContinue()} text={quizState === QuizState.ANSWERING ? "CONFIRM" : "CONTINUE"} buttonStyle={{borderRadius: 50}} isDisabled={false}/>
                     </View>
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 9da0130..1caa6bf 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -7,13 +7,18 @@ import GoHomeButton from "../../components/PlayingQuiz/GoHomeButton";
 import {NavigationProp} from "@react-navigation/native";
 import ConfirmModal from "../../components/PlayingQuiz/ComfirmModal";
 import {useState} from "react";
+import {QuizInformations} from "../../models/QuizInformations";
+import {Question} from "../../models/Question";
 
 interface Props {
+    quizInformations: QuizInformations;
+    runId?: string;
+    actualQuestion: Question;
+    score: number;
     navigation: NavigationProp<any>
-    quiz: Quiz;
 }
 
-export default function PlayingQuizHeader({navigation, quiz}: Props) {
+export default function PlayingQuizHeader({quizInformations, runId, actualQuestion, score, navigation}: Props) {
     const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);
     const {t} = useTranslation();
 
@@ -28,26 +33,24 @@ export default function PlayingQuizHeader({navigation, quiz}: Props) {
         });
     }
 
-    if (quiz.questionCount <= quiz.questionIndex - 1) return;
-
     return (
             <View style={styles.container}>
                 <View style={styles.header}>
                     <GoHomeButton navigation={navigation} onPress={setIsConfirmModalVisible}/>
-                    <Text style={styles.codeQuizText}>ID QUIZZ : {quiz ? quiz.id : "?"}</Text>
+                    <Text style={styles.codeQuizText}>ID QUIZZ : {quizInformations ? quizInformations.id : "?"}</Text>
                 </View>
                 <View style={styles.questionAndScoreContainer}>
                     <View style={styles.InformationsContainer}>
                         <Text style={TextsStyles.titleText}>{t("app.screens.question.question")}</Text>
-                        <Text style={TextsStyles.titleText}>{quiz ? quiz.questionIndex : "?"}/{quiz ? quiz.questionCount : "?"}</Text>
+                        <Text style={TextsStyles.titleText}>{actualQuestion ? actualQuestion.order + 1 :"?"}/{quizInformations ? quizInformations.questionCount : "?"}</Text>
                     </View>
                     <View style={styles.InformationsContainer}>
                         <Text style={TextsStyles.titleText}>{t("app.screens.question.score")}</Text>
-                        <Text style={TextsStyles.titleText}>{quiz ? quiz.score : 0}/{quiz ? quiz.questionCount : "?"}</Text>
+                        <Text style={TextsStyles.titleText}>{score}/{quizInformations ? quizInformations.questionCount : "?"}</Text>
                     </View>
                 </View>
                 <View style={styles.QuizQuestionContainer}>
-                    <Text style={TextsStyles.subtitleText}>{quiz.questions[quiz.questionIndex-1].text ? quiz.questions[quiz.questionIndex-1].text : "Loading..."}</Text>
+                    <Text style={TextsStyles.subtitleText}>{actualQuestion ? actualQuestion.text : "Loading..."}</Text>
                 </View>
                 <ConfirmModal visible={isConfirmModalVisible} onClose={()=>setIsConfirmModalVisible(false)} onConfirm={handleConfirmModalConfirm}/>
 
-- 
GitLab


From f75d27b9a81c0aff5bca40e3a8faabc9dff923d7 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Thu, 9 Jan 2025 18:57:12 +0100
Subject: [PATCH 214/283] feat: add new models

---
 models/Quiz.ts             |  2 +-
 models/QuizInformations.ts | 17 +++++++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 models/QuizInformations.ts

diff --git a/models/Quiz.ts b/models/Quiz.ts
index b5087c2..1acc2ce 100644
--- a/models/Quiz.ts
+++ b/models/Quiz.ts
@@ -1,6 +1,6 @@
 import {Question} from "./Question";
 
-interface Difficulty {
+export interface Difficulty {
     id: number;
     name: string;
 }
diff --git a/models/QuizInformations.ts b/models/QuizInformations.ts
new file mode 100644
index 0000000..32d4230
--- /dev/null
+++ b/models/QuizInformations.ts
@@ -0,0 +1,17 @@
+import UserModel from "./UserModel";
+import {Category, Difficulty} from "./Quiz";
+
+export interface QuizInformations {
+    id: number;
+    name: string;
+    description: string;
+    isCommunity: boolean;
+    questionCount: number;
+    categoryId: number;
+    difficultyId: number;
+    authorId?: UserModel;
+    createdAt: string;
+    updatedAt: string;
+    category: Category;
+    difficulty: Difficulty;
+}
\ No newline at end of file
-- 
GitLab


From be67746e81b462f6ee8ddbacfc9c97a569b44f20 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 9 Jan 2025 21:12:46 +0100
Subject: [PATCH 215/283] fix: replace selectListBox

---
 .../OnlineQuiz/OnlineCreateLobby.tsx            | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
index 177d4b6..73eb259 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
@@ -1,11 +1,13 @@
 import { Text,View, StyleSheet } from "react-native";
-import SelectListBox from "../../../components/PlayQuiz/SelectListBox";
-import React, {useEffect} from "react";
+import React, {useEffect, useState} from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {useQuizService} from "../../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
 import BlueButton from "../../../components/buttons/BlueButton";
+import SelectListBoxString from "../../../components/PlayQuiz/SelectListBoxString";
+import SelectListBoxCategory from "../../../components/PlayQuiz/SelectListBoxCategory";
+import { Category } from "../../../models/Quiz";
 
 const difficulty = [
     { key: "easy", value: "easy" },
@@ -35,14 +37,15 @@ interface Props {
 
 export default function OnlineCreateLobby({navigation}: Props) {
     const [difficutlyChoose, setDifficutlyChoose] = React.useState("");
-    const [categoryChoose, setCategoryChoose] = React.useState("");
+    const [categories, setCategories] = useState<Category[]>([]);
+    const [categoryChoose, setCategoryChoose] = React.useState<Category | null>(null);
     const [nbQuestions, setNbQuestions] = React.useState("10");
     const [nbPlayers, setNbPlayers] = React.useState("2");
     const [buttonIsDisabled, setButtonIsDisabled] = React.useState(true);
     const {generateQuiz} = useQuizService();
 
     useEffect(() => {
-        if(nbQuestions === "" || difficutlyChoose === "" || categoryChoose === "")
+        if(nbQuestions === "" || difficutlyChoose === "" || categoryChoose === null)
         {
             setButtonIsDisabled(true);
         }
@@ -70,9 +73,9 @@ export default function OnlineCreateLobby({navigation}: Props) {
         <View style={styles.container}>
             <View style={styles.contentContainer}>
                 <View style={styles.fieldContainer}>
-                    <SelectListBox title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
-                    <SelectListBox title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
-                    <InputPlayQuiz title="NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} defaultValue={nbQuestions}/>
+                    <SelectListBoxString title="CHOOSE A DIFFICULTY" data={difficulty} setSelected={setDifficutlyChoose} />
+                    <SelectListBoxCategory title="CHOOSE A CATEGORY" data={categories} setSelected={setCategoryChoose} />
+                    <InputPlayQuiz title="CHOOSE A NUMBER OF QUESTIONS" setText={setNbQuestions} numeric={true} defaultValue={nbQuestions}/>
                     <InputPlayQuiz title="NUMBER OF PLAYERS" setText={setNbPlayers} numeric={true} defaultValue={nbPlayers}/>
                 </View>
                 <View style={styles.buttonPlayContainer}>
-- 
GitLab


From db1390e8cd45a132efe5a55101f653f21259c38f Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 16:01:23 +0100
Subject: [PATCH 216/283] feat: add informations quiz for multiplayer community

---
 .../InformationsOfQuiz/InformationsOfQuiz.tsx | 98 +++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx

diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx
new file mode 100644
index 0000000..fdbd797
--- /dev/null
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -0,0 +1,98 @@
+import React from "react";
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import TemplateMenu from "../../../../templates/TemplateMenu";
+import {NavigationProp, RouteProp} from "@react-navigation/native";
+import {Quiz} from "../../../../models/Quiz";
+
+type RoutePropsType = {
+    InformationsOfQuiz: {
+        quiz: Quiz;
+    };
+};
+interface Props {
+    navigation: NavigationProp<any>;
+    route: RouteProp<RoutePropsType, "InformationsOfQuiz">;
+}
+
+export default function InformationsOfQuiz({ navigation, route }: Props) {
+    const { quiz } = route.params;
+
+    const onCreateLobby = () => {
+        navigation.navigate('PlayingQuiz', {quizRecovered: quiz});
+    }
+
+    return (
+        <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
+            <View style={styles.container}>
+                <Text style={styles.quizTitle}>{quiz.name}</Text>
+                <Text style={styles.quizDescription}>{quiz.category?.name}</Text>
+
+                <View style={styles.aboutContainer}>
+                    <Text style={styles.aboutTitle}>About this quiz :</Text>
+                    <Text style={styles.aboutDetails}>{quiz.questionCount} questions</Text>
+                    <Text style={styles.aboutDetails}>By : Unknown</Text>
+                </View>
+
+                <TouchableOpacity style={styles.playButton} onPress={onCreateLobby}>
+                    <Text style={styles.playButtonText}>CREATE LOBBY</Text>
+                </TouchableOpacity>
+            </View>
+        </TemplateMenu>
+
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        paddingHorizontal: 20,
+        paddingVertical: 20,
+        justifyContent: "flex-start",
+        backgroundColor: "#f4f4f4",
+    },
+    quizTitle: {
+        fontSize: 24,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+    },
+    quizDescription: {
+        fontSize: 16,
+        color: "#555",
+        marginBottom: 20,
+    },
+    aboutContainer: {
+        backgroundColor: "white",
+        borderRadius: 10,
+        padding: 15,
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.2,
+        shadowRadius: 3,
+        elevation: 5,
+    },
+    aboutTitle: {
+        fontSize: 18,
+        fontWeight: "bold",
+        marginBottom: 10,
+        color: "#000",
+    },
+    aboutDetails: {
+        fontSize: 16,
+        color: "#555",
+        marginBottom: 5,
+    },
+    playButton: {
+        backgroundColor: "#007BFF",
+        paddingVertical: 15,
+        borderRadius: 10,
+        alignItems: "center",
+        justifyContent: "center",
+        marginTop: 20,
+    },
+    playButtonText: {
+        fontSize: 18,
+        fontWeight: "bold",
+        color: "white",
+    },
+});
-- 
GitLab


From 00ea7ec1ec28aec02898333174033bcce42ac1e2 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 16:13:49 +0100
Subject: [PATCH 217/283] feat: remove modal and button createlobby

---
 .../MultiplayerCommunity.tsx                  | 23 ++++---------------
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index 18dba4d..28ce183 100644
--- a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -17,7 +17,7 @@ export default function MultiplayerCommunity({navigation}: Props) {
     const  {getCommunityQuiz, getRandomQuiz} = useQuizService();
     const [input, setInput] = useState<string>("")
     const [loading, setLoading] = useState<boolean>(false)
-    const [showModal, setShowModal] = useState<boolean>(false);
+    
     const [quiz, setQuiz] = useState<Quiz | null>(null);
 
     const fetchCommunityQuizzes = async ({pageParam = 1}) => {
@@ -29,22 +29,11 @@ export default function MultiplayerCommunity({navigation}: Props) {
         return quizzes;
     }
 
-    const onCreateLobbyPressed = () => {
-        setShowModal(true);
-    };
-
     const onQuizPressed = (quiz: Quiz) => {
         setQuiz(quiz);
     };
 
-    const onClosePressed = () => {
-        setShowModal(false);
-    };
-
-    const onPlayPressed = async (nbPlayer: number) => {
-        setShowModal(false);
-        navigation.navigate("Lobby", {quiz: quiz, nbPlayer: nbPlayer});
-    };
+    
 
 
     const {
@@ -66,13 +55,9 @@ export default function MultiplayerCommunity({navigation}: Props) {
 
     return (
         <View style={styles.containerGlobal}>
-            <View style={styles.templateQuizListContainer}>
+            {/* <View style={styles.templateQuizListContainer}> */}
                 <TemplateQuizList title={"Community"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={true} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
-            </View>
-            <View style={styles.buttonContainer}>
-                <BlueButton text="CREATE LOBBY" onPress={onCreateLobbyPressed}  isDisabled={false}/>
-            </View>
-            <ModalCreateLobby onClosePressed={onClosePressed} onPlayPressed={onPlayPressed} showModal={showModal}/>
+            {/* </View> */}
         </View>
     );
 }
-- 
GitLab


From 06d6e7a9c7678928091181a9b41d804bdf539722 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 16:21:51 +0100
Subject: [PATCH 218/283] feat: add route to info quiz  multi

---
 routes/StackNavigator.tsx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 2fbc28e..31856e8 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -13,6 +13,7 @@ import Lobby from "../screens/Multiplayer/Lobby/Lobby";
 import PlayQuiz from "../screens/Home/PlayQuiz/PlayQuiz";
 import MyQuizzes from "../screens/Home/MyQuizzes/MyQuizzes";
 import InformationsOfQuiz from "../screens/Community/InformationsOfQuiz/InformationsOfQuiz";
+import MultiInformationsOfQuiz from "../screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz";
 
 const Stack = createNativeStackNavigator();
 
@@ -34,6 +35,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="OnlineQuiz" component={OnlineQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="OngoingQuizzes" component={OngoingQuizzes} options={{ headerShown: false }}/>
                 <Stack.Screen name="Lobby" component={Lobby} options={{ headerShown: false }}/>
+                <Stack.Screen name="MultiInformationsOfQuiz" component={MultiInformationsOfQuiz} options={{ headerShown: false }}/>
             </Stack.Navigator>
         </NavigationContainer>
     );
-- 
GitLab


From d1bcec0cdbf686123a466c75761bc38da01a6c32 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 16:22:51 +0100
Subject: [PATCH 219/283] feat: change quiz pressed

---
 .../MultiplayerCommunity/MultiplayerCommunity.tsx          | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
index 28ce183..dbc402b 100644
--- a/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/MultiplayerCommunity.tsx
@@ -17,8 +17,6 @@ export default function MultiplayerCommunity({navigation}: Props) {
     const  {getCommunityQuiz, getRandomQuiz} = useQuizService();
     const [input, setInput] = useState<string>("")
     const [loading, setLoading] = useState<boolean>(false)
-    
-    const [quiz, setQuiz] = useState<Quiz | null>(null);
 
     const fetchCommunityQuizzes = async ({pageParam = 1}) => {
         const quizzes = await getCommunityQuiz(pageParam,7);//TODO: changer pour get les quiz community public
@@ -30,12 +28,9 @@ export default function MultiplayerCommunity({navigation}: Props) {
     }
 
     const onQuizPressed = (quiz: Quiz) => {
-        setQuiz(quiz);
+        navigation.navigate("MultiInformationsOfQuiz", {quiz: quiz});
     };
 
-    
-
-
     const {
         data,
         fetchNextPage,
-- 
GitLab


From a19b3c112cd38ba4d216a3183b3fe4724a1cde1a Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 16:23:45 +0100
Subject: [PATCH 220/283] feat: add modal to information quiz

---
 .../InformationsOfQuiz/InformationsOfQuiz.tsx | 22 ++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx
index fdbd797..a4ffe4e 100644
--- a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -1,8 +1,9 @@
-import React from "react";
+import React, { useState } from "react";
 import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
 import TemplateMenu from "../../../../templates/TemplateMenu";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
 import {Quiz} from "../../../../models/Quiz";
+import ModalCreateLobby from "../../../../components/Multiplayer/ModalCreateLobby";
 
 type RoutePropsType = {
     InformationsOfQuiz: {
@@ -14,13 +15,27 @@ interface Props {
     route: RouteProp<RoutePropsType, "InformationsOfQuiz">;
 }
 
-export default function InformationsOfQuiz({ navigation, route }: Props) {
+export default function MultiInformationsOfQuiz({ navigation, route }: Props) {
     const { quiz } = route.params;
+    const [showModal, setShowModal] = useState<boolean>(false);
 
     const onCreateLobby = () => {
         navigation.navigate('PlayingQuiz', {quizRecovered: quiz});
     }
 
+    const onCreateLobbyPressed = () => {
+        setShowModal(true);
+    };
+
+    const onClosePressed = () => {
+        setShowModal(false);
+    };
+
+    const onPlayPressed = async (nbPlayer: number) => {
+        setShowModal(false);
+        navigation.navigate("MultiInformationsOfQuiz", {quiz: quiz, nbPlayer: nbPlayer});
+    };
+
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
             <View style={styles.container}>
@@ -33,10 +48,11 @@ export default function InformationsOfQuiz({ navigation, route }: Props) {
                     <Text style={styles.aboutDetails}>By : Unknown</Text>
                 </View>
 
-                <TouchableOpacity style={styles.playButton} onPress={onCreateLobby}>
+                <TouchableOpacity style={styles.playButton} onPress={onCreateLobbyPressed}>
                     <Text style={styles.playButtonText}>CREATE LOBBY</Text>
                 </TouchableOpacity>
             </View>
+            <ModalCreateLobby onClosePressed={onClosePressed} onPlayPressed={onPlayPressed} showModal={showModal}/>
         </TemplateMenu>
 
     );
-- 
GitLab


From 5a824aa98cd54dd579b7809a8c19b09614dea8e7 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 16:29:20 +0100
Subject: [PATCH 221/283] refactor: rename file

---
 .../{InformationsOfQuiz.tsx => MultiInformationsOfQuiz.tsx}       | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/{InformationsOfQuiz.tsx => MultiInformationsOfQuiz.tsx} (100%)

diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
similarity index 100%
rename from screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz.tsx
rename to screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
-- 
GitLab


From 9263a718fe96c641e06c03a761aea5cdcc481016 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 16:34:48 +0100
Subject: [PATCH 222/283] refactor: change import file

---
 routes/StackNavigator.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 31856e8..377abc3 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -13,7 +13,7 @@ import Lobby from "../screens/Multiplayer/Lobby/Lobby";
 import PlayQuiz from "../screens/Home/PlayQuiz/PlayQuiz";
 import MyQuizzes from "../screens/Home/MyQuizzes/MyQuizzes";
 import InformationsOfQuiz from "../screens/Community/InformationsOfQuiz/InformationsOfQuiz";
-import MultiInformationsOfQuiz from "../screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/InformationsOfQuiz";
+import MultiInformationsOfQuiz from "../screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz";
 
 const Stack = createNativeStackNavigator();
 
-- 
GitLab


From 8c30d5f7a2f7e40bc2d049dab076d087bf22e34d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 16:35:11 +0100
Subject: [PATCH 223/283] feat: play pressed got to lobby

---
 .../InformationsOfQuiz/MultiInformationsOfQuiz.tsx              | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
index a4ffe4e..ddf1fca 100644
--- a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
@@ -33,7 +33,7 @@ export default function MultiInformationsOfQuiz({ navigation, route }: Props) {
 
     const onPlayPressed = async (nbPlayer: number) => {
         setShowModal(false);
-        navigation.navigate("MultiInformationsOfQuiz", {quiz: quiz, nbPlayer: nbPlayer});
+        navigation.navigate("Lobby", {quiz: quiz, nbPlayer: nbPlayer});
     };
 
     return (
-- 
GitLab


From 1d8259bf1f832a0f5406fad48a38e3aa9854a859 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sat, 11 Jan 2025 16:35:18 +0100
Subject: [PATCH 224/283] feat: added users stats

---
 components/Profil/LineOfUserStat.tsx    | 45 ++++++++++++++++++++++++
 components/Profil/StatsOfUsers.tsx      | 41 ++++++++++++++++++++++
 helper/UserHelper.ts                    |  6 ++--
 models/AnswerResponse.ts                |  1 -
 models/QuizInformations.ts              |  4 +--
 models/User.ts                          | 12 +++++++
 models/UserModel.ts                     | 12 -------
 screens/Home/HomeChild.tsx              |  1 +
 screens/PlayingQuiz/PlayingQuizBody.tsx | 14 ++++++--
 screens/Profil/ProfilChild.tsx          | 46 ++++++++++++++++++-------
 services/QuizService.ts                 | 17 +++++----
 services/UserService.ts                 | 10 +++---
 12 files changed, 160 insertions(+), 49 deletions(-)
 create mode 100644 components/Profil/LineOfUserStat.tsx
 create mode 100644 components/Profil/StatsOfUsers.tsx
 create mode 100644 models/User.ts
 delete mode 100644 models/UserModel.ts

diff --git a/components/Profil/LineOfUserStat.tsx b/components/Profil/LineOfUserStat.tsx
new file mode 100644
index 0000000..9a718af
--- /dev/null
+++ b/components/Profil/LineOfUserStat.tsx
@@ -0,0 +1,45 @@
+import {View, Text, StyleSheet} from "react-native";
+
+export interface Props {
+    title: string;
+    value: string;
+    isLast?: boolean;
+}
+
+export default function LineOfUserStat({title, value, isLast}: Props) {
+    return (
+        <>
+            <View style={styles.container}>
+                <Text style={styles.textTitle}>{title} :</Text>
+                <Text style={styles.textValue}>{value}</Text>
+            </View>
+            {!isLast &&<View style={styles.separator} />}
+        </>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        flexDirection: "row",
+        justifyContent: "space-between",
+        width: "85%",
+    },
+    textTitle: {
+        fontWeight: "bold",
+        fontSize: 20,
+        color: "#555",
+    },
+    textValue: {
+        fontStyle: "normal",
+        fontWeight: "bold",
+        fontSize: 20,
+        color: "#00B3F4",
+    },
+    separator: {
+        width: "90%",
+        height: 1,
+        backgroundColor: "#000",
+        marginVertical: 10, // Espacement entre la ligne et les stats
+    },
+});
\ No newline at end of file
diff --git a/components/Profil/StatsOfUsers.tsx b/components/Profil/StatsOfUsers.tsx
new file mode 100644
index 0000000..157097e
--- /dev/null
+++ b/components/Profil/StatsOfUsers.tsx
@@ -0,0 +1,41 @@
+import React from "react";
+import {View, Text, StyleSheet} from "react-native";
+import LineOfUserStat from "./LineOfUserStat";
+import {User} from "../../models/User";
+
+interface Props {
+    user?: User;
+}
+
+export default function StatsOfUsers({user}: Props) {
+    return (
+        <View style={styles.container}>
+            <LineOfUserStat title="Quizzes created" value={user?.stats ? user.stats.quizzesCreated.toString() : "?"} />
+            <LineOfUserStat title="Quizzes played" value={user?.stats ? user.stats.quizzesPlayed.toString() : "?"} />
+            <LineOfUserStat title="Correct answers" value={user?.stats ? user.stats.correctAnswers.toString() : "?"} />
+            <LineOfUserStat title="Total responses" value={user?.stats ? user.stats.totalAnswers.toString() : "?"} isLast={true}/>
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        display: "flex",
+        width: "80%",
+        height: "45%",
+        marginTop: "10%",
+        justifyContent: "space-around",
+        alignItems: "center",
+        backgroundColor: "#f9f9f9",
+        borderRadius: 15,
+        shadowColor: "#000",
+        shadowOffset: {
+            width: 0,
+            height: 4,
+        },
+        shadowOpacity: 0.3,
+        shadowRadius: 5,
+        elevation: 5,
+        paddingVertical: 15,
+    },
+});
\ No newline at end of file
diff --git a/helper/UserHelper.ts b/helper/UserHelper.ts
index 123b556..cfacf0f 100644
--- a/helper/UserHelper.ts
+++ b/helper/UserHelper.ts
@@ -1,7 +1,7 @@
-import UserModel from "../models/UserModel";
+import User from "../models/User";
 
-export const transformToUserModel = (data: any): UserModel => {
-    const user: UserModel = {
+export const transformToUserModel = (data: any): User => {
+    const user: User = {
         id: data.id,
         email: data.email,
         username: data.username,
diff --git a/models/AnswerResponse.ts b/models/AnswerResponse.ts
index 217cf6e..24a83f1 100644
--- a/models/AnswerResponse.ts
+++ b/models/AnswerResponse.ts
@@ -13,5 +13,4 @@ export interface AnswerResponse {
         answers: Answer[];
     }
     category: Category;
-
 }
\ No newline at end of file
diff --git a/models/QuizInformations.ts b/models/QuizInformations.ts
index 32d4230..5087ebc 100644
--- a/models/QuizInformations.ts
+++ b/models/QuizInformations.ts
@@ -1,4 +1,4 @@
-import UserModel from "./UserModel";
+import User from "./User";
 import {Category, Difficulty} from "./Quiz";
 
 export interface QuizInformations {
@@ -9,7 +9,7 @@ export interface QuizInformations {
     questionCount: number;
     categoryId: number;
     difficultyId: number;
-    authorId?: UserModel;
+    authorId?: User;
     createdAt: string;
     updatedAt: string;
     category: Category;
diff --git a/models/User.ts b/models/User.ts
new file mode 100644
index 0000000..96d2b30
--- /dev/null
+++ b/models/User.ts
@@ -0,0 +1,12 @@
+interface Stats {
+    quizzesCreated: number;
+    quizzesPlayed: number;
+    correctAnswers: number;
+    totalAnswers: number;
+}
+export interface User {
+    id: number;
+    email: string;
+    username: string;
+    stats: Stats;
+}
\ No newline at end of file
diff --git a/models/UserModel.ts b/models/UserModel.ts
deleted file mode 100644
index 66ecffe..0000000
--- a/models/UserModel.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export default class UserModel {
-    id: number;
-    username: string;
-    email: string;
-    constructor(id: number, username: string, email: string) {
-        this.id = id;
-        this.username = username;
-        this.email = email;
-    }
-}
-
-
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 22afb5d..1072366 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -37,6 +37,7 @@ export default function HomeChild({navigation}: Props) {
                     params: {runId: quizData.id, quizId: quizData.quizId},
                 },
             ]
+
         });
     }
     const handleButtonMyQuizzesPressed = () => {
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index b8d01b0..0992745 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -1,4 +1,4 @@
-import { View, StyleSheet, Text } from "react-native";
+import {View, StyleSheet, Text, ActivityIndicator} from "react-native";
 import DefaultButton from "../../components/buttons/DefaultButton";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
 import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
@@ -80,7 +80,7 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
         if(selectedAnswerId === null) return;
         setQuizState(QuizState.LOADING);
         const answerId = actualQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
-        if(!answerId) return;
+        if(!answerId || !runId) return;
         const answereFetched = await answerQuestion(runId, actualQuestion.id, answerId);
 
         if (HttpError.isHttpError(answereFetched)) {
@@ -134,7 +134,10 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
                     </View>
                 </>
             ) : (
-                <Text style={styles.loadingText}>Loading...</Text>
+                <View style={styles.loadingContainer}>
+                    <ActivityIndicator size="large" color="#2b73fe" />
+                    <Text style={styles.loadingText}>Loading...</Text>
+                </View>
             )}
         </View>
     );
@@ -150,6 +153,11 @@ const styles = StyleSheet.create({
         width: '100%',
         marginVertical: '3%',
     },
+    loadingContainer: {
+        flex: 1,
+        justifyContent: "center",
+        alignItems: "center",
+    },
     playButtonContainer: {
         marginTop: 20, // Ajoute un espacement au-dessus du bouton Play
         width: '80%', // S'assure que le bouton prend toute la largeur disponible
diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index 81208fc..dd96222 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -4,35 +4,57 @@ import ProfilModal from "./Modals/ProfilModal";
 import React, { useEffect, useState } from "react";
 import ProfilHeaderAccount from "./ProfilHeaderAccount";
 import { ProfilSelectModeType } from "../../models/SelectModeType";
-import UserModel from "../../models/UserModel";
 import { useUserService } from "../../services/UserService";
 import HttpError from "../../services/HttpError";
 import Icon from "react-native-vector-icons/MaterialIcons";
+import {User} from "../../models/User";
+import StatsOfUsers from "../../components/Profil/StatsOfUsers";
 
 interface Props {
     navigation: NavigationProp<any>;
 }
 
+enum UserConnectionState {
+    LOADING = "Loading",
+    NOT_CONNECTED = "NotConnected",
+    CONNECTED = "Connected",
+}
+
 export default function ProfilChild({ navigation }: Props) {
+    const [isLogged, setIsLogged] = useState(false);
     const [modalVisible, setModalVisible] = useState(false);
     const [mode, setMode] = useState<ProfilSelectModeType>("login");
-    const [user, setUser] = useState<UserModel | null>(null);
+    const [user, setUser] = useState<User | undefined>(undefined);
+    const [userConnectionState, setUserConnectionState] = useState(UserConnectionState.LOADING);
     const { getInformationsUser, logoutUser } = useUserService();
 
-    useEffect(() => {
-        getInformationsUser().then((user: UserModel | HttpError) => {
-            if (user instanceof HttpError) {
-                return;
-            }
-            setUser(user);
+    const getUser = async () => {
+        setUserConnectionState(UserConnectionState.LOADING);
+        const user = await getInformationsUser();
+        console.log(user);
+        if(user instanceof HttpError){
+            setUser(undefined);
+            setUserConnectionState(UserConnectionState.NOT_CONNECTED);
             return;
-        });
+        }
+        setUserConnectionState(UserConnectionState.CONNECTED);
+        setUser(user);
+    }
+
+    useEffect(() => {
+        getUser();
+
     }, []);
 
+    // Pour s'adapter quand l'état de connexion change
+    useEffect(() => {
+        getUser();
+    }, [isLogged]);
+
     const handleLogout = async () => {
         const result = await logoutUser();
         if (!(result instanceof HttpError)) {
-            setUser(null); // Réinitialise l'utilisateur après la déconnexion
+            setUser(undefined); // Réinitialise l'utilisateur après la déconnexion
         }
     };
 
@@ -43,9 +65,6 @@ export default function ProfilChild({ navigation }: Props) {
                 <Image source={require('../../assets/ProfilBaseImage.png')} style={styles.profilImage} />
                 <Text style={styles.pseudoText}>{user ? user.username : "?"}</Text>
             </View>
-            <View style={styles.containerPlayerStats}>
-                {/*<Text style={styles.statsText}>Played quiz : _123_</Text>*/}
-            </View>
 
             {!user && (
                 <ProfilHeaderAccount setModalVisible={setModalVisible} setMode={setMode} />
@@ -57,6 +76,7 @@ export default function ProfilChild({ navigation }: Props) {
                 setMode={setMode}
                 navigation={navigation}
             />
+            <StatsOfUsers user={user}/>
 
             {user && (
                 <TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
diff --git a/services/QuizService.ts b/services/QuizService.ts
index f65804a..72752c8 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -29,7 +29,7 @@ export const useQuizService =  () => {
             // Récupération du run ID
             return runId;
         } catch (error: any) {
-            console.error("Error while generating quiz:", error);
+            console.log("Error while generating quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -55,7 +55,7 @@ export const useQuizService =  () => {
 
             return response.data.question;
         } catch (error: any) {
-            console.error("Error while remaining quiz:", error);
+            console.log("Error while remaining quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -77,7 +77,7 @@ export const useQuizService =  () => {
             });
             return response.data;
         } catch (error: any) {
-            console.error("Error while getQuizInformations quiz:", error);
+            console.log("Error while getQuizInformations quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -89,7 +89,7 @@ export const useQuizService =  () => {
         }
     }
 
-    const answerQuestion = async (quizId: string, questionId: number, answerId: string): Promise<AnswerResponse | HttpError> => {
+    const answerQuestion = async (quizId: string, questionId: number, answerId: number): Promise<AnswerResponse | HttpError> => {
         const requestBody = {
             id: quizId,
             questionID: questionId,
@@ -105,7 +105,7 @@ export const useQuizService =  () => {
 
             return response.data;
         } catch (error: any) {
-            console.error("Error while remaining quiz:", error);
+            console.log("Error while remaining quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -132,7 +132,7 @@ export const useQuizService =  () => {
             // Récupération des données retournées par l'API
             return shuffleAnswersOfQuiz(response.data);
         } catch (error: any) {
-            console.error("Error while remaining quiz:", error);
+            console.log("Error while remaining quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -171,7 +171,7 @@ export const useQuizService =  () => {
 
             return answers;
         } catch (error: any) {
-            console.error("Error while fetching answers:", error);
+            console.log("Error while fetching answers:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -200,7 +200,7 @@ export const useQuizService =  () => {
             // Récupération du run ID
             return {id: runId, quizId: response.data.quizId};
         } catch (error: any) {
-            console.error("Error while generating quiz:", error);
+            console.log("Error while generating quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -218,7 +218,6 @@ export const useQuizService =  () => {
                 withCredentials: true, // Inclut les cookies pour une session authentifiée
             });
 
-
             return response.data;
         } catch (error: any) {
 
diff --git a/services/UserService.ts b/services/UserService.ts
index 08399a9..374a311 100644
--- a/services/UserService.ts
+++ b/services/UserService.ts
@@ -1,5 +1,5 @@
 import HttpError from "./HttpError";
-import UserModel from "../models/UserModel";
+import User from "../models/User";
 import axios from "axios";
 import {transformToUserModel} from "../helper/UserHelper";
 
@@ -35,15 +35,13 @@ export const useUserService =  () => {
         }
     };
 
-    const getInformationsUser = async (): Promise<UserModel | HttpError> => {
+    const getInformationsUser = async (): Promise<User | HttpError> => {
         try {
-            const response = await axios.get(`${url}/user/me`, {
+            const response = await axios.get<User>(`${url}/user/me`, {
                 withCredentials: true, // Inclut les cookies dans la requête
             });
 
-            const user = transformToUserModel(response.data);
-
-            return user;
+            return response.data;
         } catch (error: any) {
             if (error.response.status === 401) {
                 return new HttpError(401, "No user logged in");
-- 
GitLab


From 6dd1ff56e04bfb96cddb19ee53c2d3dd14055ed1 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 17:24:20 +0100
Subject: [PATCH 225/283] styles: show background

---
 screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx | 2 --
 1 file changed, 2 deletions(-)

diff --git a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
index a65b874..684af20 100644
--- a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -38,7 +38,6 @@ export default function InformationsOfQuiz({ navigation, route }: Props) {
                 </TouchableOpacity>
             </View>
         </TemplateMenu>
-
     );
 }
 
@@ -48,7 +47,6 @@ const styles = StyleSheet.create({
         paddingHorizontal: 20,
         paddingVertical: 20,
         justifyContent: "flex-start",
-        backgroundColor: "#f4f4f4",
     },
     quizTitle: {
         fontSize: 24,
-- 
GitLab


From 235c9712e4c6e60dc0f8906b33012d6e96d8d70d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 17:27:57 +0100
Subject: [PATCH 226/283] feat: add description of the quiz

---
 screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
index 684af20..7c95429 100644
--- a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -25,7 +25,7 @@ export default function InformationsOfQuiz({ navigation, route }: Props) {
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
             <View style={styles.container}>
                 <Text style={styles.quizTitle}>{quiz.name}</Text>
-                <Text style={styles.quizDescription}>{quiz.category?.name}</Text>
+                <Text style={styles.quizDescription}>{quiz.description && "No Descripion"}</Text>
 
                 <View style={styles.aboutContainer}>
                     <Text style={styles.aboutTitle}>About this quiz :</Text>
-- 
GitLab


From cabac7895a931bc15662f39798bd3de5c51bf5ee Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 17:37:59 +0100
Subject: [PATCH 227/283] feat: add info for quiz

---
 screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
index 7c95429..1aa7bcc 100644
--- a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -29,8 +29,8 @@ export default function InformationsOfQuiz({ navigation, route }: Props) {
 
                 <View style={styles.aboutContainer}>
                     <Text style={styles.aboutTitle}>About this quiz :</Text>
-                    <Text style={styles.aboutDetails}>{quiz.questionCount} questions</Text>
-                    <Text style={styles.aboutDetails}>By : Unknown</Text>
+                    <Text style={styles.aboutDetails}>{quiz.questionCount} questions, {quiz.difficulty.name}</Text>
+                    <Text style={styles.aboutDetails}>By : {quiz.authorId && "Unknown"}</Text>
                 </View>
 
                 <TouchableOpacity style={styles.playButton} onPress={onPlay}>
-- 
GitLab


From 1c7ba2ef6b3b8224201d759e1a74fb21a31185c2 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 17:39:12 +0100
Subject: [PATCH 228/283] refactor: delete unused function

---
 .../InformationsOfQuiz/MultiInformationsOfQuiz.tsx          | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
index ddf1fca..623305e 100644
--- a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
@@ -18,11 +18,7 @@ interface Props {
 export default function MultiInformationsOfQuiz({ navigation, route }: Props) {
     const { quiz } = route.params;
     const [showModal, setShowModal] = useState<boolean>(false);
-
-    const onCreateLobby = () => {
-        navigation.navigate('PlayingQuiz', {quizRecovered: quiz});
-    }
-
+    
     const onCreateLobbyPressed = () => {
         setShowModal(true);
     };
-- 
GitLab


From 4a93b05640f46d9df466e45aff4fcff8c0f0d182 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 17:39:33 +0100
Subject: [PATCH 229/283] styles: show background

---
 .../InformationsOfQuiz/MultiInformationsOfQuiz.tsx             | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
index 623305e..0f50a8c 100644
--- a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
@@ -18,7 +18,7 @@ interface Props {
 export default function MultiInformationsOfQuiz({ navigation, route }: Props) {
     const { quiz } = route.params;
     const [showModal, setShowModal] = useState<boolean>(false);
-    
+
     const onCreateLobbyPressed = () => {
         setShowModal(true);
     };
@@ -60,7 +60,6 @@ const styles = StyleSheet.create({
         paddingHorizontal: 20,
         paddingVertical: 20,
         justifyContent: "flex-start",
-        backgroundColor: "#f4f4f4",
     },
     quizTitle: {
         fontSize: 24,
-- 
GitLab


From d3f5712177ae2105867ab35902e2a70a85bd200e Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 17:41:16 +0100
Subject: [PATCH 230/283] feat: add information to quiz detail

---
 .../Community/InformationsOfQuiz/InformationsOfQuiz.tsx    | 2 +-
 .../InformationsOfQuiz/MultiInformationsOfQuiz.tsx         | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
index 1aa7bcc..437c944 100644
--- a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -25,7 +25,7 @@ export default function InformationsOfQuiz({ navigation, route }: Props) {
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
             <View style={styles.container}>
                 <Text style={styles.quizTitle}>{quiz.name}</Text>
-                <Text style={styles.quizDescription}>{quiz.description && "No Descripion"}</Text>
+                <Text style={styles.quizDescription}>{quiz.description && "No Description"}</Text>
 
                 <View style={styles.aboutContainer}>
                     <Text style={styles.aboutTitle}>About this quiz :</Text>
diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
index 0f50a8c..23b2a4a 100644
--- a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
@@ -36,12 +36,13 @@ export default function MultiInformationsOfQuiz({ navigation, route }: Props) {
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
             <View style={styles.container}>
                 <Text style={styles.quizTitle}>{quiz.name}</Text>
-                <Text style={styles.quizDescription}>{quiz.category?.name}</Text>
+                <Text style={styles.quizDescription}>{quiz.description && "No Description"}</Text>
+                
 
                 <View style={styles.aboutContainer}>
                     <Text style={styles.aboutTitle}>About this quiz :</Text>
-                    <Text style={styles.aboutDetails}>{quiz.questionCount} questions</Text>
-                    <Text style={styles.aboutDetails}>By : Unknown</Text>
+                    <Text style={styles.aboutDetails}>{quiz.questionCount} questions, {quiz.difficulty.name}</Text>
+                    <Text style={styles.aboutDetails}>By : {quiz.authorId && "Unknown"}</Text>
                 </View>
 
                 <TouchableOpacity style={styles.playButton} onPress={onCreateLobbyPressed}>
-- 
GitLab


From a147d5b8f0a033bcb40dd5e2cba572ab5bbf87f7 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 17:53:22 +0100
Subject: [PATCH 231/283] styles: change the size of detail container

---
 screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx   | 4 +++-
 .../InformationsOfQuiz/MultiInformationsOfQuiz.tsx            | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
index 437c944..3e6461c 100644
--- a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -58,8 +58,10 @@ const styles = StyleSheet.create({
         fontSize: 16,
         color: "#555",
         marginBottom: 20,
+        height: "15%",
     },
     aboutContainer: {
+        height: "50%",
         backgroundColor: "white",
         borderRadius: 10,
         padding: 15,
@@ -78,7 +80,7 @@ const styles = StyleSheet.create({
     aboutDetails: {
         fontSize: 16,
         color: "#555",
-        marginBottom: 5,
+        marginBottom: 10,
     },
     playButton: {
         backgroundColor: "#007BFF",
diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
index 23b2a4a..8f45d5c 100644
--- a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
@@ -72,8 +72,10 @@ const styles = StyleSheet.create({
         fontSize: 16,
         color: "#555",
         marginBottom: 20,
+        height: "15%",
     },
     aboutContainer: {
+        height: "50%",
         backgroundColor: "white",
         borderRadius: 10,
         padding: 15,
@@ -92,7 +94,7 @@ const styles = StyleSheet.create({
     aboutDetails: {
         fontSize: 16,
         color: "#555",
-        marginBottom: 5,
+        marginBottom: 10,
     },
     playButton: {
         backgroundColor: "#007BFF",
-- 
GitLab


From aa6fba8a7afedabc2dce82d86410e3d5288a90e6 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 20:45:42 +0100
Subject: [PATCH 232/283] refactor: rename answerButton -> answerButtonText

---
 components/buttons/{AnswerButton.tsx => AnswerButtonText.tsx} | 4 ++--
 screens/PlayingQuiz/PlayingQuizBody.tsx                       | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
 rename components/buttons/{AnswerButton.tsx => AnswerButtonText.tsx} (86%)

diff --git a/components/buttons/AnswerButton.tsx b/components/buttons/AnswerButtonText.tsx
similarity index 86%
rename from components/buttons/AnswerButton.tsx
rename to components/buttons/AnswerButtonText.tsx
index 2cc1fb6..6dbc8b4 100644
--- a/components/buttons/AnswerButton.tsx
+++ b/components/buttons/AnswerButtonText.tsx
@@ -11,13 +11,13 @@ interface Props{
 }
 
 /**
- * AnswerButton : Un bouton par défaut, il possède déjà un style mais on peut le surcharger grâce à la propriété buttonStyle
+ * AnswerButtonText : Un bouton par défaut, il possède déjà un style mais on peut le surcharger grâce à la propriété buttonStyle
  * @param text - Texte du bouton
  * @param handleButtonPressed - Fonction qui sera exécutée lorsque le bouton sera pressé
  * @param buttonStyle - Surcharge du style du bouton
  * @param buttonText - Surcharge du style du texte du bouton
  */
-export default function AnswerButton({text, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
+export default function AnswerButtonText({text, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
     return(
         <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
             {indicator !== undefined && (
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 0992745..5a3fd66 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -9,7 +9,7 @@ import BlueButton from "../../components/buttons/BlueButton";
 import {Question} from "../../models/Question";
 import {Answer} from "../../models/Answer";
 import {Quiz} from "../../models/Quiz";
-import AnswerButton from "../../components/buttons/AnswerButton";
+import AnswerButtonText from "../../components/buttons/AnswerButtonText";
 import {QuizInformations} from "../../models/QuizInformations";
 
 interface Props {
@@ -121,7 +121,7 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
             {actualQuestion ? (
                 <>
                     {actualQuestion.answers.map((answer, index) => (
-                        <AnswerButton
+                        <AnswerButtonText
                             key={index}
                             text={answer.text}
                             handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
-- 
GitLab


From 70190d7af9b0562e628a878615d25948a3abc2fc Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 20:58:24 +0100
Subject: [PATCH 233/283] feat: add answerButtonImage

---
 components/buttons/AnswerButtonImage.tsx | 61 ++++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 components/buttons/AnswerButtonImage.tsx

diff --git a/components/buttons/AnswerButtonImage.tsx b/components/buttons/AnswerButtonImage.tsx
new file mode 100644
index 0000000..3aaca00
--- /dev/null
+++ b/components/buttons/AnswerButtonImage.tsx
@@ -0,0 +1,61 @@
+import {TouchableOpacity, Text, StyleSheet, View, Image} from "react-native";
+import {ButtonsStyles} from "../../styles/ButtonsStyles";
+import {TextsStyles} from "../../styles/TextsStyles";
+
+interface Props{
+    url: string;
+    handleButtonPressed:() => void;
+    buttonStyle?: any;
+    buttonText?: any;
+    indicator?: number | undefined;
+}
+
+/**
+ * AnswerButtonImage : Un bouton par défaut, il possède déjà un style mais on peut le surcharger grâce à la propriété buttonStyle
+ * @param url - Texte du bouton
+ * @param handleButtonPressed - Fonction qui sera exécutée lorsque le bouton sera pressé
+ * @param buttonStyle - Surcharge du style du bouton
+ * @param buttonText - Surcharge du style du texte du bouton
+ */
+export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
+    return(
+        <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
+            {indicator !== undefined && (
+                <View style={styles.indicator}>
+                    <Text style={styles.indicatorText}>{indicator}</Text>
+                </View>
+            )}
+            <Image 
+                style={[TextsStyles.defaultButtonText, buttonText]}
+                source={{uri: url}}
+            />
+        </TouchableOpacity>
+    )
+}
+
+const styles = StyleSheet.create({
+    defaultButton: {
+        backgroundColor: "#45128C",
+        padding: 10,
+        alignItems: "center",
+        justifyContent: 'center',
+        borderRadius: 10,
+    },
+    indicator: {
+        position: "absolute",
+        top: "-16%",
+        left: "5%",
+        width: 25,
+        height: 25,
+        borderRadius: 15,
+        backgroundColor: "#D3D3D3",
+        justifyContent: "center",
+        alignItems: "center",
+        zIndex: 1,
+    },
+    indicatorText: {
+        color: "#000",
+        fontWeight: "bold",
+        fontSize: 14,
+    },
+})
\ No newline at end of file
-- 
GitLab


From 7f2622ff0b24cdde7c41a145ecd00a10c96b3b0d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 22:02:08 +0100
Subject: [PATCH 234/283] style: fix size header and body for playing quiz

---
 templates/TemplateDuo.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/TemplateDuo.tsx b/templates/TemplateDuo.tsx
index 97a225e..c347a2d 100644
--- a/templates/TemplateDuo.tsx
+++ b/templates/TemplateDuo.tsx
@@ -31,11 +31,11 @@ const styles = StyleSheet.create({
     },
     containerHeader: {
         width: '100%',
-        height: '26%',
+        height: '30%',
     },
     containerBody: {
         width: '100%',
-        height: '78%',
+        height: '70%',
         backgroundColor: '#FFFFFF',
         borderTopLeftRadius: 46,
         borderTopRightRadius: 46
-- 
GitLab


From d80ca1986ab223772545f7d11f54b75403d18f71 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 22:50:06 +0100
Subject: [PATCH 235/283] styles: show images answerButtonImage

---
 components/buttons/AnswerButtonImage.tsx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/components/buttons/AnswerButtonImage.tsx b/components/buttons/AnswerButtonImage.tsx
index 3aaca00..bf75c90 100644
--- a/components/buttons/AnswerButtonImage.tsx
+++ b/components/buttons/AnswerButtonImage.tsx
@@ -6,7 +6,7 @@ interface Props{
     url: string;
     handleButtonPressed:() => void;
     buttonStyle?: any;
-    buttonText?: any;
+    buttonImage?: any;
     indicator?: number | undefined;
 }
 
@@ -17,7 +17,7 @@ interface Props{
  * @param buttonStyle - Surcharge du style du bouton
  * @param buttonText - Surcharge du style du texte du bouton
  */
-export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
+export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle, buttonImage, indicator}: Props){
     return(
         <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
             {indicator !== undefined && (
@@ -26,7 +26,7 @@ export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle
                 </View>
             )}
             <Image 
-                style={[TextsStyles.defaultButtonText, buttonText]}
+                style={[TextsStyles.defaultButtonText, {flex: 1, width: "100%", height: "100%"}, buttonImage]}
                 source={{uri: url}}
             />
         </TouchableOpacity>
-- 
GitLab


From 52d677736ec14cc885ba21d014d03419c1999bd0 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 22:53:31 +0100
Subject: [PATCH 236/283] feat: add answer button image

---
 screens/PlayingQuiz/PlayingQuizBody.tsx | 40 ++++++++++++++++++-------
 styles/ButtonsStyles.ts                 |  2 +-
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 5a3fd66..7fe64e5 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -11,6 +11,7 @@ import {Answer} from "../../models/Answer";
 import {Quiz} from "../../models/Quiz";
 import AnswerButtonText from "../../components/buttons/AnswerButtonText";
 import {QuizInformations} from "../../models/QuizInformations";
+import AnswerButtonImage from "../../components/buttons/AnswerButtonImage";
 
 interface Props {
     quizInformations: QuizInformations;
@@ -120,15 +121,26 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
         <View style={styles.buttonContainer}>
             {actualQuestion ? (
                 <>
-                    {actualQuestion.answers.map((answer, index) => (
-                        <AnswerButtonText
-                            key={index}
-                            text={answer.text}
-                            handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
-                            buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
-                            buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
-                        />
-                    ))}
+                    <View style={styles.buttonListContainer}>
+                        {actualQuestion.answers.map((answer, index) => (
+                            actualQuestion.type === "image" ? 
+                                <AnswerButtonImage
+                                    key={index}
+                                    url={answer.text}
+                                    handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
+                                    buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                                    // buttonImage={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                                />
+                            :
+                                <AnswerButtonText
+                                    key={index}
+                                    text={answer.text}
+                                    handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
+                                    buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                                    buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                                />
+                        ))}
+                    </View>
                     <View style={styles.playButtonContainer}>
                         <BlueButton onPress={() => quizState === QuizState.ANSWERING ? onValidation() : onContinue()} text={quizState === QuizState.ANSWERING ? "CONFIRM" : "CONTINUE"} buttonStyle={{borderRadius: 50}} isDisabled={false}/>
                     </View>
@@ -201,7 +213,7 @@ const styles = StyleSheet.create({
     },
     answerButton: {
         backgroundColor: "#F3F3F3",
-        height: '15%',
+        height: '30%',
         alignItems: 'center',
         width: '80%',
         marginVertical: '3%',
@@ -212,5 +224,13 @@ const styles = StyleSheet.create({
         shadowRadius: 3.5,
         elevation: 5,
     },
+    buttonListContainer: {
+        height: '80%',
+        width: '100%',
+        display: 'flex',
+        justifyContent: 'flex-start',
+        alignItems: 'center',
+        overflow: 'scroll',
+    }
 });
 
diff --git a/styles/ButtonsStyles.ts b/styles/ButtonsStyles.ts
index 5d33ddb..12d8539 100644
--- a/styles/ButtonsStyles.ts
+++ b/styles/ButtonsStyles.ts
@@ -16,7 +16,7 @@ export const ButtonsStyles = StyleSheet.create( {
     },
     answerButton: {
         backgroundColor: "#F3F3F3",
-        height: '15%',
+        height: '30%',
         alignItems: 'center',
         width: '80%',
         marginVertical: '3%',
-- 
GitLab


From a25e07fdd3d26e8715874def6b2dcb691d337d6b Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sat, 11 Jan 2025 22:57:00 +0100
Subject: [PATCH 237/283] fix: generate quiz

---
 models/QuizInformations.ts                    |   2 +-
 models/User.ts                                |   2 +-
 package-lock.json                             | 105 +++++++++++++++++-
 package.json                                  |   5 +-
 screens/Home/HomeChild.tsx                    |   1 -
 .../Home/PlayQuiz/PlayQuizGenerateQuiz.tsx    |  23 +---
 screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx  |   2 -
 screens/Profil/ProfilChild.tsx                |   1 -
 services/QuizService.ts                       |   7 +-
 9 files changed, 115 insertions(+), 33 deletions(-)

diff --git a/models/QuizInformations.ts b/models/QuizInformations.ts
index 5087ebc..32b9aed 100644
--- a/models/QuizInformations.ts
+++ b/models/QuizInformations.ts
@@ -1,5 +1,5 @@
-import User from "./User";
 import {Category, Difficulty} from "./Quiz";
+import {User} from "./User";
 
 export interface QuizInformations {
     id: number;
diff --git a/models/User.ts b/models/User.ts
index 96d2b30..e572420 100644
--- a/models/User.ts
+++ b/models/User.ts
@@ -8,5 +8,5 @@ export interface User {
     id: number;
     email: string;
     username: string;
-    stats: Stats;
+    stats?: Stats;
 }
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 74090c7..d1035b2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,7 @@
         "@tanstack/react-query": "^5.62.8",
         "@tanstack/react-query-devtools": "^5.62.8",
         "axios": "^1.7.9",
+        "dotenv": "^16.4.7",
         "expo": "~52.0.14",
         "expo-splash-screen": "^0.29.13",
         "expo-status-bar": "~2.0.0",
@@ -31,7 +32,9 @@
         "react-native-safe-area-context": "^4.12.0",
         "react-native-screens": "~4.1.0",
         "react-native-vector-icons": "^10.2.0",
-        "react-query": "^3.39.3"
+        "react-query": "^3.39.3",
+        "rxjs": "^7.8.1",
+        "socket.io-client": "^4.8.1"
       },
       "devDependencies": {
         "@babel/core": "^7.20.0",
@@ -3971,6 +3974,12 @@
         "@sinonjs/commons": "^3.0.0"
       }
     },
+    "node_modules/@socket.io/component-emitter": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+      "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
+      "license": "MIT"
+    },
     "node_modules/@tanstack/query-core": {
       "version": "5.62.8",
       "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.8.tgz",
@@ -5736,9 +5745,9 @@
       }
     },
     "node_modules/dotenv": {
-      "version": "16.4.5",
-      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
-      "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
+      "version": "16.4.7",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
+      "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
       "license": "BSD-2-Clause",
       "engines": {
         "node": ">=12"
@@ -5804,6 +5813,49 @@
         "once": "^1.4.0"
       }
     },
+    "node_modules/engine.io-client": {
+      "version": "6.6.2",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.2.tgz",
+      "integrity": "sha512-TAr+NKeoVTjEVW8P3iHguO1LO6RlUz9O5Y8o7EY0fU+gY1NYqas7NN3slpFtbXEsLMHk0h90fJMfKjRkQ0qUIw==",
+      "license": "MIT",
+      "dependencies": {
+        "@socket.io/component-emitter": "~3.1.0",
+        "debug": "~4.3.1",
+        "engine.io-parser": "~5.2.1",
+        "ws": "~8.17.1",
+        "xmlhttprequest-ssl": "~2.1.1"
+      }
+    },
+    "node_modules/engine.io-client/node_modules/ws": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+      "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": ">=5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/engine.io-parser": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
+      "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
     "node_modules/entities": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -10168,6 +10220,15 @@
         "queue-microtask": "^1.2.2"
       }
     },
+    "node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
     "node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -10527,6 +10588,34 @@
         "node": ">=8.0.0"
       }
     },
+    "node_modules/socket.io-client": {
+      "version": "4.8.1",
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz",
+      "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@socket.io/component-emitter": "~3.1.0",
+        "debug": "~4.3.2",
+        "engine.io-client": "~6.6.1",
+        "socket.io-parser": "~4.2.4"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/socket.io-parser": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
+      "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+      "license": "MIT",
+      "dependencies": {
+        "@socket.io/component-emitter": "~3.1.0",
+        "debug": "~4.3.1"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
     "node_modules/source-map": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -11773,6 +11862,14 @@
         "node": ">=8.0"
       }
     },
+    "node_modules/xmlhttprequest-ssl": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
+      "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
diff --git a/package.json b/package.json
index c2f6b34..7a0c0d2 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
     "@tanstack/react-query": "^5.62.8",
     "@tanstack/react-query-devtools": "^5.62.8",
     "axios": "^1.7.9",
+    "dotenv": "^16.4.7",
     "expo": "~52.0.14",
     "expo-splash-screen": "^0.29.13",
     "expo-status-bar": "~2.0.0",
@@ -32,7 +33,9 @@
     "react-native-safe-area-context": "^4.12.0",
     "react-native-screens": "~4.1.0",
     "react-native-vector-icons": "^10.2.0",
-    "react-query": "^3.39.3"
+    "react-query": "^3.39.3",
+    "rxjs": "^7.8.1",
+    "socket.io-client": "^4.8.1"
   },
   "devDependencies": {
     "@babel/core": "^7.20.0",
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 1072366..85120e4 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -24,7 +24,6 @@ export default function HomeChild({navigation}: Props) {
 
     const handleButtonQuickGamePressed = async () => {
         const quizData = await getRandomQuiz()
-        console.log(quizData);
         if (quizData instanceof HttpError) {
             console.error("Error while fetching random quiz:", quizData);
             return;
diff --git a/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx b/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
index c55cf39..8f72775 100644
--- a/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
+++ b/screens/Home/PlayQuiz/PlayQuizGenerateQuiz.tsx
@@ -7,6 +7,7 @@ import {useQuizService} from "../../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
 import {Category} from "../../../models/Quiz";
 import SelectListBoxCategory from "../../../components/PlayQuiz/SelectListBoxCategory";
+import HttpError from "../../../services/HttpError";
 
 const difficulty = [
     { key: "easy", value: "easy" },
@@ -14,22 +15,6 @@ const difficulty = [
     { key: "hard", value: "hard" },
 ];
 
-const categories = [
-    { key: "9", value: "General Knowledge"},
-    { key: "10", value: "Entertainment: Books" },
-    { key: "11", value: "Entertainment: Film" },
-    { key: "12", value: "Entertainment: Music"},
-    { key: "13", value: "Entertainment: Musicals & Theatres" },
-    { key: "14", value: "Entertainment: Television" },
-    { key: "15", value: "Entertainment: Video Games" },
-    { key: "16", value: "Entertainment: Board Games" },
-    { key: "17", value: "Science & Nature" },
-    { key: "18", value: "Science: Computers" },
-    { key: "19", value: "Science: Mathematics" },
-    { key: "20", value: "Mythology" },
-    { key: "21", value: "Sports" },
-    { key: "22", value: "Geography" },
-];
 interface Props {
     navigation: NavigationProp<any>;
 }
@@ -44,7 +29,6 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
     const {generateQuiz, getCategories} = useQuizService();
     const fetchingCategories = async () => {
         const categories = await getCategories();
-        console.log(categories);
         let categoriesTemp: Category[] = [];
         categories.map((category: Category) => {
             categoriesTemp.push({'name': category.name, 'id': category.id});
@@ -70,12 +54,15 @@ export default function PlayQuizGenerateQuiz({navigation}: Props) {
 
     const handlePlayButtonPress = async () => {
         const quizGenerated = await generateQuiz(parseInt(nbQuestions), categoryChoose ? categoryChoose.id : 10 , difficutlyChoose);
+        if(HttpError.isHttpError(quizGenerated)) {
+            return;
+        }
         navigation.reset({
             index: 0,
             routes: [
                 {
                     name: "PlayingQuiz",
-                    params: {quizRecovered: quizGenerated},
+                    params: {runId: quizGenerated.id, quizId: quizGenerated.quizId},
                 },
             ]
         });
diff --git a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
index 2d8bafc..f5e49a4 100644
--- a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
@@ -19,7 +19,6 @@ export default function EndQuizChild({ navigation, quiz }: Props) {
     const handleRestartPress = async () => {
         const isRestarted = await restartQuiz(quiz.id);
         if(HttpError.isHttpError(isRestarted)){
-            console.log(isRestarted.message);
             return
         }
         if(!isRestarted) {
@@ -27,7 +26,6 @@ export default function EndQuizChild({ navigation, quiz }: Props) {
         }
         const quizRestarted = await remainingQuiz(quiz.id);
         if(HttpError.isHttpError(quizRestarted)){
-            console.log(quizRestarted.message);
             return
         }
 
diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index dd96222..dd89a53 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -31,7 +31,6 @@ export default function ProfilChild({ navigation }: Props) {
     const getUser = async () => {
         setUserConnectionState(UserConnectionState.LOADING);
         const user = await getInformationsUser();
-        console.log(user);
         if(user instanceof HttpError){
             setUser(undefined);
             setUserConnectionState(UserConnectionState.NOT_CONNECTED);
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 72752c8..2d7eb5c 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -12,7 +12,7 @@ import {QuizGenerateAnswer} from "../models/QuizGenerateAnswer";
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
 
-    const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<string | HttpError> => {
+    const generateQuiz = async (amount: number, category: number, difficulty: string) : Promise<QuizGenerateAnswer | HttpError> => {
         const requestBody = {
             amount,
             category,
@@ -20,14 +20,13 @@ export const useQuizService =  () => {
         };
 
         try {
-            const response = await axios.post(`${url}/quiz/generate`, requestBody, {
+            const response = await axios.post<QuizGenerateAnswer>(`${url}/quiz/generate`, requestBody, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
             const runId =  response.data.id;
-            // Récupération du run ID
-            return runId;
+            return {id: runId, quizId: response.data.quizId};
         } catch (error: any) {
             console.log("Error while generating quiz:", error);
 
-- 
GitLab


From 257b2577c9ff1d7c63521999459a7b4f47efd590 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sat, 11 Jan 2025 22:59:36 +0100
Subject: [PATCH 238/283] feat: strating websocket

---
 screens/Multiplayer/Lobby/Lobby.tsx           | 90 +++++++++++++------
 .../OnlineQuiz/OnlineCreateLobby.tsx          | 51 +++++------
 2 files changed, 86 insertions(+), 55 deletions(-)

diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index 6bc6cd4..2f9a512 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -1,43 +1,77 @@
 import { View, Text, StyleSheet, Button, Image, ScrollView, FlatList } from "react-native";
 import TemplateMenu from "../../../templates/TemplateMenu";
-import { NavigationProp } from "@react-navigation/native";
-import React, { useState } from "react";
+import {NavigationProp, RouteProp} from "@react-navigation/native";
+import React, {useEffect, useState} from "react";
 import WhiteButton from "../../../components/buttons/WhiteButton";
 import BlueButton from "../../../components/buttons/BlueButton";
 import { TouchableOpacity } from "react-native";
 import ModalInvitePlayer from "../../../components/Multiplayer/ModalInvitePlayer";
+import {User} from "../../../models/User";
+import {QuizGenerateAnswer} from "../../../models/QuizGenerateAnswer";
+import {io, Socket} from "socket.io-client";
 
 interface Props {
     navigation: NavigationProp<any>;
+    route: RouteProp<RoutePropsType, "Lobby">;
 }
 
-export default function Lobby({navigation}: Props) {
+type RoutePropsType = {
+    Lobby: {
+        runId: string;
+        nbPlayers: number;
+    };
+};
+
+export default function Lobby({navigation, route}: Props) {
+    const { runId, nbPlayers} = route.params;
+
     const [isHost, setIsHost] = useState<boolean>(true);
     const [showModal, setShowModal] = useState<boolean>(false);
+    const [players, setPlayers] = useState<User[]>([{ id: 0, username: 'Invite', email: 'invite@email.com'}]);
+
+
+
+    const [socket, setSocket] = useState<Socket | null>(null);
+
+    useEffect(() => {
+        // Initialise Socket.IO connection
+        const newSocket = io("http://klebert-host.com:33053/party", {
+            transports: ["websocket"], // Utilise WebSocket uniquement
+            withCredentials: true
+        });
+
+        setSocket(newSocket);
 
-    const players = [
-        { id: 0, name: 'Invite'},
-        { id: 1, name: 'John Doe'},
-        { id: 2, name: 'John Doe'},
-        { id: 3, name: 'John Doe'},
-        { id: 4, name: 'John Doe'},
-        { id: 5, name: 'John Doe'},
-        { id: 6, name: 'John Doe'},
-        { id: 7, name: 'John Doe'},
-        { id: 8, name: 'John Doe'},
-        { id: 9, name: 'John Doe'},
-        { id: 10, name: 'John Doe'},
-        { id: 11, name: 'John Doe'},
-        { id: 12, name: 'John Doe'},
-        { id: 13, name: 'John Doe'},
-        { id: 14, name: 'John Doe'},
-        { id: 15, name: 'John Doe'},
-    ];
-
-    const item = ({item}: {item: {id: number, name: string}}) => {
+        newSocket.on("connect", () => {
+            console.log("Connected to the socket server id :",runId);
+            newSocket.emit("joinRoom", { roomId: runId });
+        });
+
+        newSocket.on("connect_error", (err) => {
+            console.error("Connection error: ", err.message);
+        });
+
+        newSocket.on("error", (err) => {
+            console.error("Socket error: ", err.message);
+        });
+
+        // Mettez à jour la liste des joueurs lorsque quelqu'un rejoint
+        newSocket.on("userJoined", (data: User[]) => {
+            console.log("Updated user list:", data);
+            setPlayers(data);
+        });
+
+        // Nettoyez la connexion lorsque le composant est démonté
+        return () => {
+            newSocket.disconnect();
+            setSocket(null);
+        };
+    }, [runId]);
+
+    const item = ({ item }: { item: User }) => {
         return (
             <>
-                {item.name === 'Invite' ? 
+                {item.username === 'Invite' ?
                     <View style={styles.PlayerItem}>
                         <TouchableOpacity style={styles.imagePlayer} onPress={onInvitePressed}>
                             <Image source={require('../../../assets/add.png')}  />
@@ -47,11 +81,11 @@ export default function Lobby({navigation}: Props) {
                 :
                     <View style={styles.PlayerItem}>
                         <Image source={require('../../../assets/ProfilBaseImage.png')} style={styles.imagePlayer} />
-                        <Text style={styles.textPlayer}>{item.name}</Text>
+                        <Text style={styles.textPlayer}>{item.username}</Text>
                     </View>
                 }
             </>
-            
+
         )
     }
 
@@ -75,7 +109,7 @@ export default function Lobby({navigation}: Props) {
     return (
         <View>
             <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
-                <View style={styles.containerLobby}>  
+                <View style={styles.containerLobby}>
                     <Text style={styles.title}>{'BMW OFFICIAL QUIZ (I’m leaking oil)'}</Text>
                     <View style={styles.containerPlayers}>
                         <FlatList
@@ -90,7 +124,7 @@ export default function Lobby({navigation}: Props) {
                         <View style={styles.buttonGroup}>
                             <View style={styles.button}>
                                 <BlueButton text="PLAY" onPress={onPlayPressed} isDisabled={false}/>
-                            </View>   
+                            </View>
                             <View style={styles.button}>
                                 <WhiteButton text="CANCEL" onPress={onCancelPressed} isDisabled={false}/>
                             </View>
diff --git a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
index 73eb259..c31decb 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
@@ -1,13 +1,13 @@
 import { Text,View, StyleSheet } from "react-native";
 import React, {useEffect, useState} from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
-import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {useQuizService} from "../../../services/QuizService";
 import {NavigationProp} from "@react-navigation/native";
 import BlueButton from "../../../components/buttons/BlueButton";
 import SelectListBoxString from "../../../components/PlayQuiz/SelectListBoxString";
 import SelectListBoxCategory from "../../../components/PlayQuiz/SelectListBoxCategory";
 import { Category } from "../../../models/Quiz";
+import HttpError from "../../../services/HttpError";
 
 const difficulty = [
     { key: "easy", value: "easy" },
@@ -15,22 +15,7 @@ const difficulty = [
     { key: "hard", value: "hard" },
 ];
 
-const categories = [
-    { key: "9", value: "General Knowledge"},
-    { key: "10", value: "Entertainment: Books" },
-    { key: "11", value: "Entertainment: Film" },
-    { key: "12", value: "Entertainment: Music"},
-    { key: "13", value: "Entertainment: Musicals & Theatres" },
-    { key: "14", value: "Entertainment: Television" },
-    { key: "15", value: "Entertainment: Video Games" },
-    { key: "16", value: "Entertainment: Board Games" },
-    { key: "17", value: "Science & Nature" },
-    { key: "18", value: "Science: Computers" },
-    { key: "19", value: "Science: Mathematics" },
-    { key: "20", value: "Mythology" },
-    { key: "21", value: "Sports" },
-    { key: "22", value: "Geography" },
-];
+
 interface Props {
     navigation: NavigationProp<any>;
 }
@@ -42,7 +27,20 @@ export default function OnlineCreateLobby({navigation}: Props) {
     const [nbQuestions, setNbQuestions] = React.useState("10");
     const [nbPlayers, setNbPlayers] = React.useState("2");
     const [buttonIsDisabled, setButtonIsDisabled] = React.useState(true);
-    const {generateQuiz} = useQuizService();
+    const {generateQuiz, getCategories} = useQuizService();
+
+    const fetchingCategories = async () => {
+        const categories = await getCategories();
+        let categoriesTemp: Category[] = [];
+        categories.map((category: Category) => {
+            categoriesTemp.push({'name': category.name, 'id': category.id});
+        });
+        setCategories(categoriesTemp);
+    }
+
+    useEffect(() => {
+        fetchingCategories();
+    }, []);
 
     useEffect(() => {
         if(nbQuestions === "" || difficutlyChoose === "" || categoryChoose === null)
@@ -57,15 +55,14 @@ export default function OnlineCreateLobby({navigation}: Props) {
     }, [difficutlyChoose,categoryChoose,nbQuestions]);
 
     const handlePlayButtonPress = async () => {
-        const quizGenerated = await generateQuiz(parseInt(nbQuestions), getIdOfCategory(categoryChoose), difficutlyChoose);
-        navigation.reset({
-            index: 0,
-            routes: [
-                {
-                    name: "Lobby",
-                    params: {quizGenerated: quizGenerated, nbPlayers: parseInt(nbPlayers)},
-                },
-            ]
+        const quizGenerated = await generateQuiz(parseInt(nbQuestions), categoryChoose ? categoryChoose.id : 10, difficutlyChoose);
+        if(HttpError.isHttpError(quizGenerated)) {
+            return;
+        }
+
+        navigation.navigate("Lobby", {
+            runId: quizGenerated.id,
+            nbPlayers: parseInt(nbPlayers),
         });
     };
 
-- 
GitLab


From db1c2884edadd2ad2614d51772129bddb837b391 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sat, 11 Jan 2025 23:21:17 +0100
Subject: [PATCH 239/283] refactor: endquiz

---
 screens/PlayingQuiz/EndQuiz/EndQuiz.tsx      |  8 ++-
 screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx | 63 ++++++++++----------
 screens/PlayingQuiz/PlayingQuiz.tsx          |  2 +-
 screens/PlayingQuiz/PlayingQuizBody.tsx      | 16 ++++-
 screens/PlayingQuiz/PlayingQuizHeader.tsx    |  2 +-
 5 files changed, 53 insertions(+), 38 deletions(-)

diff --git a/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx b/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
index 8297ee0..0547db0 100644
--- a/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuiz.tsx
@@ -3,10 +3,12 @@ import { View, StyleSheet, Image, Text } from "react-native";
 import EndQuizChild from "./EndQuizChild";
 import TemplateMenu from "../../../templates/TemplateMenu";
 import {Quiz} from "../../../models/Quiz";
+import {QuizInformations} from "../../../models/QuizInformations";
 
 type RoutePropsType = {
     EndQuizChild: {
-        quiz: Quiz;
+        quizInformations: QuizInformations;
+        score: number;
     };
 };
 interface Props {
@@ -15,12 +17,12 @@ interface Props {
 }
 
 export default function EndQuiz({route,navigation}: Props) {
-    const { quiz } = route.params;
+    const { quizInformations, score } = route.params;
     return (
         <View style={styles.containerGlobal}>
             <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}>
                 <View>
-                    <EndQuizChild navigation={navigation} quiz={quiz}/>
+                    <EndQuizChild navigation={navigation} quizInformations={quizInformations} score={score}/>
                 </View>
             </TemplateMenu>
         </View>
diff --git a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
index 2d8bafc..42b98e5 100644
--- a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
@@ -4,43 +4,46 @@ import { NavigationProp, RouteProp } from "@react-navigation/native";
 import {Quiz} from "../../../models/Quiz";
 import {useQuizService} from "../../../services/QuizService";
 import HttpError from "../../../services/HttpError";
+import {QuizInformations} from "../../../models/QuizInformations";
 
 
 
 interface Props {
     navigation: NavigationProp<any>;
-    quiz: Quiz;
+    quizInformations: QuizInformations;
+    score: number;
 }
 
-export default function EndQuizChild({ navigation, quiz }: Props) {
+export default function EndQuizChild({ navigation, quizInformations, score }: Props) {
 
     const {restartQuiz, remainingQuiz} = useQuizService()
 
-    const handleRestartPress = async () => {
-        const isRestarted = await restartQuiz(quiz.id);
-        if(HttpError.isHttpError(isRestarted)){
-            console.log(isRestarted.message);
-            return
-        }
-        if(!isRestarted) {
-            return;
-        }
-        const quizRestarted = await remainingQuiz(quiz.id);
-        if(HttpError.isHttpError(quizRestarted)){
-            console.log(quizRestarted.message);
-            return
-        }
-
-        navigation.reset({
-            index: 0,
-            routes: [
-                {
-                    name: "PlayingQuiz",
-                    params: {quizRecovered: quizRestarted},
-                },
-            ]
-        });
-    };
+    // const handleRestartPress = async () => {
+    //     if(!quizInformations) return;
+    //     const isRestarted = await restartQuiz(quizInformations.id);
+    //     if(HttpError.isHttpError(isRestarted)){
+    //         console.log(isRestarted.message);
+    //         return
+    //     }
+    //     if(!isRestarted) {
+    //         return;
+    //     }
+    //     const quizRestarted = await remainingQuiz(quiz.id);
+    //     if(HttpError.isHttpError(quizRestarted)){
+    //         console.log(quizRestarted.message);
+    //         return
+    //     }
+    //
+    //     navigation.reset({
+    //         index: 0,
+    //         routes: [
+    //             {
+    //                 name: "PlayingQuiz",
+    //                 params: {quizRecovered: quizRestarted},
+    //             },
+    //         ]
+    //     });
+    // };
 
     const handleBackToMenu = () => {
         navigation.navigate('TabNavigator');
@@ -52,10 +55,10 @@ export default function EndQuizChild({ navigation, quiz }: Props) {
                 <Image source={require('../../../assets/TitleApp.png')}/>
             </View>
             <View style={styles.containerBody}>
-                <Text style={styles.TextBodyTitle}>{((quiz.score/quiz.questionCount)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
-                <Text style={styles.TextBody}>you finish the test with a score of {`${quiz.score}/${quiz.questionCount}`} ! </Text>
+                <Text style={styles.TextBodyTitle}>{((score/quizInformations.questionCount)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
+                <Text style={styles.TextBody}>you finish the test with a score of {`${score}/${quizInformations.questionCount}`} ! </Text>
                 <Image source={require('../../../assets/uWin.png')} />
-                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
+                {/*<DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>*/}
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
             </View>
         </View>
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 406582e..aab164e 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -55,7 +55,7 @@ export default function PlayingQuiz({route, navigation}:Props) {
     return (
         <TemplateDuo
             childrenHeader={<PlayingQuizHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score} navigation={navigation}></PlayingQuizHeader>}
-            childrenBody={<PlayingQuizBody quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} navigation={navigation}></PlayingQuizBody>}
+            childrenBody={<PlayingQuizBody quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} score={score} navigation={navigation}></PlayingQuizBody>}
         />
     );
 }
\ No newline at end of file
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 0992745..6a220d2 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -13,10 +13,11 @@ import AnswerButton from "../../components/buttons/AnswerButton";
 import {QuizInformations} from "../../models/QuizInformations";
 
 interface Props {
-    quizInformations: QuizInformations;
+    quizInformations?: QuizInformations;
     runId?: string;
     actualQuestion: Question;
     fetchActualQuestion: () => void;
+    score: number;
     setScore: (score: number) => void;
     navigation: NavigationProp<any>;
 }
@@ -64,7 +65,7 @@ const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number |
     return styles.answerButton;
 }
 
-export default function PlayingQuizBody({ quizInformations, runId, actualQuestion, fetchActualQuestion, setScore, navigation }: Props) {
+export default function PlayingQuizBody({ quizInformations, runId, actualQuestion, fetchActualQuestion, score, setScore, navigation }: Props) {
     const [selectedAnswerId, setSelectedAnswerId] = useState<number | null>(null);
     const [quizState, setQuizState] = useState(QuizState.ANSWERING);
     const [correctAnswerId, setCorrectAnswerId] = useState<number | null>(null);
@@ -91,6 +92,7 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
         setCorrectAnswerId(correctAnswerIdFetched);
         setQuizState(QuizState.SHOWING_RESULTS);
 
+        if (quizInformations === undefined) return;
         // Check si c'est la dernière question
         if(answereFetched.answers.order === quizInformations.questionCount - 1) {
             setIsLastQuestion(true);
@@ -100,7 +102,15 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
     };
     const onContinue = () => {
         if(isLastQuestion) {
-            console.log("go endquiz");
+            navigation.reset({
+                index: 0,
+                routes: [
+                    {
+                        name: "EndQuiz",
+                        params: {quizInformations: quizInformations, score: score},
+                    },
+                ]
+            });
             return;
         }
         fetchActualQuestion();
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 1caa6bf..2f78620 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -11,7 +11,7 @@ import {QuizInformations} from "../../models/QuizInformations";
 import {Question} from "../../models/Question";
 
 interface Props {
-    quizInformations: QuizInformations;
+    quizInformations?: QuizInformations;
     runId?: string;
     actualQuestion: Question;
     score: number;
-- 
GitLab


From a57ac6da87741b362394b5a8fa027bd0a0011ef7 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sat, 11 Jan 2025 23:59:50 +0100
Subject: [PATCH 240/283] style: scroll qui ne scroll pas

---
 screens/Home/HomeChild.tsx          |  5 +-
 screens/PlayingQuiz/PlayingQuiz.tsx | 80 ++++++++++++++++++++++++++---
 2 files changed, 75 insertions(+), 10 deletions(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 1072366..7a0b645 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -41,7 +41,8 @@ export default function HomeChild({navigation}: Props) {
         });
     }
     const handleButtonMyQuizzesPressed = () => {
-        navigation.navigate("MyQuizzes");
+        // navigation.navigate("MyQuizzes");
+        navigation.navigate("PlayingQuiz", {runId: "1", quizId: "1"});
     }
 
     const handleButtonGeneratePressed = () => {
@@ -56,7 +57,7 @@ export default function HomeChild({navigation}: Props) {
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
                 <MenuButton text={"PLAY"} handleButtonPressed={handleButtonGeneratePressed}/>
-                {/*<MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>*/}
+                <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
             </View>
              <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
         </View>
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 406582e..677fb69 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -29,18 +29,82 @@ export default function PlayingQuiz({route, navigation}:Props) {
     const [score, setScore] = useState(0);
 
     const fetchQuizInformations = async () => {
-        const quizInformationsFetched = await getQuizInformations(quizId);
-        if (HttpError.isHttpError(quizInformationsFetched)) {
-            return;
-        }
+        // const quizInformationsFetched = await getQuizInformations(quizId);
+        // if (HttpError.isHttpError(quizInformationsFetched)) {
+        //     return;
+        // }
+        const quizInformationsFetched: QuizInformations = {
+            id: 1,
+            name: "Quiz de Test",
+            description: "Ceci est un quiz de test pour vérifier l'interface.",
+            isCommunity: true,
+            questionCount: 10,
+            categoryId: 2,
+            difficultyId: 3,
+            authorId: {
+                id: 42,
+                username: "TestAuthor",
+                email: "testauthor@example.com"
+            },
+            createdAt: "2025-01-10T10:00:00Z",
+            updatedAt: "2025-01-11T12:00:00Z",
+            category: {
+                id: 2,
+                name: "Science"
+            },
+            difficulty: {
+                id: 3,
+                name: "Moyenne"
+            }
+        };
+        
         setQuizInformations(quizInformationsFetched);
     }
 
     const fetchActualQuestion = async () => {
-        const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
-        if (HttpError.isHttpError(actualQuestionFetched)) {
-            return;
-        }
+        // const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
+        // if (HttpError.isHttpError(actualQuestionFetched)) {
+        //     return;
+        // }
+        const actualQuestionFetched: Question = {
+            id: 1,
+            text: "Quelle image correspond à une étoile ?",
+            type: "image",
+            categoryId: 2,
+            quizId: "quiz123",
+            order: 1,
+            answers: [
+                {
+                    id: 1,
+                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+                    isCorrect: true,
+                    questionId: 1
+                },
+                {
+                    id: 2,
+                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+                    isCorrect: false,
+                    questionId: 1
+                },
+                {
+                    id: 3,
+                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+                    isCorrect: false,
+                    questionId: 1
+                },
+                {
+                    id: 4,
+                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+                    isCorrect: false,
+                    questionId: 1
+                }
+            ],
+            category: {
+                id: 2,
+                name: "Astronomie"
+            }
+        };
+        
         setActualQuestion(actualQuestionFetched);
     }
 
-- 
GitLab


From 08c7fbf293f0af1e676e90874e7226874573ac7d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 12 Jan 2025 00:09:37 +0100
Subject: [PATCH 241/283] refactor: join a quiz

---
 components/PlayQuiz/AboutAQuiz.tsx         | 13 +++++----
 models/RunInformations.ts                  | 14 +++++++++
 screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx | 34 +++++++++++++++-------
 screens/PlayingQuiz/PlayingQuiz.tsx        | 11 ++++++-
 screens/PlayingQuiz/PlayingQuizHeader.tsx  |  2 +-
 services/QuizService.ts                    | 24 ++++++++++++++-
 6 files changed, 80 insertions(+), 18 deletions(-)
 create mode 100644 models/RunInformations.ts

diff --git a/components/PlayQuiz/AboutAQuiz.tsx b/components/PlayQuiz/AboutAQuiz.tsx
index 94ae96e..ed01626 100644
--- a/components/PlayQuiz/AboutAQuiz.tsx
+++ b/components/PlayQuiz/AboutAQuiz.tsx
@@ -1,19 +1,22 @@
 import React from "react";
 import { View, Text, StyleSheet } from "react-native";
 import  {Quiz} from "../../models/Quiz";
+import {QuizInformations} from "../../models/QuizInformations";
+import {RunInformations} from "../../models/RunInformations";
 
 interface Props {
-    quiz?: Quiz;
+    runInformations?: RunInformations;
+    quizInformations?: QuizInformations;
 }
-export default function AboutAQuiz({quiz} : Props) {
+export default function AboutAQuiz({runInformations, quizInformations} : Props) {
     return (
         <View style={styles.container}>
             <Text style={styles.title}>About this quiz</Text>
             <View style={styles.separator} />
             <View style={styles.infoContainer}>
-                <Text style={styles.text}>Category : {quiz ? quiz.category?.name : "?"}</Text>
-                <Text style={styles.text}>Question : {quiz ? quiz.questionIndex : "?"}/{quiz ? quiz.questionCount : "?"}</Text>
-                <Text style={styles.text}>Score : {quiz ? quiz.score : "?"}</Text>
+                <Text style={styles.text}>Category : {quizInformations ? quizInformations.category.name : "?"}</Text>
+                {/*<Text style={styles.text}>Question : {quizInformations ? quizInformations.o : "?"}/{quiz ? quiz.questionCount : "?"}</Text>*/}
+                <Text style={styles.text}>Score : {runInformations ? runInformations.score : "?"}</Text>
             </View>
 
         </View>
diff --git a/models/RunInformations.ts b/models/RunInformations.ts
new file mode 100644
index 0000000..c7b74f0
--- /dev/null
+++ b/models/RunInformations.ts
@@ -0,0 +1,14 @@
+import {Category, Difficulty} from "./Quiz";
+import {User} from "./User";
+
+export interface RunInformations {
+    id: string;
+    quizId: string;
+    originalQuizId: string;
+    score: number;
+    questionIndex: number;
+    startDate: string;
+    lastChange: string;
+    quizUserId: number;
+    roomId?: number;
+}
\ No newline at end of file
diff --git a/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx b/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
index 9f856f9..e123a23 100644
--- a/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
+++ b/screens/Home/PlayQuiz/PlayQuizJoinQuiz.tsx
@@ -6,8 +6,9 @@ import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import {Quiz} from "../../../models/Quiz";
 import { useQuizService } from "../../../services/QuizService";
 import HttpError from "../../../services/HttpError";
-import {getIdOfCategory} from "../../../helper/QuizHelper";
 import {NavigationProp} from "@react-navigation/native";
+import {RunInformations} from "../../../models/RunInformations";
+import {QuizInformations} from "../../../models/QuizInformations";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -16,25 +17,38 @@ export default function PlayQuizJoinQuiz({navigation}: Props) {
     const [codeQuiz, setCodeQuiz] = React.useState("");
     const [quiz, setQuiz] = React.useState<Quiz>();
     const [error, setError] = React.useState<string>("");
+    const [runInformations, setRunInformations] = React.useState<RunInformations>();
+    const [quizInformations, setQuizInformations] = React.useState<QuizInformations>();
 
-    const { remainingQuiz } = useQuizService();
+    const { getRunsInfo, getQuizInformations } = useQuizService();
 
     useEffect(() => {
-        fetchQuiz();
+        fetchRuns();
     }, [codeQuiz]);
 
-    const fetchQuiz = async () => {
-        if(codeQuiz === "")
+    const fetchRuns = async () => {
+
+        if(codeQuiz === "") return;
+        if(codeQuiz.length < 6 )
         {
+            setError("A quiz contains 6 characters");
+            return;
+        }
+
+        const runFetched = await getRunsInfo(codeQuiz);
+        if (runFetched instanceof HttpError) {
+            setError("The quiz does not exist");
             return;
         }
-        const quizFetched = await remainingQuiz(codeQuiz);
-        if (quizFetched instanceof HttpError) {
+        const quizInformations = await getQuizInformations(runFetched.quizId);
+        if (quizInformations instanceof HttpError) {
             setError("The quiz does not exist");
             return;
         }
+
         setError("");
-        setQuiz(quizFetched);
+        setQuizInformations(quizInformations);
+        setRunInformations(runFetched);
     };
 
     const handlePlayButtonPress = () => {
@@ -43,7 +57,7 @@ export default function PlayQuizJoinQuiz({navigation}: Props) {
             routes: [
                 {
                     name: "PlayingQuiz",
-                    params: {quizRecovered: quiz},
+                    params: {runId: runInformations?.id, quizId: runInformations?.quizId },
                 },
             ]
         });
@@ -55,7 +69,7 @@ export default function PlayQuizJoinQuiz({navigation}: Props) {
                 <View style={styles.fieldContainer}>
                     {error ? <Text style={styles.errorText}>{error}</Text> : null}
                     <InputPlayQuiz placeholder={"Enter quiz ID"} setText={setCodeQuiz} noTitle={true} />
-                    <AboutAQuiz quiz={quiz} />
+                    <AboutAQuiz runInformations={runInformations} quizInformations={quizInformations} />
                 </View>
                 <View style={styles.buttonPlayContainer}>
                     <BlueButton onPress={handlePlayButtonPress} text={"PLAY"} isDisabled={codeQuiz==="" || error!==""}/>
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index aab164e..df699f9 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -23,11 +23,19 @@ interface Props {
 
 export default function PlayingQuiz({route, navigation}:Props) {
     const {runId, quizId} = route.params;
-    const { getQuizInformations, getActualQuestionOfAQuiz } = useQuizService();
+    const { getQuizInformations, getRunsInfo, getActualQuestionOfAQuiz } = useQuizService();
     const [quizInformations, setQuizInformations] = useState<QuizInformations | undefined>(undefined);
     const [actualQuestion, setActualQuestion] = useState<Question | undefined>(undefined);
     const [score, setScore] = useState(0);
 
+    const fetchRunInformations = async () => {
+        const runInformationsFetched = await getRunsInfo(runId);
+        if (HttpError.isHttpError(runInformationsFetched)) {
+            return;
+        }
+        setScore(runInformationsFetched.score);
+    }
+
     const fetchQuizInformations = async () => {
         const quizInformationsFetched = await getQuizInformations(quizId);
         if (HttpError.isHttpError(quizInformationsFetched)) {
@@ -46,6 +54,7 @@ export default function PlayingQuiz({route, navigation}:Props) {
 
     useEffect(() => {
         fetchQuizInformations();
+        fetchRunInformations();
     }, []);
 
     useEffect(() => {
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index 2f78620..ffba640 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -37,7 +37,7 @@ export default function PlayingQuizHeader({quizInformations, runId, actualQuesti
             <View style={styles.container}>
                 <View style={styles.header}>
                     <GoHomeButton navigation={navigation} onPress={setIsConfirmModalVisible}/>
-                    <Text style={styles.codeQuizText}>ID QUIZZ : {quizInformations ? quizInformations.id : "?"}</Text>
+                    <Text style={styles.codeQuizText}>ID QUIZZ : {runId}</Text>
                 </View>
                 <View style={styles.questionAndScoreContainer}>
                     <View style={styles.InformationsContainer}>
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 72752c8..f3fc6c1 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -8,6 +8,7 @@ import {AnswerResponse} from "../models/AnswerResponse";
 import {QuizInformations} from "../models/QuizInformations";
 import {QuestionResponse} from "../models/QuestionResponse";
 import {QuizGenerateAnswer} from "../models/QuizGenerateAnswer";
+import {RunInformations} from "../models/RunInformations";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -266,6 +267,26 @@ export const useQuizService =  () => {
         }
     };
 
+    const getRunsInfo = async (id: string): Promise<RunInformations | HttpError> => {
+        try {
+            const response = await axios.get<RunInformations>(`${url}/run/info/`+id, {
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            });
+            return response.data;
+        } catch (error: any) {
+            console.log("Error while getQuizInformations quiz:", error);
+
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
+
+
 
     return {
         generateQuiz: generateQuiz,
@@ -277,6 +298,7 @@ export const useQuizService =  () => {
         getCategories: getCategories,
         answerQuestion: answerQuestion,
         getActualQuestionOfAQuiz: getActualQuestionOfAQuiz,
-        getQuizInformations: getQuizInformations
+        getQuizInformations: getQuizInformations,
+        getRunsInfo: getRunsInfo
     }
 }
\ No newline at end of file
-- 
GitLab


From 50097783f5fcbab6429e1161bd898d168711adad Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 10:16:29 +0100
Subject: [PATCH 242/283] style: size image in image button

---
 components/buttons/AnswerButtonImage.tsx | 9 ++++++---
 screens/PlayingQuiz/PlayingQuizBody.tsx  | 1 -
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/components/buttons/AnswerButtonImage.tsx b/components/buttons/AnswerButtonImage.tsx
index bf75c90..61a3f09 100644
--- a/components/buttons/AnswerButtonImage.tsx
+++ b/components/buttons/AnswerButtonImage.tsx
@@ -6,7 +6,6 @@ interface Props{
     url: string;
     handleButtonPressed:() => void;
     buttonStyle?: any;
-    buttonImage?: any;
     indicator?: number | undefined;
 }
 
@@ -17,7 +16,7 @@ interface Props{
  * @param buttonStyle - Surcharge du style du bouton
  * @param buttonText - Surcharge du style du texte du bouton
  */
-export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle, buttonImage, indicator}: Props){
+export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle, indicator}: Props){
     return(
         <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
             {indicator !== undefined && (
@@ -26,7 +25,7 @@ export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle
                 </View>
             )}
             <Image 
-                style={[TextsStyles.defaultButtonText, {flex: 1, width: "100%", height: "100%"}, buttonImage]}
+                style={[styles.answerImage]}
                 source={{uri: url}}
             />
         </TouchableOpacity>
@@ -58,4 +57,8 @@ const styles = StyleSheet.create({
         fontWeight: "bold",
         fontSize: 14,
     },
+    answerImage: {
+        width: '100%',
+        height: '100%',
+    },
 })
\ No newline at end of file
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 7fe64e5..eb7fe38 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -129,7 +129,6 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
                                     url={answer.text}
                                     handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
                                     buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
-                                    // buttonImage={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
                                 />
                             :
                                 <AnswerButtonText
-- 
GitLab


From 40c569ea35b4f992ad67e04e2ab42ba00ea2bb04 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 11:17:14 +0100
Subject: [PATCH 243/283] style: center button in the list

---
 components/buttons/AnswerButtonImage.tsx | 24 +++++++++++++-----------
 screens/PlayingQuiz/PlayingQuizBody.tsx  | 19 ++++++++++++-------
 styles/ButtonsStyles.ts                  |  2 +-
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/components/buttons/AnswerButtonImage.tsx b/components/buttons/AnswerButtonImage.tsx
index 61a3f09..20b13ff 100644
--- a/components/buttons/AnswerButtonImage.tsx
+++ b/components/buttons/AnswerButtonImage.tsx
@@ -18,17 +18,19 @@ interface Props{
  */
 export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle, indicator}: Props){
     return(
-        <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
-            {indicator !== undefined && (
-                <View style={styles.indicator}>
-                    <Text style={styles.indicatorText}>{indicator}</Text>
-                </View>
-            )}
-            <Image 
-                style={[styles.answerImage]}
-                source={{uri: url}}
-            />
-        </TouchableOpacity>
+        <View style={{height: 150, width: '100%'}}>
+            <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
+                {indicator !== undefined && (
+                    <View style={styles.indicator}>
+                        <Text style={styles.indicatorText}>{indicator}</Text>
+                    </View>
+                )}
+                <Image 
+                    style={[styles.answerImage]}
+                    source={{uri: url}}
+                />
+            </TouchableOpacity>
+        </View>
     )
 }
 
diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index eb7fe38..cdbc278 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -1,4 +1,4 @@
-import {View, StyleSheet, Text, ActivityIndicator} from "react-native";
+import {View, StyleSheet, Text, ActivityIndicator, ScrollView} from "react-native";
 import DefaultButton from "../../components/buttons/DefaultButton";
 import { ButtonsStyles } from "../../styles/ButtonsStyles";
 import React, { useState, useEffect, SetStateAction, Dispatch } from "react";
@@ -121,7 +121,10 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
         <View style={styles.buttonContainer}>
             {actualQuestion ? (
                 <>
-                    <View style={styles.buttonListContainer}>
+                    <ScrollView 
+                        style={styles.buttonListContainer}
+                        contentContainerStyle={styles.buttonListContentContainer}
+                    >
                         {actualQuestion.answers.map((answer, index) => (
                             actualQuestion.type === "image" ? 
                                 <AnswerButtonImage
@@ -139,7 +142,8 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
                                     buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
                                 />
                         ))}
-                    </View>
+                        {/* </View> */}
+                    </ScrollView>
                     <View style={styles.playButtonContainer}>
                         <BlueButton onPress={() => quizState === QuizState.ANSWERING ? onValidation() : onContinue()} text={quizState === QuizState.ANSWERING ? "CONFIRM" : "CONTINUE"} buttonStyle={{borderRadius: 50}} isDisabled={false}/>
                     </View>
@@ -212,7 +216,7 @@ const styles = StyleSheet.create({
     },
     answerButton: {
         backgroundColor: "#F3F3F3",
-        height: '30%',
+        height: '75%',
         alignItems: 'center',
         width: '80%',
         marginVertical: '3%',
@@ -224,12 +228,13 @@ const styles = StyleSheet.create({
         elevation: 5,
     },
     buttonListContainer: {
-        height: '80%',
+        maxHeight: '80%',
         width: '100%',
+    },
+    buttonListContentContainer: {
         display: 'flex',
         justifyContent: 'flex-start',
-        alignItems: 'center',
-        overflow: 'scroll',
+        alignItems: 'center'
     }
 });
 
diff --git a/styles/ButtonsStyles.ts b/styles/ButtonsStyles.ts
index 12d8539..679e720 100644
--- a/styles/ButtonsStyles.ts
+++ b/styles/ButtonsStyles.ts
@@ -16,7 +16,7 @@ export const ButtonsStyles = StyleSheet.create( {
     },
     answerButton: {
         backgroundColor: "#F3F3F3",
-        height: '30%',
+        height: '75%',
         alignItems: 'center',
         width: '80%',
         marginVertical: '3%',
-- 
GitLab


From 78c706965c098045ca988dfe3a063bfb7ddeea64 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 11:18:11 +0100
Subject: [PATCH 244/283] refactor: move the style to a var

---
 components/buttons/AnswerButtonImage.tsx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/components/buttons/AnswerButtonImage.tsx b/components/buttons/AnswerButtonImage.tsx
index 20b13ff..8716144 100644
--- a/components/buttons/AnswerButtonImage.tsx
+++ b/components/buttons/AnswerButtonImage.tsx
@@ -18,7 +18,7 @@ interface Props{
  */
 export default function AnswerButtonImage({url, handleButtonPressed, buttonStyle, indicator}: Props){
     return(
-        <View style={{height: 150, width: '100%'}}>
+        <View style={styles.containerButton}>
             <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
                 {indicator !== undefined && (
                     <View style={styles.indicator}>
@@ -63,4 +63,11 @@ const styles = StyleSheet.create({
         width: '100%',
         height: '100%',
     },
+    containerButton: {
+        height: 150, 
+        width: '100%',
+        display: 'flex',
+        alignItems: 'center',
+        justifyContent: 'center'
+    }
 })
\ No newline at end of file
-- 
GitLab


From 13d4373153eac1f8bdf8bef48fe3e6266a8aa7f4 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 11:19:22 +0100
Subject: [PATCH 245/283] style: update answerbuttonText to fit with the list

---
 components/buttons/AnswerButtonText.tsx | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/components/buttons/AnswerButtonText.tsx b/components/buttons/AnswerButtonText.tsx
index 6dbc8b4..57427b4 100644
--- a/components/buttons/AnswerButtonText.tsx
+++ b/components/buttons/AnswerButtonText.tsx
@@ -19,14 +19,16 @@ interface Props{
  */
 export default function AnswerButtonText({text, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
     return(
-        <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
-            {indicator !== undefined && (
-                <View style={styles.indicator}>
-                    <Text style={styles.indicatorText}>{indicator}</Text>
-                </View>
-            )}
-            <Text style={[TextsStyles.defaultButtonText, buttonText]}>{text}</Text>
-        </TouchableOpacity>
+        <View style={styles.containerButton}>
+            <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
+                {indicator !== undefined && (
+                    <View style={styles.indicator}>
+                        <Text style={styles.indicatorText}>{indicator}</Text>
+                    </View>
+                )}
+                <Text style={[TextsStyles.defaultButtonText, buttonText]}>{text}</Text>
+            </TouchableOpacity>
+        </View>
     )
 }
 
@@ -55,4 +57,11 @@ const styles = StyleSheet.create({
         fontWeight: "bold",
         fontSize: 14,
     },
+    containerButton: {
+        height: 150, 
+        width: '100%',
+        display: 'flex',
+        alignItems: 'center',
+        justifyContent: 'center'
+    }
 })
\ No newline at end of file
-- 
GitLab


From 063991ba682ea3d6762d296360e9464105c8a0cf Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 11:20:04 +0100
Subject: [PATCH 246/283] temp: add test value

---
 screens/PlayingQuiz/PlayingQuiz.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 677fb69..9bfdfda 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -69,7 +69,7 @@ export default function PlayingQuiz({route, navigation}:Props) {
         const actualQuestionFetched: Question = {
             id: 1,
             text: "Quelle image correspond à une étoile ?",
-            type: "image",
+            type: "imae",
             categoryId: 2,
             quizId: "quiz123",
             order: 1,
-- 
GitLab


From 33c6015d28b81178eff640cc7d09c347bdf08517 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 13:40:18 +0100
Subject: [PATCH 247/283] feat: add shuffle question

---
 helper/QuizHelper.ts                | 30 ++++-----
 screens/PlayingQuiz/PlayingQuiz.tsx | 96 +++++++++++++++++++++++------
 2 files changed, 88 insertions(+), 38 deletions(-)

diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index e2ee3aa..2035db1 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -1,21 +1,15 @@
-import {Quiz} from "../models/Quiz";
-export const shuffleAnswersOfQuiz = (quiz: Quiz): Quiz => {
-    // Clone le quiz pour éviter de modifier l'original
-    const shuffledQuiz: Quiz = {
-        ...quiz,
-        questions: quiz.questions.map((question) => ({
-            ...question,
-            answers: [...question.answers], // Clone les réponses pour éviter de modifier l'original
-        })),
-    };
+import {Question} from '../models/Question';
+
+export const shuffleAnswers = (question: Question): Question => {
+    const shuffledAnswers = [...question.answers];
 
-    // Mélange les réponses de chaque question
-    shuffledQuiz.questions.forEach((question) => {
-        for (let i = question.answers.length - 1; i > 0; i--) {
-            const j = Math.floor(Math.random() * (i + 1));
-            [question.answers[i], question.answers[j]] = [question.answers[j], question.answers[i]];
-        }
-    });
+    for (let i = shuffledAnswers.length - 1; i > 0; i--) {
+        const j = Math.floor(Math.random() * (i + 1));
+        [shuffledAnswers[i], shuffledAnswers[j]] = [shuffledAnswers[j], shuffledAnswers[i]];
+    }
 
-    return shuffledQuiz;
+    return {
+        ...question,
+        answers: shuffledAnswers,
+    };
 };
\ No newline at end of file
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index df699f9..6b2dd76 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -7,6 +7,7 @@ import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
 import {Question} from "../../models/Question";
 import PlayingQuizBody from "./PlayingQuizBody";
+import { shuffleAnswers } from "../../helper/QuizHelper";
 
 
 type RoutePropsType = {
@@ -23,38 +24,93 @@ interface Props {
 
 export default function PlayingQuiz({route, navigation}:Props) {
     const {runId, quizId} = route.params;
-    const { getQuizInformations, getRunsInfo, getActualQuestionOfAQuiz } = useQuizService();
+    const { getQuizInformations, getActualQuestionOfAQuiz } = useQuizService();
     const [quizInformations, setQuizInformations] = useState<QuizInformations | undefined>(undefined);
     const [actualQuestion, setActualQuestion] = useState<Question | undefined>(undefined);
     const [score, setScore] = useState(0);
 
-    const fetchRunInformations = async () => {
-        const runInformationsFetched = await getRunsInfo(runId);
-        if (HttpError.isHttpError(runInformationsFetched)) {
-            return;
-        }
-        setScore(runInformationsFetched.score);
-    }
-
     const fetchQuizInformations = async () => {
-        const quizInformationsFetched = await getQuizInformations(quizId);
-        if (HttpError.isHttpError(quizInformationsFetched)) {
-            return;
-        }
+        // const quizInformationsFetched = await getQuizInformations(quizId);
+        // if (HttpError.isHttpError(quizInformationsFetched)) {
+        //     return;
+        // }
+        const quizInformationsFetched: QuizInformations = {
+            id: 1,
+            name: "Quiz de Test",
+            description: "Ceci est un quiz de test pour vérifier l'interface.",
+            isCommunity: true,
+            questionCount: 10,
+            categoryId: 2,
+            difficultyId: 3,
+            authorId: {
+                id: 42,
+                username: "TestAuthor",
+                email: "testauthor@example.com"
+            },
+            createdAt: "2025-01-10T10:00:00Z",
+            updatedAt: "2025-01-11T12:00:00Z",
+            category: {
+                id: 2,
+                name: "Science"
+            },
+            difficulty: {
+                id: 3,
+                name: "Moyenne"
+            }
+        };
+        
         setQuizInformations(quizInformationsFetched);
     }
 
     const fetchActualQuestion = async () => {
-        const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
-        if (HttpError.isHttpError(actualQuestionFetched)) {
-            return;
-        }
-        setActualQuestion(actualQuestionFetched);
+        // const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
+        // if (HttpError.isHttpError(actualQuestionFetched)) {
+        //     return;
+        // }
+        const actualQuestionFetched: Question = {
+            id: 1,
+            text: "Quelle image correspond à une étoile ?",
+            type: "imae",
+            categoryId: 2,
+            quizId: "quiz123",
+            order: 1,
+            answers: [
+                {
+                    id: 1,
+                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+                    isCorrect: true,
+                    questionId: 1
+                },
+                {
+                    id: 2,
+                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+                    isCorrect: false,
+                    questionId: 1
+                },
+                {
+                    id: 3,
+                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+                    isCorrect: false,
+                    questionId: 1
+                },
+                {
+                    id: 4,
+                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+                    isCorrect: false,
+                    questionId: 1
+                }
+            ],
+            category: {
+                id: 2,
+                name: "Astronomie"
+            }
+        };
+        const actualQuestionFetchedShuffle = shuffleAnswers(actualQuestionFetched);
+        setActualQuestion(actualQuestionFetchedShuffle);
     }
 
     useEffect(() => {
         fetchQuizInformations();
-        fetchRunInformations();
     }, []);
 
     useEffect(() => {
@@ -64,7 +120,7 @@ export default function PlayingQuiz({route, navigation}:Props) {
     return (
         <TemplateDuo
             childrenHeader={<PlayingQuizHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score} navigation={navigation}></PlayingQuizHeader>}
-            childrenBody={<PlayingQuizBody quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} score={score} navigation={navigation}></PlayingQuizBody>}
+            childrenBody={<PlayingQuizBody quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} navigation={navigation}></PlayingQuizBody>}
         />
     );
 }
\ No newline at end of file
-- 
GitLab


From e9c6f6ec0f0a0ac0166da4c2f2ab542517c03c52 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 12 Jan 2025 13:49:49 +0100
Subject: [PATCH 248/283] feat: lobby

---
 hooks/UseCookie.ts                  | 55 +++++++++++++++++++++++++++++
 screens/Multiplayer/Lobby/Lobby.tsx | 20 +++++++----
 services/UserService.ts             | 20 +++++++++--
 3 files changed, 86 insertions(+), 9 deletions(-)
 create mode 100644 hooks/UseCookie.ts

diff --git a/hooks/UseCookie.ts b/hooks/UseCookie.ts
new file mode 100644
index 0000000..050d762
--- /dev/null
+++ b/hooks/UseCookie.ts
@@ -0,0 +1,55 @@
+import { useState, useEffect, useCallback } from 'react';
+import AsyncStorage from '@react-native-async-storage/async-storage';
+
+const useCookie = (cookieName: string) => {
+    const [error, setError] = useState<Error | null>(null);
+
+    // Fonction pour sauvegarder le cookie
+    const saveCookie = useCallback(async (value: string, expirationInDays = 7) => {
+        try {
+            await AsyncStorage.setItem(cookieName, value);
+            setError(null);
+        } catch (e) {
+            if(e instanceof Error) {
+                setError(e);
+            }
+            setError(new Error('An error occurred while saving the cookie'));
+        }
+    }, [cookieName]);
+
+    // Fonction pour supprimer le cookie
+    const removeCookie = useCallback(async () => {
+        try {
+            await AsyncStorage.removeItem(cookieName);
+            setError(null);
+        } catch (e) {
+            if(e instanceof Error) {
+                setError(e);
+            }
+            setError(new Error('An error occurred while removing the cookie'));
+        }
+    }, [cookieName]);
+
+    const getCookie = useCallback(async () => {
+        try {
+            const value = await AsyncStorage.getItem(cookieName);
+            setError(null);
+            return value;
+        } catch (e) {
+            if(e instanceof Error) {
+                setError(e);
+            }
+            setError(new Error('An error occurred while getting the cookie'));
+        }
+    }, [cookieName]);
+
+
+    return {
+        error,
+        saveCookie,
+        removeCookie,
+        getCookie,
+    };
+};
+
+export default useCookie;
\ No newline at end of file
diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index 2f9a512..c5a24eb 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -9,6 +9,7 @@ import ModalInvitePlayer from "../../../components/Multiplayer/ModalInvitePlayer
 import {User} from "../../../models/User";
 import {QuizGenerateAnswer} from "../../../models/QuizGenerateAnswer";
 import {io, Socket} from "socket.io-client";
+import useCookie from "../../../hooks/UseCookie";
 
 interface Props {
     navigation: NavigationProp<any>;
@@ -28,16 +29,17 @@ export default function Lobby({navigation, route}: Props) {
     const [isHost, setIsHost] = useState<boolean>(true);
     const [showModal, setShowModal] = useState<boolean>(false);
     const [players, setPlayers] = useState<User[]>([{ id: 0, username: 'Invite', email: 'invite@email.com'}]);
-
-
-
+    const {getCookie} = useCookie('access_token');
     const [socket, setSocket] = useState<Socket | null>(null);
 
-    useEffect(() => {
-        // Initialise Socket.IO connection
+    const userInvite = { id: 0, username: 'Invite', email: 'invite@email.com'}
+    const initSocket = async () => {
+        const cookie = await getCookie();
         const newSocket = io("http://klebert-host.com:33053/party", {
             transports: ["websocket"], // Utilise WebSocket uniquement
-            withCredentials: true
+            extraHeaders: {
+                Cookie: `access_token=${cookie}`,
+            },
         });
 
         setSocket(newSocket);
@@ -58,7 +60,7 @@ export default function Lobby({navigation, route}: Props) {
         // Mettez à jour la liste des joueurs lorsque quelqu'un rejoint
         newSocket.on("userJoined", (data: User[]) => {
             console.log("Updated user list:", data);
-            setPlayers(data);
+            setPlayers([userInvite, ...data]);
         });
 
         // Nettoyez la connexion lorsque le composant est démonté
@@ -66,6 +68,10 @@ export default function Lobby({navigation, route}: Props) {
             newSocket.disconnect();
             setSocket(null);
         };
+    }
+
+    useEffect(() => {
+        initSocket();
     }, [runId]);
 
     const item = ({ item }: { item: User }) => {
diff --git a/services/UserService.ts b/services/UserService.ts
index 374a311..22675d4 100644
--- a/services/UserService.ts
+++ b/services/UserService.ts
@@ -1,10 +1,13 @@
 import HttpError from "./HttpError";
-import User from "../models/User";
 import axios from "axios";
 import {transformToUserModel} from "../helper/UserHelper";
+import AsyncStorage from "@react-native-async-storage/async-storage";
+import useCookie from "../hooks/UseCookie";
+import {User} from "../models/User";
 
 export const useUserService =  () => {
     const url = "https://klebert-host.com:33037";
+    const { saveCookie, removeCookie } = useCookie('access_token');
 
 
     const loginUser = async (login: string, password: string): Promise<boolean | HttpError> => {
@@ -14,10 +17,22 @@ export const useUserService =  () => {
                 password: password,
             };
 
-            await axios.post(`${url}/auth/login`, requestBody, {
+            const response =await axios.post(`${url}/auth/login`, requestBody, {
                 withCredentials: true, // Autorise Axios à inclure les cookies
             });
 
+            const cookies = response.headers['set-cookie'];
+            if (cookies) {
+                const accessToken = cookies
+                    .find(cookie => cookie.startsWith('access_token='))
+                    ?.split(';')[0]
+                    ?.split('=')[1];
+
+                if (accessToken) {
+                    saveCookie(accessToken);
+                }
+            }
+
             return true;
         } catch (error: any) {
 
@@ -57,6 +72,7 @@ export const useUserService =  () => {
 
     const logoutUser = async (): Promise<boolean | HttpError> => {
         try {
+            removeCookie();
             await axios.post(`${url}/auth/logout`, null, {
                 withCredentials: true, // Inclut les cookies dans la requête
             });
-- 
GitLab


From fdb7ef0f4b7727f9fca1d588d39b843166794dd6 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 14:24:20 +0100
Subject: [PATCH 249/283] feat: add route create run

---
 services/QuizService.ts | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index f3fc6c1..f424b3d 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -286,7 +286,27 @@ export const useQuizService =  () => {
         }
     }
 
+    const createRun = async (quizId: string): Promise<string | HttpError> => {
+        try {
+            const response = await axios.post(`${url}/run/start`, {
+                quizId: quizId,
+            }, {
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            });
+
+            return response.data.id;
+        } catch (error: any) {
+            console.log("Error while getQuizInformations quiz:", error);
 
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
 
     return {
         generateQuiz: generateQuiz,
@@ -299,6 +319,7 @@ export const useQuizService =  () => {
         answerQuestion: answerQuestion,
         getActualQuestionOfAQuiz: getActualQuestionOfAQuiz,
         getQuizInformations: getQuizInformations,
-        getRunsInfo: getRunsInfo
+        getRunsInfo: getRunsInfo,
+        createRun: createRun,
     }
 }
\ No newline at end of file
-- 
GitLab


From 21943fec9f25cd345368c23cc649ad54656dba6d Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 14:57:28 +0100
Subject: [PATCH 250/283] feat: start quiz from community

---
 .../InformationsOfQuiz/InformationsOfQuiz.tsx |  8 +++++--
 services/QuizService.ts                       | 23 ++++++++++++++++++-
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
index 3e6461c..6e6c3dd 100644
--- a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -3,6 +3,7 @@ import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
 import TemplateMenu from "../../../templates/TemplateMenu";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
 import {Quiz} from "../../../models/Quiz";
+import { useQuizService } from "../../../services/QuizService";
 
 type RoutePropsType = {
     InformationsOfQuiz: {
@@ -16,9 +17,12 @@ interface Props {
 
 export default function InformationsOfQuiz({ navigation, route }: Props) {
     const { quiz } = route.params;
+    const { createRun } = useQuizService();
 
-    const onPlay = () => {
-        navigation.navigate('PlayingQuiz', {quizRecovered: quiz});
+    const onPlay = async () => {
+        const quizId = quiz.id.toString();
+        const runId = await createRun(quizId);
+        navigation.navigate('PlayingQuiz', { runId: runId, quizId: quizId });
     }
 
     return (
diff --git a/services/QuizService.ts b/services/QuizService.ts
index f3fc6c1..f424b3d 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -286,7 +286,27 @@ export const useQuizService =  () => {
         }
     }
 
+    const createRun = async (quizId: string): Promise<string | HttpError> => {
+        try {
+            const response = await axios.post(`${url}/run/start`, {
+                quizId: quizId,
+            }, {
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            });
+
+            return response.data.id;
+        } catch (error: any) {
+            console.log("Error while getQuizInformations quiz:", error);
 
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
 
     return {
         generateQuiz: generateQuiz,
@@ -299,6 +319,7 @@ export const useQuizService =  () => {
         answerQuestion: answerQuestion,
         getActualQuestionOfAQuiz: getActualQuestionOfAQuiz,
         getQuizInformations: getQuizInformations,
-        getRunsInfo: getRunsInfo
+        getRunsInfo: getRunsInfo,
+        createRun: createRun,
     }
 }
\ No newline at end of file
-- 
GitLab


From c94b568b98ce913ebe2b3825757eb912ad26b198 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 15:00:10 +0100
Subject: [PATCH 251/283] fix: conflits

---
 helper/QuizHelper.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/helper/QuizHelper.ts b/helper/QuizHelper.ts
index 2035db1..85b1137 100644
--- a/helper/QuizHelper.ts
+++ b/helper/QuizHelper.ts
@@ -1,6 +1,6 @@
 import {Question} from '../models/Question';
 
-export const shuffleAnswers = (question: Question): Question => {
+export const shuffleAnswersOfQuiz = (question: Question): Question => {
     const shuffledAnswers = [...question.answers];
 
     for (let i = shuffledAnswers.length - 1; i > 0; i--) {
-- 
GitLab


From 7f1813f351f76a4285fbf97840fc82ce244a2269 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 12 Jan 2025 16:34:48 +0100
Subject: [PATCH 252/283] feat: starting playing quiz

---
 .../PlayingQuizMultiMode.tsx                  | 126 ++++++++++
 .../PlayingQuizMultiModeBody.tsx              | 225 ++++++++++++++++++
 .../PlayingQuizMultiModeHeader.tsx            |  95 ++++++++
 3 files changed, 446 insertions(+)
 create mode 100644 screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx
 create mode 100644 screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
 create mode 100644 screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx

diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx
new file mode 100644
index 0000000..e2e6bfc
--- /dev/null
+++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx
@@ -0,0 +1,126 @@
+import {NavigationProp, RouteProp} from "@react-navigation/native";
+import {useQuizService} from "../../../../services/QuizService";
+import React, {useEffect, useState} from "react";
+import {QuizInformations} from "../../../../models/QuizInformations";
+import {Question} from "../../../../models/Question";
+import {shuffleAnswers} from "../../../../helper/QuizHelper";
+import TemplateDuo from "../../../../templates/TemplateDuo";
+import HttpError from "../../../../services/HttpError";
+import PlayingQuizMultiModeHeader from "./PlayingQuizMultiModeHeader";
+import PlayingQuizMultiModeBody from "./PlayingQuizMultiModeBody";
+
+
+type RoutePropsType = {
+    PlayingQuiz: {
+        runId: string;
+        quizId: string;
+    };
+};
+
+interface Props {
+    route: RouteProp<RoutePropsType, "PlayingQuiz">;
+    navigation: NavigationProp<any>;
+}
+
+export default function PlayingQuizMultiMode({route, navigation}:Props) {
+    const {runId, quizId} = route.params;
+    const { getQuizInformations, getActualQuestionOfAQuiz } = useQuizService();
+    const [quizInformations, setQuizInformations] = useState<QuizInformations | undefined>(undefined);
+    const [actualQuestion, setActualQuestion] = useState<Question | undefined>(undefined);
+    const [score, setScore] = useState(0);
+
+    const fetchQuizInformations = async () => {
+        // const quizInformationsFetched = await getQuizInformations(quizId);
+        // if (HttpError.isHttpError(quizInformationsFetched)) {
+        //     return;
+        // }
+        const quizInformationsFetched: QuizInformations = {
+            id: 1,
+            name: "Quiz de Test",
+            description: "Ceci est un quiz de test pour vérifier l'interface.",
+            isCommunity: true,
+            questionCount: 10,
+            categoryId: 2,
+            difficultyId: 3,
+            authorId: {
+                id: 42,
+                username: "TestAuthor",
+                email: "testauthor@example.com"
+            },
+            createdAt: "2025-01-10T10:00:00Z",
+            updatedAt: "2025-01-11T12:00:00Z",
+            category: {
+                id: 2,
+                name: "Science"
+            },
+            difficulty: {
+                id: 3,
+                name: "Moyenne"
+            }
+        };
+
+        setQuizInformations(quizInformationsFetched);
+    }
+
+    const fetchActualQuestion = async () => {
+        const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
+        if (HttpError.isHttpError(actualQuestionFetched)) {
+            return;
+        }
+        // const actualQuestionFetched: Question = {
+        //     id: 1,
+        //     text: "Quelle image correspond à une étoile ?",
+        //     type: "imae",
+        //     categoryId: 2,
+        //     quizId: "quiz123",
+        //     order: 1,
+        //     answers: [
+        //         {
+        //             id: 1,
+        //             text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+        //             isCorrect: true,
+        //             questionId: 1
+        //         },
+        //         {
+        //             id: 2,
+        //             text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+        //             isCorrect: false,
+        //             questionId: 1
+        //         },
+        //         {
+        //             id: 3,
+        //             text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+        //             isCorrect: false,
+        //             questionId: 1
+        //         },
+        //         {
+        //             id: 4,
+        //             text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
+        //             isCorrect: false,
+        //             questionId: 1
+        //         }
+        //     ],
+        //     category: {
+        //         id: 2,
+        //         name: "Astronomie"
+        //     }
+        // };
+        const actualQuestionFetchedShuffle = shuffleAnswers(actualQuestionFetched);
+        setActualQuestion(actualQuestionFetchedShuffle);
+    }
+
+    useEffect(() => {
+        fetchQuizInformations();
+    }, []);
+
+    useEffect(() => {
+        fetchActualQuestion();
+    }, [quizId]);
+
+    return (
+        <TemplateDuo
+            childrenHeader={<PlayingQuizMultiModeHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score} navigation={navigation}></PlayingQuizMultiModeHeader>}
+            childrenBody={<PlayingQuizMultiModeBody quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} navigation={navigation}></PlayingQuizMultiModeBody>}
+        />
+    );
+}
\ No newline at end of file
diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
new file mode 100644
index 0000000..f6fc5f5
--- /dev/null
+++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
@@ -0,0 +1,225 @@
+import {QuizInformations} from "../../../../models/QuizInformations";
+import {Question} from "../../../../models/Question";
+import {NavigationProp} from "@react-navigation/native";
+import React, {useState} from "react";
+import {useQuizService} from "../../../../services/QuizService";
+import {Answer} from "../../../../models/Answer";
+import HttpError from "../../../../services/HttpError";
+import AnswerButton from "../../../../components/buttons/AnswerButton";
+import {ActivityIndicator, View, Text, StyleSheet} from "react-native";
+import BlueButton from "../../../../components/buttons/BlueButton";
+import {ButtonsStyles} from "../../../../styles/ButtonsStyles";
+
+
+interface Props {
+    quizInformations?: QuizInformations;
+    runId?: string;
+    actualQuestion: Question;
+    fetchActualQuestion: () => void;
+    score: number;
+    setScore: (score: number) => void;
+    navigation: NavigationProp<any>;
+}
+
+enum QuizState {
+    ANSWERING= "Answering",
+    LOADING= "Loading",
+    SHOWING_RESULTS= "ShowingResults",
+}
+
+const getStyleOfAnswerButtonText = (answerId: number, selectedAnswerIndex: number | null, correctAnswerId: number | null, quizState: QuizState) => {
+    if(quizState === QuizState.LOADING)
+    {
+        return styles.loadingText;
+    }
+    if(quizState === QuizState.ANSWERING)
+    {
+        return styles.answerText;
+
+    }
+    if(quizState === QuizState.SHOWING_RESULTS)
+    {
+        if(answerId === correctAnswerId) return styles.correctText;
+        if(answerId !== correctAnswerId && selectedAnswerIndex === answerId) return styles.incorrectText;
+    }
+    return styles.answerText;
+}
+
+const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number | null, correctAnswerId: number | null, quizState: QuizState) => {
+    if(quizState === QuizState.LOADING)
+    {
+        return styles.loadingAnswer;
+    }
+    if(quizState === QuizState.ANSWERING)
+    {
+        if(selectedAnswerIndex === null) return styles.answerButton;
+        if(selectedAnswerIndex === answerId) return styles.selectedAnswer;
+
+    }
+    if(quizState === QuizState.SHOWING_RESULTS)
+    {
+        if(answerId === correctAnswerId) return styles.correctAnswer;
+        if(answerId !== correctAnswerId && selectedAnswerIndex === answerId) return styles.incorrectAnswer;
+    }
+    return styles.answerButton;
+}
+
+export default function PlayingQuizMultiModeBody({ quizInformations, runId, actualQuestion, fetchActualQuestion, score, setScore, navigation }: Props) {
+    const [selectedAnswerId, setSelectedAnswerId] = useState<number | null>(null);
+    const [quizState, setQuizState] = useState(QuizState.ANSWERING);
+    const [correctAnswerId, setCorrectAnswerId] = useState<number | null>(null);
+    const [isLastQuestion, setIsLastQuestion] = useState(false);
+
+    const {answerQuestion} = useQuizService();
+    const getCorrectAnswer = (answers: Answer[]): Answer => {
+        const correctAnswer = answers.find((answer) => answer.isCorrect);
+        if (!correctAnswer) throw new Error("No correct answer found");
+        return correctAnswer;
+    };
+    const onValidation = async () => {
+        if(selectedAnswerId === null) return;
+        setQuizState(QuizState.LOADING);
+        const answerId = actualQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
+        if(!answerId || !runId) return;
+        const answereFetched = await answerQuestion(runId, actualQuestion.id, answerId);
+
+        if (HttpError.isHttpError(answereFetched)) {
+            return;
+        }
+        setScore(answereFetched.score);
+        const correctAnswerIdFetched = getCorrectAnswer(answereFetched.answers.answers).id;
+        setCorrectAnswerId(correctAnswerIdFetched);
+        setQuizState(QuizState.SHOWING_RESULTS);
+
+        if (quizInformations === undefined) return;
+        // Check si c'est la dernière question
+        if(answereFetched.answers.order === quizInformations.questionCount - 1) {
+            setIsLastQuestion(true);
+            return;
+        }
+
+    };
+    const onContinue = () => {
+        if(isLastQuestion) {
+            navigation.reset({
+                index: 0,
+                routes: [
+                    {
+                        name: "EndQuiz",
+                        params: {quizInformations: quizInformations, score: score},
+                    },
+                ]
+            });
+            return;
+        }
+        fetchActualQuestion();
+        setQuizState(QuizState.ANSWERING);
+        setSelectedAnswerId(null);
+        setCorrectAnswerId(null);
+    }
+
+    const onAnsweredButtonClicked = (answerId: number) => {
+        if(quizState === QuizState.SHOWING_RESULTS || quizState === QuizState.LOADING) {
+            return;
+        }
+        setSelectedAnswerId(answerId);
+    }
+
+    return (
+        <View style={styles.buttonContainer}>
+            {actualQuestion ? (
+                <>
+                    {actualQuestion.answers.map((answer, index) => (
+                        <AnswerButton
+                            key={index}
+                            text={answer.text}
+                            handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
+                            buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                            buttonText={getStyleOfAnswerButtonText(answer.id, selectedAnswerId, correctAnswerId, quizState)}
+                        />
+                    ))}
+                    <View style={styles.playButtonContainer}>
+                        <BlueButton onPress={() => quizState === QuizState.ANSWERING ? onValidation() : onContinue()} text={quizState === QuizState.ANSWERING ? "CONFIRM" : "CONTINUE"} buttonStyle={{borderRadius: 50}} isDisabled={false}/>
+                    </View>
+                </>
+            ) : (
+                <View style={styles.loadingContainer}>
+                    <ActivityIndicator size="large" color="#2b73fe" />
+                    <Text style={styles.loadingText}>Loading...</Text>
+                </View>
+            )}
+        </View>
+    );
+
+}
+
+const styles = StyleSheet.create({
+    buttonContainer: {
+        display: 'flex',
+        flex: 1,
+        alignItems: 'center',
+        justifyContent: 'flex-start',
+        width: '100%',
+        marginVertical: '3%',
+    },
+    loadingContainer: {
+        flex: 1,
+        justifyContent: "center",
+        alignItems: "center",
+    },
+    playButtonContainer: {
+        marginTop: 20, // Ajoute un espacement au-dessus du bouton Play
+        width: '80%', // S'assure que le bouton prend toute la largeur disponible
+        alignItems: 'center', // Centre le bouton horizontalement
+    },
+    correctAnswer: {
+        ...ButtonsStyles.answerButton,
+        borderColor: 'green',
+        borderWidth: 2,
+    },
+    incorrectAnswer: {
+        ...ButtonsStyles.answerButton,
+        borderColor: 'red',
+        borderWidth: 2,
+    },
+    loadingAnswer: {
+        ...ButtonsStyles.answerButton,
+        backgroundColor: '#4F6367',
+        borderWidth: 2,
+    },
+    selectedAnswer: {
+        ...ButtonsStyles.answerButton,
+        borderColor: 'grey',
+        borderWidth: 2,
+    },
+    answerText: {
+        color: 'black',
+        textAlign: 'center',
+    },
+    correctText: {
+        fontWeight: 'bold',
+        color: 'green',
+    },
+    incorrectText: {
+        fontWeight: 'bold',
+        color: 'red',
+    },
+    loadingText: {
+        color: 'black',
+        textAlign: 'center',
+    },
+    answerButton: {
+        backgroundColor: "#F3F3F3",
+        height: '15%',
+        alignItems: 'center',
+        width: '80%',
+        marginVertical: '3%',
+        justifyContent: "center",
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.5,
+        elevation: 5,
+    },
+});
+
diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx
new file mode 100644
index 0000000..c5da7d2
--- /dev/null
+++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx
@@ -0,0 +1,95 @@
+import {QuizInformations} from "../../../../models/QuizInformations";
+import {Question} from "../../../../models/Question";
+import {NavigationProp} from "@react-navigation/native";
+import {useTranslation} from "react-i18next";
+import {useState} from "react";
+import {View, Text, StyleSheet} from "react-native";
+import GoHomeButton from "../../../../components/PlayingQuiz/GoHomeButton";
+import {TextsStyles} from "../../../../styles/TextsStyles";
+import ConfirmModal from "../../../../components/PlayingQuiz/ComfirmModal";
+
+interface Props {
+    quizInformations?: QuizInformations;
+    runId?: string;
+    actualQuestion: Question;
+    score: number;
+    navigation: NavigationProp<any>
+}
+
+export default function PlayingQuizMultiModeHeader({quizInformations, runId, actualQuestion, score, navigation}: Props) {
+    const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);
+    const {t} = useTranslation();
+
+    const handleConfirmModalConfirm = () => {
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "TabNavigator",
+                },
+            ]
+        });
+    }
+
+    return (
+        <View style={styles.container}>
+            <View style={styles.header}>
+                <GoHomeButton navigation={navigation} onPress={setIsConfirmModalVisible}/>
+                <Text style={styles.codeQuizText}>ID QUIZZ : {runId}</Text>
+            </View>
+            <View style={styles.questionAndScoreContainer}>
+                <View style={styles.InformationsContainer}>
+                    <Text style={TextsStyles.titleText}>{t("app.screens.question.question")}</Text>
+                    <Text style={TextsStyles.titleText}>{actualQuestion ? actualQuestion.order + 1 :"?"}/{quizInformations ? quizInformations.questionCount : "?"}</Text>
+                </View>
+                <View style={styles.InformationsContainer}>
+                    <Text style={TextsStyles.titleText}>{t("app.screens.question.score")}</Text>
+                    <Text style={TextsStyles.titleText}>{score}/{quizInformations ? quizInformations.questionCount : "?"}</Text>
+                </View>
+            </View>
+            <View style={styles.QuizQuestionContainer}>
+                <Text style={TextsStyles.subtitleText}>{actualQuestion ? actualQuestion.text : "Loading..."}</Text>
+            </View>
+            <ConfirmModal visible={isConfirmModalVisible} onClose={()=>setIsConfirmModalVisible(false)} onConfirm={handleConfirmModalConfirm}/>
+
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        marginHorizontal: '5%',
+    },
+    questionAndScoreContainer: {
+        display: 'flex',
+        flexDirection: 'row',
+        justifyContent: 'space-around',
+        alignItems: 'center',
+        marginVertical: '2%',
+    },
+    InformationsContainer: {
+        display: 'flex',
+        flexDirection: 'column',
+        justifyContent: 'center',
+        alignItems: 'center',
+        gap: '5%',
+    },
+    QuizNumContainer: {
+    },
+    QuizQuestionContainer: {
+        marginVertical: "2.5%",
+    },
+    infoQuizContainer: {
+        marginBottom: '5%',
+    },
+    codeQuizText: {
+        fontSize: 18,
+        color: '#000000',
+    },
+    header: {
+        display: "flex",
+        flexDirection: "row",
+        justifyContent: "flex-start",
+        gap: '5%',
+    }
+});
\ No newline at end of file
-- 
GitLab


From d40bcad4226b58b168c6e1cfee301240e9a6fce5 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 18:31:40 +0100
Subject: [PATCH 253/283] fix: shuffle import

---
 screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx | 26 +++-----------------
 screens/PlayingQuiz/PlayingQuiz.tsx          |  4 +--
 2 files changed, 6 insertions(+), 24 deletions(-)

diff --git a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
index a9059f6..6e11276 100644
--- a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
@@ -16,30 +16,12 @@ interface Props {
 
 export default function EndQuizChild({ navigation, quizInformations, score }: Props) {
 
-    const {restartQuiz, remainingQuiz} = useQuizService()
+    const {restartQuiz, remainingQuiz, createRun} = useQuizService()
 
     const handleRestartPress = async () => {
-        const isRestarted = await restartQuiz(quiz.id);
-        if(HttpError.isHttpError(isRestarted)){
-            return
-        }
-        if(!isRestarted) {
-            return;
-        }
-        const quizRestarted = await remainingQuiz(quiz.id);
-        if(HttpError.isHttpError(quizRestarted)){
-            return
-        }
-
-        navigation.reset({
-            index: 0,
-            routes: [
-                {
-                    name: "PlayingQuiz",
-                    params: {quizRecovered: quizRestarted},
-                },
-            ]
-        });
+        const quizId = quizInformations.id.toString();
+        const runId = await createRun(quizId);
+        navigation.navigate('PlayingQuiz', {runId: runId, quizId: quizId});
     };
 
     const handleBackToMenu = () => {
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 6b2dd76..123586d 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -7,7 +7,7 @@ import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
 import {Question} from "../../models/Question";
 import PlayingQuizBody from "./PlayingQuizBody";
-import { shuffleAnswers } from "../../helper/QuizHelper";
+import { shuffleAnswersOfQuiz } from "../../helper/QuizHelper";
 
 
 type RoutePropsType = {
@@ -105,7 +105,7 @@ export default function PlayingQuiz({route, navigation}:Props) {
                 name: "Astronomie"
             }
         };
-        const actualQuestionFetchedShuffle = shuffleAnswers(actualQuestionFetched);
+        const actualQuestionFetchedShuffle = shuffleAnswersOfQuiz(actualQuestionFetched);
         setActualQuestion(actualQuestionFetchedShuffle);
     }
 
-- 
GitLab


From e899008d1659df4665588ea67751701b5eab0d93 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Sun, 12 Jan 2025 18:40:42 +0100
Subject: [PATCH 254/283] feat: restart quiz at the end

---
 screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx |  2 +-
 screens/PlayingQuiz/PlayingQuiz.tsx          | 79 ++------------------
 2 files changed, 9 insertions(+), 72 deletions(-)

diff --git a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
index 6e11276..767dce5 100644
--- a/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
+++ b/screens/PlayingQuiz/EndQuiz/EndQuizChild.tsx
@@ -37,7 +37,7 @@ export default function EndQuizChild({ navigation, quizInformations, score }: Pr
                 <Text style={styles.TextBodyTitle}>{((score/quizInformations.questionCount)*100 > 50 ) ? 'Victory' : 'Defeat'}</Text>
                 <Text style={styles.TextBody}>you finish the test with a score of {`${score}/${quizInformations.questionCount}`} ! </Text>
                 <Image source={require('../../../assets/uWin.png')} />
-                {/*<DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>*/}
+                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
             </View>
         </View>
diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 123586d..50ca0a4 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -30,81 +30,18 @@ export default function PlayingQuiz({route, navigation}:Props) {
     const [score, setScore] = useState(0);
 
     const fetchQuizInformations = async () => {
-        // const quizInformationsFetched = await getQuizInformations(quizId);
-        // if (HttpError.isHttpError(quizInformationsFetched)) {
-        //     return;
-        // }
-        const quizInformationsFetched: QuizInformations = {
-            id: 1,
-            name: "Quiz de Test",
-            description: "Ceci est un quiz de test pour vérifier l'interface.",
-            isCommunity: true,
-            questionCount: 10,
-            categoryId: 2,
-            difficultyId: 3,
-            authorId: {
-                id: 42,
-                username: "TestAuthor",
-                email: "testauthor@example.com"
-            },
-            createdAt: "2025-01-10T10:00:00Z",
-            updatedAt: "2025-01-11T12:00:00Z",
-            category: {
-                id: 2,
-                name: "Science"
-            },
-            difficulty: {
-                id: 3,
-                name: "Moyenne"
-            }
-        };
-        
+        const quizInformationsFetched = await getQuizInformations(quizId);
+        if (HttpError.isHttpError(quizInformationsFetched)) {
+            return;
+        }        
         setQuizInformations(quizInformationsFetched);
     }
 
     const fetchActualQuestion = async () => {
-        // const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
-        // if (HttpError.isHttpError(actualQuestionFetched)) {
-        //     return;
-        // }
-        const actualQuestionFetched: Question = {
-            id: 1,
-            text: "Quelle image correspond à une étoile ?",
-            type: "imae",
-            categoryId: 2,
-            quizId: "quiz123",
-            order: 1,
-            answers: [
-                {
-                    id: 1,
-                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-                    isCorrect: true,
-                    questionId: 1
-                },
-                {
-                    id: 2,
-                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-                    isCorrect: false,
-                    questionId: 1
-                },
-                {
-                    id: 3,
-                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-                    isCorrect: false,
-                    questionId: 1
-                },
-                {
-                    id: 4,
-                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-                    isCorrect: false,
-                    questionId: 1
-                }
-            ],
-            category: {
-                id: 2,
-                name: "Astronomie"
-            }
-        };
+        const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
+        if (HttpError.isHttpError(actualQuestionFetched)) {
+            return;
+        }
         const actualQuestionFetchedShuffle = shuffleAnswersOfQuiz(actualQuestionFetched);
         setActualQuestion(actualQuestionFetchedShuffle);
     }
-- 
GitLab


From 7a2795fa95ddd3ccdcae3057badbf3c1c77d8f8e Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 12 Jan 2025 18:58:41 +0100
Subject: [PATCH 255/283] feat: new model

---
 models/{ => Response}/QuestionResponse.ts  | 2 +-
 models/Response/RunsInformationResponse.ts | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)
 rename models/{ => Response}/QuestionResponse.ts (62%)
 create mode 100644 models/Response/RunsInformationResponse.ts

diff --git a/models/QuestionResponse.ts b/models/Response/QuestionResponse.ts
similarity index 62%
rename from models/QuestionResponse.ts
rename to models/Response/QuestionResponse.ts
index 4e1cee6..ccfd9ab 100644
--- a/models/QuestionResponse.ts
+++ b/models/Response/QuestionResponse.ts
@@ -1,4 +1,4 @@
-import {Question} from "./Question";
+import {Question} from "../Question";
 
 export interface QuestionResponse {
     question: Question;
diff --git a/models/Response/RunsInformationResponse.ts b/models/Response/RunsInformationResponse.ts
new file mode 100644
index 0000000..a02f92a
--- /dev/null
+++ b/models/Response/RunsInformationResponse.ts
@@ -0,0 +1,5 @@
+import {RunInformations} from "../RunInformations";
+
+export interface RunsInformationResponse {
+    runs: RunInformations[];
+}
\ No newline at end of file
-- 
GitLab


From 702bf2618cd5bdf0ad758976625623a53a1cfbbe Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 12 Jan 2025 18:58:46 +0100
Subject: [PATCH 256/283] feat: new model

---
 models/{ => Response}/AnswerResponse.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
 rename models/{ => Response}/AnswerResponse.ts (79%)

diff --git a/models/AnswerResponse.ts b/models/Response/AnswerResponse.ts
similarity index 79%
rename from models/AnswerResponse.ts
rename to models/Response/AnswerResponse.ts
index 24a83f1..ab22c33 100644
--- a/models/AnswerResponse.ts
+++ b/models/Response/AnswerResponse.ts
@@ -1,5 +1,5 @@
-import {Answer} from "./Answer";
-import {Category} from "./Quiz";
+import {Answer} from "../Answer";
+import {Category} from "../Quiz";
 
 export interface AnswerResponse {
     score: number;
-- 
GitLab


From 260c2c0b41d6adc1e8c026a5acf3786cfd9106d4 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 12 Jan 2025 18:59:19 +0100
Subject: [PATCH 257/283] feat: My quizzes

---
 components/PlayQuiz/RunStartedList.tsx        | 134 ++++++++++++++++++
 screens/Home/MyQuizzes/InformationsOfRuns.tsx | 124 ++++++++++++++++
 screens/Home/MyQuizzes/MyQuizzes.tsx          |  29 +++-
 templates/TemplateRunList.tsx                 |  70 +++++++++
 4 files changed, 352 insertions(+), 5 deletions(-)
 create mode 100644 components/PlayQuiz/RunStartedList.tsx
 create mode 100644 screens/Home/MyQuizzes/InformationsOfRuns.tsx
 create mode 100644 templates/TemplateRunList.tsx

diff --git a/components/PlayQuiz/RunStartedList.tsx b/components/PlayQuiz/RunStartedList.tsx
new file mode 100644
index 0000000..6a7da51
--- /dev/null
+++ b/components/PlayQuiz/RunStartedList.tsx
@@ -0,0 +1,134 @@
+import React from "react";
+import { FlatList, View, Text, StyleSheet, TouchableOpacity, ActivityIndicator } from "react-native";
+import {Quiz} from "../../models/Quiz";
+import { NavigationProp } from "@react-navigation/native";
+import {RunInformations} from "../../models/RunInformations";
+
+
+
+/**
+ * QuizList : Un composant affichant une liste de quiz avec leur titre, nombre de questions, et catégorie.
+ *
+ * @component
+ *
+ * @param navigation - Propriété de navigation utilisée pour naviguer vers l'écran "InformationsOfQuiz".
+ * @param quizList - Liste des quiz à afficher. Peut être null ou undefined.
+ * @param isLoadingData - Boolean indiquant si les données sont en cours de chargement.
+ *
+ * @example
+ * <QuizList
+ *     navigation={navigation}
+ *     quizList={quizzes}
+ *     isLoadingData={isLoading}
+ * />
+ *
+ * @description
+ * - Ce composant gère trois états :
+ *   1. Chargement : Affiche un spinner si `isLoadingData` est true.
+ *   2. Liste des quiz : Affiche une liste interactive des quiz si `quizList` contient des éléments.
+ *   3. Liste vide : Affiche un message si `quizList` est vide.
+ *
+ * - Chaque quiz affiche :
+ *   - Son code en tant que titre.
+ *   - Son nombre total de questions.
+ *   - Sa catégorie, affichée en majuscules.
+ *
+ * @returns Un composant React contenant une liste interactive de quiz ou des messages en fonction de l'état.
+ */
+interface Props {
+    runList: RunInformations[] | undefined;
+    onRunPressed:(runInfo: RunInformations) => void;
+    isLoadingData: boolean;
+}
+export default function RunStartedList({ runList, isLoadingData, onRunPressed }: Props) {
+    const renderQuizItem = ({ item }: { item: RunInformations }) => (
+        <TouchableOpacity style={styles.quizItem} onPress={() => onRunPressed(item)}>
+            <Text style={styles.quizTitle}>{item.id}</Text>
+            <Text style={styles.quizDetails}>
+                {item.score}
+            </Text>
+        </TouchableOpacity>
+    );
+
+    return (
+        <View style={styles.container}>
+            {isLoadingData ? (
+                <View style={styles.loadingContainer}>
+                    <ActivityIndicator size="large" color="#2b73fe" />
+                    <Text style={styles.loadingText}>Loading quizzes...</Text>
+                </View>
+            ) : runList && runList.length > 0 ? (
+                <FlatList
+                    data={runList}
+                    renderItem={renderQuizItem}
+                    keyExtractor={(item) => item.id}
+                    showsVerticalScrollIndicator={true}
+                    contentContainerStyle={styles.listContent}
+                />
+            ) : (
+                <Text style={styles.emptyMessage}>No quizzes available.</Text>
+            )}
+        </View>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        backgroundColor: "white",
+        padding: 10,
+        borderRadius: 10,
+        borderColor: "#fafafa",
+        borderWidth: 3,
+        elevation: 5, // Ombre pour Android
+        shadowColor: "#000", // Ombre pour iOS
+        shadowOffset: { width: 0, height: 4 },
+        shadowOpacity: 0.25,
+        shadowRadius: 3.84,
+        width: "100%", // Assurez-vous que le conteneur occupe toute la largeur
+    },
+    listContent: {
+    },
+    quizItem: {
+        backgroundColor: "#f3f3f3",
+        padding: 15,
+        borderRadius: 10,
+        marginVertical: 5,
+        elevation: 3, // Ombre pour Android
+        shadowColor: "#000", // Ombre pour iOS
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.2,
+        shadowRadius: 2,
+        width: "100%",
+        alignSelf: "center", // Centre les éléments dans leur conteneur
+    },
+    quizTitle: {
+        fontSize: 22,
+        fontWeight: "bold",
+        color: "#000",
+        marginBottom: 5,
+        textAlign: "center",
+    },
+    quizDetails: {
+        fontSize: 18,
+        color: "#555",
+        textAlign: "center",
+    },
+    emptyMessage: {
+        fontSize: 18,
+        color: "#888",
+        textAlign: "center",
+        marginTop: 20,
+    },
+    loadingContainer: {
+        flex: 1,
+        justifyContent: "center",
+        alignItems: "center",
+    },
+    loadingText: {
+        fontSize: 16,
+        color: "#555",
+        marginTop: 10,
+        textAlign: "center",
+    },
+});
diff --git a/screens/Home/MyQuizzes/InformationsOfRuns.tsx b/screens/Home/MyQuizzes/InformationsOfRuns.tsx
new file mode 100644
index 0000000..5ca934b
--- /dev/null
+++ b/screens/Home/MyQuizzes/InformationsOfRuns.tsx
@@ -0,0 +1,124 @@
+import React, {useEffect, useState} from "react";
+import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import TemplateMenu from "../../../templates/TemplateMenu";
+import {NavigationProp, RouteProp} from "@react-navigation/native";
+import {Quiz} from "../../../models/Quiz";
+import {RunInformations} from "../../../models/RunInformations";
+import {QuizInformations} from "../../../models/QuizInformations";
+import HttpError from "../../../services/HttpError";
+import {useQuizService} from "../../../services/QuizService";
+
+type RoutePropsType = {
+    InformationsOfRuns: {
+        runInformations: RunInformations;
+    };
+};
+interface Props {
+    navigation: NavigationProp<any>;
+    route: RouteProp<RoutePropsType, "InformationsOfRuns">;
+}
+
+export default function InformationsOfRuns({ navigation, route }: Props) {
+    const { runInformations,  } = route.params;
+    const {getQuizInformations} = useQuizService();
+    const [quizInformations, setQuizInformations] = useState<QuizInformations>();
+
+    const fetchQuizInformations = async () => {
+        const quizInformations = await getQuizInformations(runInformations.quizId);
+        if (quizInformations instanceof HttpError) {
+            return;
+        }
+        setQuizInformations(quizInformations);
+    }
+
+    useEffect(() => {
+        fetchQuizInformations();
+    }, []);
+
+    const onPlay = () => {
+        navigation.reset({
+            index: 0,
+            routes: [
+                {
+                    name: "PlayingQuiz",
+                    params: {runId: runInformations?.id, quizId: runInformations?.quizId },
+                },
+            ]
+        });
+    }
+
+    return (
+        <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
+            <View style={styles.container}>
+                <Text style={styles.quizTitle}>{quizInformations ? quizInformations.name : "Loading..."}</Text>
+                <Text style={styles.quizDescription}>{quizInformations ? quizInformations.description :"Loading..."}</Text>
+
+                <View style={styles.aboutContainer}>
+                    <Text style={styles.aboutTitle}>About this quiz :</Text>
+                    <Text style={styles.aboutDetails}>{runInformations.questionIndex}/{quizInformations ? quizInformations.questionCount : "Loading..."} questions, {quizInformations ? quizInformations.difficulty.name : "Loading..."}</Text>
+                    <Text style={styles.aboutDetails}>By : {quizInformations?.authorId && "Unknown"}</Text>
+                </View>
+
+                <TouchableOpacity style={styles.playButton} onPress={onPlay}>
+                    <Text style={styles.playButtonText}>PLAY</Text>
+                </TouchableOpacity>
+            </View>
+        </TemplateMenu>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        paddingHorizontal: 20,
+        paddingVertical: 20,
+        justifyContent: "flex-start",
+    },
+    quizTitle: {
+        fontSize: 24,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+    },
+    quizDescription: {
+        fontSize: 16,
+        color: "#555",
+        marginBottom: 20,
+        height: "15%",
+    },
+    aboutContainer: {
+        height: "50%",
+        backgroundColor: "white",
+        borderRadius: 10,
+        padding: 15,
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: 2 },
+        shadowOpacity: 0.2,
+        shadowRadius: 3,
+        elevation: 5,
+    },
+    aboutTitle: {
+        fontSize: 18,
+        fontWeight: "bold",
+        marginBottom: 10,
+        color: "#000",
+    },
+    aboutDetails: {
+        fontSize: 16,
+        color: "#555",
+        marginBottom: 10,
+    },
+    playButton: {
+        backgroundColor: "#007BFF",
+        paddingVertical: 15,
+        borderRadius: 10,
+        alignItems: "center",
+        justifyContent: "center",
+        marginTop: 20,
+    },
+    playButtonText: {
+        fontSize: 18,
+        fontWeight: "bold",
+        color: "white",
+    },
+});
diff --git a/screens/Home/MyQuizzes/MyQuizzes.tsx b/screens/Home/MyQuizzes/MyQuizzes.tsx
index 66004ca..1e5ce51 100644
--- a/screens/Home/MyQuizzes/MyQuizzes.tsx
+++ b/screens/Home/MyQuizzes/MyQuizzes.tsx
@@ -1,17 +1,36 @@
-import TemplateQuizList from "../../../templates/TemplateQuizList";
 import {NavigationProp} from "@react-navigation/native";
-import {useState} from "react";
-import {Quiz} from "../../../models/Quiz";
+import React, {useEffect, useState} from "react";
+import TemplateRunList from "../../../templates/TemplateRunList";
+import {RunInformations} from "../../../models/RunInformations";
+import {useQuizService} from "../../../services/QuizService";
+import HttpError from "../../../services/HttpError";
 
 interface Props {
     navigation: NavigationProp<any>
 }
 export default function MyQuizzes({navigation}: Props) {
-    const [quizList, setQuizList] = useState<Quiz[] | null>([]);
+    const [runList, setRunList] = useState<RunInformations[] | undefined>(undefined)
     const [input, setInput] = useState<string>("")
+    const {getAllRuns} = useQuizService();
 
+    const getRuns = async () => {
+        const runs = await getAllRuns();
+        if(HttpError.isHttpError(runs)) {
+            console.log("Error while getting runs:", runs);
+            return
+        }
+        setRunList(runs);
+    }
+
+    useEffect(() => {
+        getRuns();
+    },[]);
+
+    const onQuizPressed = (runInfo: RunInformations) => {
+        navigation.navigate("InformationsOfRuns", { runInformations: runInfo });
+    };
 
     return (
-        <TemplateQuizList title={"My quizzes"} setTextInInput={setInput} quizList={quizList} navigation={navigation} buttonGoBack={true} isLoadingData={false}/>
+        <TemplateRunList title={"My quizzes"} setTextInInput={setInput} runList={runList} navigation={navigation} buttonGoBack={true} isLoadingData={false} onRunPressed={onQuizPressed}/>
     );
 }
\ No newline at end of file
diff --git a/templates/TemplateRunList.tsx b/templates/TemplateRunList.tsx
new file mode 100644
index 0000000..20125c1
--- /dev/null
+++ b/templates/TemplateRunList.tsx
@@ -0,0 +1,70 @@
+import React from "react";
+import {View, Text, StyleSheet} from "react-native";
+import TemplateMenu from "./TemplateMenu";
+import {NavigationProp} from "@react-navigation/native";
+import InputPlayQuiz from "../components/PlayQuiz/InputPlayQuiz";
+import QuizList from "../components/lists/QuizList";
+import {Quiz} from "../models/Quiz";
+import RunStartedList from "../components/PlayQuiz/RunStartedList";
+import {RunInformations} from "../models/RunInformations";
+
+
+/**
+ * TemplateQuizList : Un composant principal pour afficher une liste de quiz.
+ * Il inclut un menu, un titre, un champ d'entrée pour les recherches et une liste de quiz.
+ *
+ * @param navigation - L'objet de navigation pour naviguer entre les écrans
+ * @param title - Le titre affiché en haut de la liste
+ * @param setTextInInput - Fonction pour gérer les modifications dans le champ d'entrée
+ * @param quizList - La liste des quiz à afficher
+ * @param buttonGoBack - boolean qui dit si le bouton de retour doit être affiché
+ */
+
+interface Props {
+    navigation: NavigationProp<any>
+    title: string
+    setTextInInput: (text: string) => void
+    runList: RunInformations[] | undefined
+    buttonGoBack: boolean
+    isLoadingData: boolean
+    nextPage?: () => void;
+    onRunPressed:(runInfo: RunInformations) => void;
+}
+
+export default function TemplateRunList({navigation, title, setTextInInput, runList, buttonGoBack, isLoadingData, onRunPressed }: Props) {
+    return (
+        <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={buttonGoBack}>
+            <View style={styles.globalContainer}>
+                <Text style={styles.title}>{title}</Text>
+                <View style={styles.contentContainer}>
+                    <RunStartedList runList={runList} isLoadingData={isLoadingData} onRunPressed={onRunPressed}/>
+                </View>
+            </View>
+        </TemplateMenu>
+    );
+}
+
+const styles = StyleSheet.create({
+    globalContainer: {
+        display: "flex",
+        height: "100%",
+        width: "100%",
+        paddingHorizontal: "3%", // Ajoute une marge de 5% à gauche et à droite
+        alignItems: "center", // Centre tous les enfants horizontalement
+    },
+    title: {
+        fontSize: 40,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+        alignSelf: "center", // Centre uniquement le titre
+    },
+    contentContainer: {
+        display: "flex",
+        flexDirection: "column",
+        width: "100%", // Utilise tout l'espace restant à l'intérieur de `globalContainer`
+        height: "75%",
+        alignItems: "center", // Centre tous les enfants horizontalement
+        gap: "2%",
+    },
+});
-- 
GitLab


From d4ae1c4a6fade65b2e42c7197f6194740ccbfe00 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 12 Jan 2025 18:59:30 +0100
Subject: [PATCH 258/283] feat: new services

---
 screens/Home/HomeChild.tsx |  2 +-
 services/QuizService.ts    | 82 ++++++++++++++++++++++++--------------
 2 files changed, 52 insertions(+), 32 deletions(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 85120e4..9532c96 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -55,7 +55,7 @@ export default function HomeChild({navigation}: Props) {
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
                 <MenuButton text={"PLAY"} handleButtonPressed={handleButtonGeneratePressed}/>
-                {/*<MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>*/}
+                <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
             </View>
              <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
         </View>
diff --git a/services/QuizService.ts b/services/QuizService.ts
index a243443..07b74d9 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -2,13 +2,13 @@ import HttpError from "./HttpError";
 import {Quiz} from "../models/Quiz";
 import axios from "axios";
 import {Answer} from "../models/Answer";
-import {shuffleAnswersOfQuiz} from "../helper/QuizHelper";
 import {Question} from "../models/Question";
-import {AnswerResponse} from "../models/AnswerResponse";
+import {AnswerResponse} from "../models/Response/AnswerResponse";
 import {QuizInformations} from "../models/QuizInformations";
-import {QuestionResponse} from "../models/QuestionResponse";
+import {QuestionResponse} from "../models/Response/QuestionResponse";
 import {QuizGenerateAnswer} from "../models/QuizGenerateAnswer";
 import {RunInformations} from "../models/RunInformations";
+import {RunsInformationResponse} from "../models/Response/RunsInformationResponse";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -117,32 +117,32 @@ export const useQuizService =  () => {
         }
     };
 
-    const remainingQuiz = async (id: string): Promise<Quiz | HttpError> => {
-        const requestBody = {
-            id,
-        };
-
-        try {
-            const response = await axios.post<Quiz>(`${url}/quiz/remaining`, requestBody, {
-                headers: {
-                    "Content-Type": "application/json",
-                },
-            });
-
-            // Récupération des données retournées par l'API
-            return shuffleAnswersOfQuiz(response.data);
-        } catch (error: any) {
-            console.log("Error while remaining quiz:", error);
-
-            if (error.response) {
-                // Gestion des erreurs HTTP
-                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
-            } else {
-                // Gestion des erreurs réseau ou autres
-                return new HttpError(500, "Unexpected error: " + error.message);
-            }
-        }
-    };
+    // const remainingQuiz = async (id: string): Promise<Quiz | HttpError> => {
+    //     const requestBody = {
+    //         id,
+    //     };
+    //
+    //     try {
+    //         const response = await axios.post<Quiz>(`${url}/quiz/remaining`, requestBody, {
+    //             headers: {
+    //                 "Content-Type": "application/json",
+    //             },
+    //         });
+    //
+    //         // Récupération des données retournées par l'API
+    //         return shuffleAnswersOfQuiz(response.data);
+    //     } catch (error: any) {
+    //         console.log("Error while remaining quiz:", error);
+    //
+    //         if (error.response) {
+    //             // Gestion des erreurs HTTP
+    //             return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+    //         } else {
+    //             // Gestion des erreurs réseau ou autres
+    //             return new HttpError(500, "Unexpected error: " + error.message);
+    //         }
+    //     }
+    // };
 
     const getAnswerQuiz = async (
         codeQuiz: string,
@@ -285,12 +285,31 @@ export const useQuizService =  () => {
         }
     }
 
+    const getAllRuns = async (): Promise<RunInformations[] | HttpError> => {
+        try {
+            const response = await axios.get<RunsInformationResponse>(`${url}/run/userRuns`, {
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            });
+
+            return response.data.runs;
+        } catch (error: any) {
+            console.log("Error while getAllRuns:", error);
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
+
 
 
     return {
         generateQuiz: generateQuiz,
         getAnswerQuiz: getAnswerQuiz,
-        remainingQuiz: remainingQuiz,
+        // remainingQuiz: remainingQuiz,
         getRandomQuiz: getRandomQuiz,
         getCommunityQuiz: getCommunityQuiz,
         restartQuiz: restartQuiz,
@@ -298,6 +317,7 @@ export const useQuizService =  () => {
         answerQuestion: answerQuestion,
         getActualQuestionOfAQuiz: getActualQuestionOfAQuiz,
         getQuizInformations: getQuizInformations,
-        getRunsInfo: getRunsInfo
+        getRunsInfo: getRunsInfo,
+        getAllRuns: getAllRuns
     }
 }
\ No newline at end of file
-- 
GitLab


From 3ec74ecbf6d2f4c22bb5316beeead3e11452a9ba Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Sun, 12 Jan 2025 18:59:56 +0100
Subject: [PATCH 259/283] feat: navigator

---
 routes/StackNavigator.tsx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 377abc3..86ab70b 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -14,6 +14,7 @@ import PlayQuiz from "../screens/Home/PlayQuiz/PlayQuiz";
 import MyQuizzes from "../screens/Home/MyQuizzes/MyQuizzes";
 import InformationsOfQuiz from "../screens/Community/InformationsOfQuiz/InformationsOfQuiz";
 import MultiInformationsOfQuiz from "../screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz";
+import InformationsOfRuns from "../screens/Home/MyQuizzes/InformationsOfRuns";
 
 const Stack = createNativeStackNavigator();
 
@@ -29,6 +30,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="EndQuiz" component={EndQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="MyQuizzes" component={MyQuizzes} options={{ headerShown: false }}/>
                 <Stack.Screen name="InformationsOfQuiz" component={InformationsOfQuiz} options={{ headerShown: false }}/>
+                <Stack.Screen name="InformationsOfRuns" component={InformationsOfRuns} options={{ headerShown: false }}/>
 
                 <Stack.Screen name="Multiplayer" component={Multiplayer} options={{ headerShown: false }}/>
                 <Stack.Screen name="MultiplayerCommunity" component={MultiplayerCommunity} options={{ headerShown: false }}/>
-- 
GitLab


From 646d6dfff279ade7c9a768daa0727cb8ca20accf Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 13 Jan 2025 02:40:45 +0100
Subject: [PATCH 260/283] feat: play game with websockets

---
 components/Multiplayer/ModalInvitePlayer.tsx  |   7 +-
 models/Response/AnswerWsResponse.ts           |   5 +
 routes/StackNavigator.tsx                     |   3 +-
 screens/Multiplayer/Lobby/Lobby.tsx           |  69 +++++++--
 .../PlayingQuizMultiMode.tsx                  | 134 ++++++------------
 .../PlayingQuizMultiModeBody.tsx              |  95 +++++++------
 .../PlayingQuizMultiModeHeader.tsx            |   8 +-
 .../MultiInformationsOfQuiz.tsx               |   2 +-
 .../OnlineQuiz/OnlineCreateLobby.tsx          |   3 +-
 .../Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx |  47 +++---
 .../OnlineQuiz/OnlineSelectMode.tsx           |   2 +-
 screens/PlayingQuiz/PlayingQuizHeader.tsx     |   2 +-
 12 files changed, 192 insertions(+), 185 deletions(-)
 create mode 100644 models/Response/AnswerWsResponse.ts

diff --git a/components/Multiplayer/ModalInvitePlayer.tsx b/components/Multiplayer/ModalInvitePlayer.tsx
index dbf2294..2c5fab8 100644
--- a/components/Multiplayer/ModalInvitePlayer.tsx
+++ b/components/Multiplayer/ModalInvitePlayer.tsx
@@ -4,9 +4,10 @@ import WhiteButton from "../buttons/WhiteButton";
 interface Props {
     showModal: boolean;
     onClosePressed: () => void;
+    roomId: string;
 }
 
-export default function ModalInvitePlayer({showModal, onClosePressed,}: Props) {
+export default function ModalInvitePlayer({showModal, onClosePressed, roomId}: Props) {
     return (
         <Modal visible={showModal} animationType="slide" transparent={true}>
             <View style={styles.centeredView}>
@@ -14,7 +15,7 @@ export default function ModalInvitePlayer({showModal, onClosePressed,}: Props) {
                     <Text style={styles.title}>JOIN</Text>
                     <Image source={require('../../assets/favicon.png')}/>
                     <Text style={styles.or}>OR</Text>
-                    <Text style={styles.link}>https://klebert-host.com/join_quiz/6975</Text>
+                    <Text style={styles.link}>Room ID: {roomId}</Text>
                     <View style={styles.buttonGroup}>
                         <WhiteButton text="CLOSE" onPress={onClosePressed} isDisabled={false}/>
                     </View>
@@ -68,5 +69,7 @@ const styles = StyleSheet.create({
     },
     link: {
         color: '#0000EE',
+        fontSize: 22,
+        fontWeight: "bold",
     }
 });
\ No newline at end of file
diff --git a/models/Response/AnswerWsResponse.ts b/models/Response/AnswerWsResponse.ts
new file mode 100644
index 0000000..41d72db
--- /dev/null
+++ b/models/Response/AnswerWsResponse.ts
@@ -0,0 +1,5 @@
+import {Answer} from "../Answer";
+
+export interface AnswerWsResponse {
+    answers: Answer[];
+}
\ No newline at end of file
diff --git a/routes/StackNavigator.tsx b/routes/StackNavigator.tsx
index 86ab70b..58dd246 100644
--- a/routes/StackNavigator.tsx
+++ b/routes/StackNavigator.tsx
@@ -15,6 +15,7 @@ import MyQuizzes from "../screens/Home/MyQuizzes/MyQuizzes";
 import InformationsOfQuiz from "../screens/Community/InformationsOfQuiz/InformationsOfQuiz";
 import MultiInformationsOfQuiz from "../screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz";
 import InformationsOfRuns from "../screens/Home/MyQuizzes/InformationsOfRuns";
+import PlayingQuizMultiMode from "../screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode";
 
 const Stack = createNativeStackNavigator();
 
@@ -31,7 +32,7 @@ export default function StackNavigator() {
                 <Stack.Screen name="MyQuizzes" component={MyQuizzes} options={{ headerShown: false }}/>
                 <Stack.Screen name="InformationsOfQuiz" component={InformationsOfQuiz} options={{ headerShown: false }}/>
                 <Stack.Screen name="InformationsOfRuns" component={InformationsOfRuns} options={{ headerShown: false }}/>
-
+                <Stack.Screen name="PlayingQuizMultiMode" component={PlayingQuizMultiMode} options={{ headerShown: false }}/>
                 <Stack.Screen name="Multiplayer" component={Multiplayer} options={{ headerShown: false }}/>
                 <Stack.Screen name="MultiplayerCommunity" component={MultiplayerCommunity} options={{ headerShown: false }}/>
                 <Stack.Screen name="OnlineQuiz" component={OnlineQuiz} options={{ headerShown: false }}/>
diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index c5a24eb..bdcdb42 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -18,19 +18,24 @@ interface Props {
 
 type RoutePropsType = {
     Lobby: {
-        runId: string;
+        quizIdOrRoomId: string;
         nbPlayers: number;
+        isHost: boolean;
     };
 };
 
+
+
 export default function Lobby({navigation, route}: Props) {
-    const { runId, nbPlayers} = route.params;
+    const { quizIdOrRoomId, nbPlayers, isHost} = route.params;
 
-    const [isHost, setIsHost] = useState<boolean>(true);
+    // const [isHost, setIsHost] = useState<boolean>(true);
     const [showModal, setShowModal] = useState<boolean>(false);
     const [players, setPlayers] = useState<User[]>([{ id: 0, username: 'Invite', email: 'invite@email.com'}]);
     const {getCookie} = useCookie('access_token');
     const [socket, setSocket] = useState<Socket | null>(null);
+    const [roomId, setRoomId] = useState<string>("");
+    const [runId, setRunId] = useState<string>("");
 
     const userInvite = { id: 0, username: 'Invite', email: 'invite@email.com'}
     const initSocket = async () => {
@@ -43,11 +48,39 @@ export default function Lobby({navigation, route}: Props) {
         });
 
         setSocket(newSocket);
+        console.log(isHost);
 
-        newSocket.on("connect", () => {
-            console.log("Connected to the socket server id :",runId);
-            newSocket.emit("joinRoom", { roomId: runId });
-        });
+        if(isHost) {
+            newSocket.on("roomCreated", (data) => {
+                console.log("Room created : ", data.id);
+                console.log("Connected to the server");
+
+                setRoomId(data.id);
+                console.log("Host id room : ", data.id);
+                newSocket.emit("joinRoom", { roomId: data.id });
+
+                setTimeout(() => {
+                    console.log("Sending generateRun");
+                    newSocket.emit("generateRun");
+                },1000);
+            });
+
+            newSocket.on("connect", () => {
+                newSocket.emit("createRoom", { quizId: quizIdOrRoomId });
+            });
+            console.log("Host");
+
+        }
+        else {
+            console.log("pas Host id room : ", quizIdOrRoomId);
+            newSocket.emit("joinRoom", { roomId: quizIdOrRoomId });
+
+            setTimeout(() => {
+                console.log("Sending generateRun");
+                newSocket.emit("generateRun");
+            },1000);
+
+        }
 
         newSocket.on("connect_error", (err) => {
             console.error("Connection error: ", err.message);
@@ -63,16 +96,22 @@ export default function Lobby({navigation, route}: Props) {
             setPlayers([userInvite, ...data]);
         });
 
-        // Nettoyez la connexion lorsque le composant est démonté
-        return () => {
-            newSocket.disconnect();
-            setSocket(null);
-        };
+        newSocket.on("runId", (data) => {
+            console.log("Run ID:", data);
+            setRunId(data);
+        });
     }
 
+
+
     useEffect(() => {
         initSocket();
-    }, [runId]);
+        // return () => {
+        //     if(socket === null) return;
+        //     socket.disconnect();
+        //     setSocket(null);
+        // };
+    }, []);
 
     const item = ({ item }: { item: User }) => {
         return (
@@ -101,7 +140,7 @@ export default function Lobby({navigation, route}: Props) {
     };
 
     const onPlayPressed = () => {
-        navigation.navigate("PlayingQuiz", {quizId: 1});//TODO : changer le quizId
+        navigation.navigate("PlayingQuizMultiMode", {runId: runId, socket: socket, roomId: roomId});
     };
 
     const onCancelPressed = () => {
@@ -142,7 +181,7 @@ export default function Lobby({navigation, route}: Props) {
                     }
                 </View>
             </TemplateMenu>
-            <ModalInvitePlayer showModal={showModal} onClosePressed={() => setShowModal(false)}/>
+            <ModalInvitePlayer showModal={showModal} onClosePressed={() => setShowModal(false)} roomId={roomId} />
         </View>
     )
 }
diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx
index e2e6bfc..78c1760 100644
--- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx
+++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx
@@ -3,124 +3,82 @@ import {useQuizService} from "../../../../services/QuizService";
 import React, {useEffect, useState} from "react";
 import {QuizInformations} from "../../../../models/QuizInformations";
 import {Question} from "../../../../models/Question";
-import {shuffleAnswers} from "../../../../helper/QuizHelper";
 import TemplateDuo from "../../../../templates/TemplateDuo";
 import HttpError from "../../../../services/HttpError";
 import PlayingQuizMultiModeHeader from "./PlayingQuizMultiModeHeader";
 import PlayingQuizMultiModeBody from "./PlayingQuizMultiModeBody";
+import {Socket} from "socket.io-client";
+import {QuestionResponse} from "../../../../models/Response/QuestionResponse";
+import {RunInformations} from "../../../../models/RunInformations";
 
 
 type RoutePropsType = {
-    PlayingQuiz: {
+    PlayingQuizMultiMode: {
         runId: string;
-        quizId: string;
+        socket: Socket;
+        roomId: string;
     };
 };
 
 interface Props {
-    route: RouteProp<RoutePropsType, "PlayingQuiz">;
+    route: RouteProp<RoutePropsType, "PlayingQuizMultiMode">;
     navigation: NavigationProp<any>;
 }
 
 export default function PlayingQuizMultiMode({route, navigation}:Props) {
-    const {runId, quizId} = route.params;
-    const { getQuizInformations, getActualQuestionOfAQuiz } = useQuizService();
+    const {runId, socket, roomId} = route.params;
+    const { getQuizInformations, getRunsInfo } = useQuizService();
     const [quizInformations, setQuizInformations] = useState<QuizInformations | undefined>(undefined);
-    const [actualQuestion, setActualQuestion] = useState<Question | undefined>(undefined);
+    const [runInformations, setRunInformations] = useState<RunInformations>();
+    const [actualQuestion, setActualQuestion] = useState<QuestionResponse | undefined>(undefined);
     const [score, setScore] = useState(0);
 
-    const fetchQuizInformations = async () => {
-        // const quizInformationsFetched = await getQuizInformations(quizId);
-        // if (HttpError.isHttpError(quizInformationsFetched)) {
-        //     return;
-        // }
-        const quizInformationsFetched: QuizInformations = {
-            id: 1,
-            name: "Quiz de Test",
-            description: "Ceci est un quiz de test pour vérifier l'interface.",
-            isCommunity: true,
-            questionCount: 10,
-            categoryId: 2,
-            difficultyId: 3,
-            authorId: {
-                id: 42,
-                username: "TestAuthor",
-                email: "testauthor@example.com"
-            },
-            createdAt: "2025-01-10T10:00:00Z",
-            updatedAt: "2025-01-11T12:00:00Z",
-            category: {
-                id: 2,
-                name: "Science"
-            },
-            difficulty: {
-                id: 3,
-                name: "Moyenne"
-            }
-        };
+    const initSocket = async () => {
+        socket.on("gameStarted", (data) => {
+            console.log("Game started:", data);
+        });
+
+        socket.on("newQuestion", (data) => {
+            const question: QuestionResponse = data as QuestionResponse
+            setActualQuestion(question);
+            // console.log(JSON.stringify(question, null, 2)); // Beautifie le JSON avec 2 espaces d'indentation
+        });
 
-        setQuizInformations(quizInformationsFetched);
     }
 
-    const fetchActualQuestion = async () => {
-        const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
-        if (HttpError.isHttpError(actualQuestionFetched)) {
+    const fetchRuns = async () => {
+        if(runId === undefined) return;
+        const runFetched = await getRunsInfo(runId);
+        if (runFetched instanceof HttpError) {
+            console.log("Error fetching runs info", runFetched);
             return;
         }
-        // const actualQuestionFetched: Question = {
-        //     id: 1,
-        //     text: "Quelle image correspond à une étoile ?",
-        //     type: "imae",
-        //     categoryId: 2,
-        //     quizId: "quiz123",
-        //     order: 1,
-        //     answers: [
-        //         {
-        //             id: 1,
-        //             text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-        //             isCorrect: true,
-        //             questionId: 1
-        //         },
-        //         {
-        //             id: 2,
-        //             text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-        //             isCorrect: false,
-        //             questionId: 1
-        //         },
-        //         {
-        //             id: 3,
-        //             text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-        //             isCorrect: false,
-        //             questionId: 1
-        //         },
-        //         {
-        //             id: 4,
-        //             text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-        //             isCorrect: false,
-        //             questionId: 1
-        //         }
-        //     ],
-        //     category: {
-        //         id: 2,
-        //         name: "Astronomie"
-        //     }
-        // };
-        const actualQuestionFetchedShuffle = shuffleAnswers(actualQuestionFetched);
-        setActualQuestion(actualQuestionFetchedShuffle);
-    }
+        const quizInformationsFetched = await getQuizInformations(runFetched.quizId);
+        if (quizInformationsFetched instanceof HttpError) {
+            console.log("Error fetching quiz info", quizInformationsFetched);
+            return;
+        }
+        setQuizInformations(quizInformationsFetched);
+        setRunInformations(runFetched);
+    };
 
     useEffect(() => {
-        fetchQuizInformations();
-    }, []);
+        console.log("PlayingQuizMultiMode starting");
+        initSocket();
+        fetchRuns();
+        setTimeout(() => {
+            socket.emit("startGame")
+        },500);
 
-    useEffect(() => {
-        fetchActualQuestion();
-    }, [quizId]);
+        setTimeout(() => {
+            socket.emit("nextQuestion");
+        },2000);
+    }, []);
 
     return (
         <TemplateDuo
-            childrenHeader={<PlayingQuizMultiModeHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score} navigation={navigation}></PlayingQuizMultiModeHeader>}
-            childrenBody={<PlayingQuizMultiModeBody quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} navigation={navigation}></PlayingQuizMultiModeBody>}
+            childrenHeader={<PlayingQuizMultiModeHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score}  navigation={navigation}></PlayingQuizMultiModeHeader>}
+            childrenBody={<PlayingQuizMultiModeBody runId={runId} actualQuestion={actualQuestion} socket={socket} fetchActualQuestion={()=>{}} roomId={roomId} navigation={navigation}></PlayingQuizMultiModeBody>}
         />
     );
 }
\ No newline at end of file
diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
index f6fc5f5..1a5d713 100644
--- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
+++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
@@ -1,7 +1,7 @@
 import {QuizInformations} from "../../../../models/QuizInformations";
 import {Question} from "../../../../models/Question";
 import {NavigationProp} from "@react-navigation/native";
-import React, {useState} from "react";
+import React, {useEffect, useState} from "react";
 import {useQuizService} from "../../../../services/QuizService";
 import {Answer} from "../../../../models/Answer";
 import HttpError from "../../../../services/HttpError";
@@ -9,15 +9,18 @@ import AnswerButton from "../../../../components/buttons/AnswerButton";
 import {ActivityIndicator, View, Text, StyleSheet} from "react-native";
 import BlueButton from "../../../../components/buttons/BlueButton";
 import {ButtonsStyles} from "../../../../styles/ButtonsStyles";
+import {QuestionResponse} from "../../../../models/Response/QuestionResponse";
+import {RunInformations} from "../../../../models/RunInformations";
+import {Socket} from "socket.io-client";
+import {AnswerWsResponse} from "../../../../models/Response/AnswerWsResponse";
 
 
 interface Props {
-    quizInformations?: QuizInformations;
     runId?: string;
-    actualQuestion: Question;
+    actualQuestion?: QuestionResponse;
     fetchActualQuestion: () => void;
-    score: number;
-    setScore: (score: number) => void;
+    socket: Socket;
+    roomId: string;
     navigation: NavigationProp<any>;
 }
 
@@ -46,6 +49,9 @@ const getStyleOfAnswerButtonText = (answerId: number, selectedAnswerIndex: numbe
 }
 
 const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number | null, correctAnswerId: number | null, quizState: QuizState) => {
+    console.log("answerId :", answerId);
+    console.log("selectedAnswerIndex :", selectedAnswerIndex);
+    console.log("correctAnswerId :", correctAnswerId);
     if(quizState === QuizState.LOADING)
     {
         return styles.loadingAnswer;
@@ -64,58 +70,61 @@ const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number |
     return styles.answerButton;
 }
 
-export default function PlayingQuizMultiModeBody({ quizInformations, runId, actualQuestion, fetchActualQuestion, score, setScore, navigation }: Props) {
+export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchActualQuestion, roomId, socket, navigation }: Props) {
     const [selectedAnswerId, setSelectedAnswerId] = useState<number | null>(null);
     const [quizState, setQuizState] = useState(QuizState.ANSWERING);
     const [correctAnswerId, setCorrectAnswerId] = useState<number | null>(null);
     const [isLastQuestion, setIsLastQuestion] = useState(false);
+    const [quizInformations, setQuizInformations] = useState<QuizInformations>();
+    const [runInformations, setRunInformations] = useState<RunInformations>();
 
-    const {answerQuestion} = useQuizService();
+    const {answerQuestion, getRunsInfo, getQuizInformations} = useQuizService();
     const getCorrectAnswer = (answers: Answer[]): Answer => {
+        console.log("starting getCorrectAnswer");
         const correctAnswer = answers.find((answer) => answer.isCorrect);
-        if (!correctAnswer) throw new Error("No correct answer found");
+        if (!correctAnswer) return answers[0];
         return correctAnswer;
     };
-    const onValidation = async () => {
-        if(selectedAnswerId === null) return;
-        setQuizState(QuizState.LOADING);
-        const answerId = actualQuestion.answers.find((answer) => answer.id === selectedAnswerId)?.id;
-        if(!answerId || !runId) return;
-        const answereFetched = await answerQuestion(runId, actualQuestion.id, answerId);
 
-        if (HttpError.isHttpError(answereFetched)) {
-            return;
-        }
-        setScore(answereFetched.score);
-        const correctAnswerIdFetched = getCorrectAnswer(answereFetched.answers.answers).id;
-        setCorrectAnswerId(correctAnswerIdFetched);
-        setQuizState(QuizState.SHOWING_RESULTS);
-
-        if (quizInformations === undefined) return;
-        // Check si c'est la dernière question
-        if(answereFetched.answers.order === quizInformations.questionCount - 1) {
-            setIsLastQuestion(true);
-            return;
-        }
+    const initSocket = async () => {
+        console.log("init socket in body");
+        socket.on("answersRevealed", (data: AnswerWsResponse) => {
+            const correctAnswerIdFetched = getCorrectAnswer(data.answers).id;
+            console.log("correctAnswerIdFetched", correctAnswerIdFetched);
+            setCorrectAnswerId(correctAnswerIdFetched);
+            setQuizState(QuizState.SHOWING_RESULTS);
+        });
+        // socket.on("score", (data) => {
+        //     console.log("Score:", data);
+        // });
+    }
+
+    useEffect(() => {
+        initSocket();
+    }, []);
+
 
+
+    const onValidation = async () => {
+
+        if(selectedAnswerId === null || actualQuestion === undefined) return;
+        setQuizState(QuizState.LOADING);
+        socket.emit("submitAnswer", {
+            roomId,
+            runId,
+            questionId: actualQuestion.question.id,
+            answerId: selectedAnswerId,
+        });
+
+        setTimeout(() => {
+            socket.emit("revealAnswer", {runId: runId});
+        },500);
     };
     const onContinue = () => {
-        if(isLastQuestion) {
-            navigation.reset({
-                index: 0,
-                routes: [
-                    {
-                        name: "EndQuiz",
-                        params: {quizInformations: quizInformations, score: score},
-                    },
-                ]
-            });
-            return;
-        }
-        fetchActualQuestion();
+        socket.emit("nextQuestion");
         setQuizState(QuizState.ANSWERING);
-        setSelectedAnswerId(null);
         setCorrectAnswerId(null);
+        setSelectedAnswerId(null);
     }
 
     const onAnsweredButtonClicked = (answerId: number) => {
@@ -129,7 +138,7 @@ export default function PlayingQuizMultiModeBody({ quizInformations, runId, actu
         <View style={styles.buttonContainer}>
             {actualQuestion ? (
                 <>
-                    {actualQuestion.answers.map((answer, index) => (
+                    {actualQuestion.question.answers.map((answer, index) => (
                         <AnswerButton
                             key={index}
                             text={answer.text}
diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx
index c5da7d2..427c8cd 100644
--- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx
+++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx
@@ -7,11 +7,12 @@ import {View, Text, StyleSheet} from "react-native";
 import GoHomeButton from "../../../../components/PlayingQuiz/GoHomeButton";
 import {TextsStyles} from "../../../../styles/TextsStyles";
 import ConfirmModal from "../../../../components/PlayingQuiz/ComfirmModal";
+import {QuestionResponse} from "../../../../models/Response/QuestionResponse";
 
 interface Props {
     quizInformations?: QuizInformations;
     runId?: string;
-    actualQuestion: Question;
+    actualQuestion?: QuestionResponse;
     score: number;
     navigation: NavigationProp<any>
 }
@@ -20,6 +21,7 @@ export default function PlayingQuizMultiModeHeader({quizInformations, runId, act
     const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);
     const {t} = useTranslation();
 
+
     const handleConfirmModalConfirm = () => {
         navigation.reset({
             index: 0,
@@ -40,7 +42,7 @@ export default function PlayingQuizMultiModeHeader({quizInformations, runId, act
             <View style={styles.questionAndScoreContainer}>
                 <View style={styles.InformationsContainer}>
                     <Text style={TextsStyles.titleText}>{t("app.screens.question.question")}</Text>
-                    <Text style={TextsStyles.titleText}>{actualQuestion ? actualQuestion.order + 1 :"?"}/{quizInformations ? quizInformations.questionCount : "?"}</Text>
+                    <Text style={TextsStyles.titleText}>{actualQuestion ? actualQuestion.question.order + 1 :"?"}/{quizInformations ? quizInformations.questionCount : "?"}</Text>
                 </View>
                 <View style={styles.InformationsContainer}>
                     <Text style={TextsStyles.titleText}>{t("app.screens.question.score")}</Text>
@@ -48,7 +50,7 @@ export default function PlayingQuizMultiModeHeader({quizInformations, runId, act
                 </View>
             </View>
             <View style={styles.QuizQuestionContainer}>
-                <Text style={TextsStyles.subtitleText}>{actualQuestion ? actualQuestion.text : "Loading..."}</Text>
+                <Text style={TextsStyles.subtitleText}>{actualQuestion ? actualQuestion.question.text : "Loading..."}</Text>
             </View>
             <ConfirmModal visible={isConfirmModalVisible} onClose={()=>setIsConfirmModalVisible(false)} onConfirm={handleConfirmModalConfirm}/>
 
diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
index 8f45d5c..14b3875 100644
--- a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
@@ -29,7 +29,7 @@ export default function MultiInformationsOfQuiz({ navigation, route }: Props) {
 
     const onPlayPressed = async (nbPlayer: number) => {
         setShowModal(false);
-        navigation.navigate("Lobby", {quiz: quiz, nbPlayer: nbPlayer});
+        navigation.navigate("Lobby", {quiz: quiz, nbPlayer: nbPlayer, isHost: true});
     };
 
     return (
diff --git a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
index c31decb..f8f5d1a 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
@@ -61,8 +61,9 @@ export default function OnlineCreateLobby({navigation}: Props) {
         }
 
         navigation.navigate("Lobby", {
-            runId: quizGenerated.id,
+            quizIdOrRoomId: quizGenerated.quizId,
             nbPlayers: parseInt(nbPlayers),
+            isHost: true,
         });
     };
 
diff --git a/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx b/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
index d298d8c..03aba42 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
@@ -14,38 +14,28 @@ interface Props {
 }
 export default function OnlinePlayQuiz({navigation}: Props) {
     const [codeQuiz, setCodeQuiz] = React.useState("");
-    const [quiz, setQuiz] = React.useState<Quiz>();
     const [error, setError] = React.useState<string>("");
+    const {getRunsInfo} = useQuizService();
 
-    const { remainingQuiz } = useQuizService();
-
-    useEffect(() => {
-        fetchQuiz();
-    }, [codeQuiz]);
-
-    const fetchQuiz = async () => {
-        if(codeQuiz === "")
-        {
-            return;
+    const checkRoomExist = async () : Promise<boolean> => {
+        const runFetched = await getRunsInfo(codeQuiz);
+        if(runFetched instanceof HttpError) {
+            return false;
         }
-        const quizFetched = await remainingQuiz(codeQuiz);
-        if (quizFetched instanceof HttpError) {
-            setError("The quiz does not exist");
+        return true;
+    }
+
+    const joinLobby = async ()  => {
+        const response = await checkRoomExist()
+        if(!response) {
+            setError("The room does not exist");
             return;
         }
         setError("");
-        setQuiz(quizFetched);
-    };
-
-    const handlePlayButtonPress = () => {
-        navigation.reset({
-            index: 0,
-            routes: [
-                {
-                    name: "PlayingQuiz",
-                    params: {quizRecovered: quiz},
-                },
-            ]
+        navigation.navigate("Lobby", {
+            quizIdOrRoomId: codeQuiz,
+            nbPlayers: 10,
+            isHost: false,
         });
     };
 
@@ -54,11 +44,10 @@ export default function OnlinePlayQuiz({navigation}: Props) {
             <View style={styles.contentContainer}>
                 <View style={styles.fieldContainer}>
                     {error ? <Text style={styles.errorText}>{error}</Text> : null}
-                    <InputPlayQuiz placeholder={"Enter quiz ID"} setText={setCodeQuiz} noTitle={true} />
-                    <AboutAQuiz quiz={quiz} />
+                    <InputPlayQuiz placeholder={"Enter room ID"} setText={setCodeQuiz} noTitle={true} />
                 </View>
                 <View style={styles.buttonPlayContainer}>
-                    <BlueButton onPress={handlePlayButtonPress} text={"JOIN"} isDisabled={codeQuiz==="" || error!==""}/>
+                    <BlueButton onPress={joinLobby} text={"JOIN"} isDisabled={codeQuiz==="" || error!==""}/>
                 </View>
             </View>
         </View>
diff --git a/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx b/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
index bf33162..cc45226 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineSelectMode.tsx
@@ -18,7 +18,7 @@ export default function OnlineSelectMode({ mode, setMode }: Props) {
 
             <View style={styles.buttonContainer}>
                 <TouchableOpacity onPress={() => setMode("join")}>
-                    <Text style={[styles.text, mode === "join" && styles.activeText]}>JOIN A QUIZ</Text>
+                    <Text style={[styles.text, mode === "join" && styles.activeText]}>JOIN A ROOM</Text>
                 </TouchableOpacity>
                 <View style={[styles.bar, mode === "join" ? styles.activeBar : styles.inactiveBar]} />
             </View>
diff --git a/screens/PlayingQuiz/PlayingQuizHeader.tsx b/screens/PlayingQuiz/PlayingQuizHeader.tsx
index ffba640..c03c6d0 100644
--- a/screens/PlayingQuiz/PlayingQuizHeader.tsx
+++ b/screens/PlayingQuiz/PlayingQuizHeader.tsx
@@ -13,7 +13,7 @@ import {Question} from "../../models/Question";
 interface Props {
     quizInformations?: QuizInformations;
     runId?: string;
-    actualQuestion: Question;
+    actualQuestion?: Question;
     score: number;
     navigation: NavigationProp<any>
 }
-- 
GitLab


From 046b6d4dc24d63a3a5be18c4e30f05d2d2938232 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 13 Jan 2025 21:14:21 +0100
Subject: [PATCH 261/283] fix: stable version of mobile

---
 .../PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx |  6 +--
 components/PlayingQuiz/EndQuiz/UserScore.tsx  |  4 +-
 components/lists/QuizList.tsx                 |  2 +-
 models/Quiz.ts                                |  5 ++-
 screens/Home/Home.tsx                         | 21 ----------
 .../EndQuizMulti/EndQuizMultiChild.tsx        | 40 +++----------------
 services/QuizService.ts                       |  6 +--
 7 files changed, 19 insertions(+), 65 deletions(-)

diff --git a/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx b/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx
index a2378cb..819fabe 100644
--- a/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx
+++ b/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx
@@ -1,14 +1,14 @@
 import React from "react";
 import { FlatList, View, Text, StyleSheet, Image } from "react-native";
-import UserModel from "../../../models/UserModel";
+import {User} from "../../../models/User";
 
 interface Props {
-    users: UserModel[];
+    users: User[];
     maxScore: number;
 }
 
 export default function EndQuizListPlayer({ users, maxScore }: Props) {
-    const renderUser = ({ item, index }: { item: UserModel; index: number }) => (
+    const renderUser = ({ item, index }: { item: User; index: number }) => (
         <View style={[styles.userContainer, index === 0 && styles.firstPlace]}>
             <Image
                 source={require("../../../assets/ProfilBaseImage.png")} // Replace with actual profile picture if available
diff --git a/components/PlayingQuiz/EndQuiz/UserScore.tsx b/components/PlayingQuiz/EndQuiz/UserScore.tsx
index d57489c..6583622 100644
--- a/components/PlayingQuiz/EndQuiz/UserScore.tsx
+++ b/components/PlayingQuiz/EndQuiz/UserScore.tsx
@@ -1,8 +1,8 @@
-import UserModel from "../../../models/UserModel";
 import { View, Text, StyleSheet, Image } from "react-native";
+import {User} from "../../../models/User";
 
 interface Props {
-    user: UserModel;
+    user: User;
     score: number;
     maxScore: number;
     isFirst: boolean;
diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 6cb9f80..535915f 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -61,7 +61,7 @@ export default function QuizList({ quizList, isLoadingData, nextPage, onQuizPres
                 <FlatList
                     data={quizList}
                     renderItem={renderQuizItem}
-                    keyExtractor={(item) => item.id}
+                    keyExtractor={(item,index) => item.id+ ""+ index}
                     showsVerticalScrollIndicator={true}
                     contentContainerStyle={styles.listContent}
                     onEndReached={() => {
diff --git a/models/Quiz.ts b/models/Quiz.ts
index 1acc2ce..c717243 100644
--- a/models/Quiz.ts
+++ b/models/Quiz.ts
@@ -1,5 +1,8 @@
 import {Question} from "./Question";
-
+export interface QuizCommunityResponse {
+    quizzes: Quiz[];
+    total: number;
+}
 export interface Difficulty {
     id: number;
     name: string;
diff --git a/screens/Home/Home.tsx b/screens/Home/Home.tsx
index 1369070..4fb5203 100644
--- a/screens/Home/Home.tsx
+++ b/screens/Home/Home.tsx
@@ -10,28 +10,7 @@ interface Props {
 }
 
 export default function Home({navigation}: Props) {
-    const debugQuiz: Quiz = {
-        id: "debug-quiz-001",
-        name: "Debug Quiz",
-        description: "This is a basic quiz for debugging purposes.",
-        score: 0,
-        questionIndex: 0,
-        questionCount: 0,
-        categoryId: 1,
-        difficultyId: 1,
-        authorId: 1,
-        category: {
-            id: 1,
-            name: "General Knowledge",
-        },
-        difficulty: {
-            id: 1,
-            name: "Easy",
-        },
-        questions: [], // Tableau de questions vide
-    };
 
-    navigation.navigate("EndQuizMulti", {quiz: debugQuiz});
     return (
         <View style={styles.containerGlobal}>
                 <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}>
diff --git a/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx b/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx
index 3ba9918..b53eb9f 100644
--- a/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx
+++ b/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx
@@ -5,7 +5,6 @@ import {Quiz} from "../../../models/Quiz";
 import {useQuizService} from "../../../services/QuizService";
 import HttpError from "../../../services/HttpError";
 import UserScore from "../../../components/PlayingQuiz/EndQuiz/UserScore";
-import UserModel from "../../../models/UserModel";
 import EndQuizListPlayer from "../../../components/PlayingQuiz/EndQuiz/EndQuizListPlayer";
 
 
@@ -17,38 +16,11 @@ interface Props {
 
 export default function EndQuizMultiChild({ navigation, quiz }: Props) {
 
-    const {restartQuiz, remainingQuiz} = useQuizService()
-
-    const handleRestartPress = async () => {
-        const isRestarted = await restartQuiz(quiz.id);
-        if(HttpError.isHttpError(isRestarted)){
-            console.log(isRestarted.message);
-            return
-        }
-        if(!isRestarted) {
-            return;
-        }
-        const quizRestarted = await remainingQuiz(quiz.id);
-        if(HttpError.isHttpError(quizRestarted)){
-            console.log(quizRestarted.message);
-            return
-        }
-
-        navigation.reset({
-            index: 0,
-            routes: [
-                {
-                    name: "PlayingQuiz",
-                    params: {quizRecovered: quizRestarted},
-                },
-            ]
-        });
-    };
+    const userTest = {id: 1, email: "user1@email.com", username: "user1", stats: undefined};
 
     const handleBackToMenu = () => {
         navigation.navigate('TabNavigator');
     };
-    const user = new UserModel(10,"Thomassss", "Thomas");
 
     return (
         <View style={styles.container}>
@@ -61,13 +33,13 @@ export default function EndQuizMultiChild({ navigation, quiz }: Props) {
                     style={styles.stars}
                 />
                 <View style={styles.usersContainer}>
-                    <UserScore user={user} score={10} maxScore={quiz.questionCount} isFirst={false}/>
-                    <UserScore user={user} score={10} maxScore={quiz.questionCount} isFirst={true}/>
-                    <UserScore user={user} score={10} maxScore={quiz.questionCount} isFirst={false}/>
+                    <UserScore user={userTest} score={10} maxScore={quiz.questionCount} isFirst={false}/>
+                    <UserScore user={userTest} score={10} maxScore={quiz.questionCount} isFirst={true}/>
+                    <UserScore user={userTest} score={10} maxScore={quiz.questionCount} isFirst={false}/>
                 </View>
-                <EndQuizListPlayer users={[new UserModel(1, "user1", "user1@email.com"), new UserModel(2, "user2", "user2@email.com")]} maxScore={quiz.questionCount}/>
+                <EndQuizListPlayer users={[userTest, userTest]} maxScore={quiz.questionCount}/>
 
-                <DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>
+                {/*<DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>*/}
                 <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton>
             </View>
         </View>
diff --git a/services/QuizService.ts b/services/QuizService.ts
index 19cb0e9..8dbbc26 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -1,5 +1,5 @@
 import HttpError from "./HttpError";
-import {Quiz} from "../models/Quiz";
+import {Quiz, QuizCommunityResponse} from "../models/Quiz";
 import axios from "axios";
 import {Answer} from "../models/Answer";
 import {Question} from "../models/Question";
@@ -214,11 +214,11 @@ export const useQuizService =  () => {
 
     const getCommunityQuiz = async (skip: number, take: number) => {
         try {
-            const response = await axios.get<Quiz[]>(`${url}/quiz/paginated?skip=${skip}&take=${take}`, {
+            const response = await axios.get<QuizCommunityResponse>(`${url}/quiz/paginated?skip=${skip}&take=${take}`, {
                 withCredentials: true, // Inclut les cookies pour une session authentifiée
             });
 
-            return response.data;
+            return response.data.quizzes;
         } catch (error: any) {
 
             if (error.response) {
-- 
GitLab


From dd179b6a4505ca42dd7a25a1bdf5d502f9b97101 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Mon, 13 Jan 2025 22:26:54 +0100
Subject: [PATCH 262/283] refactor: show good values

---
 components/lists/QuizList.tsx | 7 +++++--
 models/Quiz.ts                | 7 +++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index 535915f..dfad0f6 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -41,11 +41,14 @@ interface Props {
     onQuizPressed:(quiz: Quiz) => void;
 }
 export default function QuizList({ quizList, isLoadingData, nextPage, onQuizPressed }: Props) {
+    if (quizList) {
+        console.log(quizList[0]);
+    }
     const renderQuizItem = ({ item }: { item: Quiz }) => (
         <TouchableOpacity style={styles.quizItem} onPress={() => onQuizPressed(item)}>
-            <Text style={styles.quizTitle}>{item.id}</Text>
+            <Text style={styles.quizTitle}>{item.name}</Text>
             <Text style={styles.quizDetails}>
-                {item.questionCount} QUESTIONS | {item.category ? item.category.name.toUpperCase() : ""}
+                {item.questionCount} QUESTIONS | {item.difficulty.name} | {item.author.username}
             </Text>
         </TouchableOpacity>
     );
diff --git a/models/Quiz.ts b/models/Quiz.ts
index c717243..83a6284 100644
--- a/models/Quiz.ts
+++ b/models/Quiz.ts
@@ -13,6 +13,12 @@ export interface Category {
     name: string;
 }
 
+interface Author {
+    id: number;
+    username: string;
+}
+
+
 export interface Quiz {
     id: string;
     name: string;
@@ -22,6 +28,7 @@ export interface Quiz {
     questionCount: number;
     categoryId: number;
     difficultyId: number;
+    author: Author,
     authorId: number,
     category?: Category,
     difficulty: Difficulty,
-- 
GitLab


From e95d7ef9128d18859b08713f5da7713409d2fc63 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 10:57:56 +0100
Subject: [PATCH 263/283] refactor: login and signup

---
 models/User.ts                                |   6 ++
 screens/Multiplayer/MultiplayerChild.tsx      |  62 ++++++++---
 screens/Profil/Connection/Connection.tsx      |  72 +++++++++++++
 .../ConnectionLogin.tsx}                      |   6 +-
 .../ConnectionSignup.tsx}                     |  12 ++-
 screens/Profil/Modals/ProfilModal.tsx         | 100 ------------------
 screens/Profil/ProfilChild.tsx                |  54 +++++-----
 screens/Profil/ProfilHeaderAccount.tsx        |  51 ---------
 8 files changed, 163 insertions(+), 200 deletions(-)
 create mode 100644 screens/Profil/Connection/Connection.tsx
 rename screens/Profil/{Modals/ProfilModalLogin.tsx => Connection/ConnectionLogin.tsx} (92%)
 rename screens/Profil/{Modals/ProfilModalSignup.tsx => Connection/ConnectionSignup.tsx} (93%)
 delete mode 100644 screens/Profil/Modals/ProfilModal.tsx
 delete mode 100644 screens/Profil/ProfilHeaderAccount.tsx

diff --git a/models/User.ts b/models/User.ts
index e572420..506d8f0 100644
--- a/models/User.ts
+++ b/models/User.ts
@@ -9,4 +9,10 @@ export interface User {
     email: string;
     username: string;
     stats?: Stats;
+}
+
+export enum UserConnectionState {
+    LOADING = "Loading",
+    NOT_CONNECTED = "NotConnected",
+    CONNECTED = "Connected",
 }
\ No newline at end of file
diff --git a/screens/Multiplayer/MultiplayerChild.tsx b/screens/Multiplayer/MultiplayerChild.tsx
index be9843a..f7eee12 100644
--- a/screens/Multiplayer/MultiplayerChild.tsx
+++ b/screens/Multiplayer/MultiplayerChild.tsx
@@ -1,18 +1,20 @@
-import { View, StyleSheet, Image, Modal, TextInput } from "react-native";
-import DefaultButton from "../../components/DefaultButton";
+import {Image, StyleSheet, Text, View} from "react-native";
 import {useTranslation} from "react-i18next";
-import { useState } from "react";
-import { TextsStyles } from "../../styles/TextsStyles";
+import React, {useEffect, useState} from "react";
 import ModalJoinQuiz from "../../components/ModalJoinQuiz";
 import MenuButton from "../../components/buttons/MenuButton";
 import {NavigationProp} from "@react-navigation/native";
-import {useQuizService} from "../../services/QuizService";
 import HttpError from "../../services/HttpError";
+import {useUserService} from "../../services/UserService";
+import {UserConnectionState} from "../../models/User";
+import LoadingIndicator from "../../components/loading/LoadingIndicator";
+import Connection from "../Profil/Connection/Connection";
 
 interface Props {
     navigation: NavigationProp<any>;
 }
 
+
 /**
  * HomeChild : Enfant de l'écran Home, il contient le menu principal
  * @param navigation - navigation
@@ -20,6 +22,22 @@ interface Props {
 export default function MultiplayerChild({navigation}: Props) {
     const [modalVisible, setModalVisible] = useState(false);
     const {t} = useTranslation();
+    const [userConnectionState, setUserConnectionState] = useState(UserConnectionState.LOADING);
+    const { getInformationsUser, logoutUser } = useUserService();
+
+    const getUser = async () => {
+        setUserConnectionState(UserConnectionState.LOADING);
+        const user = await getInformationsUser();
+        if(user instanceof HttpError){
+            setUserConnectionState(UserConnectionState.NOT_CONNECTED);
+            return;
+        }
+        setUserConnectionState(UserConnectionState.CONNECTED);
+    }
+
+    useEffect(() => {
+        getUser();
+    }, []);
 
     const handleButtonCommunityPressed = async () => {
         navigation.navigate("MultiplayerCommunity");
@@ -35,15 +53,24 @@ export default function MultiplayerChild({navigation}: Props) {
 
     return (
         <View style={styles.containerGlobal}>
-            <View style={styles.imageContainer}>
-                <Image source={require('../../assets/TitleApp.png')} style={styles.image} />
-            </View>
-            <View style={styles.buttonContainer}>
-                <MenuButton text={"COMMUNITY"} handleButtonPressed={handleButtonCommunityPressed}/>
-                <MenuButton text={"PLAY AN ONLINE QUIZ"} handleButtonPressed={handleOnlineQuizPressed}/>
-                <MenuButton text={"ONGOING QUIZZES"} handleButtonPressed={handleButtonOngoingQuizzesPressed}/>
-            </View>
-             <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
+            {userConnectionState === UserConnectionState.LOADING && (
+                <LoadingIndicator/>
+            )}
+            {userConnectionState === UserConnectionState.CONNECTED && (
+                <>
+                <View style={styles.imageContainer}>
+                    <Image source={require('../../assets/TitleApp.png')} style={styles.image} />
+                </View>
+                <View style={styles.buttonContainer}>
+                    <MenuButton text={"COMMUNITY"} handleButtonPressed={handleButtonCommunityPressed}/>
+                    <MenuButton text={"PLAY AN ONLINE QUIZ"} handleButtonPressed={handleOnlineQuizPressed}/>
+                    <MenuButton text={"ONGOING QUIZZES"} handleButtonPressed={handleButtonOngoingQuizzesPressed}/>
+                </View>
+            </>
+            )}
+            {userConnectionState === UserConnectionState.NOT_CONNECTED && (
+                <Connection title={"Multiplayer"} navigation={navigation}/>
+            )}
         </View>
     );
 }
@@ -58,6 +85,13 @@ const styles = StyleSheet.create({
     },
     image: {
     },
+    title: {
+        fontSize: 40,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+        alignSelf: "center", // Centre uniquement le titre
+    },
     button: {
         borderRadius: 40,
         height: '35%',
diff --git a/screens/Profil/Connection/Connection.tsx b/screens/Profil/Connection/Connection.tsx
new file mode 100644
index 0000000..34e5023
--- /dev/null
+++ b/screens/Profil/Connection/Connection.tsx
@@ -0,0 +1,72 @@
+import {Keyboard, StyleSheet, Text, TouchableOpacity, TouchableWithoutFeedback, View} from "react-native";
+import ProfilSelectMode from "../ProfilSelectMode";
+import React, {useState} from "react";
+import {ProfilSelectModeType} from "../../../models/SelectModeType";
+import {NavigationProp} from "@react-navigation/native";
+import ConnectionLogin from "./ConnectionLogin";
+import ConnectionSignup from "./ConnectionSignup";
+
+interface Props {
+    title: string;
+    navigation: NavigationProp<any>;
+}
+
+export default function Connection({title, navigation}: Props) {
+    const [mode, setMode] = useState<ProfilSelectModeType>("login");
+
+    return (
+        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
+            <View style={styles.container}>
+                <Text style={styles.title}>{title}</Text>
+                <View style={styles.containerModal}>
+                    <ProfilSelectMode mode={mode} setMode={setMode} />
+                    {mode === "login" ? (
+                        <ConnectionLogin navigation={navigation} />
+                    ) : (
+                        <ConnectionSignup navigation={navigation} />
+                    )}
+                </View>
+            </View>
+        </TouchableWithoutFeedback>
+    );
+}
+
+const styles = StyleSheet.create({
+    container: {
+        flex: 1,
+        justifyContent: "center",
+        alignItems: "center",
+        height: "100%",
+        width: "100%",
+    },
+    title: {
+        fontSize: 40,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+        alignSelf: "center", // Centre uniquement le titre
+    },
+    backgroundShadow: {
+        height: "100%",
+        width: "100%",
+        backgroundColor: "#000000",
+        opacity: 0.55,
+        position: "absolute",
+    },
+    containerModal: {
+        height: 600,
+        width: "90%",
+        backgroundColor: "#D9D9D9",
+        borderRadius: 40,
+        padding: '7%',
+    },
+    closeButton: {
+        position: "absolute",
+        top: '1%',
+        right: '1%',
+        zIndex: 1,
+        backgroundColor: "white",
+        borderRadius: 10,
+        margin: '5%',
+    },
+});
\ No newline at end of file
diff --git a/screens/Profil/Modals/ProfilModalLogin.tsx b/screens/Profil/Connection/ConnectionLogin.tsx
similarity index 92%
rename from screens/Profil/Modals/ProfilModalLogin.tsx
rename to screens/Profil/Connection/ConnectionLogin.tsx
index 41c3553..0dcd824 100644
--- a/screens/Profil/Modals/ProfilModalLogin.tsx
+++ b/screens/Profil/Connection/ConnectionLogin.tsx
@@ -8,9 +8,8 @@ import BlueButton from "../../../components/buttons/BlueButton";
 
 interface Props {
     navigation: NavigationProp<any>;
-    closeModal: () => void;
 }
-export default function ProfilModalLogin({navigation, closeModal}: Props) {
+export default function ConnectionLogin({navigation}: Props) {
     const [email, setEmail] = useState("");
     const [password, setPassword] = useState("");
     const [error, setError] = useState<string | null>(null);
@@ -27,7 +26,6 @@ export default function ProfilModalLogin({navigation, closeModal}: Props) {
             return;
         }
         setError(null);
-        closeModal();
         navigation.reset({
             routes: [{name: "TabNavigator"}],
         });
@@ -54,6 +52,7 @@ const styles = StyleSheet.create({
         justifyContent: 'flex-start',
         rowGap: '7%',
         marginTop: "3%",
+        marginBottom: "auto", // Espacement entre le texte d'erreur et les inputs
     },
     container:{
         height: 475,
@@ -80,7 +79,6 @@ const styles = StyleSheet.create({
     errorText: {
         color: 'red',
         fontSize: 16,
-        marginBottom: 10, // Espacement entre le texte d'erreur et les inputs
         textAlign: 'center', // Centrer le message d'erreur
     },
 });
diff --git a/screens/Profil/Modals/ProfilModalSignup.tsx b/screens/Profil/Connection/ConnectionSignup.tsx
similarity index 93%
rename from screens/Profil/Modals/ProfilModalSignup.tsx
rename to screens/Profil/Connection/ConnectionSignup.tsx
index 124a42e..542012f 100644
--- a/screens/Profil/Modals/ProfilModalSignup.tsx
+++ b/screens/Profil/Connection/ConnectionSignup.tsx
@@ -9,9 +9,8 @@ import BlueButton from "../../../components/buttons/BlueButton";
 
 interface Props {
     navigation: NavigationProp<any>;
-    closeModal: () => void;
 }
-export default function ProfilModalSignup({navigation, closeModal}: Props) {
+export default function ConnectionSignup({navigation}: Props) {
 
     const [email, setEmail] = useState("");
     const [username, setUsername] = useState("");
@@ -25,6 +24,10 @@ export default function ProfilModalSignup({navigation, closeModal}: Props) {
             setError("Please fill in all fields");
             return;
         }
+        if(password.length < 8){
+            setError("Password must be at least 8 characters long");
+            return;
+        }
         if(password !== repeatPassword){
             setError("Passwords do not match");
             return;
@@ -35,7 +38,6 @@ export default function ProfilModalSignup({navigation, closeModal}: Props) {
             return;
         }
         setError(null);
-        closeModal();
         navigation.reset({
             routes: [{name: "TabNavigator"}],
         });
@@ -62,13 +64,13 @@ const styles = StyleSheet.create({
         display: 'flex',
         flexDirection: 'column',
         justifyContent: 'flex-start',
-        rowGap: '7%',
+        rowGap: '5%',
         marginTop: "3%",
     },
     container:{
         height: 475,
         paddingTop: '5%',
-        isplay: 'flex',
+        display: 'flex',
         justifyContent: 'space-between'
     },
     textInput: {
diff --git a/screens/Profil/Modals/ProfilModal.tsx b/screens/Profil/Modals/ProfilModal.tsx
deleted file mode 100644
index c24d3fc..0000000
--- a/screens/Profil/Modals/ProfilModal.tsx
+++ /dev/null
@@ -1,100 +0,0 @@
-import React from "react";
-import {
-    Modal,
-    View,
-    StyleSheet,
-    TextInput,
-    TouchableOpacity,
-    Keyboard,
-    TouchableWithoutFeedback,
-} from "react-native";
-import ProfilSelectMode from "../ProfilSelectMode";
-import { ProfilSelectModeType } from "../../../models/SelectModeType";
-import ProfilModalLogin from "./ProfilModalLogin";
-import ProfilModalSignup from "./ProfilModalSignup";
-import Icon from "react-native-vector-icons/MaterialIcons";
-import {NavigationProp} from "@react-navigation/native";
-
-interface Props {
-    modalVisible: boolean;
-    setModalVisible: (visible: boolean) => void;
-    mode: ProfilSelectModeType;
-    setMode: (mode: ProfilSelectModeType) => void;
-    navigation: NavigationProp<any>;
-}
-
-export default function ProfilModal({
-        modalVisible,
-        setModalVisible,
-        mode,
-        setMode,
-        navigation
-    }: Props) {
-    const closeModal = () => {
-        setModalVisible(false);
-    }
-
-    return (
-        <Modal
-            animationType="slide"
-            transparent={true}
-            visible={modalVisible}
-            onRequestClose={() => {
-                setModalVisible(!modalVisible);
-            }}
-        >
-            <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
-                <View style={styles.container}>
-                    <TouchableOpacity
-                        style={styles.closeButton}
-                        onPress={() => setModalVisible(false)} // Ferme la modal
-                    >
-                        <Icon name="close" size={50} color="#000" />
-                    </TouchableOpacity>
-                    <View style={styles.backgroundShadow} />
-                    <View style={styles.containerModal}>
-                        <ProfilSelectMode mode={mode} setMode={setMode} />
-                        {mode === "login" ? (
-                            <ProfilModalLogin navigation={navigation} closeModal={closeModal}/>
-                        ) : (
-                            <ProfilModalSignup navigation={navigation} closeModal={closeModal}/>
-                        )}
-                    </View>
-                </View>
-            </TouchableWithoutFeedback>
-        </Modal>
-    );
-}
-
-const styles = StyleSheet.create({
-    container: {
-        flex: 1,
-        justifyContent: "center",
-        alignItems: "center",
-        height: "100%",
-        width: "100%",
-    },
-    backgroundShadow: {
-        height: "100%",
-        width: "100%",
-        backgroundColor: "#000000",
-        opacity: 0.55,
-        position: "absolute",
-    },
-    containerModal: {
-        height: 600,
-        width: "90%",
-        backgroundColor: "#D9D9D9",
-        borderRadius: 40,
-        padding: '7%',
-    },
-    closeButton: {
-        position: "absolute",
-        top: '1%',
-        right: '1%',
-        zIndex: 1,
-        backgroundColor: "white",
-        borderRadius: 10,
-        margin: '5%',
-    },
-});
diff --git a/screens/Profil/ProfilChild.tsx b/screens/Profil/ProfilChild.tsx
index dd89a53..bb601bf 100644
--- a/screens/Profil/ProfilChild.tsx
+++ b/screens/Profil/ProfilChild.tsx
@@ -1,24 +1,20 @@
 import { NavigationProp } from "@react-navigation/native";
 import { View, StyleSheet, Image, Text, TouchableOpacity } from "react-native";
-import ProfilModal from "./Modals/ProfilModal";
 import React, { useEffect, useState } from "react";
-import ProfilHeaderAccount from "./ProfilHeaderAccount";
 import { ProfilSelectModeType } from "../../models/SelectModeType";
 import { useUserService } from "../../services/UserService";
 import HttpError from "../../services/HttpError";
 import Icon from "react-native-vector-icons/MaterialIcons";
-import {User} from "../../models/User";
+import {User, UserConnectionState} from "../../models/User";
 import StatsOfUsers from "../../components/Profil/StatsOfUsers";
+import LoadingIndicator from "../../components/loading/LoadingIndicator";
+import Connection from "./Connection/Connection";
 
 interface Props {
     navigation: NavigationProp<any>;
 }
 
-enum UserConnectionState {
-    LOADING = "Loading",
-    NOT_CONNECTED = "NotConnected",
-    CONNECTED = "Connected",
-}
+
 
 export default function ProfilChild({ navigation }: Props) {
     const [isLogged, setIsLogged] = useState(false);
@@ -28,6 +24,7 @@ export default function ProfilChild({ navigation }: Props) {
     const [userConnectionState, setUserConnectionState] = useState(UserConnectionState.LOADING);
     const { getInformationsUser, logoutUser } = useUserService();
 
+
     const getUser = async () => {
         setUserConnectionState(UserConnectionState.LOADING);
         const user = await getInformationsUser();
@@ -42,7 +39,6 @@ export default function ProfilChild({ navigation }: Props) {
 
     useEffect(() => {
         getUser();
-
     }, []);
 
     // Pour s'adapter quand l'état de connexion change
@@ -55,33 +51,32 @@ export default function ProfilChild({ navigation }: Props) {
         if (!(result instanceof HttpError)) {
             setUser(undefined); // Réinitialise l'utilisateur après la déconnexion
         }
+        navigation.reset({
+            routes: [{name: "TabNavigator"}],
+        });
     };
 
     return (
         <View style={styles.containerGlobal}>
+            {userConnectionState === UserConnectionState.LOADING && (
+                <LoadingIndicator/>
+            )}
+            {userConnectionState === UserConnectionState.CONNECTED && (
+                <>
             <View style={styles.containerPlayerInfos}>
                 <Image source={require('../../assets/TitleApp.png')} style={styles.titleImage} />
                 <Image source={require('../../assets/ProfilBaseImage.png')} style={styles.profilImage} />
                 <Text style={styles.pseudoText}>{user ? user.username : "?"}</Text>
             </View>
-
-            {!user && (
-                <ProfilHeaderAccount setModalVisible={setModalVisible} setMode={setMode} />
-            )}
-            <ProfilModal
-                modalVisible={modalVisible}
-                setModalVisible={setModalVisible}
-                mode={mode}
-                setMode={setMode}
-                navigation={navigation}
-            />
             <StatsOfUsers user={user}/>
-
-            {user && (
-                <TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
-                    <Icon name="logout" size={40} color="#FF0000" />
-                </TouchableOpacity>
-            )}
+            <TouchableOpacity style={styles.logoutButton} onPress={handleLogout}>
+                <Icon name="logout" size={40} color="#FF0000" />
+            </TouchableOpacity>
+            </>
+        )}
+            {userConnectionState === UserConnectionState.NOT_CONNECTED && (
+                <Connection title={"Profil"} navigation={navigation}  />
+                )}
         </View>
     );
 }
@@ -99,6 +94,13 @@ const styles = StyleSheet.create({
         display: "flex",
         alignItems: "center",
     },
+    title: {
+        fontSize: 40,
+        fontWeight: "bold",
+        color: "#00b3f4",
+        marginBottom: 10,
+        alignSelf: "center", // Centre uniquement le titre
+    },
     titleImage: {
         width: "45%",
         resizeMode: "contain",
diff --git a/screens/Profil/ProfilHeaderAccount.tsx b/screens/Profil/ProfilHeaderAccount.tsx
deleted file mode 100644
index 6afcc5d..0000000
--- a/screens/Profil/ProfilHeaderAccount.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
-import { ProfilSelectModeType } from "../../models/SelectModeType";
-
-interface Props {
-    setModalVisible: (visible:boolean) => void;
-    setMode: (mode: ProfilSelectModeType) => void;
-}
-
-export default function ProfilHeaderAccount({ setModalVisible, setMode }: Props) {
-    const handleAccountPress = (mode:ProfilSelectModeType) => {
-        setMode(mode);
-        setModalVisible(true);
-    };
-
-    return (
-        <View style={styles.containerHeader}>
-            <TouchableOpacity onPress={() => handleAccountPress('login')}>
-                <Text style={styles.buttonHeader}>LOGIN</Text>
-            </TouchableOpacity>
-            <Text style={styles.textHeader}>{' OR '}</Text>
-            <TouchableOpacity onPress={() => handleAccountPress('signup')}>
-                <Text style={styles.buttonHeader}>CREATE AN ACCOUNT</Text>
-            </TouchableOpacity>
-        </View>
-    )
-}
-
-
-const styles = StyleSheet.create({
-    containerHeader: {
-        backgroundColor: '#D9D9D9',
-        height: '10%',
-        width: '100%',
-        position: 'absolute',
-        display: 'flex', 
-        flexDirection: 'row',
-        justifyContent: 'center',
-        alignItems: 'center'
-    },
-    textHeader: {
-        color: '#000000',
-        fontSize: 20,
-        fontWeight: 'bold',
-    },
-    buttonHeader: {
-        textDecorationLine: 'underline',
-        color: '#000000',
-        fontSize: 20,
-        fontWeight: 'bold',
-    },
-});
\ No newline at end of file
-- 
GitLab


From 1d2632ca3d6d69506ff4f756a53aa5cde363cf5a Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 11:11:33 +0100
Subject: [PATCH 264/283] chore: clean code

---
 components/lists/QuizList.tsx                                | 1 -
 screens/Multiplayer/Lobby/Lobby.tsx                          | 1 -
 .../Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx  | 5 -----
 3 files changed, 7 deletions(-)

diff --git a/components/lists/QuizList.tsx b/components/lists/QuizList.tsx
index dfad0f6..81051a6 100644
--- a/components/lists/QuizList.tsx
+++ b/components/lists/QuizList.tsx
@@ -42,7 +42,6 @@ interface Props {
 }
 export default function QuizList({ quizList, isLoadingData, nextPage, onQuizPressed }: Props) {
     if (quizList) {
-        console.log(quizList[0]);
     }
     const renderQuizItem = ({ item }: { item: Quiz }) => (
         <TouchableOpacity style={styles.quizItem} onPress={() => onQuizPressed(item)}>
diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index bdcdb42..fee0d0d 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -48,7 +48,6 @@ export default function Lobby({navigation, route}: Props) {
         });
 
         setSocket(newSocket);
-        console.log(isHost);
 
         if(isHost) {
             newSocket.on("roomCreated", (data) => {
diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
index 1a5d713..f7cda1a 100644
--- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
+++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx
@@ -49,9 +49,6 @@ const getStyleOfAnswerButtonText = (answerId: number, selectedAnswerIndex: numbe
 }
 
 const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number | null, correctAnswerId: number | null, quizState: QuizState) => {
-    console.log("answerId :", answerId);
-    console.log("selectedAnswerIndex :", selectedAnswerIndex);
-    console.log("correctAnswerId :", correctAnswerId);
     if(quizState === QuizState.LOADING)
     {
         return styles.loadingAnswer;
@@ -77,10 +74,8 @@ export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchAc
     const [isLastQuestion, setIsLastQuestion] = useState(false);
     const [quizInformations, setQuizInformations] = useState<QuizInformations>();
     const [runInformations, setRunInformations] = useState<RunInformations>();
-
     const {answerQuestion, getRunsInfo, getQuizInformations} = useQuizService();
     const getCorrectAnswer = (answers: Answer[]): Answer => {
-        console.log("starting getCorrectAnswer");
         const correctAnswer = answers.find((answer) => answer.isCorrect);
         if (!correctAnswer) return answers[0];
         return correctAnswer;
-- 
GitLab


From e9f62cca466e165e855bcbbcd0dc4a863b935c1d Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 21:48:25 +0100
Subject: [PATCH 265/283] feat: new models

---
 models/Response/AllRunsResponse.ts |  5 +++++
 models/RunsInformationsAllRuns.tsx | 20 ++++++++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 models/Response/AllRunsResponse.ts
 create mode 100644 models/RunsInformationsAllRuns.tsx

diff --git a/models/Response/AllRunsResponse.ts b/models/Response/AllRunsResponse.ts
new file mode 100644
index 0000000..8e7c71c
--- /dev/null
+++ b/models/Response/AllRunsResponse.ts
@@ -0,0 +1,5 @@
+import {RunsInformationsAllRuns} from "../RunsInformationsAllRuns";
+
+export interface AllRunsResponse{
+    runs: RunsInformationsAllRuns[];
+}
\ No newline at end of file
diff --git a/models/RunsInformationsAllRuns.tsx b/models/RunsInformationsAllRuns.tsx
new file mode 100644
index 0000000..f70c778
--- /dev/null
+++ b/models/RunsInformationsAllRuns.tsx
@@ -0,0 +1,20 @@
+import {Category, Difficulty} from "./Quiz";
+
+export interface QuizInfoRun{
+    category: Category;
+    difficulty: Difficulty;
+    name?: string;
+    questionCount: string;
+}
+export interface RunsInformationsAllRuns{
+    id: string;
+    quizId: string;
+    originalQuizId: string;
+    score: number;
+    questionIndex: number;
+    startDate: string;
+    lastChange: string;
+    quizUserId: number;
+    roomId: number;
+    quiz: QuizInfoRun;
+}
\ No newline at end of file
-- 
GitLab


From 3bc4d53d465f04f182e7508ad8707834b16272a5 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 21:48:44 +0100
Subject: [PATCH 266/283] feat: new packages

---
 package-lock.json | 7 +++++++
 package.json      | 1 +
 2 files changed, 8 insertions(+)

diff --git a/package-lock.json b/package-lock.json
index d1035b2..2a605a2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -31,6 +31,7 @@
         "react-native-progress": "^5.0.1",
         "react-native-safe-area-context": "^4.12.0",
         "react-native-screens": "~4.1.0",
+        "react-native-sse": "^1.2.1",
         "react-native-vector-icons": "^10.2.0",
         "react-query": "^3.39.3",
         "rxjs": "^7.8.1",
@@ -9775,6 +9776,12 @@
         "react-native": "*"
       }
     },
+    "node_modules/react-native-sse": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/react-native-sse/-/react-native-sse-1.2.1.tgz",
+      "integrity": "sha512-zejanlScF+IB9tYnbdry0MT34qjBXbiV/E72qGz33W/tX1bx8MXsbB4lxiuPETc9v/008vYZ60yjIstW22VlVg==",
+      "license": "MIT"
+    },
     "node_modules/react-native-svg": {
       "version": "15.10.1",
       "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.10.1.tgz",
diff --git a/package.json b/package.json
index 7a0c0d2..fd3a2bf 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
     "react-native-progress": "^5.0.1",
     "react-native-safe-area-context": "^4.12.0",
     "react-native-screens": "~4.1.0",
+    "react-native-sse": "^1.2.1",
     "react-native-vector-icons": "^10.2.0",
     "react-query": "^3.39.3",
     "rxjs": "^7.8.1",
-- 
GitLab


From f065f8a98176e4fa87e5d32f3bac1b413703c7bc Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 21:49:02 +0100
Subject: [PATCH 267/283] feat: new service

---
 services/MultiService.ts | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 services/MultiService.ts

diff --git a/services/MultiService.ts b/services/MultiService.ts
new file mode 100644
index 0000000..f0de634
--- /dev/null
+++ b/services/MultiService.ts
@@ -0,0 +1,36 @@
+import axios from "axios";
+import {QuestionResponse} from "../models/Response/QuestionResponse";
+import HttpError from "./HttpError";
+
+export const useMultiService = () => {
+    const url = "https://klebert-host.com:33037"
+
+    const createParty = async (quizId: string) : Promise<string | HttpError> => {
+        console.log("Create party with ID :", quizId);
+        console.log(url+"/party");
+        const requestBody = {
+            quizId: quizId,
+        };
+
+        try {
+            const response = await axios.post(`${url}/party`, requestBody, {
+                withCredentials: true,
+            });
+            console.log("Response data:", response.data.id);
+            return response.data.id;
+        } catch (error: any) {
+            console.log("Error while create party:", error);
+
+            if (error.response) {
+                return new HttpError(error.response.status, error.response.data?.message || "HTTP error");
+            } else {
+                return new HttpError(500, "Unexpected error: " + error.message);
+            }
+        }
+    }
+
+    return {
+        createParty: createParty,
+    }
+
+}
\ No newline at end of file
-- 
GitLab


From 4bd7cbb9fec9694f9fdd6053a52f5156d3931253 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 21:52:14 +0100
Subject: [PATCH 268/283] refactor: edit service

---
 services/QuizService.ts | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index 8dbbc26..18da399 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -1,5 +1,5 @@
 import HttpError from "./HttpError";
-import {Quiz, QuizCommunityResponse} from "../models/Quiz";
+import {QuizCommunityResponse} from "../models/Quiz";
 import axios from "axios";
 import {Answer} from "../models/Answer";
 import {Question} from "../models/Question";
@@ -8,7 +8,7 @@ import {QuizInformations} from "../models/QuizInformations";
 import {QuestionResponse} from "../models/Response/QuestionResponse";
 import {QuizGenerateAnswer} from "../models/QuizGenerateAnswer";
 import {RunInformations} from "../models/RunInformations";
-import {RunsInformationResponse} from "../models/Response/RunsInformationResponse";
+import {AllRunsResponse} from "../models/Response/AllRunsResponse";
 
 export const useQuizService =  () => {
     const url = "https://klebert-host.com:33037"; // Remplace par l'URL de ton endpoint API
@@ -200,7 +200,7 @@ export const useQuizService =  () => {
             // Récupération du run ID
             return {id: runId, quizId: response.data.quizId};
         } catch (error: any) {
-            console.log("Error while generating quiz:", error);
+            console.log("Error while generating random quiz:", error);
 
             if (error.response) {
                 // Gestion des erreurs HTTP
@@ -285,15 +285,15 @@ export const useQuizService =  () => {
         }
     }
     
-    const getAllRuns = async (): Promise<RunInformations[] | HttpError> => {
+    const getAllRuns = async (): Promise<AllRunsResponse | HttpError> => {
         try {
-            const response = await axios.get<RunsInformationResponse>(`${url}/run/userRuns`, {
+            const response = await axios.get<AllRunsResponse>(`${url}/run/userRuns`, {
                 headers: {
                     "Content-Type": "application/json",
                 },
             });
 
-            return response.data.runs;
+            return response.data;
         } catch (error: any) {
             console.log("Error while getAllRuns:", error);
             if (error.response) {
-- 
GitLab


From 09f0fcb6d23fa360acae6a8e299c0210b4adb175 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 21:52:52 +0100
Subject: [PATCH 269/283] refactor: lobby

---
 screens/Multiplayer/Lobby/Lobby.tsx           | 121 +++++++-----------
 .../OnlineQuiz/OnlineCreateLobby.tsx          |   5 +-
 .../Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx |   7 +-
 3 files changed, 53 insertions(+), 80 deletions(-)

diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index fee0d0d..c20d61a 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -1,16 +1,17 @@
-import { View, Text, StyleSheet, Button, Image, ScrollView, FlatList } from "react-native";
-import TemplateMenu from "../../../templates/TemplateMenu";
+import {View, Text, StyleSheet, Image, FlatList} from "react-native";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
 import React, {useEffect, useState} from "react";
-import WhiteButton from "../../../components/buttons/WhiteButton";
-import BlueButton from "../../../components/buttons/BlueButton";
 import { TouchableOpacity } from "react-native";
-import ModalInvitePlayer from "../../../components/Multiplayer/ModalInvitePlayer";
 import {User} from "../../../models/User";
-import {QuizGenerateAnswer} from "../../../models/QuizGenerateAnswer";
 import {io, Socket} from "socket.io-client";
 import useCookie from "../../../hooks/UseCookie";
-
+import {useMultiService} from "../../../services/MultiService";
+import HttpError from "../../../services/HttpError";
+import TemplateMenu from "../../../templates/TemplateMenu";
+import BlueButton from "../../../components/buttons/BlueButton";
+import WhiteButton from "../../../components/buttons/WhiteButton";
+import ModalInvitePlayer from "../../../components/Multiplayer/ModalInvitePlayer";
+import EventSource from "react-native-sse";
 interface Props {
     navigation: NavigationProp<any>;
     route: RouteProp<RoutePropsType, "Lobby">;
@@ -18,98 +19,70 @@ interface Props {
 
 type RoutePropsType = {
     Lobby: {
-        quizIdOrRoomId: string;
+        quizId?: string;
+        roomId?: string;
         nbPlayers: number;
         isHost: boolean;
     };
 };
 
+type CustomEventType = "userJoined" | "nextQuestion"
 
 
 export default function Lobby({navigation, route}: Props) {
-    const { quizIdOrRoomId, nbPlayers, isHost} = route.params;
+    const { quizId, roomId, nbPlayers, isHost} = route.params;
 
-    // const [isHost, setIsHost] = useState<boolean>(true);
-    const [showModal, setShowModal] = useState<boolean>(false);
     const [players, setPlayers] = useState<User[]>([{ id: 0, username: 'Invite', email: 'invite@email.com'}]);
-    const {getCookie} = useCookie('access_token');
     const [socket, setSocket] = useState<Socket | null>(null);
-    const [roomId, setRoomId] = useState<string>("");
+    const [roomIdCreated, setRoomIdCreated] = useState<string | undefined>(roomId);
     const [runId, setRunId] = useState<string>("");
+    const [showModal, setShowModal] = useState<boolean>(false);
 
-    const userInvite = { id: 0, username: 'Invite', email: 'invite@email.com'}
-    const initSocket = async () => {
-        const cookie = await getCookie();
-        const newSocket = io("http://klebert-host.com:33053/party", {
-            transports: ["websocket"], // Utilise WebSocket uniquement
-            extraHeaders: {
-                Cookie: `access_token=${cookie}`,
-            },
-        });
+    const {createParty} = useMultiService();
 
-        setSocket(newSocket);
+    const userInvite = { id: 0, username: 'Invite', email: 'invite@email.com'}
+    let goodId = roomId;
+    const initSSE = async () => {
+        console.log("Init SSE for quiz ID:", quizId);
+        if(isHost && quizId) {
+            const response = await createParty(quizId);
+            if (HttpError.isHttpError(response)) {
+                console.error("Failed to create party:", response.message);
+                return;
+            }
+            console.log("Created party with ID:", response);
+            goodId = response;
+            setRoomIdCreated(response);
+        }
+        console.log("User try to joined party with ID:", goodId);
+        console.log(`https://klebert-host.com:33037/party/join/${goodId}`)
 
-        if(isHost) {
-            newSocket.on("roomCreated", (data) => {
-                console.log("Room created : ", data.id);
-                console.log("Connected to the server");
+        const es = new EventSource<CustomEventType>(`https://klebert-host.com:33037/party/join/${goodId}`);
 
-                setRoomId(data.id);
-                console.log("Host id room : ", data.id);
-                newSocket.emit("joinRoom", { roomId: data.id });
+        es.addEventListener("userJoined", (event) => {
+            console.log("User joined event data:", event.data);
+            if(!event.data) return;
 
-                setTimeout(() => {
-                    console.log("Sending generateRun");
-                    newSocket.emit("generateRun");
-                },1000);
-            });
+            const newUsers: User[] = JSON.parse(event.data);
 
-            newSocket.on("connect", () => {
-                newSocket.emit("createRoom", { quizId: quizIdOrRoomId });
+            setPlayers((prevPlayers) => {
+                const ids = new Set(prevPlayers.map((player) => player.id));
+                const filteredNewUsers = newUsers.filter((user) => !ids.has(user.id));
+                return [...prevPlayers, ...filteredNewUsers];
             });
-            console.log("Host");
-
-        }
-        else {
-            console.log("pas Host id room : ", quizIdOrRoomId);
-            newSocket.emit("joinRoom", { roomId: quizIdOrRoomId });
 
-            setTimeout(() => {
-                console.log("Sending generateRun");
-                newSocket.emit("generateRun");
-            },1000);
 
-        }
-
-        newSocket.on("connect_error", (err) => {
-            console.error("Connection error: ", err.message);
         });
 
-        newSocket.on("error", (err) => {
-            console.error("Socket error: ", err.message);
+        es.addEventListener("error", (err) => {
+            console.error("Error with SSE:", err);
         });
 
-        // Mettez à jour la liste des joueurs lorsque quelqu'un rejoint
-        newSocket.on("userJoined", (data: User[]) => {
-            console.log("Updated user list:", data);
-            setPlayers([userInvite, ...data]);
-        });
-
-        newSocket.on("runId", (data) => {
-            console.log("Run ID:", data);
-            setRunId(data);
-        });
-    }
-
-
+        return () => es.close();
+    };
 
     useEffect(() => {
-        initSocket();
-        // return () => {
-        //     if(socket === null) return;
-        //     socket.disconnect();
-        //     setSocket(null);
-        // };
+        initSSE();
     }, []);
 
     const item = ({ item }: { item: User }) => {
@@ -139,7 +112,7 @@ export default function Lobby({navigation, route}: Props) {
     };
 
     const onPlayPressed = () => {
-        navigation.navigate("PlayingQuizMultiMode", {runId: runId, socket: socket, roomId: roomId});
+        navigation.navigate("PlayingQuizMultiMode", {runId: runId, socket: socket, roomId: roomIdCreated});
     };
 
     const onCancelPressed = () => {
@@ -180,7 +153,7 @@ export default function Lobby({navigation, route}: Props) {
                     }
                 </View>
             </TemplateMenu>
-            <ModalInvitePlayer showModal={showModal} onClosePressed={() => setShowModal(false)} roomId={roomId} />
+            <ModalInvitePlayer showModal={showModal} onClosePressed={() => setShowModal(false)} roomId={roomIdCreated} />
         </View>
     )
 }
diff --git a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
index f8f5d1a..7f7e8ee 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlineCreateLobby.tsx
@@ -1,4 +1,4 @@
-import { Text,View, StyleSheet } from "react-native";
+import { View, StyleSheet } from "react-native";
 import React, {useEffect, useState} from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
 import {useQuizService} from "../../../services/QuizService";
@@ -61,7 +61,8 @@ export default function OnlineCreateLobby({navigation}: Props) {
         }
 
         navigation.navigate("Lobby", {
-            quizIdOrRoomId: quizGenerated.quizId,
+            quizId: quizGenerated.quizId,
+            roomId: null,
             nbPlayers: parseInt(nbPlayers),
             isHost: true,
         });
diff --git a/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx b/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
index 03aba42..c91647d 100644
--- a/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
+++ b/screens/Multiplayer/OnlineQuiz/OnlinePlayQuiz.tsx
@@ -1,8 +1,6 @@
 import { StyleSheet, View, Text } from "react-native";
-import AboutAQuiz from "../../../components/PlayQuiz/AboutAQuiz";
-import React, { useEffect } from "react";
+import React from "react";
 import InputPlayQuiz from "../../../components/PlayQuiz/InputPlayQuiz";
-import {Quiz} from "../../../models/Quiz";
 import { useQuizService } from "../../../services/QuizService";
 import HttpError from "../../../services/HttpError";
 // import {getIdOfCategory} from "../../../helper/QuizHelper";
@@ -33,7 +31,8 @@ export default function OnlinePlayQuiz({navigation}: Props) {
         }
         setError("");
         navigation.navigate("Lobby", {
-            quizIdOrRoomId: codeQuiz,
+            quizId: null,
+            roomId: codeQuiz,
             nbPlayers: 10,
             isHost: false,
         });
-- 
GitLab


From 6c0931cd19712a20ee709cebe32a432ab7ce24c9 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 21:53:44 +0100
Subject: [PATCH 270/283] refactor: type of runs return

---
 components/Multiplayer/ModalInvitePlayer.tsx  |  2 +-
 components/PlayQuiz/RunStartedList.tsx        | 16 ++++-----
 screens/Home/MyQuizzes/InformationsOfRuns.tsx | 34 +++++--------------
 screens/Home/MyQuizzes/MyQuizzes.tsx          |  9 ++---
 templates/TemplateRunList.tsx                 |  9 ++---
 5 files changed, 24 insertions(+), 46 deletions(-)

diff --git a/components/Multiplayer/ModalInvitePlayer.tsx b/components/Multiplayer/ModalInvitePlayer.tsx
index 2c5fab8..de1e14c 100644
--- a/components/Multiplayer/ModalInvitePlayer.tsx
+++ b/components/Multiplayer/ModalInvitePlayer.tsx
@@ -4,7 +4,7 @@ import WhiteButton from "../buttons/WhiteButton";
 interface Props {
     showModal: boolean;
     onClosePressed: () => void;
-    roomId: string;
+    roomId?: string;
 }
 
 export default function ModalInvitePlayer({showModal, onClosePressed, roomId}: Props) {
diff --git a/components/PlayQuiz/RunStartedList.tsx b/components/PlayQuiz/RunStartedList.tsx
index 6a7da51..34da385 100644
--- a/components/PlayQuiz/RunStartedList.tsx
+++ b/components/PlayQuiz/RunStartedList.tsx
@@ -1,8 +1,6 @@
 import React from "react";
 import { FlatList, View, Text, StyleSheet, TouchableOpacity, ActivityIndicator } from "react-native";
-import {Quiz} from "../../models/Quiz";
-import { NavigationProp } from "@react-navigation/native";
-import {RunInformations} from "../../models/RunInformations";
+import {RunsInformationsAllRuns} from "../../models/RunsInformationsAllRuns";
 
 
 
@@ -36,17 +34,15 @@ import {RunInformations} from "../../models/RunInformations";
  * @returns Un composant React contenant une liste interactive de quiz ou des messages en fonction de l'état.
  */
 interface Props {
-    runList: RunInformations[] | undefined;
-    onRunPressed:(runInfo: RunInformations) => void;
+    runList: RunsInformationsAllRuns[] | undefined;
+    onRunPressed:(runInfo: RunsInformationsAllRuns) => void;
     isLoadingData: boolean;
 }
 export default function RunStartedList({ runList, isLoadingData, onRunPressed }: Props) {
-    const renderQuizItem = ({ item }: { item: RunInformations }) => (
+    const renderQuizItem = ({ item }: { item: RunsInformationsAllRuns }) => (
         <TouchableOpacity style={styles.quizItem} onPress={() => onRunPressed(item)}>
-            <Text style={styles.quizTitle}>{item.id}</Text>
-            <Text style={styles.quizDetails}>
-                {item.score}
-            </Text>
+            <Text style={styles.quizTitle}>{item.quiz.name ? item.quiz.name : item.id}</Text>
+            <Text style={styles.quizDetails}>{item.quiz.category ? item.quiz.category.name : "Community quiz"}</Text>
         </TouchableOpacity>
     );
 
diff --git a/screens/Home/MyQuizzes/InformationsOfRuns.tsx b/screens/Home/MyQuizzes/InformationsOfRuns.tsx
index 5ca934b..367b942 100644
--- a/screens/Home/MyQuizzes/InformationsOfRuns.tsx
+++ b/screens/Home/MyQuizzes/InformationsOfRuns.tsx
@@ -1,16 +1,12 @@
-import React, {useEffect, useState} from "react";
+import React from "react";
 import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
 import TemplateMenu from "../../../templates/TemplateMenu";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
-import {Quiz} from "../../../models/Quiz";
-import {RunInformations} from "../../../models/RunInformations";
-import {QuizInformations} from "../../../models/QuizInformations";
-import HttpError from "../../../services/HttpError";
-import {useQuizService} from "../../../services/QuizService";
+import {RunsInformationsAllRuns} from "../../../models/RunsInformationsAllRuns";
 
 type RoutePropsType = {
     InformationsOfRuns: {
-        runInformations: RunInformations;
+        runInformations: RunsInformationsAllRuns;
     };
 };
 interface Props {
@@ -20,20 +16,6 @@ interface Props {
 
 export default function InformationsOfRuns({ navigation, route }: Props) {
     const { runInformations,  } = route.params;
-    const {getQuizInformations} = useQuizService();
-    const [quizInformations, setQuizInformations] = useState<QuizInformations>();
-
-    const fetchQuizInformations = async () => {
-        const quizInformations = await getQuizInformations(runInformations.quizId);
-        if (quizInformations instanceof HttpError) {
-            return;
-        }
-        setQuizInformations(quizInformations);
-    }
-
-    useEffect(() => {
-        fetchQuizInformations();
-    }, []);
 
     const onPlay = () => {
         navigation.reset({
@@ -50,13 +32,15 @@ export default function InformationsOfRuns({ navigation, route }: Props) {
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
             <View style={styles.container}>
-                <Text style={styles.quizTitle}>{quizInformations ? quizInformations.name : "Loading..."}</Text>
-                <Text style={styles.quizDescription}>{quizInformations ? quizInformations.description :"Loading..."}</Text>
+                <Text style={styles.quizTitle}>{runInformations.quiz.name ? runInformations.quiz.name : "Loading..."}</Text>
+                {/*<Text style={styles.quizDescription}>{runInformations ? runInformations.description :"Loading..."}</Text>*/}
 
                 <View style={styles.aboutContainer}>
                     <Text style={styles.aboutTitle}>About this quiz :</Text>
-                    <Text style={styles.aboutDetails}>{runInformations.questionIndex}/{quizInformations ? quizInformations.questionCount : "Loading..."} questions, {quizInformations ? quizInformations.difficulty.name : "Loading..."}</Text>
-                    <Text style={styles.aboutDetails}>By : {quizInformations?.authorId && "Unknown"}</Text>
+                    <Text style={styles.aboutDetails}>Current score : {runInformations ? runInformations.score : "Loading..."}</Text>
+                    <Text style={styles.aboutDetails}>Question : {runInformations.questionIndex}/{runInformations ? runInformations.quiz.questionCount : "Loading..."}</Text>
+                    <Text style={styles.aboutDetails}>Difficulty : {runInformations ? runInformations.quiz.difficulty.name : "Loading..."}</Text>
+                    {/*<Text style={styles.aboutDetails}>By : {runInformations.authorId && "Unknown"}</Text>*/}
                 </View>
 
                 <TouchableOpacity style={styles.playButton} onPress={onPlay}>
diff --git a/screens/Home/MyQuizzes/MyQuizzes.tsx b/screens/Home/MyQuizzes/MyQuizzes.tsx
index 1e5ce51..d7d94bc 100644
--- a/screens/Home/MyQuizzes/MyQuizzes.tsx
+++ b/screens/Home/MyQuizzes/MyQuizzes.tsx
@@ -1,15 +1,16 @@
 import {NavigationProp} from "@react-navigation/native";
 import React, {useEffect, useState} from "react";
 import TemplateRunList from "../../../templates/TemplateRunList";
-import {RunInformations} from "../../../models/RunInformations";
 import {useQuizService} from "../../../services/QuizService";
 import HttpError from "../../../services/HttpError";
+import {AllRunsResponse} from "../../../models/Response/AllRunsResponse";
+import {RunsInformationsAllRuns} from "../../../models/RunsInformationsAllRuns";
 
 interface Props {
     navigation: NavigationProp<any>
 }
 export default function MyQuizzes({navigation}: Props) {
-    const [runList, setRunList] = useState<RunInformations[] | undefined>(undefined)
+    const [runList, setRunList] = useState<AllRunsResponse | undefined>(undefined)
     const [input, setInput] = useState<string>("")
     const {getAllRuns} = useQuizService();
 
@@ -26,11 +27,11 @@ export default function MyQuizzes({navigation}: Props) {
         getRuns();
     },[]);
 
-    const onQuizPressed = (runInfo: RunInformations) => {
+    const onQuizPressed = (runInfo: RunsInformationsAllRuns) => {
         navigation.navigate("InformationsOfRuns", { runInformations: runInfo });
     };
 
     return (
-        <TemplateRunList title={"My quizzes"} setTextInInput={setInput} runList={runList} navigation={navigation} buttonGoBack={true} isLoadingData={false} onRunPressed={onQuizPressed}/>
+        <TemplateRunList title={"My quizzes"} setTextInInput={setInput} runList={runList?.runs} navigation={navigation} buttonGoBack={true} isLoadingData={false} onRunPressed={onQuizPressed}/>
     );
 }
\ No newline at end of file
diff --git a/templates/TemplateRunList.tsx b/templates/TemplateRunList.tsx
index 20125c1..8a542ab 100644
--- a/templates/TemplateRunList.tsx
+++ b/templates/TemplateRunList.tsx
@@ -2,11 +2,8 @@ import React from "react";
 import {View, Text, StyleSheet} from "react-native";
 import TemplateMenu from "./TemplateMenu";
 import {NavigationProp} from "@react-navigation/native";
-import InputPlayQuiz from "../components/PlayQuiz/InputPlayQuiz";
-import QuizList from "../components/lists/QuizList";
-import {Quiz} from "../models/Quiz";
 import RunStartedList from "../components/PlayQuiz/RunStartedList";
-import {RunInformations} from "../models/RunInformations";
+import {RunsInformationsAllRuns} from "../models/RunsInformationsAllRuns";
 
 
 /**
@@ -24,11 +21,11 @@ interface Props {
     navigation: NavigationProp<any>
     title: string
     setTextInInput: (text: string) => void
-    runList: RunInformations[] | undefined
+    runList: RunsInformationsAllRuns[] | undefined
     buttonGoBack: boolean
     isLoadingData: boolean
     nextPage?: () => void;
-    onRunPressed:(runInfo: RunInformations) => void;
+    onRunPressed:(runInfo: RunsInformationsAllRuns) => void;
 }
 
 export default function TemplateRunList({navigation, title, setTextInInput, runList, buttonGoBack, isLoadingData, onRunPressed }: Props) {
-- 
GitLab


From d5f858189982e3c5745a4b242849b6295e513fd4 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 23:17:30 +0100
Subject: [PATCH 271/283] style: info of quiz or run

---
 .../InformationsOfQuiz/InformationsOfQuiz.tsx | 89 +++++++++++++++++--
 screens/Home/MyQuizzes/InformationsOfRuns.tsx | 86 ++++++++++++++++--
 2 files changed, 160 insertions(+), 15 deletions(-)

diff --git a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
index 6e6c3dd..379dffc 100644
--- a/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
+++ b/screens/Community/InformationsOfQuiz/InformationsOfQuiz.tsx
@@ -1,5 +1,5 @@
 import React from "react";
-import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import {View, Text, StyleSheet, TouchableOpacity, Dimensions} from "react-native";
 import TemplateMenu from "../../../templates/TemplateMenu";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
 import {Quiz} from "../../../models/Quiz";
@@ -14,6 +14,7 @@ interface Props {
     navigation: NavigationProp<any>;
     route: RouteProp<RoutePropsType, "InformationsOfQuiz">;
 }
+const { width, height } = Dimensions.get('window');
 
 export default function InformationsOfQuiz({ navigation, route }: Props) {
     const { quiz } = route.params;
@@ -25,18 +26,47 @@ export default function InformationsOfQuiz({ navigation, route }: Props) {
         navigation.navigate('PlayingQuiz', { runId: runId, quizId: quizId });
     }
 
+    const QuizStatistic = ({ label, value }: { label: string, value: string }) => (
+        <View style={styles.statItem}>
+            <Text style={styles.statLabel}>{label}</Text>
+            <Text style={styles.statValue}>{value || "Loading..."}</Text>
+        </View>
+    );
+
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
             <View style={styles.container}>
                 <Text style={styles.quizTitle}>{quiz.name}</Text>
-                <Text style={styles.quizDescription}>{quiz.description && "No Description"}</Text>
 
-                <View style={styles.aboutContainer}>
-                    <Text style={styles.aboutTitle}>About this quiz :</Text>
-                    <Text style={styles.aboutDetails}>{quiz.questionCount} questions, {quiz.difficulty.name}</Text>
-                    <Text style={styles.aboutDetails}>By : {quiz.authorId && "Unknown"}</Text>
+                <View style={styles.infoCard}>
+                    <View style={styles.statsContainer}>
+                        {/*<QuizStatistic*/}
+                        {/*    label="Current Score"*/}
+                        {/*    value={quiz.score ? quiz.score.toString() : "Loading..."}*/}
+                        {/*/>*/}
+                        {/*<QuizStatistic*/}
+                        {/*    label="Progress"*/}
+                        {/*    value={`${quiz.questionIndex}/${quiz.questionCount}`}*/}
+                        {/*/>*/}
+                        <QuizStatistic
+                            label="Difficulty"
+                            value={quiz.difficulty.name}
+                        />
+                    </View>
+                    <View style={styles.descriptionContainer}>
+                        <Text style={styles.descriptionLabel}>Description</Text>
+                        <Text style={styles.descriptionText}>
+                            {quiz.description}
+                        </Text>
+                    </View>
                 </View>
 
+                {/*<View style={styles.aboutContainer}>*/}
+                {/*    <Text style={styles.aboutTitle}>About this quiz :</Text>*/}
+                {/*    <Text style={styles.aboutDetails}>{quiz.questionCount} questions, {quiz.difficulty.name}</Text>*/}
+                {/*    <Text style={styles.aboutDetails}>By : {quiz.authorId && "Unknown"}</Text>*/}
+                {/*</View>*/}
+
                 <TouchableOpacity style={styles.playButton} onPress={onPlay}>
                     <Text style={styles.playButtonText}>PLAY</Text>
                 </TouchableOpacity>
@@ -52,6 +82,35 @@ const styles = StyleSheet.create({
         paddingVertical: 20,
         justifyContent: "flex-start",
     },
+    descriptionContainer: {
+        marginTop: 8,
+    },
+    descriptionLabel: {
+        fontSize: 16,
+        fontWeight: "600",
+        color: "#666",
+        marginBottom: 8,
+    },
+    descriptionText: {
+        fontSize: 15,
+        color: "#4a4a4a",
+        lineHeight: 22,
+    },
+    infoCard: {
+        height: '65%',
+        backgroundColor: "white",
+        borderRadius: width * 0.04,
+        paddingHorizontal: '5%',
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: width * 0.01 },
+        shadowOpacity: 0.1,
+        shadowRadius: width * 0.03,
+        elevation: 5,
+    },
+    statsContainer: {
+        height: '15%',
+        justifyContent: 'space-around',
+    },
     quizTitle: {
         fontSize: 24,
         fontWeight: "bold",
@@ -81,6 +140,24 @@ const styles = StyleSheet.create({
         marginBottom: 10,
         color: "#000",
     },
+    statItem: {
+        flexDirection: 'row',
+        justifyContent: 'space-between',
+        alignItems: 'center',
+        paddingVertical: '3%',
+        borderBottomWidth: 1,
+        borderBottomColor: '#f0f0f0',
+    },
+    statLabel: {
+        fontSize: width * 0.04,
+        color: "#666",
+        fontWeight: "500",
+    },
+    statValue: {
+        fontSize: 16,
+        color: "#2d2d2d",
+        fontWeight: "600",
+    },
     aboutDetails: {
         fontSize: 16,
         color: "#555",
diff --git a/screens/Home/MyQuizzes/InformationsOfRuns.tsx b/screens/Home/MyQuizzes/InformationsOfRuns.tsx
index 367b942..6a461fd 100644
--- a/screens/Home/MyQuizzes/InformationsOfRuns.tsx
+++ b/screens/Home/MyQuizzes/InformationsOfRuns.tsx
@@ -1,5 +1,5 @@
 import React from "react";
-import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
+import {View, Text, StyleSheet, TouchableOpacity, Dimensions} from "react-native";
 import TemplateMenu from "../../../templates/TemplateMenu";
 import {NavigationProp, RouteProp} from "@react-navigation/native";
 import {RunsInformationsAllRuns} from "../../../models/RunsInformationsAllRuns";
@@ -14,6 +14,8 @@ interface Props {
     route: RouteProp<RoutePropsType, "InformationsOfRuns">;
 }
 
+const { width, height } = Dimensions.get('window');
+
 export default function InformationsOfRuns({ navigation, route }: Props) {
     const { runInformations,  } = route.params;
 
@@ -28,19 +30,38 @@ export default function InformationsOfRuns({ navigation, route }: Props) {
             ]
         });
     }
+    const QuizStatistic = ({ label, value }: { label: string, value: string }) => (
+        <View style={styles.statItem}>
+            <Text style={styles.statLabel}>{label}</Text>
+            <Text style={styles.statValue}>{value || "Loading..."}</Text>
+        </View>
+    );
 
     return (
         <TemplateMenu navigation={navigation} headerNavigation={true} buttonGoBack={true}>
             <View style={styles.container}>
                 <Text style={styles.quizTitle}>{runInformations.quiz.name ? runInformations.quiz.name : "Loading..."}</Text>
-                {/*<Text style={styles.quizDescription}>{runInformations ? runInformations.description :"Loading..."}</Text>*/}
-
-                <View style={styles.aboutContainer}>
-                    <Text style={styles.aboutTitle}>About this quiz :</Text>
-                    <Text style={styles.aboutDetails}>Current score : {runInformations ? runInformations.score : "Loading..."}</Text>
-                    <Text style={styles.aboutDetails}>Question : {runInformations.questionIndex}/{runInformations ? runInformations.quiz.questionCount : "Loading..."}</Text>
-                    <Text style={styles.aboutDetails}>Difficulty : {runInformations ? runInformations.quiz.difficulty.name : "Loading..."}</Text>
-                    {/*<Text style={styles.aboutDetails}>By : {runInformations.authorId && "Unknown"}</Text>*/}
+                <View style={styles.infoCard}>
+                    <View style={styles.statsContainer}>
+                        <QuizStatistic
+                            label="Current Score"
+                            value={runInformations?.score.toString()}
+                        />
+                        <QuizStatistic
+                            label="Progress"
+                            value={`${runInformations.questionIndex}/${runInformations?.quiz.questionCount}`}
+                        />
+                        <QuizStatistic
+                            label="Difficulty"
+                            value={runInformations?.quiz.difficulty.name}
+                        />
+                    </View>
+                    <View style={styles.descriptionContainer}>
+                        <Text style={styles.descriptionLabel}>Description</Text>
+                        <Text style={styles.descriptionText}>
+                            {runInformations.quiz.description}
+                        </Text>
+                    </View>
                 </View>
 
                 <TouchableOpacity style={styles.playButton} onPress={onPlay}>
@@ -58,6 +79,20 @@ const styles = StyleSheet.create({
         paddingVertical: 20,
         justifyContent: "flex-start",
     },
+    descriptionContainer: {
+        marginTop: 8,
+    },
+    descriptionLabel: {
+        fontSize: 16,
+        fontWeight: "600",
+        color: "#666",
+        marginBottom: 8,
+    },
+    descriptionText: {
+        fontSize: 15,
+        color: "#4a4a4a",
+        lineHeight: 22,
+    },
     quizTitle: {
         fontSize: 24,
         fontWeight: "bold",
@@ -81,6 +116,39 @@ const styles = StyleSheet.create({
         shadowRadius: 3,
         elevation: 5,
     },
+    statsContainer: {
+        height: '40%',
+        justifyContent: 'space-around',
+    },
+    statValue: {
+        fontSize: 16,
+        color: "#2d2d2d",
+        fontWeight: "600",
+    },
+    infoCard: {
+        height: '65%',
+        backgroundColor: "white",
+        borderRadius: width * 0.04,
+        padding: '5%',
+        shadowColor: "#000",
+        shadowOffset: { width: 0, height: width * 0.01 },
+        shadowOpacity: 0.1,
+        shadowRadius: width * 0.03,
+        elevation: 5,
+    },
+    statItem: {
+        flexDirection: 'row',
+        justifyContent: 'space-between',
+        alignItems: 'center',
+        paddingVertical: '3%',
+        borderBottomWidth: 1,
+        borderBottomColor: '#f0f0f0',
+    },
+    statLabel: {
+        fontSize: width * 0.04,
+        color: "#666",
+        fontWeight: "500",
+    },
     aboutTitle: {
         fontSize: 18,
         fontWeight: "bold",
-- 
GitLab


From a98ad176c73c408af8ed4f0859bced4af0fc2b14 Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Tue, 14 Jan 2025 23:18:00 +0100
Subject: [PATCH 272/283] refactor: clean code

---
 components/ModalJoinQuiz.tsx             | 135 -----------------------
 models/RunsInformationsAllRuns.tsx       |   1 +
 screens/Home/HomeChild.tsx               |   2 -
 screens/Multiplayer/MultiplayerChild.tsx |   1 -
 4 files changed, 1 insertion(+), 138 deletions(-)
 delete mode 100644 components/ModalJoinQuiz.tsx

diff --git a/components/ModalJoinQuiz.tsx b/components/ModalJoinQuiz.tsx
deleted file mode 100644
index be899d2..0000000
--- a/components/ModalJoinQuiz.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import { Modal, View, Text, StyleSheet, TextInput } from "react-native";
-import DefaultButton from "./buttons/DefaultButton";
-import {useState} from "react";
-import {useQuizService} from "../services/QuizService";
-import HttpError from "../services/HttpError";
-
-interface Props {
-    navigation: any;
-    modalVisible: boolean;
-    setModalVisible: (newModalVisible: boolean) => void;
-}
-
-export default function ModalJoinQuiz({ navigation, modalVisible, setModalVisible }: Props) {
-
-    const [isError, setIsError] = useState<boolean>(false);
-    const [errorMessage, setErrorMessage] = useState<string>("");
-    const [codeQuiz, setCodeQuiz] = useState<string>("");
-    const {remainingQuiz} = useQuizService();
-    const handleButtonClosePressed = () => {
-        setModalVisible(!modalVisible);
-        setIsError(false);
-        setErrorMessage("");
-    }
-
-    const handleButtonJoinQuizPressed = async () => {
-        const quiz = await remainingQuiz(codeQuiz);
-        if(HttpError.isHttpError(quiz)){
-            setIsError(true);
-            setErrorMessage("Code quiz invalide");
-            return;
-        }
-
-        navigation.reset({
-            index: 0,
-            routes: [
-                {
-                    name: "PlayingQuiz",
-                    params: {quizRecovered: quiz},
-                },
-            ]
-        });
-
-
-    }
-
-    return (
-        <Modal
-            animationType="slide"
-            transparent={true}
-            visible={modalVisible}
-            onRequestClose={() => {
-                setModalVisible(!modalVisible);
-            }}
-        >
-            <View style={styles.centeredView}>
-                <View style={styles.modalView}>
-                    <View style={styles.containerMenu}>
-                        <Text style={styles.textMenu}>PLAY YOUR QUIZ</Text>
-                        <DefaultButton text="X" handleButtonPressed={handleButtonClosePressed} buttonStyle={styles.buttonMenu} buttonText={styles.buttonTextMenu}/>
-                    </View>
-                    <View style={styles.containerCode}>
-                        <Text style={styles.textCode}>ENTER THE QUIZ ID</Text>
-                        {isError && <Text style={styles.textError}>{errorMessage}</Text>}
-                        <TextInput placeholder="TYPE A CODE" style={styles.textInputCode} onChangeText={(text) => setCodeQuiz(text)}></TextInput>
-                        <DefaultButton text="PLAY" handleButtonPressed={handleButtonJoinQuizPressed} buttonStyle={styles.buttonCode}/>
-                    </View>
-                </View>
-            </View>
-        </Modal>
-    );
-}
-
-const styles = StyleSheet.create({
-    centeredView: {
-        flex: 1,
-        justifyContent: 'center',
-        alignItems: 'center',
-    },
-    modalView: {
-        height: '35%',
-        width: '80%',
-        margin: '10%',
-        padding: '10%',
-        backgroundColor: 'white',
-        borderRadius: 20,
-        alignItems: 'center',
-        shadowColor: '#000',
-        shadowOffset: {
-            width: 0,
-            height: 2,
-        },
-        shadowOpacity: 0.25,
-        shadowRadius: 4,
-        elevation: 5,
-    },
-    containerMenu: {
-        flexDirection: 'row', 
-        alignItems: 'center',
-        justifyContent: 'space-between', 
-        height: '30%', 
-    },
-    textMenu: {
-        flex: 1,
-        textAlign: 'center',
-        fontSize: 20,
-        fontWeight: 'bold',
-    },
-    buttonMenu: {
-        padding: 10,
-        backgroundColor: '#FFFFFF',
-    },
-    buttonTextMenu: {
-        color: '#D5D5D5',
-        fontSize: 24,
-    },
-    containerCode: {
-        height: '100%',
-        width: '100%',
-    },
-    textCode: {
-        fontSize: 14
-    },
-    textError: {
-        fontSize: 14,
-        color: "red"
-    },
-    textInputCode: {
-        borderColor: '#1FA9FF',
-        borderRadius: 10,
-        borderWidth: 2,
-    },
-    buttonCode: {
-        margin: 20
-    }
-});
\ No newline at end of file
diff --git a/models/RunsInformationsAllRuns.tsx b/models/RunsInformationsAllRuns.tsx
index f70c778..0022d66 100644
--- a/models/RunsInformationsAllRuns.tsx
+++ b/models/RunsInformationsAllRuns.tsx
@@ -5,6 +5,7 @@ export interface QuizInfoRun{
     difficulty: Difficulty;
     name?: string;
     questionCount: string;
+    description: string;
 }
 export interface RunsInformationsAllRuns{
     id: string;
diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 9532c96..5aaf326 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -3,7 +3,6 @@ import DefaultButton from "../../components/buttons/DefaultButton";
 import {useTranslation} from "react-i18next";
 import { useState } from "react";
 import { TextsStyles } from "../../styles/TextsStyles";
-import ModalJoinQuiz from "../../components/ModalJoinQuiz";
 import MenuButton from "../../components/buttons/MenuButton";
 import {NavigationProp} from "@react-navigation/native";
 import {useQuizService} from "../../services/QuizService";
@@ -57,7 +56,6 @@ export default function HomeChild({navigation}: Props) {
                 <MenuButton text={"PLAY"} handleButtonPressed={handleButtonGeneratePressed}/>
                 <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
             </View>
-             <ModalJoinQuiz modalVisible={modalVisible} setModalVisible={setModalVisible} navigation={navigation}/>
         </View>
     );
 }
diff --git a/screens/Multiplayer/MultiplayerChild.tsx b/screens/Multiplayer/MultiplayerChild.tsx
index f7eee12..c766368 100644
--- a/screens/Multiplayer/MultiplayerChild.tsx
+++ b/screens/Multiplayer/MultiplayerChild.tsx
@@ -1,7 +1,6 @@
 import {Image, StyleSheet, Text, View} from "react-native";
 import {useTranslation} from "react-i18next";
 import React, {useEffect, useState} from "react";
-import ModalJoinQuiz from "../../components/ModalJoinQuiz";
 import MenuButton from "../../components/buttons/MenuButton";
 import {NavigationProp} from "@react-navigation/native";
 import HttpError from "../../services/HttpError";
-- 
GitLab


From 65f1465b41c91de80d7fb2d81e5f682cba6c783a Mon Sep 17 00:00:00 2001
From: GOEPP THOMAS <thomas@saturne-digital.fr>
Date: Wed, 15 Jan 2025 14:18:24 +0100
Subject: [PATCH 273/283] create lobby by community list

---
 screens/Multiplayer/Lobby/Lobby.tsx                           | 4 ++--
 .../InformationsOfQuiz/MultiInformationsOfQuiz.tsx            | 2 +-
 screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx         | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx
index c20d61a..8aaff52 100644
--- a/screens/Multiplayer/Lobby/Lobby.tsx
+++ b/screens/Multiplayer/Lobby/Lobby.tsx
@@ -108,7 +108,7 @@ export default function Lobby({navigation, route}: Props) {
 
 
     const onLeavePressed = () => {
-        navigation.navigate("Multiplayer");
+        navigation.navigate("TabNavigator");
     };
 
     const onPlayPressed = () => {
@@ -116,7 +116,7 @@ export default function Lobby({navigation, route}: Props) {
     };
 
     const onCancelPressed = () => {
-        navigation.navigate("Multiplayer");
+        navigation.navigate("TabNavigator");
     };
 
     const onInvitePressed = () => {
diff --git a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
index 14b3875..ca222f4 100644
--- a/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
+++ b/screens/Multiplayer/MultiplayerCommunity/InformationsOfQuiz/MultiInformationsOfQuiz.tsx
@@ -29,7 +29,7 @@ export default function MultiInformationsOfQuiz({ navigation, route }: Props) {
 
     const onPlayPressed = async (nbPlayer: number) => {
         setShowModal(false);
-        navigation.navigate("Lobby", {quiz: quiz, nbPlayer: nbPlayer, isHost: true});
+        navigation.navigate("Lobby", {quizId: quiz.id, roomId: null, nbPlayer: nbPlayer, isHost: true});
     };
 
     return (
diff --git a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
index f368297..6374b8b 100644
--- a/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
+++ b/screens/Multiplayer/OngoingQuizzes/OngoingQuizzes.tsx
@@ -56,7 +56,7 @@ export default function Community({navigation}: Props) {
                 <TemplateQuizList title={"Ongoing Quizzes"} setTextInInput={setInput} quizList={data?.pages.flat() ?? []} navigation={navigation} buttonGoBack={true} isLoadingData={loading} nextPage={fetchNextPage} onQuizPressed={onQuizPressed}/>
             </View>
             <View style={styles.buttonContainer}>
-                <BlueButton text="JOIN" onPress={onJoinPressed} isDisabled={false}/>
+                <BlueButton text="JOINa" onPress={onJoinPressed} isDisabled={false}/>
             </View>
         </View>
     );
-- 
GitLab


From 3dca0cbbec5b411713e0af1a2d62b1944413fd47 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 14:18:29 +0100
Subject: [PATCH 274/283] refactor: rename file answerbutton

---
 components/buttons/{AnswerButtonText.tsx => AnswerButton.tsx} | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
 rename components/buttons/{AnswerButtonText.tsx => AnswerButton.tsx} (88%)

diff --git a/components/buttons/AnswerButtonText.tsx b/components/buttons/AnswerButton.tsx
similarity index 88%
rename from components/buttons/AnswerButtonText.tsx
rename to components/buttons/AnswerButton.tsx
index 57427b4..00e8876 100644
--- a/components/buttons/AnswerButtonText.tsx
+++ b/components/buttons/AnswerButton.tsx
@@ -11,13 +11,13 @@ interface Props{
 }
 
 /**
- * AnswerButtonText : Un bouton par défaut, il possède déjà un style mais on peut le surcharger grâce à la propriété buttonStyle
+ * AnswerButton : Un bouton par défaut, il possède déjà un style mais on peut le surcharger grâce à la propriété buttonStyle
  * @param text - Texte du bouton
  * @param handleButtonPressed - Fonction qui sera exécutée lorsque le bouton sera pressé
  * @param buttonStyle - Surcharge du style du bouton
  * @param buttonText - Surcharge du style du texte du bouton
  */
-export default function AnswerButtonText({text, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
+export default function AnswerButton({text, handleButtonPressed, buttonStyle, buttonText, indicator}: Props){
     return(
         <View style={styles.containerButton}>
             <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
-- 
GitLab


From 558c3f2f07a16abe496fea36d6e9583555486ccb Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 14:19:11 +0100
Subject: [PATCH 275/283] feat: remove brut quiz

---
 screens/PlayingQuiz/PlayingQuiz.tsx | 86 ++++-------------------------
 1 file changed, 11 insertions(+), 75 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 8c6546d..50867a5 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -30,85 +30,21 @@ export default function PlayingQuiz({route, navigation}:Props) {
     const [score, setScore] = useState(0);
 
     const fetchQuizInformations = async () => {
-        // const quizInformationsFetched = await getQuizInformations(quizId);
-        // if (HttpError.isHttpError(quizInformationsFetched)) {
-        //     return;
-        // }
-        const quizInformationsFetched: QuizInformations = {
-            id: 1,
-            name: "Quiz de Test",
-            description: "Ceci est un quiz de test pour vérifier l'interface.",
-            isCommunity: true,
-            questionCount: 10,
-            categoryId: 2,
-            difficultyId: 3,
-            authorId: {
-                id: 42,
-                username: "TestAuthor",
-                email: "testauthor@example.com"
-            },
-            createdAt: "2025-01-10T10:00:00Z",
-            updatedAt: "2025-01-11T12:00:00Z",
-            category: {
-                id: 2,
-                name: "Science"
-            },
-            difficulty: {
-                id: 3,
-                name: "Moyenne"
-            }
-        };
-        
+        const quizInformationsFetched = await getQuizInformations(quizId);
+        if (HttpError.isHttpError(quizInformationsFetched)) {
+            return;
+        }
+               
         setQuizInformations(quizInformationsFetched);
     }
 
     const fetchActualQuestion = async () => {
-        // const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
-        // if (HttpError.isHttpError(actualQuestionFetched)) {
-        //     return;
-        // }
-        // const actualQuestionFetchedShuffle = shuffleAnswersOfQuiz(actualQuestionFetched);
-        // setActualQuestion(actualQuestionFetchedShuffle);
-        const actualQuestionFetched: Question = {
-            id: 1,
-            text: "Quelle image correspond à une étoile ?",
-            type: "imae",
-            categoryId: 2,
-            quizId: "quiz123",
-            order: 1,
-            answers: [
-                {
-                    id: 1,
-                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-                    isCorrect: true,
-                    questionId: 1
-                },
-                {
-                    id: 2,
-                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-                    isCorrect: false,
-                    questionId: 1
-                },
-                {
-                    id: 3,
-                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-                    isCorrect: false,
-                    questionId: 1
-                },
-                {
-                    id: 4,
-                    text: "https://st3.depositphotos.com/4164031/15614/i/450/depositphotos_156147646-stock-photo-star-field-in-deep-space.jpg",
-                    isCorrect: false,
-                    questionId: 1
-                }
-            ],
-            category: {
-                id: 2,
-                name: "Astronomie"
-            }
-        };
-        
-        setActualQuestion(actualQuestionFetched);
+        const actualQuestionFetched = await getActualQuestionOfAQuiz(runId);
+        if (HttpError.isHttpError(actualQuestionFetched)) {
+            return;
+        }
+        const actualQuestionFetchedShuffle = shuffleAnswersOfQuiz(actualQuestionFetched);
+        setActualQuestion(actualQuestionFetchedShuffle);
     }
 
     useEffect(() => {
-- 
GitLab


From cd0abbfe55f5e6135dbb7bd487afa4d9bfcde942 Mon Sep 17 00:00:00 2001
From: HUSS THEOPHILE <theophile.huss@etu.unistra.fr>
Date: Thu, 16 Jan 2025 13:34:14 +0000
Subject: [PATCH 276/283] feat: Update QuizService -> getRandomQuiz

---
 services/QuizService.ts | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/services/QuizService.ts b/services/QuizService.ts
index 18da399..f742340 100644
--- a/services/QuizService.ts
+++ b/services/QuizService.ts
@@ -184,10 +184,12 @@ export const useQuizService =  () => {
     };
 
     const getRandomQuiz = async (): Promise<QuizGenerateAnswer | HttpError> => {
+        const categories = await getCategories();
+        const difficulties = ['easy', 'medium', 'hard'];
         const requestBody = {
             amount: 10,
-            category: 10,
-            difficulty: "easy",
+            category: categories[Math.floor(Math.random() * categories.length)].id,
+            difficulty: difficulties[Math.floor(Math.random() * difficulties.length)],
         };
 
         try {
-- 
GitLab


From 2c6f197c9b850a0e5170b317621db4fedf939c7e Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 14:39:48 +0100
Subject: [PATCH 277/283] feat: allow image and text

---
 components/buttons/AnswerButton.tsx | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/components/buttons/AnswerButton.tsx b/components/buttons/AnswerButton.tsx
index 00e8876..5577e08 100644
--- a/components/buttons/AnswerButton.tsx
+++ b/components/buttons/AnswerButton.tsx
@@ -1,4 +1,4 @@
-import {TouchableOpacity, Text, StyleSheet, View} from "react-native";
+import {TouchableOpacity, Text, StyleSheet, View, Image} from "react-native";
 import {ButtonsStyles} from "../../styles/ButtonsStyles";
 import {TextsStyles} from "../../styles/TextsStyles";
 
@@ -23,10 +23,21 @@ export default function AnswerButton({text, handleButtonPressed, buttonStyle, bu
             <TouchableOpacity onPress={handleButtonPressed} style={[styles.defaultButton,buttonStyle]}>
                 {indicator !== undefined && (
                     <View style={styles.indicator}>
-                        <Text style={styles.indicatorText}>{indicator}</Text>
+                       <Text style={styles.indicatorText}>{indicator}</Text>
                     </View>
                 )}
-                <Text style={[TextsStyles.defaultButtonText, buttonText]}>{text}</Text>
+                {
+                text.includes('data:image') ?
+                    <Image 
+                        style={[styles.answerImage]}
+                        source={{uri: text}}
+                    />
+                :
+                    text.includes('data:sound') ?
+                    ''
+                    :
+                    <Text style={[TextsStyles.defaultButtonText, buttonText]}>{text}</Text>
+                }
             </TouchableOpacity>
         </View>
     )
@@ -63,5 +74,9 @@ const styles = StyleSheet.create({
         display: 'flex',
         alignItems: 'center',
         justifyContent: 'center'
-    }
+    },
+    answerImage: {
+        width: '100%',
+        height: '100%',
+    },
 })
\ No newline at end of file
-- 
GitLab


From 602694dbf5586d89b247d35b62638aab32d8b291 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 14:40:00 +0100
Subject: [PATCH 278/283] feat: use answerbutton

---
 screens/PlayingQuiz/PlayingQuizBody.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/screens/PlayingQuiz/PlayingQuizBody.tsx b/screens/PlayingQuiz/PlayingQuizBody.tsx
index 8c4f472..619e3b7 100644
--- a/screens/PlayingQuiz/PlayingQuizBody.tsx
+++ b/screens/PlayingQuiz/PlayingQuizBody.tsx
@@ -9,7 +9,7 @@ import BlueButton from "../../components/buttons/BlueButton";
 import {Question} from "../../models/Question";
 import {Answer} from "../../models/Answer";
 import {Quiz} from "../../models/Quiz";
-import AnswerButtonText from "../../components/buttons/AnswerButtonText";
+import AnswerButton from "../../components/buttons/AnswerButton";
 import {QuizInformations} from "../../models/QuizInformations";
 import AnswerButtonImage from "../../components/buttons/AnswerButtonImage";
 
@@ -144,7 +144,7 @@ export default function PlayingQuizBody({ quizInformations, runId, actualQuestio
                                     buttonStyle={getStyleOfAnswerButton(answer.id, selectedAnswerId, correctAnswerId, quizState)}
                                 />
                             :
-                                <AnswerButtonText
+                                <AnswerButton
                                     key={index}
                                     text={answer.text}
                                     handleButtonPressed={() => onAnsweredButtonClicked(answer.id)}
-- 
GitLab


From 4b80b76095090c6a6c0068aebd79fd87ddbaee1e Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 15:00:15 +0100
Subject: [PATCH 279/283] feat: sound not supported

---
 components/buttons/AnswerButton.tsx | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/components/buttons/AnswerButton.tsx b/components/buttons/AnswerButton.tsx
index 5577e08..5b861da 100644
--- a/components/buttons/AnswerButton.tsx
+++ b/components/buttons/AnswerButton.tsx
@@ -1,6 +1,7 @@
 import {TouchableOpacity, Text, StyleSheet, View, Image} from "react-native";
 import {ButtonsStyles} from "../../styles/ButtonsStyles";
 import {TextsStyles} from "../../styles/TextsStyles";
+import React from "react";
 
 interface Props{
     text: string;
@@ -33,8 +34,8 @@ export default function AnswerButton({text, handleButtonPressed, buttonStyle, bu
                         source={{uri: text}}
                     />
                 :
-                    text.includes('data:sound') ?
-                    ''
+                    text.includes('data:audio') ?
+                    <Text style={[TextsStyles.defaultButtonText, buttonText]}>sound: not supported</Text>
                     :
                     <Text style={[TextsStyles.defaultButtonText, buttonText]}>{text}</Text>
                 }
-- 
GitLab


From 36ad94d31a017befa93b90c92d5c1496163f5c4a Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 15:12:32 +0100
Subject: [PATCH 280/283] feat: hide multiplayer

---
 routes/TabNavigation.tsx | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/routes/TabNavigation.tsx b/routes/TabNavigation.tsx
index 332a6cb..bc58c3e 100644
--- a/routes/TabNavigation.tsx
+++ b/routes/TabNavigation.tsx
@@ -37,9 +37,9 @@ export default function TabNavigator() {
                     } else if (route.name === "Community") {
                         iconName = "people";
                     }
-                    else if (route.name === "Multiplayer") {
-                        iconName = "diversity-2";
-                    }
+                    // else if (route.name === "Multiplayer") {
+                    //     iconName = "diversity-2";
+                    // }
                     return <Icon name={iconName ?? ''} size={64} color={color} />;
                 },
             })}
@@ -52,10 +52,10 @@ export default function TabNavigator() {
                 name="Community"
                 component={Community}
             />
-            <Tab.Screen
+            {/* <Tab.Screen
                 name="Multiplayer"
                 component={Multiplayer}
-            />
+            /> */}
             <Tab.Screen
                 name="Profil"
                 component={Profil}
-- 
GitLab


From 5d4f6547124ec88a6d638eccb54598e2a97846de Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 15:14:12 +0100
Subject: [PATCH 281/283] feat: hide my quizzes

---
 screens/Home/HomeChild.tsx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index 718249e..f17f6fe 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -39,8 +39,8 @@ export default function HomeChild({navigation}: Props) {
         });
     }
     const handleButtonMyQuizzesPressed = () => {
-        // navigation.navigate("MyQuizzes");
-        navigation.navigate("PlayingQuiz", {runId: "1", quizId: "1"});
+        navigation.navigate("MyQuizzes");
+        // navigation.navigate("PlayingQuiz", {runId: "1", quizId: "1"});
     }
 
     const handleButtonGeneratePressed = () => {
@@ -55,7 +55,7 @@ export default function HomeChild({navigation}: Props) {
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
                 <MenuButton text={"PLAY"} handleButtonPressed={handleButtonGeneratePressed}/>
-                <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
+                {/* <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/> */}
             </View>
         </View>
     );
-- 
GitLab


From c8fbf4c10a199f52658d040ccbdaeb6cccf1b8b6 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 15:17:26 +0100
Subject: [PATCH 282/283] feat: add score to param playingquizbody

---
 screens/PlayingQuiz/PlayingQuiz.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/PlayingQuiz/PlayingQuiz.tsx b/screens/PlayingQuiz/PlayingQuiz.tsx
index 50867a5..3f9134b 100644
--- a/screens/PlayingQuiz/PlayingQuiz.tsx
+++ b/screens/PlayingQuiz/PlayingQuiz.tsx
@@ -58,7 +58,7 @@ export default function PlayingQuiz({route, navigation}:Props) {
     return (
         <TemplateDuo
             childrenHeader={<PlayingQuizHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score} navigation={navigation}></PlayingQuizHeader>}
-            childrenBody={<PlayingQuizBody quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} navigation={navigation}></PlayingQuizBody>}
+            childrenBody={<PlayingQuizBody score={score} quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} fetchActualQuestion={fetchActualQuestion} setScore={setScore} navigation={navigation}></PlayingQuizBody>}
         />
     );
 }
\ No newline at end of file
-- 
GitLab


From c55cf7f5a82de1270dd2e98a6a1f11ea47a69b07 Mon Sep 17 00:00:00 2001
From: "h.hartz" <henri.hartz@etu.unistra.fr>
Date: Thu, 16 Jan 2025 15:19:11 +0100
Subject: [PATCH 283/283] feat: show my quizzes

---
 screens/Home/HomeChild.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/screens/Home/HomeChild.tsx b/screens/Home/HomeChild.tsx
index f17f6fe..fa17672 100644
--- a/screens/Home/HomeChild.tsx
+++ b/screens/Home/HomeChild.tsx
@@ -55,7 +55,7 @@ export default function HomeChild({navigation}: Props) {
             <View style={styles.buttonContainer}>
                 <MenuButton text={"QUICK GAME"} handleButtonPressed={handleButtonQuickGamePressed}/>
                 <MenuButton text={"PLAY"} handleButtonPressed={handleButtonGeneratePressed}/>
-                {/* <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/> */}
+                <MenuButton text={"MY QUIZZES"} handleButtonPressed={handleButtonMyQuizzesPressed}/>
             </View>
         </View>
     );
-- 
GitLab