Compare commits
	
		
			134 Commits
		
	
	
		
			back-postg
			...
			ba99b3c2b0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ba99b3c2b0 | |||
| 31d82f6271 | |||
| 37e631a096 | |||
| 6306a00eca | |||
|  | c4ba7646d5 | ||
|  | 4e1908d528 | ||
|  | 03bbc77e8a | ||
| ad1fd45bed | |||
| f0c4a3a10d | |||
|  | 70658e4fb9 | ||
|  | 2b31753265 | ||
| f8991e90ab | |||
|  | 60290956ec | ||
|  | b9647ce36e | ||
| 8c4b9ceb9d | |||
|  | 84d8d4523b | ||
| 647812576e | |||
|  | 2dfee66958 | ||
|  | 2b1666c949 | ||
|  | 0c724cae7f | ||
|  | 6de45801d2 | ||
| 03897e1139 | |||
| 00a733c03b | |||
| 3dc8131c33 | |||
|  | 7c271d8c47 | ||
| ead11215ba | |||
| 259d56271c | |||
|  | b9f3bbbe15 | ||
| 14a2a59786 | |||
| 0ae6e7dfda | |||
| 15ccb5630a | |||
| 4ec292cca7 | |||
| 14a953536a | |||
| 288f983816 | |||
| dd6032f3ef | |||
|  | 7e2f5bc506 | ||
|  | 4ef92efd0e | ||
| e769dd6757 | |||
|  | 550a51523f | ||
| 323cb05388 | |||
|  | 7e0851bfef | ||
|  | 98b6d167e8 | ||
| 79baddb8f6 | |||
|  | 0f8c83c2e2 | ||
|  | fad52644d2 | ||
|  | 5f51a1008b | ||
|  | 137bc84c21 | ||
|  | 3c61fdca93 | ||
|  | 5ee3755548 | ||
| 279c171ba2 | |||
| 9ba8e3e84e | |||
|  | 52511dd4c4 | ||
| 6de38a9725 | |||
|  | 84b70f8f38 | ||
|  | 834d68949c | ||
|  | fea8687664 | ||
|  | c94d3654ce | ||
|  | d5c89bf8f4 | ||
|  | 78c72bdd72 | ||
|  | 307c7e700b | ||
|  | 8d486dce89 | ||
|  | 653f923693 | ||
|  | 64da3c9ab0 | ||
|  | 419ceec1bc | ||
|  | e011a5534e | ||
|  | ef964c4d35 | ||
|  | 5608b12f84 | ||
|  | 467babab79 | ||
|  | a2e2395cc2 | ||
|  | e3393c8834 | ||
|  | 5f8fe4a374 | ||
|  | c5e7736a16 | ||
|  | 04589392cb | ||
|  | 1106cf8478 | ||
|  | 215d80ad70 | ||
|  | dded62c25a | ||
|  | 3de7ebe2b1 | ||
|  | 8153496a0f | ||
|  | 861e7495a7 | ||
|  | d78e43f7e0 | ||
|  | 3ca97cf378 | ||
|  | e6a8d98d63 | ||
|  | 8894fea6d4 | ||
|  | 236bb0d167 | ||
|  | d4dcc95d9b | ||
|  | dc843299eb | ||
|  | f3eaf8fe34 | ||
|  | 628c61fb8b | ||
|  | 4880f3829c | ||
|  | 80b2d087e4 | ||
|  | b5c03798fc | ||
|  | 1d970ce5f5 | ||
|  | f9de5ed6bf | ||
|  | e75a5c9d2c | ||
|  | 5c3b2b138d | ||
|  | 8d4dc7916d | ||
|  | 1a6db7c953 | ||
|  | 3890aed158 | ||
|  | dd5ca2cbd7 | ||
|  | 024deeba41 | ||
|  | 1cebebf1a5 | ||
|  | d8bc7cc9b6 | ||
| 067eeb9494 | |||
|  | e66fa33577 | ||
|  | f48b570494 | ||
|  | 0733f8d5af | ||
|  | 8071c01c5d | ||
| b355463dd9 | |||
|  | 27e70ee109 | ||
|  | 153501c8d4 | ||
|  | 40afde89b7 | ||
| 4ee3d9bc44 | |||
|  | 4698aa549f | ||
| d75d45e204 | |||
| 79e949bdd4 | |||
|  | 9f3754776f | ||
|  | 04a73073c1 | ||
|  | 11ab5e1dc4 | ||
|  | 3cb12dab4f | ||
| 651fb2b1a1 | |||
|  | aa5988ce75 | ||
|  | 9ae18e1e4b | ||
|  | 0a9d83655f | ||
| ef8c8e896d | |||
| 22ebb0e1f4 | |||
| 09e4b3262f | |||
| 6a3d4239ab | |||
| 9d71c93b5b | |||
|  | 5145b833ae | ||
|  | 4080cee818 | ||
|  | f4d73654d1 | ||
| 4fda5513a9 | |||
| 32407b0e8f | |||
| b30e1196f4 | 
| @@ -15,4 +15,4 @@ jobs: | ||||
|  | ||||
|       - uses: axel-op/googlejavaformat-action@v3 | ||||
|         with: | ||||
|           args: "--set-exit-if-changed --skip-sorting-imports --aosp -n" | ||||
|           args: "--set-exit-if-changed --skip-sorting-imports --skip-reflowing-long-strings --aosp -n" | ||||
|   | ||||
							
								
								
									
										33
									
								
								.gitea/workflows/build-back.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								.gitea/workflows/build-back.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| name: Build | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|  | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - name: Checkout sources | ||||
|       uses: actions/checkout@v4 | ||||
|  | ||||
|     - name: Load .env file | ||||
|       uses: xom9ikk/dotenv@v2.3.0 | ||||
|       with: | ||||
|         path: ./config/ | ||||
|         mode: dev | ||||
|         load-mode: strict | ||||
|  | ||||
|     - name: Setup Java | ||||
|       uses: actions/setup-java@v4 | ||||
|       with: | ||||
|         distribution: 'temurin' | ||||
|         java-version: 21 | ||||
|      | ||||
|     - name: Setup Gradle | ||||
|       uses: gradle/actions/setup-gradle@v4 | ||||
|       with: | ||||
|         cache-disabled: true # Once the code has been pushed once in main, this should be reenabled.  | ||||
|  | ||||
|     - name: init gradle | ||||
|       working-directory: ./MyINPulse-back/ | ||||
|       run: ./gradlew build # todo: run test, currently fail because no database is present  | ||||
							
								
								
									
										741
									
								
								Documentation/openapi/main.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										741
									
								
								Documentation/openapi/main.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,741 @@ | ||||
| openapi: 3.0.3 | ||||
| info: | ||||
|   title: MyInpulse Backend Api | ||||
|   description: this document servers as a documentation for the backend api.   | ||||
|   version: 0.0.0 | ||||
|  | ||||
| tags: | ||||
|   - name: Entrepreneurs API | ||||
|     description: La partie de l'api dédiée aux entrepreneurs | ||||
|   - name: Admin API | ||||
|     description: La partie de l'api dédiée aux entrepreneurs | ||||
|   - name: Shared API | ||||
|     description: La partie de l'api dédiée aux entrepreneurs et admins | ||||
|  | ||||
|  | ||||
| components: | ||||
|   schemas: | ||||
|     user: | ||||
|       type: object | ||||
|       properties: | ||||
|         nom: | ||||
|           type: string | ||||
|         prenom: | ||||
|           type: string | ||||
|         email: | ||||
|           type: string | ||||
|           example: "example@exmaple.com" | ||||
|         secondaryEmail: | ||||
|           type: string | ||||
|           example: "example@exmaple.com" | ||||
|         tel: | ||||
|           type: string | ||||
|           example: "0612345678" | ||||
|     user-entrepreneur: | ||||
|       type: object | ||||
|       properties: | ||||
|         user: | ||||
|           $ref: "#/components/schemas/user" | ||||
|         entrepreneur: | ||||
|           type: object | ||||
|           properties: | ||||
|             ecole:  | ||||
|               type: string | ||||
|               example: "enseirb" | ||||
|             filiere: | ||||
|               type: string | ||||
|               example: "info" | ||||
|             status: | ||||
|               type: boolean | ||||
|               example: false | ||||
|     user-admin: | ||||
|       type: object | ||||
|       properties: | ||||
|         admin: | ||||
|           $ref: "#/components/schemas/user" | ||||
|  | ||||
|   securitySchemes: | ||||
|       MyINPulse: | ||||
|         type: oauth2 | ||||
|         flows: | ||||
|           implicit: | ||||
|             authorizationUrl: https://petstore3.swagger.io/oauth/authorize | ||||
|             scopes: | ||||
|               MyINPulse-admin: Administrateur | ||||
|               MyINPulse-entrepreneur: Utilisateur | ||||
|  | ||||
| paths: | ||||
|  | ||||
| #          _    ____  __  __ ___ _   _      _    ____ ___  | ||||
| #         / \  |  _ \|  \/  |_ _| \ | |    / \  |  _ \_ _| | ||||
| #        / _ \ | | | | |\/| || ||  \| |   / _ \ | |_) | |  | ||||
| #       / ___ \| |_| | |  | || || |\  |  / ___ \|  __/| |  | ||||
| #      /_/   \_\____/|_|  |_|___|_| \_| /_/   \_\_|  |___| | ||||
| # | ||||
|  | ||||
|   /admin/projects: | ||||
|     get: | ||||
|       summary: Retourne la liste of projets associés à l'admin | ||||
|       tags:  | ||||
|         - Admin API  | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|             - MyINPulse-admin | ||||
|       description: | ||||
|         JSON array of who's elements are objects containing necessary information for the view  | ||||
|         (project name, entrepreneur names, etc..) | ||||
|         of the projects an admin is watching over. | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           content: | ||||
|             application/json: | ||||
|               schema: | ||||
|                 type: array | ||||
|                 items: | ||||
|                   type: object | ||||
|                   properties: | ||||
|                     name: | ||||
|                       type: string | ||||
|                     E_names: | ||||
|                       type: string | ||||
|                       description: entrepreneur names | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is missing or invalid | ||||
|   /admin/projects/pending/decision: | ||||
|     post: | ||||
|       summary: valider un projet en attente de validation | ||||
|       tags: | ||||
|         - Admin API | ||||
|       description: | ||||
|         if the request is accepted the status of the | ||||
|         project is changed to ongoing, entrepreneur | ||||
|         account is confirmed and the project is linked | ||||
|         to the admin accepting the request and the | ||||
|         entrepreneur requesting it. Else the pending | ||||
|         project and user info are deleted. | ||||
|       security: | ||||
|           - MyINPulse: | ||||
|               - MyINPulse-admin | ||||
|       requestBody: | ||||
|         required: true | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 pedingProjectId:  | ||||
|                   type: integer | ||||
|                 decision: | ||||
|                   type: boolean | ||||
|                  | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|              | ||||
|   /admin/projects/add: | ||||
|     post: | ||||
|       summary: Ajout manuel d'un projet | ||||
|       description: | ||||
|         Adds a project with the | ||||
|         inputed details | ||||
|       tags: | ||||
|         - Admin API | ||||
|       security: | ||||
|           - MyINPulse: | ||||
|               - MyINPulse-admin | ||||
|       requestBody: | ||||
|         required: true | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 name: | ||||
|                   type: string | ||||
|                 founder: | ||||
|                   $ref: "#/components/schemas/user-entrepreneur" | ||||
|                  | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|    | ||||
|   /admin/appointments/report/{appointmentId}: | ||||
|     put: | ||||
|       summary: enregistrer un rapport du rendez-vous | ||||
|       description: | ||||
|         Generate a PDF file formatted  | ||||
|         from input text and links it  | ||||
|         to the appointement. | ||||
|       tags: | ||||
|         - Admin API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|           - MyINPulse-admin | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: appointmentId | ||||
|           required: true | ||||
|           schema: | ||||
|             type: integer | ||||
|       requestBody: | ||||
|         required: true | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 title: | ||||
|                   type: string | ||||
|                 body: | ||||
|                   type: string | ||||
|                 conclusion: | ||||
|                   type: string | ||||
|          | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|                     missing or invalid | ||||
|     post: | ||||
|       summary: modifier un rapport déja éxistant du rendez-vous | ||||
|       description: | ||||
|         Modifies the report file to input  | ||||
|         text and links it to the appointement. | ||||
|       tags: | ||||
|         - Admin API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|           - MyINPulse-admin | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: appointmentId | ||||
|           required: true | ||||
|           schema: | ||||
|             type: integer | ||||
|       requestBody: | ||||
|         required: true | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 title: | ||||
|                   type: string | ||||
|                 body: | ||||
|                   type: string | ||||
|                 conclusion: | ||||
|                   type: string | ||||
|          | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|                     missing or invalid | ||||
|  | ||||
|  | ||||
|   /admin/projects/remove/{projectId}: | ||||
|     delete: | ||||
|       summary: supression d'un project | ||||
|       description: | ||||
|         Removes the project | ||||
|         with the inputed id projectId | ||||
|       tags: | ||||
|         - Admin API | ||||
|       security: | ||||
|           - MyINPulse: | ||||
|               - MyINPulse-admin | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: projectId | ||||
|           required: true | ||||
|           schema: | ||||
|             type: integer | ||||
|            | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|       | ||||
|  | ||||
|   /admin/projects/pending: | ||||
|     get: | ||||
|       summary: Retourne la liste des projets en attente de validation | ||||
|       tags:  | ||||
|         - Admin API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|             - MyINPulse-admin | ||||
|       description: | ||||
|         JSON array of who's elements are objects containing | ||||
|         necessary information for the view (project name, | ||||
|         entrepreneur names, etc..) of all pending projects. | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           content: | ||||
|             application/json: | ||||
|               schema: | ||||
|                 type: array | ||||
|                 items: | ||||
|                   type: object | ||||
|                   properties: | ||||
|                     name: | ||||
|                       type: string | ||||
|                     founder: | ||||
|                       $ref: "#/components/schemas/user-entrepreneur" | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is missing or invalid | ||||
|  | ||||
| # | ||||
| #       ____  _                        _      _    ____ ___  | ||||
| #      / ___|| |__   __ _ _ __ ___  __| |    / \  |  _ \_ _| | ||||
| #      \___ \| '_ \ / _` | '__/ _ \/ _` |   / _ \ | |_) | |  | ||||
| #       ___) | | | | (_| | | |  __/ (_| |  / ___ \|  __/| |  | ||||
| #      |____/|_| |_|\__,_|_|  \___|\__,_| /_/   \_\_|  |___| | ||||
| #                    | ||||
|  | ||||
|   /shared/appointments/upcoming: | ||||
|     get: | ||||
|       summary: Retourne la list des prochains rendez-vous de l'utilisateur | ||||
|       tags:  | ||||
|         - Shared API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|             - MyINPulse-admin | ||||
|             - MyINPulse-entrepreneur | ||||
|       description: | ||||
|         JSON array of upcoming appointment data (name, date, time etc..) for a user. | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           content: | ||||
|             application/json: | ||||
|               schema: | ||||
|                 type: array | ||||
|                 items: | ||||
|                   type: object | ||||
|                   properties: | ||||
|                     name: | ||||
|                       type: string | ||||
|                     date: | ||||
|                       type: string | ||||
|                     time: | ||||
|                       type: string | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is missing or invalid         | ||||
|  | ||||
|   /shared/projects/lcsection/{projectId}/{title}/{date}: | ||||
|       get: | ||||
|         summary: Retourne la liste de sections de LC avec un titre donné | ||||
|         tags:  | ||||
|           - Shared API | ||||
|         security: | ||||
|         - MyINPulse: | ||||
|             - MyINPulse-admin | ||||
|             - MyINPulse-entrepreneur | ||||
|         description: | ||||
|           JSON array containing Lean Canvas  | ||||
|           section data with a title for the | ||||
|           current date (or given date if the | ||||
|           date parameter is passed) | ||||
|         parameters: | ||||
|           - in: path | ||||
|             required: true | ||||
|             name: projectId | ||||
|             schema: | ||||
|               type: integer | ||||
|           - in: path | ||||
|             required: true | ||||
|             description: this number can be 1, 2,...,8. It is associated with the title of the lcsection | ||||
|             name: title | ||||
|             schema: | ||||
|               type: integer | ||||
|               enum: [1, 2, 3, 4, 5, 6, 7, 8]  | ||||
|              | ||||
|           - in: path | ||||
|             required: true | ||||
|             name: date | ||||
|             description: the date corresponding to the wanted version of lc section. "Nan" for the latest version | ||||
|             example: "NaN" | ||||
|             schema: | ||||
|               type: string | ||||
|                | ||||
|         responses: | ||||
|           "200": | ||||
|             description: OK | ||||
|             content: | ||||
|               application/json: | ||||
|                 schema: | ||||
|                   type: array | ||||
|                   items: | ||||
|                     type: object | ||||
|                     properties: | ||||
|                       section: | ||||
|                         type: string | ||||
|                       txt: | ||||
|                         type: string | ||||
|                       time: | ||||
|                         type: string | ||||
|           "400": | ||||
|             description: Bad request | ||||
|           "401": | ||||
|             description: Authorization information is missing or invalid | ||||
|    | ||||
|   /shared/projects/entrepreneurs/{projectId}: | ||||
|     get: | ||||
|       summary: Retourne la liste d'entrepreneurs associée à un projet donné | ||||
|       tags:  | ||||
|           - Shared API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|             - MyINPulse-admin | ||||
|             - MyINPulse-entrepreneur | ||||
|       description: | ||||
|         JSON array of entrepreneur | ||||
|         names associated with a project | ||||
|       parameters: | ||||
|           - in: path | ||||
|             name: projectId | ||||
|             schema: | ||||
|               type: integer | ||||
|             required: true | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           content: | ||||
|             application/json: | ||||
|               schema: | ||||
|                 type: array | ||||
|                 items: | ||||
|                   $ref: "#/components/schemas/user-entrepreneur" | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is missing or invalid | ||||
|    | ||||
|   /shared/projects/admin/{projectId}: | ||||
|     get: | ||||
|       summary: Retourne les informations de l'admin qui accompagne le projet | ||||
|       tags:  | ||||
|           - Shared API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|             - MyINPulse-admin | ||||
|             - MyINPulse-entrepreneur | ||||
|       description:  | ||||
|         JSON object containing information (name, gmail, tel, etc..)  | ||||
|         the admin supervising the project with id projectID. | ||||
|       parameters: | ||||
|             - in: path | ||||
|               name: projectId | ||||
|               schema: | ||||
|                 type: integer | ||||
|               required: true | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           content: | ||||
|             application/json: | ||||
|               schema: | ||||
|                 $ref: "#/components/schemas/user-admin" | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|    | ||||
|   /shared/projects/appointments/{projectId}: | ||||
|     get: | ||||
|       summary: Retourne les rendez-vous du projet  | ||||
|       tags:  | ||||
|           - Shared API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|             - MyINPulse-admin | ||||
|             - MyINPulse-entrepreneur | ||||
|       description:  | ||||
|         JSON array of upcoming and past appointment  | ||||
|         data for the project with id projectID. | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: projectId | ||||
|           schema: | ||||
|             type: integer | ||||
|           required: true | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           content: | ||||
|             application/json: | ||||
|               schema: | ||||
|                 type: array | ||||
|                 items: | ||||
|                   type: object | ||||
|                   properties: | ||||
|                     appointementId: | ||||
|                       type: integer | ||||
|                     name:  | ||||
|                       type: string | ||||
|                     date:  | ||||
|                       type: string | ||||
|                     time:  | ||||
|                       type: string | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|   /shared/projects/appointments/report/{apointementId}: | ||||
|     get: | ||||
|       summary: Retourne le rapport pdf du rendez-vous | ||||
|       tags:  | ||||
|           - Shared API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|             - MyINPulse-admin | ||||
|             - MyINPulse-entrepreneur | ||||
|       description: | ||||
|         PDF file containing the ap- | ||||
|         pointment report | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: apointementId | ||||
|           schema: | ||||
|             type: integer | ||||
|           required: true | ||||
|       responses: | ||||
|         "200": | ||||
|           description: OK | ||||
|           content: | ||||
|             application/pdf: | ||||
|               schema: | ||||
|                 type: string | ||||
|                 format: binary | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|    | ||||
|   /shared/appointments/request: | ||||
|     post: | ||||
|       summary: demander un rendez-vous | ||||
|       description: | ||||
|         will add an appointement request request by the applicant  | ||||
|         to have an appointment to be confirmed or denied by the | ||||
|         specified participants of the appointement. | ||||
|       tags: | ||||
|         - Shared API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|           - MyINPulse-entrepreneur | ||||
|           - MyINPulse-admin | ||||
|       requestBody: | ||||
|         description: \"participants\" property is an array containing userids of the participants in the appointement | ||||
|         required: true | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 title: | ||||
|                   type: string | ||||
|                 start_time: | ||||
|                   type: string | ||||
|                 end_time: | ||||
|                   type: string | ||||
|                 place: | ||||
|                   type: string | ||||
|                 applicantId: | ||||
|                   type: integer | ||||
|                 participants: | ||||
|                   #/* */ | ||||
|                   type: array | ||||
|                   items: | ||||
|                     type: integer | ||||
|                      | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|                     missing or invalid         | ||||
|    | ||||
|  | ||||
|  | ||||
| #      _____ _   _ _____ ____  _____ ____  ____  _____ _   _ _____ _   _ ____   | ||||
| #     | ____| \ | |_   _|  _ \| ____|  _ \|  _ \| ____| \ | | ____| | | |  _ \  | ||||
| #     |  _| |  \| | | | | |_) |  _| | |_) | |_) |  _| |  \| |  _| | | | | |_) | | ||||
| #     | |___| |\  | | | |  _ <| |___|  __/|  _ <| |___| |\  | |___| |_| |  _ <  | ||||
| #     |_____|_|_\_| |_| |_| \_\_____|_|   |_| \_\_____|_| \_|_____|\___/|_| \_\ | ||||
| #        / \  |  _ \_ _|                                                        | ||||
| #       / _ \ | |_) | |                                                         | ||||
| #      / ___ \|  __/| |                                                         | ||||
| #     /_/   \_\_|  |___|                                                        | ||||
| # | ||||
|  | ||||
|                      | ||||
|   /entrepreneur/projects/request: | ||||
|     post: | ||||
|       summary: demander la création et validation d'un projet | ||||
|       tags: | ||||
|         - Entrepreneurs API | ||||
|       description:  | ||||
|         Adds project to pending projects  | ||||
|         to then be accepted or rejected by | ||||
|         an admin | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|           - MyINPulse-entrepreneur | ||||
|       requestBody: | ||||
|         required: true | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 name: | ||||
|                   type: string | ||||
|                 founder: | ||||
|                   $ref: "#/components/schemas/user-entrepreneur" | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|              | ||||
|             | ||||
|   /entrepreneur/lcsection/add/{projectId}: | ||||
|     post: | ||||
|       summary: ajouter une sections au LC | ||||
|       description:  | ||||
|         Adds input data to the user's LC  | ||||
|         with a specified title. | ||||
|       tags: | ||||
|        - Entrepreneurs API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|           - MyINPulse-entrepreneur | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: projectId | ||||
|           schema: | ||||
|             type: integer | ||||
|           required: true | ||||
|       requestBody: | ||||
|         required: true | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 title: | ||||
|                   type: string | ||||
|                 txt: | ||||
|                   type: string | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|   /entrepreneur/lcsection/modify/{sectionId}: | ||||
|     put: | ||||
|       summary: modifier les données d'une section LC | ||||
|       description:  | ||||
|         Modifies input Lean Canvas section by changing it to  | ||||
|         the information in the request body and changes the | ||||
|         time stamp. | ||||
|       tags: | ||||
|        - Entrepreneurs API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|           - MyINPulse-entrepreneur | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: sectionId | ||||
|           schema: | ||||
|             type: integer | ||||
|           required: true | ||||
|       requestBody: | ||||
|         required: true | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 title: | ||||
|                   type: string | ||||
|                 txt: | ||||
|                   type: string | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|             missing or invalid | ||||
|              | ||||
|   /entrepreneur/lcsection/remove/{sectionId}: | ||||
|     delete: | ||||
|       summary: supprimer une section LC. | ||||
|       description: | ||||
|         Deletes section from Lean Canvas | ||||
|       tags: | ||||
|         - Entrepreneurs API | ||||
|       security: | ||||
|         - MyINPulse: | ||||
|           - MyINPulse-entrepreneur | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: sectionId | ||||
|           schema: | ||||
|             type: integer | ||||
|           required: true | ||||
|       responses: | ||||
|         "200":  | ||||
|           description: OK | ||||
|         "400": | ||||
|           description: Bad request | ||||
|         "401": | ||||
|           description: Authorization information is | ||||
|                       missing or invalid | ||||
|    | ||||
|    | ||||
|    | ||||
|    | ||||
							
								
								
									
										27
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								Makefile
									
									
									
									
									
								
							| @@ -19,25 +19,34 @@ front/MyINPulse-front/.installed: | ||||
|  | ||||
| vite: ./front/MyINPulse-front/.installed | ||||
|  | ||||
| keycloak: ./keycloak/.installed | ||||
|  | ||||
| dev-front: clean vite | ||||
| keycloak/.installed: | ||||
| 	@echo "running one time install" | ||||
| 	@cd keycloak/CAS && sudo sh build.sh | ||||
| 	@touch ./keycloak/.installed | ||||
|  | ||||
| dev-front: clean vite keycloak | ||||
| 	@cp config/frontdev.env front/MyINPulse-front/.env | ||||
| 	@cp config/frontdev.env .env | ||||
| 	@cp config/frontdev.env MyINPulse-back/.env | ||||
| 	@cp config/frontdev.docker-compose.yaml docker-compose.yaml | ||||
| 	@docker compose up -d --build | ||||
| 	@cd ./front/MyINPulse-front/ && npm run dev | ||||
| 	@echo "cd MyINPulse-back" && echo 'export $$(cat .env | xargs)' | ||||
| 	@echo "./gradlew bootRun --args='--server.port=8081'" | ||||
|  | ||||
| prod: clean | ||||
| prod: clean keycloak | ||||
| 	@cp config/prod.env front/MyINPulse-front/.env | ||||
| 	@cp config/prod.env .env | ||||
| 	@cp config/prod.env .env | ||||
| 	@cp config/prod.docker-compose.yaml docker-compose.yaml | ||||
| 	@docker compose up -d --build | ||||
| 	 | ||||
|  | ||||
|  | ||||
|  | ||||
| dev-back: | ||||
| dev-back: keycloak | ||||
| 	@cp config/backdev.env front/MyINPulse-front/.env | ||||
| 	@cp config/backdev.env .env | ||||
| 	@cp config/backdev.env MyINPulse-back/.env | ||||
| @@ -46,7 +55,7 @@ dev-back: | ||||
| 	@echo "cd MyINPulse-back" && echo 'export $$(cat .env | xargs)' | ||||
| 	@echo "./gradlew bootRun --args='--server.port=8081'" | ||||
| 	 | ||||
| dev: clean vite | ||||
| dev: clean vite keycloak | ||||
| 	@cp config/dev.env front/MyINPulse-front/.env | ||||
| 	@cp config/dev.env .env | ||||
| 	@cp config/dev.env MyINPulse-back/.env | ||||
| @@ -55,3 +64,13 @@ dev: clean vite | ||||
| 	@echo "cd MyINPulse-back" && echo 'export $$(cat .env | xargs)' | ||||
| 	@echo "./gradlew bootRun --args='--server.port=8081'" | ||||
| 	@cd ./front/MyINPulse-front/ && npm run dev & | ||||
|  | ||||
| test-back: clean keycloak | ||||
| 	@cp config/dev.env front/MyINPulse-front/.env | ||||
| 	@cp config/dev.env .env | ||||
| 	@cp config/dev.env MyINPulse-back/.env | ||||
| 	@cp config/dev.docker-compose.yaml docker-compose.yaml | ||||
| 	@docker compose up -d --build | ||||
| 	@echo "cd MyINPulse-back" && echo 'export $$(cat .env | xargs)' | ||||
| 	@cd ./MyINPulse-back/ && ./gradlew test && ./gradlew jacocoTestReport | ||||
| 	@firefox ./MyINPulse-back/build/jacocoHtml/index.html | ||||
|   | ||||
| @@ -1,33 +1,59 @@ | ||||
| plugins { | ||||
| 	id 'java' | ||||
| 	id 'org.springframework.boot' version '3.4.2' | ||||
| 	id 'io.spring.dependency-management' version '1.1.7' | ||||
|     id 'java' | ||||
|     id 'org.springframework.boot' version '3.4.2' | ||||
|     id 'io.spring.dependency-management' version '1.1.7' | ||||
|     id 'jacoco' | ||||
| } | ||||
|  | ||||
| group = 'enseirb' | ||||
| version = '0.0.1-SNAPSHOT' | ||||
|  | ||||
| java { | ||||
| 	toolchain { | ||||
| 		languageVersion = JavaLanguageVersion.of(21) | ||||
| 	} | ||||
|     toolchain { | ||||
|         languageVersion = JavaLanguageVersion.of(21) | ||||
|     } | ||||
| } | ||||
|  | ||||
| repositories { | ||||
| 	mavenCentral() | ||||
|     mavenCentral() | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
| 	implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' | ||||
| 	implementation 'org.springframework.boot:spring-boot-starter-web' | ||||
| 	implementation 'org.springframework.boot:spring-boot-starter-data-jpa' | ||||
| 	implementation 'org.springframework.boot:spring-boot-starter-validation' | ||||
| 	implementation 'org.springframework.boot:spring-boot-starter-data-rest' | ||||
| 	implementation 'org.postgresql:postgresql' | ||||
| 	testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||||
| 	testRuntimeOnly 'org.junit.platform:junit-platform-launcher' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-web' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-data-jpa' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-validation' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-data-rest' | ||||
|     implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+' | ||||
|     implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+' | ||||
|     implementation 'org.postgresql:postgresql' | ||||
|     implementation group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13.3' | ||||
|  | ||||
|     testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||||
|     testImplementation 'com.h2database:h2' | ||||
|  | ||||
|     testRuntimeOnly 'org.junit.platform:junit-platform-launcher' | ||||
| } | ||||
|  | ||||
| tasks.named('test') { | ||||
| 	useJUnitPlatform() | ||||
|     useJUnitPlatform() | ||||
| } | ||||
|  | ||||
|  | ||||
| test { | ||||
|     finalizedBy jacocoTestReport // report is always generated after tests run | ||||
| } | ||||
| jacocoTestReport { | ||||
|     dependsOn test // tests are required to run before generating the report | ||||
|     reports { | ||||
|         xml.required = false | ||||
|         csv.required = false | ||||
|         html.outputLocation = layout.buildDirectory.dir('jacocoHtml') | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| jacoco { | ||||
|     toolVersion = "0.8.12" | ||||
|     reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir') | ||||
| } | ||||
|   | ||||
| @@ -1,40 +0,0 @@ | ||||
| package enseirb.myinpulse.api; | ||||
|  | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
|  | ||||
| import java.security.Principal; | ||||
|  | ||||
| import javax.management.relation.RoleNotFoundException; | ||||
|  | ||||
| @SpringBootApplication | ||||
| @RestController | ||||
| public class GetUserInfo { | ||||
|     // TODO: understand how to get data | ||||
|     @GetMapping("/getUserInfo") | ||||
|     public Object user(Principal principal) { | ||||
|         System.out.println("GetUserInfo + " + principal); | ||||
|         System.out.println(SecurityContextHolder.getContext().getAuthentication()); | ||||
|         return SecurityContextHolder.getContext().getAuthentication().getPrincipal(); | ||||
|     } | ||||
|  | ||||
|     @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.OPTIONS}) | ||||
|     @GetMapping("/unauth/random") | ||||
|     public boolean rand(@RequestHeader("Authorization") String token) throws RoleNotFoundException { | ||||
|         System.err.println(token); | ||||
|         return Math.random() > 0.5; | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/admin/random") | ||||
|     public boolean rand2() { | ||||
|         return Math.random() > 0.5; | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/entrepreneur/random") | ||||
|     public boolean rand3() { | ||||
|         return Math.random() > 0.5; | ||||
|     } | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * Source: https://github.com/ChristianHuff-DEV/secure-spring-rest-api-using-keycloak/blob/main/src/main/java/io/betweendata/RestApi/security/oauth2/KeycloakJwtRolesConverter.java | ||||
|  * edited by Pierre Tellier | ||||
|  */ | ||||
| package enseirb.myinpulse.security; | ||||
| package enseirb.myinpulse.config; | ||||
| 
 | ||||
| import static java.util.stream.Collectors.toSet; | ||||
| 
 | ||||
| @@ -2,8 +2,6 @@ package enseirb.myinpulse.config; | ||||
|  | ||||
| import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole; | ||||
|  | ||||
| import enseirb.myinpulse.security.KeycloakJwtRolesConverter; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| @@ -58,9 +56,9 @@ public class WebSecurityCustomConfiguration { | ||||
|         http.authorizeHttpRequests( | ||||
|                         authorize -> | ||||
|                                 authorize | ||||
|                                         .requestMatchers("/entrepreneur/**") | ||||
|                                         .requestMatchers("/entrepreneur/**", "/shared/**") | ||||
|                                         .access(hasRole("REALM_MyINPulse-entrepreneur")) | ||||
|                                         .requestMatchers("/admin/**") | ||||
|                                         .requestMatchers("/admin/**", "/shared/**") | ||||
|                                         .access(hasRole("REALM_MyINPulse-admin")) | ||||
|                                         .requestMatchers("/unauth/**") | ||||
|                                         .permitAll() | ||||
|   | ||||
| @@ -0,0 +1,102 @@ | ||||
| package enseirb.myinpulse.controller; | ||||
|  | ||||
| import enseirb.myinpulse.model.*; | ||||
| import enseirb.myinpulse.service.AdminApiService; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||
| import org.springframework.security.oauth2.jwt.Jwt; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| @SpringBootApplication | ||||
| @RestController | ||||
| public class AdminApi { | ||||
|  | ||||
|     private final AdminApiService adminApiService; | ||||
|  | ||||
|     @Autowired | ||||
|     AdminApi(AdminApiService adminApiService) { | ||||
|         this.adminApiService = adminApiService; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: description | ||||
|      * | ||||
|      * @return a list of all project managed by the current admin user | ||||
|      */ | ||||
|     @GetMapping("/admin/projects") | ||||
|     public Iterable<Project> getProjects(@AuthenticationPrincipal Jwt principal) { | ||||
|         return adminApiService.getProjectsOfAdmin(principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: Why in admin instead of shared ? + desc | ||||
|      * | ||||
|      * @return a list of upcoming appointments for the current user | ||||
|      */ | ||||
|     @GetMapping("/admin/appointments/upcoming") | ||||
|     public Iterable<Appointment> getUpcomingAppointments(@AuthenticationPrincipal Jwt principal) { | ||||
|         return adminApiService.getUpcomingAppointments(principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: description | ||||
|      * | ||||
|      * @return a list of current unvalidated projects, waiting to be accepted | ||||
|      */ | ||||
|     @GetMapping("/admin/projects/pending") | ||||
|     public Iterable<Project> getPendingProjects() { | ||||
|         return adminApiService.getPendingProjects(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Endpoint used to make a decision about a project. | ||||
|      * | ||||
|      * <p>The decision must contain the administrator | ||||
|      * | ||||
|      * @return the status code of the request | ||||
|      */ | ||||
|     @PostMapping("/admin/projects/decision") | ||||
|     public void validateProject(@RequestBody ProjectDecision decision) { | ||||
|         adminApiService.validateProject(decision); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Endpoint used to manually add a project by an admin | ||||
|      * | ||||
|      * @return the status code of the request | ||||
|      */ | ||||
|     @PostMapping("/admin/project/add") | ||||
|     public void addNewProject(@RequestBody Project project) { | ||||
|         adminApiService.addNewProject(project); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: shouldn't it be an PUT request ? / What is the rerun type | ||||
|      * | ||||
|      * <p>Endpoint used to add a new report to an appointment | ||||
|      * | ||||
|      * @return the status code of the request | ||||
|      */ | ||||
|     @PostMapping("/admin/appoitements/report/{appointmentId}") | ||||
|     public void createAppointmentReport( | ||||
|             @PathVariable long appointmentId, | ||||
|             @RequestBody Report report, | ||||
|             @AuthenticationPrincipal Jwt principal) { | ||||
|         adminApiService.createAppointmentReport( | ||||
|                 appointmentId, report, principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: Shouldn't a project be kept in history ? 2 different endpoints ? | ||||
|      * | ||||
|      * <p>Endpoint used to completely remove a project. | ||||
|      * | ||||
|      * @return the status code of the request | ||||
|      */ | ||||
|     @DeleteMapping("/admin/projects/remove/{projectId}") | ||||
|     public void deleteProject(@PathVariable long projectId) { | ||||
|         adminApiService.deleteProject(projectId); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,78 @@ | ||||
| package enseirb.myinpulse.controller; | ||||
|  | ||||
| import enseirb.myinpulse.model.SectionCell; | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.service.EntrepreneurApiService; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||
| import org.springframework.security.oauth2.jwt.Jwt; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| @SpringBootApplication | ||||
| @RestController | ||||
| public class EntrepreneurApi { | ||||
|  | ||||
|     private final EntrepreneurApiService entrepreneurApiService; | ||||
|  | ||||
|     @Autowired | ||||
|     EntrepreneurApi(EntrepreneurApiService entrepreneurApiService) { | ||||
|         this.entrepreneurApiService = entrepreneurApiService; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: check return type | ||||
|      * | ||||
|      * <p>Endpoint used to update a LC section. | ||||
|      * | ||||
|      * @return status code | ||||
|      */ | ||||
|     @PutMapping("/entrepreneur/lcsection/modify/{sectionId}") | ||||
|     public void editSectionCell( | ||||
|             @PathVariable Long sectionId, | ||||
|             @RequestBody SectionCell sectionCell, | ||||
|             @AuthenticationPrincipal Jwt principal) { | ||||
|         entrepreneurApiService.editSectionCell( | ||||
|                 sectionId, sectionCell, principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: checkReturn Type | ||||
|      * | ||||
|      * <p>Endpoint used to delete a LC section | ||||
|      * | ||||
|      * @return status code | ||||
|      */ | ||||
|     @DeleteMapping("/entrepreneur/lcsection/remove/{sectionId}") | ||||
|     public void removeSectionCell( | ||||
|             @PathVariable Long sectionId, @AuthenticationPrincipal Jwt principal) { | ||||
|         entrepreneurApiService.removeSectionCell(sectionId, principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: check return type | ||||
|      * | ||||
|      * <p>Endpoint used to create a new LC section | ||||
|      * | ||||
|      * @return status code | ||||
|      */ | ||||
|     @PostMapping("/entrepreneur/lcsection/add") // remove id from doc aswell | ||||
|     public void addLCSection( | ||||
|             @RequestBody SectionCell sectionCell, @AuthenticationPrincipal Jwt principal) { | ||||
|         entrepreneurApiService.addSectionCell(sectionCell, principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: check return type | ||||
|      * | ||||
|      * <p>Endpoint used to request the creation of a new project | ||||
|      * | ||||
|      * @return status code | ||||
|      */ | ||||
|     @PostMapping("/entrepreneur/project/request") | ||||
|     public void requestNewProject( | ||||
|             @RequestBody Project project, @AuthenticationPrincipal Jwt principal) { | ||||
|         entrepreneurApiService.requestNewProject(project, principal.getClaimAsString("email")); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,105 @@ | ||||
| package enseirb.myinpulse.controller; | ||||
|  | ||||
| import com.itextpdf.text.DocumentException; | ||||
|  | ||||
| import enseirb.myinpulse.model.*; | ||||
| import enseirb.myinpulse.service.SharedApiService; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||
| import org.springframework.security.oauth2.jwt.Jwt; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.net.URISyntaxException; | ||||
|  | ||||
| @SpringBootApplication | ||||
| @RestController | ||||
| public class SharedApi { | ||||
|  | ||||
|     private final SharedApiService sharedApiService; | ||||
|  | ||||
|     @Autowired | ||||
|     SharedApi(SharedApiService sharedApiService) { | ||||
|         this.sharedApiService = sharedApiService; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Endpoint used to get the data inside the lean canvas | ||||
|      * | ||||
|      * @return a list of lean canvas sections | ||||
|      */ | ||||
|     @GetMapping("/shared/project/lcsection/{projectId}/{sectionId}/{date}") | ||||
|     public Iterable<SectionCell> getLCSection( | ||||
|             @PathVariable("projectId") Long projectId, | ||||
|             @PathVariable("sectionId") Long sectionId, | ||||
|             @PathVariable("date") String date, | ||||
|             @AuthenticationPrincipal Jwt principal) { | ||||
|         return sharedApiService.getSectionCells( | ||||
|                 projectId, sectionId, date, principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Endpoint used to get entrepreneurs details | ||||
|      * | ||||
|      * @return a list of all entrepreneurs in a project | ||||
|      */ | ||||
|     @GetMapping("/shared/entrepreneurs/{projectId}") | ||||
|     public Iterable<Entrepreneur> getEntrepreneursByProjectId( | ||||
|             @PathVariable int projectId, @AuthenticationPrincipal Jwt principal) { | ||||
|         return sharedApiService.getEntrepreneursByProjectId( | ||||
|                 projectId, principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Endpoint used to get the administrator of a project. | ||||
|      * | ||||
|      * @return the admin of a project | ||||
|      */ | ||||
|     @GetMapping("/shared/projects/admin/{projectId}") | ||||
|     public Administrator getAdminByProjectId( | ||||
|             @PathVariable int projectId, @AuthenticationPrincipal Jwt principal) { | ||||
|         return sharedApiService.getAdminByProjectId(projectId, principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Endpoint used to get all appointments of a single project. | ||||
|      * | ||||
|      * @return a list of all appointments. | ||||
|      */ | ||||
|     @GetMapping("/shared/projects/appointments/{projectId}") | ||||
|     public Iterable<Appointment> getAppointmentsByProjectId( | ||||
|             @PathVariable int projectId, @AuthenticationPrincipal Jwt principal) { | ||||
|         return sharedApiService.getAppointmentsByProjectId( | ||||
|                 projectId, principal.getClaimAsString("email")); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Endpoint used to generate a PDF report | ||||
|      * | ||||
|      * @return a PDF file? TODO: how does that works ? | ||||
|      */ | ||||
|     @GetMapping("/shared/projects/appointments/report/{appointmentId}") | ||||
|     public void getPDFReport( | ||||
|             @PathVariable int appointmentId, @AuthenticationPrincipal Jwt principal) { | ||||
|         try { | ||||
|             sharedApiService.getPDFReport(appointmentId, principal.getClaimAsString("email")); | ||||
|         } catch (DocumentException e) { | ||||
|             System.out.println(e + "Document exception"); | ||||
|         } catch (URISyntaxException e) { | ||||
|             System.out.println(e + "Error with URI"); | ||||
|         } catch (IOException e) { | ||||
|             System.out.println(e + "Failed to access file"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return TODO | ||||
|      */ | ||||
|     @PostMapping("/shared/appointment/request") | ||||
|     public void createAppointmentRequest( | ||||
|             @RequestBody Appointment appointment, @AuthenticationPrincipal Jwt principal) { | ||||
|         sharedApiService.createAppointmentRequest(appointment, principal.getClaimAsString("email")); | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| package enseirb.myinpulse.exceptions; | ||||
| package enseirb.myinpulse.exception; | ||||
| 
 | ||||
| public class RoleNotFoudException extends RuntimeException { | ||||
|     public RoleNotFoudException(String message) { | ||||
| @@ -1,4 +1,4 @@ | ||||
| package enseirb.myinpulse.exceptions; | ||||
| package enseirb.myinpulse.exception; | ||||
| 
 | ||||
| public class UserNotFoundException extends RuntimeException { | ||||
|     public UserNotFoundException(String message) { | ||||
| @@ -0,0 +1,66 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.persistence.PrimaryKeyJoinColumn; | ||||
| import jakarta.persistence.Table; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "administrator") | ||||
| @PrimaryKeyJoinColumn(name = "idAdministrator", referencedColumnName = "idUser") | ||||
| public class Administrator extends User { | ||||
|  | ||||
|     @OneToMany(mappedBy = "projectAdministrator", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<Project> listProject = new ArrayList<>(); | ||||
|  | ||||
|     /*@OneToMany(mappedBy = "administratorSectionCell", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private List<SectionCell> listSectionCell = new ArrayList<>();*/ | ||||
|     // should now be useless | ||||
|  | ||||
|     @OneToMany(mappedBy = "administratorAnnotation", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<Annotation> listAnnotation = new ArrayList<>(); | ||||
|  | ||||
|     /*@OneToMany(mappedBy = "administratorAppointment", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<Appointment> listAppointment = new ArrayList<>();*/ | ||||
|     // should now be useless | ||||
|  | ||||
|     @OneToOne(mappedBy = "administratorAppointment", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private MakeAppointment makeAppointment; | ||||
|  | ||||
|     public Administrator() {} | ||||
|  | ||||
|     public Administrator( | ||||
|             String userSurname, | ||||
|             String username, | ||||
|             String primaryMail, | ||||
|             String secondaryMail, | ||||
|             String phoneNumber) { | ||||
|         super(null, userSurname, username, primaryMail, secondaryMail, phoneNumber); | ||||
|     } | ||||
|  | ||||
|     public List<Project> getListProject() { | ||||
|         return listProject; | ||||
|     } | ||||
|  | ||||
|     public void updateListProject(Project project) { | ||||
|         listProject.add(project); | ||||
|     } | ||||
|  | ||||
|     public List<Annotation> getListAnnotation() { | ||||
|         return listAnnotation; | ||||
|     } | ||||
|  | ||||
|     public void updateListAnnotation(Annotation annotation) { | ||||
|         listAnnotation.add(annotation); | ||||
|     } | ||||
|  | ||||
|     public MakeAppointment getMakeAppointment() { | ||||
|         return makeAppointment; | ||||
|     } | ||||
|  | ||||
|     public void setMakeAppointment(MakeAppointment makeAppointment) { | ||||
|         this.makeAppointment = makeAppointment; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,61 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "annotation") | ||||
| public class Annotation { | ||||
|  | ||||
|     @Id | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long idAnnotation; | ||||
|  | ||||
|     private String comment; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idSectionCell") | ||||
|     private SectionCell sectionCellAnnotation; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idAdministrator") | ||||
|     private Administrator administratorAnnotation; | ||||
|  | ||||
|     public Annotation() {} | ||||
|  | ||||
|     public Annotation(Long idAnnotation, String commentary) { | ||||
|         this.idAnnotation = idAnnotation; | ||||
|         this.comment = comment; | ||||
|     } | ||||
|  | ||||
|     public String getComment() { | ||||
|         return comment; | ||||
|     } | ||||
|  | ||||
|     public void setComment(String comment) { | ||||
|         this.comment = comment; | ||||
|     } | ||||
|  | ||||
|     public Long getIdAnnotation() { | ||||
|         return idAnnotation; | ||||
|     } | ||||
|  | ||||
|     public void setIdAnnotation(Long idAnnotation) { | ||||
|         this.idAnnotation = idAnnotation; | ||||
|     } | ||||
|  | ||||
|     public SectionCell getSectionCellAnnotation() { | ||||
|         return sectionCellAnnotation; | ||||
|     } | ||||
|  | ||||
|     public void setSectionCellAnnotation(SectionCell sectionCellAnnotation) { | ||||
|         this.sectionCellAnnotation = sectionCellAnnotation; | ||||
|     } | ||||
|  | ||||
|     public Administrator getAdministratorAnnotation() { | ||||
|         return administratorAnnotation; | ||||
|     } | ||||
|  | ||||
|     public void setAdministratorAnnotation(Administrator administratorAnnotation) { | ||||
|         this.administratorAnnotation = administratorAnnotation; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,126 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "appointment") | ||||
| public class Appointment { | ||||
|  | ||||
|     /*@OneToMany(mappedBy = "appointmentEntrepreneurs", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<Entrepreneur> listEntrepreneur = | ||||
|             new ArrayList<>(); */ | ||||
|     // should now be useless | ||||
|  | ||||
|     @ManyToMany( | ||||
|             fetch = FetchType.LAZY, | ||||
|             cascade = {CascadeType.ALL}) | ||||
|     @JoinTable( | ||||
|             name = "concern", | ||||
|             joinColumns = @JoinColumn(name = "idAppointment"), | ||||
|             inverseJoinColumns = @JoinColumn(name = "idSectionCell")) | ||||
|     List<SectionCell> listSectionCell = new ArrayList<>(); | ||||
|  | ||||
|     @OneToOne(mappedBy = "appointmentReport", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private Report report; | ||||
|  | ||||
|     @Id | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long idAppointment; | ||||
|  | ||||
|     private LocalDate appointmentDate; | ||||
|  | ||||
|     private LocalTime appointmentTime; | ||||
|  | ||||
|     private LocalTime appointmentDuration; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String appointmentPlace; | ||||
|  | ||||
|     private String appointmentSubject; | ||||
|  | ||||
|     public Appointment() {} | ||||
|  | ||||
|     public Appointment( | ||||
|             Long idAppointment, | ||||
|             LocalDate appointmentDate, | ||||
|             LocalTime appointmentTime, | ||||
|             LocalTime appointmentDuration, | ||||
|             String appointmentPlace, | ||||
|             String appointmentSubject) { | ||||
|         this.idAppointment = idAppointment; | ||||
|         this.appointmentDate = appointmentDate; | ||||
|         this.appointmentTime = appointmentTime; | ||||
|         this.appointmentDuration = appointmentDuration; | ||||
|         this.appointmentPlace = appointmentPlace; | ||||
|         this.appointmentSubject = appointmentSubject; | ||||
|     } | ||||
|  | ||||
|     public Long getIdAppointment() { | ||||
|         return idAppointment; | ||||
|     } | ||||
|  | ||||
|     public void setIdAppointment(Long idAppointment) { | ||||
|         this.idAppointment = idAppointment; | ||||
|     } | ||||
|  | ||||
|     public LocalDate getAppointmentDate() { | ||||
|         return appointmentDate; | ||||
|     } | ||||
|  | ||||
|     public void setAppointmentDate(LocalDate appointmentDate) { | ||||
|         this.appointmentDate = appointmentDate; | ||||
|     } | ||||
|  | ||||
|     public LocalTime getAppointmentTime() { | ||||
|         return appointmentTime; | ||||
|     } | ||||
|  | ||||
|     public void setAppointmentTime(LocalTime appointmentTime) { | ||||
|         this.appointmentTime = appointmentTime; | ||||
|     } | ||||
|  | ||||
|     public LocalTime getAppointmentDuration() { | ||||
|         return appointmentDuration; | ||||
|     } | ||||
|  | ||||
|     public void setAppointmentDuration(LocalTime appointmentDuration) { | ||||
|         this.appointmentDuration = appointmentDuration; | ||||
|     } | ||||
|  | ||||
|     public String getAppointmentPlace() { | ||||
|         return appointmentPlace; | ||||
|     } | ||||
|  | ||||
|     public void setAppointmentPlace(String appointmentPlace) { | ||||
|         this.appointmentPlace = appointmentPlace; | ||||
|     } | ||||
|  | ||||
|     public String getAppointmentSubject() { | ||||
|         return appointmentSubject; | ||||
|     } | ||||
|  | ||||
|     public void setAppointmentSubject(String appointmentSubject) { | ||||
|         this.appointmentSubject = appointmentSubject; | ||||
|     } | ||||
|  | ||||
|     public List<SectionCell> getAppointmentListSectionCell() { | ||||
|         return listSectionCell; | ||||
|     } | ||||
|  | ||||
|     public void updateListSectionCell(SectionCell sectionCell) { | ||||
|         listSectionCell.add(sectionCell); | ||||
|     } | ||||
|  | ||||
|     public Report getAppointmentReport() { | ||||
|         return report; | ||||
|     } | ||||
|  | ||||
|     public void setAppointmentReport(Report report) { | ||||
|         this.report = report; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,123 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.persistence.Entity; | ||||
| import jakarta.persistence.Table; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "entrepreneur") | ||||
| @PrimaryKeyJoinColumn(name = "idEntrepreneur", referencedColumnName = "idUser") | ||||
| public class Entrepreneur extends User { | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String school; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String course; | ||||
|  | ||||
|     private boolean sneeStatus; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idProjectParticipation", referencedColumnName = "idProject") | ||||
|     private Project projectParticipation; | ||||
|  | ||||
|     // @Column(insertable=false, updatable=false) | ||||
|     @OneToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idProjectProposed", referencedColumnName = "idProject") | ||||
|     private Project projectProposed; | ||||
|  | ||||
|     /*@ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idAppointment") | ||||
|     private Appointment appointmentEntrepreneur;*/ | ||||
|     // should now be useless | ||||
|  | ||||
|     @OneToOne(mappedBy = "entrepreneurAppointment", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private MakeAppointment makeAppointment; | ||||
|  | ||||
|     public Entrepreneur() {} | ||||
|  | ||||
|     public Entrepreneur( | ||||
|             String userSurname, | ||||
|             String username, | ||||
|             String primaryMail, | ||||
|             String secondaryMail, | ||||
|             String phoneNumber, | ||||
|             String school, | ||||
|             String course, | ||||
|             boolean sneeStatus) { | ||||
|         super(userSurname, username, primaryMail, secondaryMail, phoneNumber); | ||||
|         this.school = school; | ||||
|         this.course = course; | ||||
|         this.sneeStatus = sneeStatus; | ||||
|     } | ||||
|  | ||||
|     public Entrepreneur( | ||||
|             Long idUser, | ||||
|             String userSurname, | ||||
|             String userName, | ||||
|             String primaryMail, | ||||
|             String secondaryMail, | ||||
|             String phoneNumber, | ||||
|             String school, | ||||
|             String course, | ||||
|             boolean sneeStatus, | ||||
|             Project projectParticipation, | ||||
|             Project projectProposed, | ||||
|             MakeAppointment makeAppointment) { | ||||
|         super(idUser, userSurname, userName, primaryMail, secondaryMail, phoneNumber); | ||||
|         this.school = school; | ||||
|         this.course = course; | ||||
|         this.sneeStatus = sneeStatus; | ||||
|         this.projectParticipation = projectParticipation; | ||||
|         this.projectProposed = projectProposed; | ||||
|         this.makeAppointment = makeAppointment; | ||||
|     } | ||||
|  | ||||
|     public String getSchool() { | ||||
|         return school; | ||||
|     } | ||||
|  | ||||
|     public void setSchool(String school) { | ||||
|         this.school = school; | ||||
|     } | ||||
|  | ||||
|     public String getCourse() { | ||||
|         return course; | ||||
|     } | ||||
|  | ||||
|     public void setCourse(String course) { | ||||
|         this.course = course; | ||||
|     } | ||||
|  | ||||
|     public boolean isSneeStatus() { | ||||
|         return sneeStatus; | ||||
|     } | ||||
|  | ||||
|     public void setSneeStatus(boolean statusSnee) { | ||||
|         this.sneeStatus = sneeStatus; | ||||
|     } | ||||
|  | ||||
|     public Project getProjectParticipation() { | ||||
|         return projectParticipation; | ||||
|     } | ||||
|  | ||||
|     public void setProjectParticipation(Project projectParticipation) { | ||||
|         this.projectParticipation = projectParticipation; | ||||
|     } | ||||
|  | ||||
|     public Project getProjectProposed() { | ||||
|         return projectProposed; | ||||
|     } | ||||
|  | ||||
|     public void setProjectProposed(Project projectProposed) { | ||||
|         this.projectProposed = projectProposed; | ||||
|     } | ||||
|  | ||||
|     public MakeAppointment getMakeAppointment() { | ||||
|         return makeAppointment; | ||||
|     } | ||||
|  | ||||
|     public void setMakeAppointment(MakeAppointment makeAppointment) { | ||||
|         this.makeAppointment = makeAppointment; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,26 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "make_appointment") | ||||
| public class MakeAppointment { | ||||
|  | ||||
|     @Id | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long idMakeAppointment; | ||||
|  | ||||
|     @OneToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idAdministrator") | ||||
|     private Administrator administratorAppointment; | ||||
|  | ||||
|     @OneToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idEntrepreneur") | ||||
|     private Entrepreneur entrepreneurAppointment; | ||||
|  | ||||
|     public MakeAppointment() {} | ||||
|  | ||||
|     public MakeAppointment(Long idMakeAppointment) { | ||||
|         this.idMakeAppointment = idMakeAppointment; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,140 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "project") | ||||
| public class Project { | ||||
|  | ||||
|     @OneToMany(mappedBy = "projectParticipation", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<Entrepreneur> listEntrepreneurParticipation = new ArrayList<>(); | ||||
|  | ||||
|     @OneToMany(mappedBy = "projectSectionCell", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<SectionCell> listSectionCell = new ArrayList<>(); | ||||
|  | ||||
|     @Id | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long idProject; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String projectName; | ||||
|  | ||||
|     private byte[] logo; | ||||
|     private LocalDate creationDate; | ||||
|  | ||||
|     @Column private ProjectDecisionValue projectStatus; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idAdministrator") | ||||
|     private Administrator projectAdministrator; | ||||
|  | ||||
|     @OneToOne(mappedBy = "projectProposed", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private Entrepreneur entrepreneurProposed; | ||||
|  | ||||
|     public Project() {} | ||||
|  | ||||
|     public Project( | ||||
|             String projectName, | ||||
|             byte[] logo, | ||||
|             LocalDate creationDate, | ||||
|             ProjectDecisionValue projectStatus, | ||||
|             Administrator projectAdministrator) { | ||||
|         this.projectName = projectName; | ||||
|         this.logo = logo; | ||||
|         this.creationDate = creationDate; | ||||
|         // this.projectStatus = (long) projectStatus.ordinal(); | ||||
|         this.projectStatus = projectStatus; | ||||
|         this.projectAdministrator = projectAdministrator; | ||||
|     } | ||||
|  | ||||
|     public Project( | ||||
|             String projectName, | ||||
|             byte[] logo, | ||||
|             LocalDate creationDate, | ||||
|             ProjectDecisionValue projectStatus, | ||||
|             Administrator projectAdministrator, | ||||
|             Entrepreneur entrepreneurProposed) { | ||||
|         this.projectName = projectName; | ||||
|         this.logo = logo; | ||||
|         this.creationDate = creationDate; | ||||
|         this.projectStatus = projectStatus; | ||||
|         this.projectAdministrator = projectAdministrator; | ||||
|         this.entrepreneurProposed = entrepreneurProposed; | ||||
|     } | ||||
|  | ||||
|     public Long getIdProject() { | ||||
|         return idProject; | ||||
|     } | ||||
|  | ||||
|     public void setIdProject(Long idProject) { | ||||
|         this.idProject = idProject; | ||||
|     } | ||||
|  | ||||
|     public String getProjectName() { | ||||
|         return projectName; | ||||
|     } | ||||
|  | ||||
|     public void setProjectName(String projectName) { | ||||
|         this.projectName = projectName; | ||||
|     } | ||||
|  | ||||
|     public byte[] getLogo() { | ||||
|         return logo; | ||||
|     } | ||||
|  | ||||
|     public void setLogo(byte[] logo) { | ||||
|         this.logo = logo; | ||||
|     } | ||||
|  | ||||
|     public LocalDate getCreationDate() { | ||||
|         return creationDate; | ||||
|     } | ||||
|  | ||||
|     public void setCreationDate(LocalDate creationDate) { | ||||
|         this.creationDate = creationDate; | ||||
|     } | ||||
|  | ||||
|     public ProjectDecisionValue getProjectStatus() { | ||||
|         return projectStatus; | ||||
|     } | ||||
|  | ||||
|     public void setProjectStatus(ProjectDecisionValue projectStatus) { | ||||
|         this.projectStatus = projectStatus; | ||||
|     } | ||||
|  | ||||
|     public List<Entrepreneur> getListEntrepreneurParticipation() { | ||||
|         return listEntrepreneurParticipation; | ||||
|     } | ||||
|  | ||||
|     public void updateListEntrepreneurParticipation(Entrepreneur projectParticipant) { | ||||
|         listEntrepreneurParticipation.add(projectParticipant); | ||||
|     } | ||||
|  | ||||
|     public List<SectionCell> getListSectionCell() { | ||||
|         return listSectionCell; | ||||
|     } | ||||
|  | ||||
|     public void updateListSectionCell(SectionCell projectSectionCell) { | ||||
|         listSectionCell.add(projectSectionCell); | ||||
|     } | ||||
|  | ||||
|     public Administrator getProjectAdministrator() { | ||||
|         return projectAdministrator; | ||||
|     } | ||||
|  | ||||
|     public void setProjectAdministrator(Administrator projectAdministrator) { | ||||
|         this.projectAdministrator = projectAdministrator; | ||||
|     } | ||||
|  | ||||
|     public Entrepreneur getEntrepreneurProposed() { | ||||
|         return entrepreneurProposed; | ||||
|     } | ||||
|  | ||||
|     public void setEntrepreneurProposed(Entrepreneur entrepreneurProposed) { | ||||
|         this.entrepreneurProposed = entrepreneurProposed; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| public class ProjectDecision { | ||||
|     public long projectId; | ||||
|     public long adminId; | ||||
|     public long isAccepted; | ||||
|  | ||||
|     public ProjectDecision(long projectId, long adminId, long isAccepted) { | ||||
|         this.projectId = projectId; | ||||
|         this.adminId = adminId; | ||||
|         this.isAccepted = isAccepted; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return "ProjectDecision{" | ||||
|                 + "projectId=" | ||||
|                 + projectId | ||||
|                 + ", adminId=" | ||||
|                 + adminId | ||||
|                 + ", isAccepted=" | ||||
|                 + isAccepted | ||||
|                 + '}'; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| public enum ProjectDecisionValue { | ||||
|     PENDING, | ||||
|     ACTIVE, | ||||
|     ENDED, | ||||
|     ABORTED, | ||||
|     REJECTED, | ||||
| } | ||||
| @@ -0,0 +1,48 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.persistence.Entity; | ||||
| import jakarta.persistence.Id; | ||||
| import jakarta.persistence.Table; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "report") | ||||
| public class Report { | ||||
|  | ||||
|     @Id | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long idReport; | ||||
|  | ||||
|     private String reportContent; | ||||
|  | ||||
|     @OneToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idAppointment") | ||||
|     private Appointment appointmentReport; | ||||
|  | ||||
|     public Report() {} | ||||
|  | ||||
|     public Report(Long idReport, String reportContent) { | ||||
|         this.idReport = idReport; | ||||
|         this.reportContent = reportContent; | ||||
|     } | ||||
|  | ||||
|     public Long getIdReport() { | ||||
|         return idReport; | ||||
|     } | ||||
|  | ||||
|     public String getReportContent() { | ||||
|         return reportContent; | ||||
|     } | ||||
|  | ||||
|     public void setReportContent(String reportContent) { | ||||
|         this.reportContent = reportContent; | ||||
|     } | ||||
|  | ||||
|     public Appointment getAppointmentReport() { | ||||
|         return appointmentReport; | ||||
|     } | ||||
|  | ||||
|     public void setAppointmentReport(Appointment appointmentReport) { | ||||
|         this.appointmentReport = appointmentReport; | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| package enseirb.myinpulse.utils.keycloak.datatypes; | ||||
| package enseirb.myinpulse.model; | ||||
| 
 | ||||
| public class RoleRepresentation { | ||||
|     public String id; | ||||
| @@ -0,0 +1,110 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "section_cell") | ||||
| public class SectionCell { | ||||
|  | ||||
|     @ManyToMany(mappedBy = "listSectionCell") | ||||
|     private final List<Appointment> listAppointment = new ArrayList<>(); | ||||
|  | ||||
|     @OneToMany(mappedBy = "sectionCellAnnotation", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<Annotation> listAnnotation = new ArrayList<>(); | ||||
|  | ||||
|     @Id | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long idSectionCell; | ||||
|  | ||||
|     @Column() private long sectionId; | ||||
|     private String contentSectionCell; | ||||
|  | ||||
|     /*@ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idAdministrator") | ||||
|     private Administrator administratorSectionCell;*/ | ||||
|     // should now be useless | ||||
|     private LocalDateTime modificationDate; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "idProject") | ||||
|     private Project projectSectionCell; | ||||
|  | ||||
|     public SectionCell() {} | ||||
|  | ||||
|     public SectionCell( | ||||
|             Long idSectionCell, | ||||
|             Long sectionId, | ||||
|             String contentSectionCell, | ||||
|             LocalDateTime modificationDate, | ||||
|             Project projectSectionCell) { | ||||
|         this.idSectionCell = idSectionCell; | ||||
|         this.sectionId = sectionId; | ||||
|         this.contentSectionCell = contentSectionCell; | ||||
|         this.modificationDate = modificationDate; | ||||
|         this.projectSectionCell = projectSectionCell; | ||||
|     } | ||||
|  | ||||
|     public Long getIdSectionCell() { | ||||
|         return idSectionCell; | ||||
|     } | ||||
|  | ||||
|     public void setIdSectionCell(Long idSectionCell) { | ||||
|         this.idSectionCell = idSectionCell; | ||||
|     } | ||||
|  | ||||
|     public Long getSectionId() { | ||||
|         return sectionId; | ||||
|     } | ||||
|  | ||||
|     public void setSectionId(Long sectionId) { | ||||
|         this.sectionId = sectionId; | ||||
|     } | ||||
|  | ||||
|     public String getContentSectionCell() { | ||||
|         return contentSectionCell; | ||||
|     } | ||||
|  | ||||
|     public void setContentSectionCell(String contentSectionCell) { | ||||
|         this.contentSectionCell = contentSectionCell; | ||||
|     } | ||||
|  | ||||
|     public LocalDateTime getModificationDate() { | ||||
|         return modificationDate; | ||||
|     } | ||||
|  | ||||
|     public void setModificationDate(LocalDateTime modificationDate) { | ||||
|         this.modificationDate = modificationDate; | ||||
|     } | ||||
|  | ||||
|     public Project getProjectSectionCell() { | ||||
|         return projectSectionCell; | ||||
|     } | ||||
|  | ||||
|     public List<Appointment> getAppointmentSectionCell() { | ||||
|         return listAppointment; | ||||
|     } | ||||
|  | ||||
|     public void updateAppointmentSectionCell(Appointment appointment) { | ||||
|         listAppointment.add(appointment); | ||||
|     } | ||||
|  | ||||
|     public List<Annotation> getListAnnotation() { | ||||
|         return listAnnotation; | ||||
|     } | ||||
|  | ||||
|     public void updateListAnnotation(Annotation annotation) { | ||||
|         listAnnotation.add(annotation); | ||||
|     } | ||||
|  | ||||
|     public void setSectionId(long sectionId) { | ||||
|         this.sectionId = sectionId; | ||||
|     } | ||||
|  | ||||
|     public void setProjectSectionCell(Project projectSectionCell) { | ||||
|         this.projectSectionCell = projectSectionCell; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										108
									
								
								MyINPulse-back/src/main/java/enseirb/myinpulse/model/User.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								MyINPulse-back/src/main/java/enseirb/myinpulse/model/User.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| package enseirb.myinpulse.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "user_inpulse") | ||||
| @Inheritance(strategy = InheritanceType.JOINED) | ||||
| public class User { | ||||
|  | ||||
|     @Id | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long idUser; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String userSurname; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String userName; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String primaryMail; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String secondaryMail; | ||||
|  | ||||
|     @Column(length = 20) | ||||
|     private String phoneNumber; | ||||
|  | ||||
|     public User() {} | ||||
|  | ||||
|     // TODO: this should be removed as we shouldn't be able to chose the ID. Leaving it for | ||||
|     // compatibility purposes, as soon as it's not used anymore, delete it | ||||
|     public User( | ||||
|             Long idUser, | ||||
|             String userSurname, | ||||
|             String userName, | ||||
|             String primaryMail, | ||||
|             String secondaryMail, | ||||
|             String phoneNumber) { | ||||
|         this.idUser = idUser; | ||||
|         this.userSurname = userSurname; | ||||
|         this.userName = userName; | ||||
|         this.primaryMail = primaryMail; | ||||
|         this.secondaryMail = secondaryMail; | ||||
|         this.phoneNumber = phoneNumber; | ||||
|     } | ||||
|  | ||||
|     public User( | ||||
|             String userSurname, | ||||
|             String userName, | ||||
|             String primaryMail, | ||||
|             String secondaryMail, | ||||
|             String phoneNumber) { | ||||
|         this.userSurname = userSurname; | ||||
|         this.userName = userName; | ||||
|         this.primaryMail = primaryMail; | ||||
|         this.secondaryMail = secondaryMail; | ||||
|         this.phoneNumber = phoneNumber; | ||||
|     } | ||||
|  | ||||
|     public Long getIdUser() { | ||||
|         return idUser; | ||||
|     } | ||||
|  | ||||
|     public void setIdUser(Long idUser) { | ||||
|         this.idUser = idUser; | ||||
|     } | ||||
|  | ||||
|     public String getUserSurname() { | ||||
|         return userSurname; | ||||
|     } | ||||
|  | ||||
|     public void setUserSurname(String userSurname) { | ||||
|         userSurname = userSurname; | ||||
|     } | ||||
|  | ||||
|     public String getUserName() { | ||||
|         return userName; | ||||
|     } | ||||
|  | ||||
|     public void setUserName(String userName) { | ||||
|         userName = userName; | ||||
|     } | ||||
|  | ||||
|     public String getPrimaryMail() { | ||||
|         return primaryMail; | ||||
|     } | ||||
|  | ||||
|     public void setPrimaryMail(String primaryMail) { | ||||
|         this.primaryMail = primaryMail; | ||||
|     } | ||||
|  | ||||
|     public String getSecondaryMail() { | ||||
|         return secondaryMail; | ||||
|     } | ||||
|  | ||||
|     public void setSecondaryMail(String secondaryMail) { | ||||
|         this.secondaryMail = secondaryMail; | ||||
|     } | ||||
|  | ||||
|     public String getPhoneNumber() { | ||||
|         return phoneNumber; | ||||
|     } | ||||
|  | ||||
|     public void setPhoneNumber(String phoneNumber) { | ||||
|         phoneNumber = phoneNumber; | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| package enseirb.myinpulse.utils.keycloak.datatypes; | ||||
| package enseirb.myinpulse.model; | ||||
| 
 | ||||
| public class UserRepresentation { | ||||
|     public String id; | ||||
| @@ -1,38 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.controller; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Administrateurs; | ||||
| import enseirb.myinpulse.postgres_db.repository.AdministrateursRepository; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RestController | ||||
| public class AdministrateursController { | ||||
|  | ||||
|     @Autowired AdministrateursRepository administrateursRepository; | ||||
|  | ||||
|     @GetMapping("/Administrateurs") | ||||
|     @ResponseBody | ||||
|     public Iterable<Administrateurs> allAdministrateurs() { | ||||
|         return this.administrateursRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/Administrateurs/{id}") | ||||
|     public Administrateurs getAdministrateursById(@PathVariable Long id) { | ||||
|         Optional<Administrateurs> administrateur = this.administrateursRepository.findById(id); | ||||
|         if (administrateur.isEmpty()) { | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cet administrateur n'existe pas"); | ||||
|         } | ||||
|         return administrateur.get(); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Administrateurs") | ||||
|     public Administrateurs addAdministrateurs(@RequestBody Administrateurs administrateurs) { | ||||
|         return this.administrateursRepository.save(administrateurs); | ||||
|     } | ||||
| } | ||||
| @@ -1,49 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.controller; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.ComptesRendus; | ||||
| import enseirb.myinpulse.postgres_db.repository.ComptesRendusRepository; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RestController | ||||
| public class ComptesRendusController { | ||||
|  | ||||
|     @Autowired ComptesRendusRepository comptesRendusRepository; | ||||
|  | ||||
|     @GetMapping("/ComptesRendus") | ||||
|     @ResponseBody | ||||
|     public Iterable<ComptesRendus> allComptesRendus() { | ||||
|         return this.comptesRendusRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/ComptesRendus/{id}") | ||||
|     public ComptesRendus getComptesRendusById(@PathVariable Long id) { | ||||
|         Optional<ComptesRendus> compteRendu = this.comptesRendusRepository.findById(id); | ||||
|         if (compteRendu.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce compte rendu n'existe pas"); | ||||
|         } | ||||
|         return compteRendu.get(); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/ComptesRendus") | ||||
|     public ComptesRendus addComptesRendus(@RequestBody ComptesRendus comptesRendus) { | ||||
|         return this.comptesRendusRepository.save(comptesRendus); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/ComptesRendus/{id}") | ||||
|     public ComptesRendus updateProjets(@PathVariable Long id, String contenu_compte_rendu) { | ||||
|         Optional<ComptesRendus> compteRendu = this.comptesRendusRepository.findById(id); | ||||
|         if (compteRendu.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce compte rendu n'existe pas"); | ||||
|         } | ||||
|         if (contenu_compte_rendu != null) { | ||||
|             compteRendu.get().setContenu_compte_rendu(contenu_compte_rendu); | ||||
|         } | ||||
|         return this.comptesRendusRepository.save(compteRendu.get()); | ||||
|     } | ||||
| } | ||||
| @@ -1,58 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.controller; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Entrepreneurs; | ||||
| import enseirb.myinpulse.postgres_db.repository.EntrepreneursRepository; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RestController | ||||
| public class EntrepreneursController { | ||||
|  | ||||
|     @Autowired EntrepreneursRepository entrepreneursRepository; | ||||
|  | ||||
|     @GetMapping("/Entrepreneurs") | ||||
|     @ResponseBody | ||||
|     public Iterable<Entrepreneurs> allEntrepreneurs() { | ||||
|         return this.entrepreneursRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/Entrepreneurs/{id}") | ||||
|     public Entrepreneurs getEntrepreneursById(@PathVariable Long id) { | ||||
|         Optional<Entrepreneurs> entrepreneur = entrepreneursRepository.findById(id); | ||||
|         if (entrepreneur.isEmpty()) { | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cet entrepreneur n'existe pas"); | ||||
|         } | ||||
|         return entrepreneur.get(); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Entrepreneurs") | ||||
|     public Entrepreneurs addEntrepreneurs(@RequestBody Entrepreneurs entrepreneurs) { | ||||
|         return this.entrepreneursRepository.save(entrepreneurs); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Entrepreneurs/{id}") | ||||
|     public Entrepreneurs updateEntrepreneurs( | ||||
|             @PathVariable Long id, String ecole, String filiere, Boolean status_snee) { | ||||
|         Optional<Entrepreneurs> entrepreneur = entrepreneursRepository.findById(id); | ||||
|         if (entrepreneur.isEmpty()) { | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cet entrepreneur n'existe pas"); | ||||
|         } | ||||
|         if (ecole != null) { | ||||
|             entrepreneur.get().setEcole(ecole); | ||||
|         } | ||||
|         if (filiere != null) { | ||||
|             entrepreneur.get().setFiliere(filiere); | ||||
|         } | ||||
|         if (status_snee != null) { | ||||
|             entrepreneur.get().setStatus_snee(status_snee); | ||||
|         } | ||||
|         return this.entrepreneursRepository.save(entrepreneur.get()); | ||||
|     } | ||||
| } | ||||
| @@ -1,64 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.controller; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Projets; | ||||
| import enseirb.myinpulse.postgres_db.repository.ProjetsRepository; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RestController | ||||
| public class ProjetsController { | ||||
|  | ||||
|     @Autowired ProjetsRepository projetsRepository; | ||||
|  | ||||
|     @GetMapping("/Projets") | ||||
|     @ResponseBody | ||||
|     public Iterable<Projets> allProjets() { | ||||
|         return this.projetsRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/Projets/{id}") | ||||
|     public Projets getProjetsById(@PathVariable Long id) { | ||||
|         Optional<Projets> projet = this.projetsRepository.findById(id); | ||||
|         if (projet.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); | ||||
|         } | ||||
|         return projet.get(); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Projets") | ||||
|     public Projets addProjets(@RequestBody Projets projet) { | ||||
|         return this.projetsRepository.save(projet); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Projets/{id}") | ||||
|     public Projets updateProjets( | ||||
|             @PathVariable Long id, | ||||
|             String nom_projet, | ||||
|             byte[] logo, | ||||
|             LocalDate date_creation, | ||||
|             String status_projet) { | ||||
|         Optional<Projets> projet = this.projetsRepository.findById(id); | ||||
|         if (projet.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); | ||||
|         } | ||||
|         if (nom_projet != null) { | ||||
|             projet.get().setNom_projet(nom_projet); | ||||
|         } | ||||
|         if (logo != null) { | ||||
|             projet.get().setLogo(logo); | ||||
|         } | ||||
|         if (date_creation != null) { | ||||
|             projet.get().setDate_creation(date_creation); | ||||
|         } | ||||
|         if (status_projet != null) { | ||||
|             projet.get().setStatus_projet(status_projet); | ||||
|         } | ||||
|         return this.projetsRepository.save(projet.get()); | ||||
|     } | ||||
| } | ||||
| @@ -1,67 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.controller; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.RendezVous; | ||||
| import enseirb.myinpulse.postgres_db.repository.RendezVousRepository; | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalTime; | ||||
| import java.util.Optional; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| @RestController | ||||
| public class RendezVousController { | ||||
|  | ||||
|     @Autowired RendezVousRepository rendezVousRepository; | ||||
|  | ||||
|     @GetMapping("/RendezVous") | ||||
|     @ResponseBody | ||||
|     public Iterable<RendezVous> allRendezVous() { | ||||
|         return this.rendezVousRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/RendezVous/{id}") | ||||
|     public RendezVous getRendezVousById(@PathVariable Long id) { | ||||
|         Optional<RendezVous> rendezVous = this.rendezVousRepository.findById(id); | ||||
|         if (rendezVous.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce rendez vous n'existe pas"); | ||||
|         } | ||||
|         return rendezVous.get(); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/RendezVous") | ||||
|     public RendezVous addRendezVous(@RequestBody RendezVous rendezVous) { | ||||
|         return this.rendezVousRepository.save(rendezVous); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/RendezVous/{id}") | ||||
|     public RendezVous updateRendezVous( | ||||
|             @PathVariable Long id, | ||||
|             LocalDate date_rdv, | ||||
|             LocalTime heure_rdv, | ||||
|             LocalTime duree_rdv, | ||||
|             String lieu_rdv, | ||||
|             String sujet_rdv) { | ||||
|         Optional<RendezVous> rendezVous = this.rendezVousRepository.findById(id); | ||||
|         if (rendezVous.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce rendez vous n'existe pas"); | ||||
|         } | ||||
|         if (date_rdv != null) { | ||||
|             rendezVous.get().setDate_rdv(date_rdv); | ||||
|         } | ||||
|         if (heure_rdv != null) { | ||||
|             rendezVous.get().setHeure_rdv(heure_rdv); | ||||
|         } | ||||
|         if (duree_rdv != null) { | ||||
|             rendezVous.get().setDuree_rdv(duree_rdv); | ||||
|         } | ||||
|         if (lieu_rdv != null) { | ||||
|             rendezVous.get().setLieu_rdv(lieu_rdv); | ||||
|         } | ||||
|         if (sujet_rdv != null) { | ||||
|             rendezVous.get().setSujet_rdv(sujet_rdv); | ||||
|         } | ||||
|         return this.rendezVousRepository.save(rendezVous.get()); | ||||
|     } | ||||
| } | ||||
| @@ -1,60 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.controller; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Sections; | ||||
| import enseirb.myinpulse.postgres_db.repository.SectionsRepository; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RestController | ||||
| public class SectionsController { | ||||
|  | ||||
|     @Autowired SectionsRepository sectionsRepository; | ||||
|  | ||||
|     @GetMapping("/Sections") | ||||
|     @ResponseBody | ||||
|     public Iterable<Sections> allSections() { | ||||
|         return this.sectionsRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/Sections/{id}") | ||||
|     public Sections getSectionsById(@PathVariable Long id) { | ||||
|         Optional<Sections> section = this.sectionsRepository.findById(id); | ||||
|         if (section.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cette section n'extise pas"); | ||||
|         } | ||||
|         return section.get(); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Sections") | ||||
|     public Sections addSections(@RequestBody Sections sections) { | ||||
|         return this.sectionsRepository.save(sections); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Sections/{id}") | ||||
|     public Sections updateSections( | ||||
|             @PathVariable Long id, | ||||
|             String titre, | ||||
|             String contenu_section, | ||||
|             LocalDateTime date_modification) { | ||||
|         Optional<Sections> section = this.sectionsRepository.findById(id); | ||||
|         if (section.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cette section n'extise pas"); | ||||
|         } | ||||
|         if (titre != null) { | ||||
|             section.get().setTitre(titre); | ||||
|         } | ||||
|         if (contenu_section != null) { | ||||
|             section.get().setContenu_section(contenu_section); | ||||
|         } | ||||
|         if (date_modification != null) { | ||||
|             section.get().setDate_modification(date_modification); | ||||
|         } | ||||
|         return this.sectionsRepository.save(section.get()); | ||||
|     } | ||||
| } | ||||
| @@ -1,67 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.controller; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Utilisateurs; | ||||
| import enseirb.myinpulse.postgres_db.repository.UtilisateursRepository; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RestController | ||||
| public class UtilisateursController { | ||||
|  | ||||
|     @Autowired UtilisateursRepository utilisateursRepository; | ||||
|  | ||||
|     @GetMapping("/Utilisateurs") | ||||
|     @ResponseBody | ||||
|     public Iterable<Utilisateurs> allUtilisateurs() { | ||||
|         return this.utilisateursRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/Utilisateurs/{id}") | ||||
|     public Utilisateurs getUtilisateursById(@PathVariable Long id) { | ||||
|         Optional<Utilisateurs> utilisateur = utilisateursRepository.findById(id); | ||||
|         if (utilisateur.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); | ||||
|         } | ||||
|         return utilisateur.get(); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Utilisateurs") | ||||
|     public Utilisateurs addUtilisateurs(@RequestBody Utilisateurs utilisateurs) { | ||||
|         return this.utilisateursRepository.save(utilisateurs); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/Utilisateurs/{id}") | ||||
|     public Utilisateurs updateUtilisateurs( | ||||
|             @PathVariable Long id, | ||||
|             String nom_utilisateur, | ||||
|             String prenom_utilisateur, | ||||
|             String mail_principal, | ||||
|             String mail_secondaire, | ||||
|             String numero_telephone) { | ||||
|         Optional<Utilisateurs> utilisateur = utilisateursRepository.findById(id); | ||||
|         if (utilisateur.isEmpty()) { | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); | ||||
|         } | ||||
|         if (nom_utilisateur != null) { | ||||
|             utilisateur.get().setNom_utilisateur(nom_utilisateur); | ||||
|         } | ||||
|         if (prenom_utilisateur != null) { | ||||
|             utilisateur.get().setPrenom_utilisateur(prenom_utilisateur); | ||||
|         } | ||||
|         if (mail_principal != null) { | ||||
|             utilisateur.get().setMail_principal(mail_principal); | ||||
|         } | ||||
|         if (mail_secondaire != null) { | ||||
|             utilisateur.get().setMail_secondaire(mail_secondaire); | ||||
|         } | ||||
|         if (numero_telephone != null) { | ||||
|             utilisateur.get().setNumero_telephone(numero_telephone); | ||||
|         } | ||||
|         return this.utilisateursRepository.save(utilisateur.get()); | ||||
|     } | ||||
| } | ||||
| @@ -1,43 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.persistence.PrimaryKeyJoinColumn; | ||||
| import jakarta.persistence.Table; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "administrateurs") | ||||
| @PrimaryKeyJoinColumn(name = "id_administrateur", referencedColumnName = "id_utilisateur") | ||||
| public class Administrateurs extends Utilisateurs { | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "id_projet") | ||||
|     private Projets projetsAdministrateurs; | ||||
|  | ||||
|     @OneToMany(mappedBy = "administrateursSections", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private List<Sections> ListSections = new ArrayList<>(); | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "id_rdv") | ||||
|     private RendezVous rendezVousAdministrateurs; | ||||
|  | ||||
|     public Administrateurs() {} | ||||
|  | ||||
|     public Administrateurs( | ||||
|             String nom_utilisateur, | ||||
|             Long id_utilisateur, | ||||
|             String prenom_utilisateur, | ||||
|             String mail_principal, | ||||
|             String mail_secondaire, | ||||
|             String numero_telephone) { | ||||
|         super( | ||||
|                 nom_utilisateur, | ||||
|                 id_utilisateur, | ||||
|                 prenom_utilisateur, | ||||
|                 mail_principal, | ||||
|                 mail_secondaire, | ||||
|                 numero_telephone); | ||||
|     } | ||||
| } | ||||
| @@ -1,46 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.persistence.Entity; | ||||
| import jakarta.persistence.Id; | ||||
| import jakarta.persistence.Table; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "comptes_rendus") | ||||
| public class ComptesRendus { | ||||
|  | ||||
|     @Id | ||||
|     @NotNull | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long id_compte_rendu; | ||||
|  | ||||
|     private String contenu_compte_rendu; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "id_rdv") | ||||
|     private RendezVous rendezVousComptesRendus; | ||||
|  | ||||
|     public ComptesRendus() {} | ||||
|  | ||||
|     public ComptesRendus(Long id_compte_rendu, String contenu_compte_rendu) { | ||||
|         this.id_compte_rendu = id_compte_rendu; | ||||
|         this.contenu_compte_rendu = contenu_compte_rendu; | ||||
|     } | ||||
|  | ||||
|     public Long getId_compte_rendu() { | ||||
|         return id_compte_rendu; | ||||
|     } | ||||
|  | ||||
|     public void setId_compte_rendu(Long id_compte_rendu) { | ||||
|         this.id_compte_rendu = id_compte_rendu; | ||||
|     } | ||||
|  | ||||
|     public String getContenu_compte_rendu() { | ||||
|         return contenu_compte_rendu; | ||||
|     } | ||||
|  | ||||
|     public void setContenu_compte_rendu(String contenu_compte_rendu) { | ||||
|         this.contenu_compte_rendu = contenu_compte_rendu; | ||||
|     } | ||||
| } | ||||
| @@ -1,80 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.persistence.Entity; | ||||
| import jakarta.persistence.Table; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "entrepreneurs") | ||||
| @PrimaryKeyJoinColumn(name = "id_entrepreneur", referencedColumnName = "id_utilisateur") | ||||
| public class Entrepreneurs extends Utilisateurs { | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String ecole; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String filiere; | ||||
|  | ||||
|     private boolean status_snee; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "id_projet_participation", referencedColumnName = "id_projet") | ||||
|     private Projets projetsParticipation; | ||||
|  | ||||
|     // @Column(insertable=false, updatable=false) | ||||
|     @OneToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "id_projet_propose", referencedColumnName = "id_projet") | ||||
|     private Projets projetsPropose; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "id_rdv") | ||||
|     private RendezVous rendezVousEntrepreneurs; | ||||
|  | ||||
|     public Entrepreneurs() {} | ||||
|  | ||||
|     public Entrepreneurs( | ||||
|             String nom_utilisateur, | ||||
|             Long id_utilisateur, | ||||
|             String prenom_utilisateur, | ||||
|             String mail_principal, | ||||
|             String mail_secondaire, | ||||
|             String numero_telephone, | ||||
|             String ecole, | ||||
|             boolean status_snee, | ||||
|             String filiere) { | ||||
|         super( | ||||
|                 nom_utilisateur, | ||||
|                 id_utilisateur, | ||||
|                 prenom_utilisateur, | ||||
|                 mail_principal, | ||||
|                 mail_secondaire, | ||||
|                 numero_telephone); | ||||
|         this.ecole = ecole; | ||||
|         this.status_snee = status_snee; | ||||
|         this.filiere = filiere; | ||||
|     } | ||||
|  | ||||
|     public String getEcole() { | ||||
|         return ecole; | ||||
|     } | ||||
|  | ||||
|     public void setEcole(String ecole) { | ||||
|         this.ecole = ecole; | ||||
|     } | ||||
|  | ||||
|     public String getFiliere() { | ||||
|         return filiere; | ||||
|     } | ||||
|  | ||||
|     public void setFiliere(String filiere) { | ||||
|         this.filiere = filiere; | ||||
|     } | ||||
|  | ||||
|     public boolean isStatus_snee() { | ||||
|         return status_snee; | ||||
|     } | ||||
|  | ||||
|     public void setStatus_snee(boolean status_snee) { | ||||
|         this.status_snee = status_snee; | ||||
|     } | ||||
| } | ||||
| @@ -1,98 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "projets") | ||||
| public class Projets { | ||||
|  | ||||
|     @Id | ||||
|     @NotNull | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long id_projet; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String nom_projet; | ||||
|  | ||||
|     private byte[] logo; | ||||
|  | ||||
|     private LocalDate date_creation; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String status_projet; | ||||
|  | ||||
|     @OneToMany(mappedBy = "projetsAdministrateurs", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private List<Administrateurs> listAdministrateurs = new ArrayList<>(); | ||||
|  | ||||
|     @OneToMany(mappedBy = "projetsParticipation", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private List<Entrepreneurs> ListEntrepreneursParticipation = new ArrayList<>(); | ||||
|  | ||||
|     @OneToOne(mappedBy = "projetsPropose", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private Entrepreneurs entrepreneursPropose; | ||||
|  | ||||
|     @OneToMany(mappedBy = "projetsSections", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private List<Sections> ListSections = new ArrayList<>(); | ||||
|  | ||||
|     // Hibernate expects entities to have a no-arg constructor, | ||||
|     // though it does not necessarily have to be public. | ||||
|  | ||||
|     public Projets() {} | ||||
|  | ||||
|     public Projets( | ||||
|             Long id_projet, | ||||
|             String nom_projet, | ||||
|             byte[] logo, | ||||
|             LocalDate date_creation, | ||||
|             String status_projet) { | ||||
|         this.id_projet = id_projet; | ||||
|         this.nom_projet = nom_projet; | ||||
|         this.logo = logo; | ||||
|         this.date_creation = date_creation; | ||||
|         this.status_projet = status_projet; | ||||
|     } | ||||
|  | ||||
|     public Long getId_projet() { | ||||
|         return id_projet; | ||||
|     } | ||||
|  | ||||
|     public void setId_projet(Long id_projet) { | ||||
|         this.id_projet = id_projet; | ||||
|     } | ||||
|  | ||||
|     public String getNom_projet() { | ||||
|         return nom_projet; | ||||
|     } | ||||
|  | ||||
|     public void setNom_projet(String nom_projet) { | ||||
|         this.nom_projet = nom_projet; | ||||
|     } | ||||
|  | ||||
|     public byte[] getLogo() { | ||||
|         return logo; | ||||
|     } | ||||
|  | ||||
|     public void setLogo(byte[] logo) { | ||||
|         this.logo = logo; | ||||
|     } | ||||
|  | ||||
|     public LocalDate getDate_creation() { | ||||
|         return date_creation; | ||||
|     } | ||||
|  | ||||
|     public void setDate_creation(LocalDate date_creation) { | ||||
|         this.date_creation = date_creation; | ||||
|     } | ||||
|  | ||||
|     public String getStatus_projet() { | ||||
|         return status_projet; | ||||
|     } | ||||
|  | ||||
|     public void setStatus_projet(String status_projet) { | ||||
|         this.status_projet = status_projet; | ||||
|     } | ||||
| } | ||||
| @@ -1,111 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "rendez_vous") | ||||
| public class RendezVous { | ||||
|  | ||||
|     @OneToMany(mappedBy = "rendezVousEntrepreneurs", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<Entrepreneurs> ListEntrepreneurs = new ArrayList<>(); | ||||
|  | ||||
|     @OneToMany(mappedBy = "rendezVousAdministrateurs", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<Administrateurs> ListAdministrateurs = new ArrayList<>(); | ||||
|  | ||||
|     @OneToMany(mappedBy = "rendezVousComptesRendus", fetch = FetchType.LAZY, orphanRemoval = true) | ||||
|     private final List<ComptesRendus> ListComptesRendus = new ArrayList<>(); | ||||
|  | ||||
|     @ManyToMany( | ||||
|             fetch = FetchType.LAZY, | ||||
|             cascade = {CascadeType.ALL}) | ||||
|     @JoinTable( | ||||
|             name = "concerner", | ||||
|             joinColumns = @JoinColumn(name = "id_rdv"), | ||||
|             inverseJoinColumns = @JoinColumn(name = "id_section")) | ||||
|     List<Sections> ListSections = new ArrayList<>(); | ||||
|  | ||||
|     @Id | ||||
|     @NotNull | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long id_rdv; | ||||
|  | ||||
|     private LocalDate date_rdv; | ||||
|     private LocalTime heure_rdv; | ||||
|     private LocalTime duree_rdv; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String lieu_rdv; | ||||
|  | ||||
|     private String sujet_rdv; | ||||
|  | ||||
|     public RendezVous() {} | ||||
|  | ||||
|     public RendezVous( | ||||
|             Long id_rdv, | ||||
|             LocalDate date_rdv, | ||||
|             LocalTime heure_rdv, | ||||
|             LocalTime duree_rdv, | ||||
|             String lieu_rdv, | ||||
|             String sujet_rdv) { | ||||
|         this.id_rdv = id_rdv; | ||||
|         this.date_rdv = date_rdv; | ||||
|         this.heure_rdv = heure_rdv; | ||||
|         this.duree_rdv = duree_rdv; | ||||
|         this.lieu_rdv = lieu_rdv; | ||||
|         this.sujet_rdv = sujet_rdv; | ||||
|     } | ||||
|  | ||||
|     public Long getId_rdv() { | ||||
|         return id_rdv; | ||||
|     } | ||||
|  | ||||
|     public void setId_rdv(Long id_rdv) { | ||||
|         this.id_rdv = id_rdv; | ||||
|     } | ||||
|  | ||||
|     public LocalDate getDate_rdv() { | ||||
|         return date_rdv; | ||||
|     } | ||||
|  | ||||
|     public void setDate_rdv(LocalDate date_rdv) { | ||||
|         this.date_rdv = date_rdv; | ||||
|     } | ||||
|  | ||||
|     public LocalTime getHeure_rdv() { | ||||
|         return heure_rdv; | ||||
|     } | ||||
|  | ||||
|     public void setHeure_rdv(LocalTime heure_rdv) { | ||||
|         this.heure_rdv = heure_rdv; | ||||
|     } | ||||
|  | ||||
|     public LocalTime getDuree_rdv() { | ||||
|         return duree_rdv; | ||||
|     } | ||||
|  | ||||
|     public void setDuree_rdv(LocalTime duree_rdv) { | ||||
|         this.duree_rdv = duree_rdv; | ||||
|     } | ||||
|  | ||||
|     public String getLieu_rdv() { | ||||
|         return lieu_rdv; | ||||
|     } | ||||
|  | ||||
|     public void setLieu_rdv(String lieu_rdv) { | ||||
|         this.lieu_rdv = lieu_rdv; | ||||
|     } | ||||
|  | ||||
|     public String getSujet_rdv() { | ||||
|         return sujet_rdv; | ||||
|     } | ||||
|  | ||||
|     public void setSujet_rdv(String sujet_rdv) { | ||||
|         this.sujet_rdv = sujet_rdv; | ||||
|     } | ||||
| } | ||||
| @@ -1,81 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "sections") | ||||
| public class Sections { | ||||
|  | ||||
|     @Id | ||||
|     @NotNull | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long id_section; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String titre; | ||||
|  | ||||
|     private String contenu_section; | ||||
|  | ||||
|     private LocalDateTime date_modification; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "id_projet") | ||||
|     private Projets projetsSections; | ||||
|  | ||||
|     @ManyToOne(fetch = FetchType.LAZY) | ||||
|     @JoinColumn(name = "id_admnistrateur") | ||||
|     private Administrateurs administrateursSections; | ||||
|  | ||||
|     @ManyToMany(mappedBy = "ListSections") | ||||
|     private List<RendezVous> rendezVous = new ArrayList<>(); | ||||
|  | ||||
|     public Sections() {} | ||||
|  | ||||
|     public Sections( | ||||
|             Long id_section, | ||||
|             String titre, | ||||
|             String contenu_section, | ||||
|             LocalDateTime date_modification) { | ||||
|         this.id_section = id_section; | ||||
|         this.titre = titre; | ||||
|         this.contenu_section = contenu_section; | ||||
|         this.date_modification = date_modification; | ||||
|     } | ||||
|  | ||||
|     public String getTitre() { | ||||
|         return titre; | ||||
|     } | ||||
|  | ||||
|     public void setTitre(String titre) { | ||||
|         this.titre = titre; | ||||
|     } | ||||
|  | ||||
|     public Long getId_section() { | ||||
|         return id_section; | ||||
|     } | ||||
|  | ||||
|     public void setId_section(Long id_section) { | ||||
|         this.id_section = id_section; | ||||
|     } | ||||
|  | ||||
|     public String getContenu_section() { | ||||
|         return contenu_section; | ||||
|     } | ||||
|  | ||||
|     public void setContenu_section(String contenu_section) { | ||||
|         this.contenu_section = contenu_section; | ||||
|     } | ||||
|  | ||||
|     public LocalDateTime getDate_modification() { | ||||
|         return date_modification; | ||||
|     } | ||||
|  | ||||
|     public void setDate_modification(LocalDateTime date_modification) { | ||||
|         this.date_modification = date_modification; | ||||
|     } | ||||
| } | ||||
| @@ -1,95 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.model; | ||||
|  | ||||
| import jakarta.persistence.*; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
|  | ||||
| @Entity | ||||
| @Table(name = "utilisateurs") | ||||
| @Inheritance(strategy = InheritanceType.JOINED) | ||||
| public class Utilisateurs { | ||||
|  | ||||
|     @Id | ||||
|     @NotNull | ||||
|     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||
|     private Long id_utilisateur; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String nom_utilisateur; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String prenom_utilisateur; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String mail_principal; | ||||
|  | ||||
|     @Column(length = 255) | ||||
|     private String mail_secondaire; | ||||
|  | ||||
|     @Column(length = 20) | ||||
|     private String numero_telephone; | ||||
|  | ||||
|     public Utilisateurs() {} | ||||
|  | ||||
|     public Utilisateurs( | ||||
|             String nom_utilisateur, | ||||
|             Long id_utilisateur, | ||||
|             String prenom_utilisateur, | ||||
|             String mail_principal, | ||||
|             String mail_secondaire, | ||||
|             String numero_telephone) { | ||||
|         this.nom_utilisateur = nom_utilisateur; | ||||
|         this.id_utilisateur = id_utilisateur; | ||||
|         this.prenom_utilisateur = prenom_utilisateur; | ||||
|         this.mail_principal = mail_principal; | ||||
|         this.mail_secondaire = mail_secondaire; | ||||
|         this.numero_telephone = numero_telephone; | ||||
|     } | ||||
|  | ||||
|     public Long getId_utilisateur() { | ||||
|         return id_utilisateur; | ||||
|     } | ||||
|  | ||||
|     public void setId_utilisateur(Long id_utilisateur) { | ||||
|         this.id_utilisateur = id_utilisateur; | ||||
|     } | ||||
|  | ||||
|     public String getNom_utilisateur() { | ||||
|         return nom_utilisateur; | ||||
|     } | ||||
|  | ||||
|     public void setNom_utilisateur(String nom_utilisateur) { | ||||
|         this.nom_utilisateur = nom_utilisateur; | ||||
|     } | ||||
|  | ||||
|     public String getPrenom_utilisateur() { | ||||
|         return prenom_utilisateur; | ||||
|     } | ||||
|  | ||||
|     public void setPrenom_utilisateur(String prenom_utilisateur) { | ||||
|         this.prenom_utilisateur = prenom_utilisateur; | ||||
|     } | ||||
|  | ||||
|     public String getMail_principal() { | ||||
|         return mail_principal; | ||||
|     } | ||||
|  | ||||
|     public void setMail_principal(String mail_principal) { | ||||
|         this.mail_principal = mail_principal; | ||||
|     } | ||||
|  | ||||
|     public String getMail_secondaire() { | ||||
|         return mail_secondaire; | ||||
|     } | ||||
|  | ||||
|     public void setMail_secondaire(String mail_secondaire) { | ||||
|         this.mail_secondaire = mail_secondaire; | ||||
|     } | ||||
|  | ||||
|     public String getNumero_telephone() { | ||||
|         return numero_telephone; | ||||
|     } | ||||
|  | ||||
|     public void setNumero_telephone(String numero_telephone) { | ||||
|         this.numero_telephone = numero_telephone; | ||||
|     } | ||||
| } | ||||
| @@ -1,14 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.repository; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Administrateurs; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface AdministrateursRepository extends JpaRepository<Administrateurs, Long> { | ||||
|  | ||||
|     /* @Query("SELECT a from Administrateurs a") | ||||
|     Administrateurs findAllAdministrateurs(); */ | ||||
|  | ||||
| } | ||||
| @@ -1,9 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.repository; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.ComptesRendus; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface ComptesRendusRepository extends JpaRepository<ComptesRendus, Long> {} | ||||
| @@ -1,14 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.repository; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Entrepreneurs; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface EntrepreneursRepository extends JpaRepository<Entrepreneurs, Long> { | ||||
|  | ||||
|     /* @Query("SELECT e from Entrepreneurs e") | ||||
|     Entrepreneurs findAllEntrepreneurs(); */ | ||||
|  | ||||
| } | ||||
| @@ -1,9 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.repository; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Projets; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface ProjetsRepository extends JpaRepository<Projets, Long> {} | ||||
| @@ -1,9 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.repository; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.RendezVous; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface RendezVousRepository extends JpaRepository<RendezVous, Long> {} | ||||
| @@ -1,9 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.repository; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Sections; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface SectionsRepository extends JpaRepository<Sections, Long> {} | ||||
| @@ -1,14 +0,0 @@ | ||||
| package enseirb.myinpulse.postgres_db.repository; | ||||
|  | ||||
| import enseirb.myinpulse.postgres_db.model.Utilisateurs; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface UtilisateursRepository extends JpaRepository<Utilisateurs, Long> { | ||||
|  | ||||
|     /* @Query("SELECT u from Utilisateurs u") | ||||
|     Utilisateurs findAllUtilisateurs(); */ | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,17 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.Administrator; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface AdministratorRepository extends JpaRepository<Administrator, Long> { | ||||
|  | ||||
|     /* @Query("SELECT a from Administrators a") | ||||
|     Administrator findAllAdministrator(); */ | ||||
|  | ||||
|     Optional<Administrator> findByPrimaryMail(String PrimaryMail); | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.Annotation; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface AnnotationRepository extends JpaRepository<Annotation, Long> {} | ||||
| @@ -0,0 +1,9 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.Appointment; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface AppointmentRepository extends JpaRepository<Appointment, Long> {} | ||||
| @@ -0,0 +1,17 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.Entrepreneur; | ||||
| import enseirb.myinpulse.model.Project; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface EntrepreneurRepository extends JpaRepository<Entrepreneur, Long> { | ||||
|  | ||||
|     Iterable<Entrepreneur> getEntrepreneurByProjectParticipation(Project project); | ||||
|  | ||||
|     /* @Query("SELECT e from Entrepreneur e") | ||||
|     Entrepreneur findAllEntrepreneurl(); */ | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.MakeAppointment; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface MakeAppointmentRepository extends JpaRepository<MakeAppointment, Long> {} | ||||
| @@ -0,0 +1,19 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.Administrator; | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.model.ProjectDecisionValue; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface ProjectRepository extends JpaRepository<Project, Long> { | ||||
|     Iterable<Project> findByProjectAdministrator(Administrator administrator); | ||||
|  | ||||
|     Iterable<Project> findByProjectStatus(ProjectDecisionValue status); | ||||
|  | ||||
|     Optional<Project> findByProjectName(String projectName); | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.Report; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface ReportRepository extends JpaRepository<Report, Long> {} | ||||
| @@ -0,0 +1,18 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.model.SectionCell; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface SectionCellRepository extends JpaRepository<SectionCell, Long> { | ||||
|  | ||||
|     Iterable<SectionCell> findByProjectSectionCellAndSectionId(Project project, long sectionId); | ||||
|  | ||||
|     Iterable<SectionCell> findByProjectSectionCellAndSectionIdAndModificationDateBefore( | ||||
|             Project project, long sectionId, LocalDateTime date); | ||||
| } | ||||
| @@ -0,0 +1,17 @@ | ||||
| package enseirb.myinpulse.repository; | ||||
|  | ||||
| import enseirb.myinpulse.model.User; | ||||
|  | ||||
| import org.springframework.data.jpa.repository.JpaRepository; | ||||
| import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @RepositoryRestResource | ||||
| public interface UserRepository extends JpaRepository<User, Long> { | ||||
|     Optional<User> findByPrimaryMail(String email); | ||||
|  | ||||
|     /* @Query("SELECT u from User u") | ||||
|     User findAllUser(); */ | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,166 @@ | ||||
| package enseirb.myinpulse.service; | ||||
|  | ||||
| import static enseirb.myinpulse.model.ProjectDecisionValue.ACTIVE; | ||||
| import static enseirb.myinpulse.model.ProjectDecisionValue.REJECTED; | ||||
|  | ||||
| import enseirb.myinpulse.model.*; | ||||
| import enseirb.myinpulse.service.database.*; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Service | ||||
| public class AdminApiService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final ProjectService projectService; | ||||
|     private final UserService userService; | ||||
|     private final AdministratorService administratorService; | ||||
|     private final UtilsService utilsService; | ||||
|     private final AppointmentService appointmentService; | ||||
|     private final ReportService reportService; | ||||
|     private final SectionCellService sectionCellService; | ||||
|  | ||||
|     @Autowired | ||||
|     AdminApiService( | ||||
|             ProjectService projectService, | ||||
|             UserService userService, | ||||
|             AdministratorService administratorService, | ||||
|             UtilsService utilsService, | ||||
|             AppointmentService appointmentService, | ||||
|             ReportService reportService, | ||||
|             SectionCellService sectionCellService) { | ||||
|         this.projectService = projectService; | ||||
|         this.userService = userService; | ||||
|         this.administratorService = administratorService; | ||||
|         this.utilsService = utilsService; | ||||
|         this.appointmentService = appointmentService; | ||||
|         this.reportService = reportService; | ||||
|         this.sectionCellService = sectionCellService; | ||||
|     } | ||||
|  | ||||
|     // TODO: check if tests are sufficient - peer verification required | ||||
|     public Iterable<Project> getProjectsOfAdmin(String mail) { | ||||
|         return projectService.getProjectsByAdminId( | ||||
|                 administratorService.getAdministratorById( | ||||
|                         this.userService.getUserByEmail(mail).getIdUser())); | ||||
|     } | ||||
|  | ||||
|     public Iterable<Appointment> getUpcomingAppointments(String mail) { | ||||
|         logger.info("User {} check their upcoming appointments", mail); | ||||
|         User user = this.userService.getUserByEmail(mail); | ||||
|         List<Appointment> appointments = new ArrayList<>(); | ||||
|         if (user instanceof Administrator) { | ||||
|             List<Project> projects = new ArrayList<>(((Administrator) user).getListProject()); | ||||
|             projects.forEach( | ||||
|                     project -> { | ||||
|                         project.getListSectionCell() | ||||
|                                 .forEach( | ||||
|                                         sectionCell -> { | ||||
|                                             appointments.addAll( | ||||
|                                                     this.sectionCellService | ||||
|                                                             .getAppointmentsBySectionCellId( | ||||
|                                                                     sectionCell | ||||
|                                                                             .getIdSectionCell())); | ||||
|                                         }); | ||||
|                     }); | ||||
|         } | ||||
|         if (user instanceof Entrepreneur) { | ||||
|             Project project = ((Entrepreneur) user).getProjectParticipation(); | ||||
|             project.getListSectionCell() | ||||
|                     .forEach( | ||||
|                             sectionCell -> { | ||||
|                                 appointments.addAll( | ||||
|                                         this.sectionCellService.getAppointmentsBySectionCellId( | ||||
|                                                 sectionCell.getIdSectionCell())); | ||||
|                             }); | ||||
|         } | ||||
|         return appointments; | ||||
|     } | ||||
|  | ||||
|     // TODO: check if tests are sufficient - peer verification required | ||||
|     public Iterable<Project> getPendingProjects() { | ||||
|         return this.projectService.getPendingProjects(); | ||||
|     } | ||||
|  | ||||
|     // TODO: check if tests are sufficient - peer verification required | ||||
|     public void validateProject(ProjectDecision decision) { | ||||
|         projectService.updateProject( | ||||
|                 decision.projectId, | ||||
|                 null, | ||||
|                 null, | ||||
|                 null, | ||||
|                 (decision.isAccepted == 1) ? ACTIVE : REJECTED, | ||||
|                 this.administratorService.getAdministratorById(decision.adminId)); | ||||
|     } | ||||
|  | ||||
|     // TODO: check if tests are sufficient - peer verification required | ||||
|     public void addNewProject(Project project) { | ||||
|         project.setIdProject(null); | ||||
|         // We remove the ID from the request to be sure that it will be auto generated | ||||
|         try { | ||||
|             this.projectService.getProjectByName(project.getProjectName(), true); | ||||
|             throw new ResponseStatusException(HttpStatus.CONFLICT, "Project already exists"); | ||||
|         } catch (ResponseStatusException e) { | ||||
|             if (e.getStatusCode() == HttpStatus.CONFLICT) { | ||||
|                 throw new ResponseStatusException(HttpStatus.CONFLICT, "Project already exists"); | ||||
|             } | ||||
|         } | ||||
|         Project newProject = projectService.addNewProject(project); | ||||
|         if (project.getProjectAdministrator() != null) { | ||||
|             newProject.getProjectAdministrator().updateListProject(newProject); | ||||
|         } | ||||
|         if (newProject.getEntrepreneurProposed() != null) { | ||||
|             Entrepreneur proposed = newProject.getEntrepreneurProposed(); | ||||
|             proposed.setProjectProposed(newProject); | ||||
|             proposed.setProjectParticipation(newProject); | ||||
|         } | ||||
|         newProject | ||||
|                 .getListEntrepreneurParticipation() | ||||
|                 .forEach( | ||||
|                         participation -> { | ||||
|                             participation.setProjectParticipation(newProject); | ||||
|                         }); | ||||
|         newProject | ||||
|                 .getListSectionCell() | ||||
|                 .forEach( | ||||
|                         sectionCell -> { | ||||
|                             sectionCell.setProjectSectionCell(newProject); | ||||
|                         }); | ||||
|     } | ||||
|  | ||||
|     public void createAppointmentReport(long appointmentId, Report report, String mail) { | ||||
|         long projectId = | ||||
|                 this.appointmentService | ||||
|                         .getAppointmentById(appointmentId) | ||||
|                         .getAppointmentListSectionCell() | ||||
|                         .getFirst() | ||||
|                         .getProjectSectionCell() | ||||
|                         .getIdProject(); | ||||
|         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to add an report for appointment {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     projectId); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         logger.info("User {} added a report for appointment {}", mail, projectId); | ||||
|         Report addedReport = this.reportService.addNewReport(report); | ||||
|         addedReport.setAppointmentReport(this.appointmentService.getAppointmentById(appointmentId)); | ||||
|         this.appointmentService.getAppointmentById(appointmentId).setAppointmentReport(addedReport); | ||||
|     } | ||||
|  | ||||
|     // TODO: test | ||||
|     public void deleteProject(long projectId) { | ||||
|         this.projectService.deleteProjectById(projectId); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,135 @@ | ||||
| package enseirb.myinpulse.service; | ||||
|  | ||||
| import static enseirb.myinpulse.model.ProjectDecisionValue.PENDING; | ||||
|  | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.model.SectionCell; | ||||
| import enseirb.myinpulse.service.database.ProjectService; | ||||
| import enseirb.myinpulse.service.database.SectionCellService; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| @Service | ||||
| public class EntrepreneurApiService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final SectionCellService sectionCellService; | ||||
|     private final ProjectService projectService; | ||||
|     private final UtilsService utilsService; | ||||
|  | ||||
|     @Autowired | ||||
|     EntrepreneurApiService( | ||||
|             SectionCellService sectionCellService, | ||||
|             ProjectService projectService, | ||||
|             UtilsService utilsService) { | ||||
|         this.sectionCellService = sectionCellService; | ||||
|         this.projectService = projectService; | ||||
|         this.utilsService = utilsService; | ||||
|     } | ||||
|  | ||||
|     public void editSectionCell(Long sectionCellId, SectionCell sectionCell, String mail) { | ||||
|         SectionCell editSectionCell = sectionCellService.getSectionCellById(sectionCellId); | ||||
|         if (editSectionCell == null) { | ||||
|             System.err.println("Trying to edit unknown section cell"); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cette cellule de section n'existe pas"); | ||||
|         } | ||||
|         if (!utilsService.isAllowedToCheckProject( | ||||
|                 mail, this.sectionCellService.getProjectId(sectionCellId))) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to edit section cells {} of the project {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     sectionCellId, | ||||
|                     this.sectionCellService.getProjectId(sectionCellId)); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         logger.info( | ||||
|                 "User {} edited section cell {} of the project with id {}", | ||||
|                 mail, | ||||
|                 sectionCellId, | ||||
|                 this.sectionCellService.getProjectId(sectionCellId)); | ||||
|         sectionCellService.updateSectionCell( | ||||
|                 sectionCellId, | ||||
|                 sectionCell.getSectionId(), | ||||
|                 sectionCell.getContentSectionCell(), | ||||
|                 sectionCell.getModificationDate()); | ||||
|     } | ||||
|  | ||||
|     public void removeSectionCell(Long sectionCellId, String mail) { | ||||
|         SectionCell editSectionCell = sectionCellService.getSectionCellById(sectionCellId); | ||||
|         if (editSectionCell == null) { | ||||
|             System.err.println("Trying to remove unknown section cell"); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cette cellule de section n'existe pas"); | ||||
|         } | ||||
|         if (!utilsService.isAllowedToCheckProject( | ||||
|                 mail, this.sectionCellService.getProjectId(sectionCellId))) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to remove section cells {} of the project {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     sectionCellId, | ||||
|                     this.sectionCellService.getSectionCellById(sectionCellId)); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         logger.info( | ||||
|                 "User {} removed section cell {} of the project with id {}", | ||||
|                 mail, | ||||
|                 sectionCellId, | ||||
|                 this.sectionCellService.getProjectId(sectionCellId)); | ||||
|         sectionCellService.removeSectionCellById(sectionCellId); | ||||
|     } | ||||
|  | ||||
|     public void addSectionCell(SectionCell sectionCell, String mail) { | ||||
|         if (sectionCell == null) { | ||||
|             System.err.println("Trying to create an empty section cell"); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.BAD_REQUEST, "La cellule de section fournie est vide"); | ||||
|         } | ||||
|         if (!utilsService.isAllowedToCheckProject( | ||||
|                 mail, this.sectionCellService.getProjectId(sectionCell.getIdSectionCell()))) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to add a section cell to the project {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     this.sectionCellService.getProjectId(sectionCell.getIdSectionCell())); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         logger.info( | ||||
|                 "User {} added a new section cell {} to the project with id {}", | ||||
|                 mail, | ||||
|                 sectionCell.getIdSectionCell(), | ||||
|                 this.sectionCellService.getProjectId(sectionCell.getIdSectionCell())); | ||||
|         SectionCell newSectionCell = sectionCellService.addNewSectionCell(sectionCell); | ||||
|         newSectionCell.getProjectSectionCell().updateListSectionCell(newSectionCell); | ||||
|         newSectionCell | ||||
|                 .getAppointmentSectionCell() | ||||
|                 .forEach( | ||||
|                         appointment -> { | ||||
|                             appointment.updateListSectionCell(newSectionCell); | ||||
|                         }); | ||||
|         newSectionCell | ||||
|                 .getListAnnotation() | ||||
|                 .forEach( | ||||
|                         annotation -> { | ||||
|                             annotation.setSectionCellAnnotation(newSectionCell); | ||||
|                         }); | ||||
|     } | ||||
|  | ||||
|     public void requestNewProject(Project project, String mail) { | ||||
|         if (project == null) { | ||||
|             logger.error("Trying to request the creation of a null project"); | ||||
|             throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Le projet fourni est vide"); | ||||
|         } | ||||
|         logger.info("User {} created a new project with id {}", mail, project.getIdProject()); | ||||
|         project.setProjectStatus(PENDING); | ||||
|         projectService.addNewProject(project); | ||||
|     } | ||||
| } | ||||
| @@ -1,10 +1,10 @@ | ||||
| package enseirb.myinpulse.utils.keycloak; | ||||
| package enseirb.myinpulse.service; | ||||
| 
 | ||||
| import static org.springframework.http.MediaType.APPLICATION_JSON; | ||||
| 
 | ||||
| import enseirb.myinpulse.exceptions.UserNotFoundException; | ||||
| import enseirb.myinpulse.utils.keycloak.datatypes.RoleRepresentation; | ||||
| import enseirb.myinpulse.utils.keycloak.datatypes.UserRepresentation; | ||||
| import enseirb.myinpulse.exception.UserNotFoundException; | ||||
| import enseirb.myinpulse.model.RoleRepresentation; | ||||
| import enseirb.myinpulse.model.UserRepresentation; | ||||
| 
 | ||||
| import org.springframework.web.client.RestClient; | ||||
| 
 | ||||
| @@ -0,0 +1,252 @@ | ||||
| package enseirb.myinpulse.service; | ||||
|  | ||||
| import com.itextpdf.text.*; | ||||
| import com.itextpdf.text.pdf.PdfWriter; | ||||
|  | ||||
| import enseirb.myinpulse.model.*; | ||||
| import enseirb.myinpulse.service.database.*; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.net.URI; | ||||
| import java.net.URISyntaxException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Paths; | ||||
| import java.nio.file.StandardCopyOption; | ||||
| import java.time.LocalDateTime; | ||||
| import java.time.format.DateTimeFormatter; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @Service | ||||
| public class SharedApiService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final ProjectService projectService; | ||||
|     private final EntrepreneurService entrepreneurService; | ||||
|     private final SectionCellService sectionCellService; | ||||
|     private final AppointmentService appointmentService; | ||||
|  | ||||
|     private final UtilsService utilsService; | ||||
|  | ||||
|     @Autowired | ||||
|     SharedApiService( | ||||
|             ProjectService projectService, | ||||
|             EntrepreneurService entrepreneurService, | ||||
|             SectionCellService sectionCellService, | ||||
|             AppointmentService appointmentService, | ||||
|             UtilsService utilsService) { | ||||
|         this.projectService = projectService; | ||||
|         this.entrepreneurService = entrepreneurService; | ||||
|         this.sectionCellService = sectionCellService; | ||||
|         this.appointmentService = appointmentService; | ||||
|         this.utilsService = utilsService; | ||||
|     } | ||||
|  | ||||
|     // TODO filter this with date | ||||
|     public Iterable<SectionCell> getSectionCells( | ||||
|             long projectId, long sectionId, String date, String mail) { | ||||
|  | ||||
|         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to check section cells of the project {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     projectId); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|  | ||||
|         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); | ||||
|         LocalDateTime dateTime = LocalDateTime.parse(date, formatter); | ||||
|  | ||||
|         Project project = this.projectService.getProjectById(projectId); | ||||
|         return this.sectionCellService.getSectionCellsByProjectAndSectionIdBeforeDate( | ||||
|                 project, sectionId, dateTime); | ||||
|     } | ||||
|  | ||||
|     // TODO: test | ||||
|     public Iterable<Entrepreneur> getEntrepreneursByProjectId(long projectId, String mail) { | ||||
|         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to check the member of the project {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     projectId); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         Project project = this.projectService.getProjectById(projectId); | ||||
|         return this.entrepreneurService.GetEntrepreneurByProject(project); | ||||
|     } | ||||
|  | ||||
|     // TODO: test | ||||
|     public Administrator getAdminByProjectId(long projectId, String mail) { | ||||
|         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to check the admin of the project {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     projectId); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         Project project = this.projectService.getProjectById(projectId); | ||||
|         return project.getProjectAdministrator(); | ||||
|     } | ||||
|  | ||||
|     public Iterable<Appointment> getAppointmentsByProjectId(long projectId, String mail) { | ||||
|         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to check the appointments related to the project {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     projectId); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         logger.info( | ||||
|                 "User {} tried to check the appointments related to the project {}", | ||||
|                 mail, | ||||
|                 projectId); | ||||
|         Iterable<SectionCell> sectionCells = | ||||
|                 this.sectionCellService.getSectionCellsByProject( | ||||
|                         projectService.getProjectById(projectId), | ||||
|                         2L); // sectionId useless in this function ? | ||||
|         List<Appointment> appointments = new ArrayList<Appointment>(); | ||||
|         sectionCells.forEach( | ||||
|                 sectionCell -> { | ||||
|                     appointments.addAll( | ||||
|                             this.sectionCellService.getAppointmentsBySectionCellId( | ||||
|                                     sectionCell.getIdSectionCell())); | ||||
|                 }); | ||||
|         return appointments; | ||||
|     } | ||||
|  | ||||
|     public void getPDFReport(long appointmentId, String mail) | ||||
|             throws DocumentException, URISyntaxException, IOException { | ||||
|         long projectId = | ||||
|                 this.appointmentService | ||||
|                         .getAppointmentById(appointmentId) | ||||
|                         .getAppointmentListSectionCell() | ||||
|                         .getFirst() | ||||
|                         .getProjectSectionCell() | ||||
|                         .getIdProject(); | ||||
|         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to generate the PDF report {} related to the appointment {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     this.appointmentService | ||||
|                             .getAppointmentById(appointmentId) | ||||
|                             .getAppointmentReport() | ||||
|                             .getIdReport(), | ||||
|                     appointmentId); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         logger.info( | ||||
|                 "User {} generated the PDF report related to appointment {}", mail, appointmentId); | ||||
|  | ||||
|         String reportContent = | ||||
|                 this.appointmentService | ||||
|                         .getAppointmentById(appointmentId) | ||||
|                         .getAppointmentReport() | ||||
|                         .getReportContent(); | ||||
|  | ||||
|         // PDF generation | ||||
|         Document document = new Document(); | ||||
|         PdfWriter.getInstance(document, new FileOutputStream("Report" + appointmentId + ".pdf")); | ||||
|         document.open(); | ||||
|  | ||||
|         Paragraph title = | ||||
|                 new Paragraph( | ||||
|                         new Phrase( | ||||
|                                 "Compte Rendu - Réunion du " | ||||
|                                         + this.appointmentService | ||||
|                                                 .getAppointmentById(appointmentId) | ||||
|                                                 .getAppointmentDate() | ||||
|                                                 .toString(), | ||||
|                                 FontFactory.getFont( | ||||
|                                         FontFactory.HELVETICA, | ||||
|                                         20, | ||||
|                                         Font.BOLDITALIC, | ||||
|                                         BaseColor.BLACK))); | ||||
|         title.setAlignment(Element.ALIGN_CENTER); | ||||
|         document.add(title); | ||||
|  | ||||
|         Font subsection = | ||||
|                 FontFactory.getFont(FontFactory.HELVETICA, 14, Font.UNDERLINE, BaseColor.DARK_GRAY); | ||||
|         Font body = FontFactory.getFont(FontFactory.COURIER, 12, BaseColor.BLACK); | ||||
|  | ||||
|         String[] split = reportContent.split(" "); | ||||
|  | ||||
|         String tmp = ""; | ||||
|         int counter = 1; | ||||
|         for (String s : split) { | ||||
|             if (s.equals("//")) { | ||||
|                 Chunk chunk = new Chunk(tmp, body); | ||||
|                 document.add(chunk); | ||||
|                 document.add(new Paragraph("\n")); | ||||
|                 tmp = ""; | ||||
|                 Paragraph paragraph = new Paragraph("Point n°" + counter + " : ", subsection); | ||||
|                 document.add(paragraph); | ||||
|                 document.add(new Paragraph("\n")); | ||||
|                 counter++; | ||||
|             } else { | ||||
|                 tmp = tmp.concat(s + " "); | ||||
|             } | ||||
|         } | ||||
|         Chunk chunk = new Chunk(tmp, body); | ||||
|         document.add(chunk); | ||||
|         document.add(new Paragraph("\n")); | ||||
|  | ||||
|         document.close(); | ||||
|  | ||||
|         // Replace uri with website address | ||||
|         Files.copy( | ||||
|                 new URI( | ||||
|                                 "http://localhost:8080/shared/projects/appointments/report/" | ||||
|                                         + appointmentId) | ||||
|                         .toURL() | ||||
|                         .openStream(), | ||||
|                 Paths.get("Report" + appointmentId + ".pdf"), | ||||
|                 StandardCopyOption.REPLACE_EXISTING); | ||||
|  | ||||
|         // delete file, we don't want to stock all reports on the server | ||||
|         File file = new File("Report" + appointmentId + ".pdf"); | ||||
|         if (!file.delete()) { | ||||
|             logger.warn("Failed to delete report {}", file.getAbsolutePath()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void createAppointmentRequest(Appointment appointment, String mail) { | ||||
|         long projectId = | ||||
|                 appointment | ||||
|                         .getAppointmentListSectionCell() | ||||
|                         .getFirst() | ||||
|                         .getProjectSectionCell() | ||||
|                         .getIdProject(); | ||||
|         if (!utilsService.isAllowedToCheckProject(mail, projectId)) { | ||||
|             logger.warn( | ||||
|                     "User {} tried to create for the project {} but is not allowed to.", | ||||
|                     mail, | ||||
|                     projectId); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.UNAUTHORIZED, "You're not allowed to check this project"); | ||||
|         } | ||||
|         logger.info("User {} tried to create an appointment for project {}", mail, projectId); | ||||
|         Appointment newAppointment = this.appointmentService.addNewAppointment(appointment); | ||||
|         newAppointment | ||||
|                 .getAppointmentListSectionCell() | ||||
|                 .forEach( | ||||
|                         sectionCell -> { | ||||
|                             sectionCell.updateAppointmentSectionCell(newAppointment); | ||||
|                         }); | ||||
|         newAppointment.getAppointmentReport().setAppointmentReport(newAppointment); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,62 @@ | ||||
| package enseirb.myinpulse.service; | ||||
|  | ||||
| import enseirb.myinpulse.model.Administrator; | ||||
| import enseirb.myinpulse.model.Entrepreneur; | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.model.User; | ||||
| import enseirb.myinpulse.service.database.AdministratorService; | ||||
| import enseirb.myinpulse.service.database.EntrepreneurService; | ||||
| import enseirb.myinpulse.service.database.ProjectService; | ||||
| import enseirb.myinpulse.service.database.UserService; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| @Service | ||||
| public class UtilsService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final UserService userService; | ||||
|     private final ProjectService projectService; | ||||
|     private final EntrepreneurService entrepreneurService; | ||||
|     private final AdministratorService administratorService; | ||||
|  | ||||
|     @Autowired | ||||
|     UtilsService( | ||||
|             ProjectService projectService, | ||||
|             UserService userService, | ||||
|             EntrepreneurService entrepreneurService, | ||||
|             AdministratorService administratorService) { | ||||
|         this.userService = userService; | ||||
|         this.projectService = projectService; | ||||
|         this.entrepreneurService = entrepreneurService; | ||||
|         this.administratorService = administratorService; | ||||
|     } | ||||
|  | ||||
|     // TODO: test? | ||||
|     public Boolean isAllowedToCheckProject(String mail, long projectId) { | ||||
|         if (isAnAdmin(mail)) { | ||||
|             return true; | ||||
|         } | ||||
|         User user = this.userService.getUserByEmail(mail); | ||||
|         Entrepreneur entrepreneur = this.entrepreneurService.getEntrepreneurById(user.getIdUser()); | ||||
|         Project project = this.projectService.getProjectById(projectId); | ||||
|         return entrepreneur.getProjectParticipation() == project; | ||||
|     } | ||||
|  | ||||
|     // TODO: test | ||||
|     Boolean isAnAdmin(String mail) { | ||||
|         try { | ||||
|             long userId = this.userService.getUserByEmail(mail).getIdUser(); | ||||
|             Administrator a = this.administratorService.getAdministratorById(userId); | ||||
|             return true; | ||||
|         } catch (ResponseStatusException e) { | ||||
|             logger.info(e); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,60 @@ | ||||
| package enseirb.myinpulse.service.database; | ||||
|  | ||||
| import enseirb.myinpulse.model.Administrator; | ||||
| import enseirb.myinpulse.repository.AdministratorRepository; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @Service | ||||
| public class AdministratorService { | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final AdministratorRepository administratorRepository; | ||||
|  | ||||
|     @Autowired | ||||
|     AdministratorService(AdministratorRepository administratorRepository) { | ||||
|         this.administratorRepository = administratorRepository; | ||||
|     } | ||||
|  | ||||
|     public Iterable<Administrator> allAdministrators() { | ||||
|         return this.administratorRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     public Administrator getAdministratorById(long id) { | ||||
|         Optional<Administrator> administrator = this.administratorRepository.findById(id); | ||||
|         if (administrator.isEmpty()) { | ||||
|             logger.error("No administrator found with id {}", id); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cet administrateur n'existe pas"); | ||||
|         } | ||||
|         return administrator.get(); | ||||
|     } | ||||
|  | ||||
|     public Administrator getAdministratorByPrimaryMain(String primaryMail) { | ||||
|         Optional<Administrator> administrator = | ||||
|                 this.administratorRepository.findByPrimaryMail(primaryMail); | ||||
|         if (administrator.isEmpty()) { | ||||
|             logger.error("No administrator found with the mail {}", primaryMail); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cet administrateur n'existe pas"); | ||||
|         } | ||||
|         return administrator.get(); | ||||
|     } | ||||
|  | ||||
|     public Administrator addAdministrator(Administrator administrator) { | ||||
|         return this.administratorRepository.save(administrator); | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|     public Administrator getAdministratorByProject(Project project) { | ||||
|         r | ||||
|     } | ||||
|      */ | ||||
| } | ||||
| @@ -0,0 +1,61 @@ | ||||
| package enseirb.myinpulse.service.database; | ||||
|  | ||||
| import enseirb.myinpulse.model.Annotation; | ||||
| import enseirb.myinpulse.repository.AnnotationRepository; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @Service | ||||
| public class AnnotationService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final AnnotationRepository annotationRepository; | ||||
|  | ||||
|     @Autowired | ||||
|     AnnotationService(AnnotationRepository annotationRepository) { | ||||
|         this.annotationRepository = annotationRepository; | ||||
|     } | ||||
|  | ||||
|     public Iterable<Annotation> getAllAnnotations() { | ||||
|         return annotationRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     public Annotation getAnnotationById(Long id) { | ||||
|         Optional<Annotation> annotation = annotationRepository.findById(id); | ||||
|         if (annotation.isEmpty()) { | ||||
|             logger.error("getAnnotationById : No annotation found with id {}", id); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cette annotation n'existe pas"); | ||||
|         } | ||||
|         return annotation.get(); | ||||
|     } | ||||
|  | ||||
|     public Annotation addNewAnnotation(Annotation annotation) { | ||||
|         return this.annotationRepository.save(annotation); | ||||
|     } | ||||
|  | ||||
|     public void deleteAnnotationById(Long id) { | ||||
|         this.annotationRepository.deleteById(id); | ||||
|     } | ||||
|  | ||||
|     public Annotation updateAnnotation(Long id, String comment) { | ||||
|         Optional<Annotation> annotation = annotationRepository.findById(id); | ||||
|         if (annotation.isEmpty()) { | ||||
|             logger.error("updateAnnotation : No annotation found with id {}", id); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cette annotation n'existe pas"); | ||||
|         } | ||||
|         if (comment != null) { | ||||
|             annotation.get().setComment(comment); | ||||
|         } | ||||
|         return this.annotationRepository.save(annotation.get()); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,79 @@ | ||||
| package enseirb.myinpulse.service.database; | ||||
|  | ||||
| import enseirb.myinpulse.model.Appointment; | ||||
| import enseirb.myinpulse.repository.AppointmentRepository; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalTime; | ||||
| import java.util.Optional; | ||||
|  | ||||
| @Service | ||||
| public class AppointmentService { | ||||
|  | ||||
|     private static final Logger logger = LogManager.getLogger(AppointmentService.class); | ||||
|  | ||||
|     private AppointmentRepository appointmentRepository; | ||||
|  | ||||
|     @Autowired | ||||
|     AppointmentService(AppointmentRepository appointmentRepository) { | ||||
|         this.appointmentRepository = appointmentRepository; | ||||
|     } | ||||
|  | ||||
|     public Iterable<Appointment> getallAppointments() { | ||||
|         return this.appointmentRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     public Appointment getAppointmentById(Long id) { | ||||
|         Optional<Appointment> appointment = this.appointmentRepository.findById(id); | ||||
|         if (appointment.isEmpty()) { | ||||
|             logger.error("getAppointmentById : No appointment found with id {}", id); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce rendez vous n'existe pas"); | ||||
|         } | ||||
|         return appointment.get(); | ||||
|     } | ||||
|  | ||||
|     public Appointment addNewAppointment(Appointment appointment) { | ||||
|         return this.appointmentRepository.save(appointment); | ||||
|     } | ||||
|  | ||||
|     public void deleteAppointmentById(Long id) { | ||||
|         this.appointmentRepository.deleteById(id); | ||||
|     } | ||||
|  | ||||
|     public Appointment updateAppointment( | ||||
|             Long id, | ||||
|             LocalDate appointmentDate, | ||||
|             LocalTime appointmentTime, | ||||
|             LocalTime appointmentDuration, | ||||
|             String appointmentPlace, | ||||
|             String appointmentSubject) { | ||||
|         Optional<Appointment> appointment = this.appointmentRepository.findById(id); | ||||
|         if (appointment.isEmpty()) { | ||||
|             logger.error("updateAppointment : No appointment found with id {}", id); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce rendez vous n'existe pas"); | ||||
|         } | ||||
|         if (appointmentDate != null) { | ||||
|             appointment.get().setAppointmentDate(appointmentDate); | ||||
|         } | ||||
|         if (appointmentTime != null) { | ||||
|             appointment.get().setAppointmentTime(appointmentTime); | ||||
|         } | ||||
|         if (appointmentDuration != null) { | ||||
|             appointment.get().setAppointmentDuration(appointmentDuration); | ||||
|         } | ||||
|         if (appointmentPlace != null) { | ||||
|             appointment.get().setAppointmentPlace(appointmentPlace); | ||||
|         } | ||||
|         if (appointmentSubject != null) { | ||||
|             appointment.get().setAppointmentSubject(appointmentSubject); | ||||
|         } | ||||
|         return this.appointmentRepository.save(appointment.get()); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,67 @@ | ||||
| package enseirb.myinpulse.service.database; | ||||
|  | ||||
| import enseirb.myinpulse.model.Entrepreneur; | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.repository.EntrepreneurRepository; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @Service | ||||
| public class EntrepreneurService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final EntrepreneurRepository entrepreneurRepository; | ||||
|  | ||||
|     EntrepreneurService(EntrepreneurRepository entrepreneurRepository) { | ||||
|         this.entrepreneurRepository = entrepreneurRepository; | ||||
|     } | ||||
|  | ||||
|     public Iterable<Entrepreneur> getAllEntrepreneurs() { | ||||
|         return this.entrepreneurRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     public Entrepreneur getEntrepreneurById(Long id) { | ||||
|         Optional<Entrepreneur> entrepreneur = entrepreneurRepository.findById(id); | ||||
|         if (entrepreneur.isEmpty()) { | ||||
|             logger.error("getEntrepreneurById : No entrepreneur found with id {}", id); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cet entrepreneur n'existe pas"); | ||||
|         } | ||||
|         return entrepreneur.get(); | ||||
|     } | ||||
|  | ||||
|     public Entrepreneur addEntrepreneur(Entrepreneur entrepreneur) { | ||||
|         return this.entrepreneurRepository.save(entrepreneur); | ||||
|     } | ||||
|  | ||||
|     public Entrepreneur updateEntrepreneur( | ||||
|             Long id, String school, String course, Boolean sneeStatus) { | ||||
|         Optional<Entrepreneur> entrepreneur = entrepreneurRepository.findById(id); | ||||
|         if (entrepreneur.isEmpty()) { | ||||
|             logger.error("updateEntrepreneur : No entrepreneur found with id {}", id); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cet entrepreneur n'existe pas"); | ||||
|         } | ||||
|         if (school != null) { | ||||
|             entrepreneur.get().setSchool(school); | ||||
|         } | ||||
|         if (course != null) { | ||||
|             entrepreneur.get().setCourse(course); | ||||
|         } | ||||
|         if (sneeStatus != null) { | ||||
|             entrepreneur.get().setSneeStatus(sneeStatus); | ||||
|         } | ||||
|         return this.entrepreneurRepository.save(entrepreneur.get()); | ||||
|     } | ||||
|  | ||||
|     public Iterable<Entrepreneur> GetEntrepreneurByProject(Project project) { | ||||
|         return this.entrepreneurRepository.getEntrepreneurByProjectParticipation(project); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,124 @@ | ||||
| package enseirb.myinpulse.service.database; | ||||
|  | ||||
| import static enseirb.myinpulse.model.ProjectDecisionValue.PENDING; | ||||
|  | ||||
| import enseirb.myinpulse.model.Administrator; | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.model.ProjectDecisionValue; | ||||
| import enseirb.myinpulse.repository.ProjectRepository; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
|  | ||||
| @Service | ||||
| public class ProjectService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final ProjectRepository projectRepository; | ||||
|  | ||||
|     @Autowired | ||||
|     ProjectService(ProjectRepository projectRepository) { | ||||
|         this.projectRepository = projectRepository; | ||||
|     } | ||||
|  | ||||
|     public Iterable<Project> getAllProjects() { | ||||
|         return this.projectRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     public Project getProjectById(Long id) { | ||||
|         Optional<Project> project = this.projectRepository.findById(id); | ||||
|         if (project.isEmpty()) { | ||||
|             logger.error("No project found with id {}", id); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); | ||||
|         } | ||||
|         return project.get(); | ||||
|     } | ||||
|  | ||||
|     public Iterable<Project> getProjectsByAdminId(Administrator administrator) { | ||||
|         return this.projectRepository.findByProjectAdministrator(administrator); | ||||
|     } | ||||
|  | ||||
|     // TODO: validation | ||||
|     public Project addNewProject(Project project) { | ||||
|         return this.projectRepository.save(project); | ||||
|     } | ||||
|  | ||||
|     public Project updateProject( | ||||
|             Long id, | ||||
|             String projectName, | ||||
|             byte[] logo, | ||||
|             LocalDate creationDate, | ||||
|             ProjectDecisionValue projectStatus, | ||||
|             Administrator administrator) { | ||||
|         Optional<Project> project = this.projectRepository.findById(id); | ||||
|  | ||||
|         if (project.isEmpty()) { | ||||
|             logger.error("Project with id {} not found.", id); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); | ||||
|         } | ||||
|  | ||||
|         if (projectName != null) { | ||||
|             project.get().setProjectName(projectName); | ||||
|         } | ||||
|  | ||||
|         if (logo != null) { | ||||
|             project.get().setLogo(logo); | ||||
|         } | ||||
|  | ||||
|         if (creationDate != null) { | ||||
|             project.get().setCreationDate(creationDate); | ||||
|         } | ||||
|  | ||||
|         if (projectStatus != null) { | ||||
|             // TODO: check if this is really useful | ||||
|             /* | ||||
|             if (!validateStatus(projectStatus)) { | ||||
|                 logger.error("updateProjectStatus: Invalid status {}", projectStatus); | ||||
|                 throw new ResponseStatusException( | ||||
|                         HttpStatus.NOT_ACCEPTABLE, "Ce status n'est pas accepté"); | ||||
|             } | ||||
|             */ | ||||
|             project.get().setProjectStatus(projectStatus); | ||||
|         } | ||||
|  | ||||
|         if (administrator != null) { | ||||
|             project.get().setProjectAdministrator(administrator); | ||||
|         } | ||||
|  | ||||
|         return this.projectRepository.save(project.get()); | ||||
|     } | ||||
|  | ||||
|     public Boolean validateStatus(String status) { | ||||
|         return List.of("PENDING", "ACTIVE", "ENDED").contains(status); | ||||
|     } | ||||
|  | ||||
|     public Iterable<Project> getPendingProjects() { | ||||
|         return this.projectRepository.findByProjectStatus(PENDING); | ||||
|     } | ||||
|  | ||||
|     public void deleteProjectById(Long id) { | ||||
|         this.projectRepository.deleteById(id); | ||||
|     } | ||||
|  | ||||
|     public Project getProjectByName(String name, boolean noerror) { | ||||
|         Optional<Project> project = this.projectRepository.findByProjectName(name); | ||||
|         if (project.isEmpty()) { | ||||
|             if (noerror) logger.error("No project found with name {}", name); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce projet n'existe pas"); | ||||
|         } | ||||
|         return project.get(); | ||||
|     } | ||||
|  | ||||
|     public Project getProjectByName(String name) { | ||||
|         return getProjectByName(name, false); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,60 @@ | ||||
| package enseirb.myinpulse.service.database; | ||||
|  | ||||
| import enseirb.myinpulse.model.Report; | ||||
| import enseirb.myinpulse.repository.ReportRepository; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @Service | ||||
| public class ReportService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final ReportRepository reportRepository; | ||||
|  | ||||
|     @Autowired | ||||
|     ReportService(ReportRepository reportRepository) { | ||||
|         this.reportRepository = reportRepository; | ||||
|     } | ||||
|  | ||||
|     public Iterable<Report> getAllReports() { | ||||
|         return this.reportRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     public Report getReportById(Long id) { | ||||
|         Optional<Report> report = this.reportRepository.findById(id); | ||||
|         if (report.isEmpty()) { | ||||
|             logger.error("getReportById : No report found with id {}", id); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce compte rendu n'existe pas"); | ||||
|         } | ||||
|         return report.get(); | ||||
|     } | ||||
|  | ||||
|     // TODO: do some validation | ||||
|     public Report addNewReport(Report report) { | ||||
|         return this.reportRepository.save(report); | ||||
|     } | ||||
|  | ||||
|     public void deleteReportById(Long id) { | ||||
|         this.reportRepository.deleteById(id); | ||||
|     } | ||||
|  | ||||
|     public Report updateReport(Long id, String reportContent) { | ||||
|         Optional<Report> report = this.reportRepository.findById(id); | ||||
|         if (report.isEmpty()) { | ||||
|             logger.error("updateReport : No report found with id {}", id); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Ce compte rendu n'existe pas"); | ||||
|         } | ||||
|         if (reportContent != null) { | ||||
|             report.get().setReportContent(reportContent); | ||||
|         } | ||||
|         return this.reportRepository.save(report.get()); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,93 @@ | ||||
| package enseirb.myinpulse.service.database; | ||||
|  | ||||
| import enseirb.myinpulse.model.Appointment; | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.model.SectionCell; | ||||
| import enseirb.myinpulse.repository.SectionCellRepository; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
|  | ||||
| @Service | ||||
| public class SectionCellService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final SectionCellRepository sectionCellRepository; | ||||
|  | ||||
|     @Autowired | ||||
|     SectionCellService(SectionCellRepository sectionCellRepository) { | ||||
|         this.sectionCellRepository = sectionCellRepository; | ||||
|     } | ||||
|  | ||||
|     public Iterable<SectionCell> getAllSectionCells() { | ||||
|         return this.sectionCellRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     public SectionCell getSectionCellById(Long id) { | ||||
|         Optional<SectionCell> sectionCell = this.sectionCellRepository.findById(id); | ||||
|         if (sectionCell.isEmpty()) { | ||||
|             logger.error("getSectionCellById : No sectionCell found with id {}", id); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cette cellule de section n'existe pas"); | ||||
|         } | ||||
|         return sectionCell.get(); | ||||
|     } | ||||
|  | ||||
|     public SectionCell addNewSectionCell(SectionCell sectionCell) { | ||||
|         return this.sectionCellRepository.save(sectionCell); | ||||
|     } | ||||
|  | ||||
|     public void removeSectionCellById(Long id) { | ||||
|         this.sectionCellRepository.deleteById(id); | ||||
|     } | ||||
|  | ||||
|     public SectionCell updateSectionCell( | ||||
|             Long id, Long sectionId, String contentSectionCell, LocalDateTime modificationDate) { | ||||
|         Optional<SectionCell> sectionCell = this.sectionCellRepository.findById(id); | ||||
|         if (sectionCell.isEmpty()) { | ||||
|             logger.error("updateSectionCell : No sectionCell found with id {}", id); | ||||
|             throw new ResponseStatusException( | ||||
|                     HttpStatus.NOT_FOUND, "Cette cellule de section n'existe pas"); | ||||
|         } | ||||
|         if (sectionId != null) { | ||||
|             sectionCell.get().setSectionId(sectionId); | ||||
|         } | ||||
|         if (contentSectionCell != null) { | ||||
|             sectionCell.get().setContentSectionCell(contentSectionCell); | ||||
|         } | ||||
|         if (modificationDate != null) { | ||||
|             sectionCell.get().setModificationDate(modificationDate); | ||||
|         } | ||||
|         return this.sectionCellRepository.save(sectionCell.get()); | ||||
|     } | ||||
|  | ||||
|     public Iterable<SectionCell> getSectionCellsByProject(Project project, Long sectionId) { | ||||
|         return this.sectionCellRepository.findByProjectSectionCellAndSectionId(project, sectionId); | ||||
|     } | ||||
|  | ||||
|     public Long getProjectId(Long sectionCellId) { | ||||
|         SectionCell sectionCell = getSectionCellById(sectionCellId); | ||||
|         Project sectionProject = sectionCell.getProjectSectionCell(); | ||||
|         return sectionProject.getIdProject(); | ||||
|     } | ||||
|  | ||||
|     public List<Appointment> getAppointmentsBySectionCellId(Long sectionCellId) { | ||||
|         SectionCell sectionCell = getSectionCellById(sectionCellId); | ||||
|         return sectionCell.getAppointmentSectionCell(); | ||||
|     } | ||||
|  | ||||
|     public Iterable<SectionCell> getSectionCellsByProjectAndSectionIdBeforeDate( | ||||
|             Project project, long sectionId, LocalDateTime date) { | ||||
|         return sectionCellRepository.findByProjectSectionCellAndSectionIdAndModificationDateBefore( | ||||
|                 project, sectionId, date); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,81 @@ | ||||
| package enseirb.myinpulse.service.database; | ||||
|  | ||||
| import enseirb.myinpulse.model.User; | ||||
| import enseirb.myinpulse.repository.UserRepository; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.web.bind.annotation.PathVariable; | ||||
| import org.springframework.web.bind.annotation.RequestBody; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.util.Optional; | ||||
|  | ||||
| @Service | ||||
| public class UserService { | ||||
|  | ||||
|     protected static final Logger logger = LogManager.getLogger(); | ||||
|  | ||||
|     private final UserRepository userRepository; | ||||
|  | ||||
|     @Autowired | ||||
|     UserService(UserRepository userRepository) { | ||||
|         this.userRepository = userRepository; | ||||
|     } | ||||
|  | ||||
|     public Iterable<User> getAllUsers() { | ||||
|         return this.userRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     // TODO | ||||
|     public User getUserByEmail(String email) { | ||||
|         Optional<User> opt_user = this.userRepository.findByPrimaryMail(email); | ||||
|  | ||||
|         if (opt_user.isEmpty()) { | ||||
|             logger.error("getUserByEmail : No user found with email {}", email); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); | ||||
|         } | ||||
|         return opt_user.get(); | ||||
|     } | ||||
|  | ||||
|     public Iterable<User> allUsers() { | ||||
|         return this.userRepository.findAll(); | ||||
|     } | ||||
|  | ||||
|     public User addUser(@RequestBody User user) { | ||||
|         return this.userRepository.save(user); | ||||
|     } | ||||
|  | ||||
|     public User updateUser( | ||||
|             @PathVariable Long id, | ||||
|             String userSurname, | ||||
|             String userName, | ||||
|             String primaryMail, | ||||
|             String secondaryMail, | ||||
|             String phoneNumber) { | ||||
|         Optional<User> user = userRepository.findById(id); | ||||
|         if (user.isEmpty()) { | ||||
|             logger.error("updateUser : No user found with id {}", id); | ||||
|             throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Cet utilisateur n'existe pas"); | ||||
|         } | ||||
|         if (userName != null) { | ||||
|             user.get().setUserName(userName); | ||||
|         } | ||||
|         if (userSurname != null) { | ||||
|             user.get().setUserSurname(userSurname); | ||||
|         } | ||||
|         if (primaryMail != null) { | ||||
|             user.get().setPrimaryMail(primaryMail); | ||||
|         } | ||||
|         if (secondaryMail != null) { | ||||
|             user.get().setSecondaryMail(secondaryMail); | ||||
|         } | ||||
|         if (phoneNumber != null) { | ||||
|             user.get().setPhoneNumber(phoneNumber); | ||||
|         } | ||||
|         return this.userRepository.save(user.get()); | ||||
|     } | ||||
| } | ||||
| @@ -1,8 +1,8 @@ | ||||
| spring.application.name=myinpulse | ||||
| spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:7080/realms/test/protocol/openid-connect/certs | ||||
| spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:7080/realms/test | ||||
| logging.level.org.springframework.security=DEBUG | ||||
| spring.datasource.url=jdbc:postgresql://${DATABASE_URL}/${BACKEND_DB} | ||||
| spring.datasource.username=${BACKEND_USER} | ||||
| spring.datasource.password=${BACKEND_PASSWORD} | ||||
| spring.jpa.hibernate.ddl-auto=update | ||||
| logging.pattern.console=%d{yyyy-MMM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n | ||||
| @@ -1,57 +1,88 @@ | ||||
| TRUNCATE projets, utilisateurs, entrepreneurs, sections, rendez_vous, comptes_rendus CASCADE; | ||||
| TRUNCATE project, user_inpulse, entrepreneur, administrator, section_cell, appointment, report, annotation CASCADE; | ||||
|  | ||||
| INSERT INTO projets (nom_projet, logo, date_creation, status_projet) | ||||
| SELECT setval('annotation_id_annotation_seq', 1, false); | ||||
| SELECT setval('appointment_id_appointment_seq', 1, false); | ||||
| SELECT setval('make_appointment_id_make_appointment_seq', 1, false); | ||||
| SELECT setval('project_id_project_seq', 1, false); | ||||
| SELECT setval('report_id_report_seq', 1, false); | ||||
| SELECT setval('section_cell_id_section_cell_seq', 1, false); | ||||
| SELECT setval('user_inpulse_id_user_seq', 1, false); | ||||
|  | ||||
| INSERT INTO user_inpulse (user_surname, user_name, primary_mail, secondary_mail, phone_number) | ||||
| VALUES ('Dupont', 'Dupond', 'super@mail.fr', 'super2@mail.fr', '06 45 72 45 98'), | ||||
|        ('Martin', 'Matin', 'genial@mail.fr', 'genial2@mail.fr', '06 52 14 58 73'), | ||||
|        ('Charvet', 'Lautre', 'mieux@tmail.fr', 'mieux2@tmail.fr', '07 49 82 16 35'), | ||||
|        ('Leguez', 'Theo', 'bof@mesmails.fr', 'bof2@mesmails.fr', '+33 6 78 14 25 29'), | ||||
|        ('Kia', 'Bi', 'special@mail.fr', 'special2@mail.fr', '07 65 31 38 95'), | ||||
|        ('Ducaillou', 'Pierre', 'maildefou@xyz.fr', 'maildefou2@xyz.fr', '06 54 78 12 62'), | ||||
|        ('Janine', 'Dave', 'janine@labri.fr', 'janine2@labri.fr', '06 87 12 45 95'); | ||||
|  | ||||
| INSERT INTO administrator (id_administrator) | ||||
| VALUES (7); | ||||
|  | ||||
| INSERT INTO project (project_name, logo, creation_date, project_status, id_administrator) | ||||
| VALUES ('Eau du robinet', decode('013d7d16d7ad4fefb61bd95b765c8ceb', 'hex'), TO_DATE('01-OCT-2023', 'DD-MON-YYYY'), | ||||
|         'En cours'), | ||||
|        ('Air oxygéné', decode('150647a0984e8f228cd14b54', 'hex'), TO_DATE('04-APR-2024', 'DD-MON-YYYY'), 'En cours'), | ||||
|         'En cours', 7), | ||||
|        ('Air oxygéné', decode('150647a0984e8f228cd14b54', 'hex'), TO_DATE('04-APR-2024', 'DD-MON-YYYY'), 'En cours', 7), | ||||
|        ('Débat concours', decode('022024abd5486e245c145dda65116f', 'hex'), TO_DATE('22-NOV-2023', 'DD-MON-YYYY'), | ||||
|         'Suspendu'), | ||||
|         'Suspendu', 7), | ||||
|        ('HDeirbMI', decode('ab548d6c1d595a2975e6476f544d14c55a', 'hex'), TO_DATE('07-DEC-2024', 'DD-MON-YYYY'), | ||||
|         'Lancement'); | ||||
|  | ||||
| INSERT INTO utilisateurs (nom_utilisateur, prenom_utilisateur, mail_principal, mail_secondaire, numero_telephone) VALUES | ||||
| ('Dupont', 'Dupond', 'super@mail.fr', 'super2@mail.fr', '06 45 72 45 98'), | ||||
| ('Martin', 'Matin', 'genial@mail.fr', 'genial2@mail.fr', '06 52 14 58 73'), | ||||
| ('Charvet', 'Lautre', 'mieux@tmail.fr', 'mieux2@tmail.fr', '07 49 82 16 35'), | ||||
| ('Leguez', 'Theo', 'bof@mesmails.fr', 'bof2@mesmails.fr', '+33 6 78 14 25 29'), | ||||
| ('Kia', 'Bi', 'special@mail.fr', 'special2@mail.fr', '07 65 31 38 95'), | ||||
| ('Ducaillou', 'Pierre', 'maildefou@xyz.fr', 'maildefou2@xyz.fr', '06 54 78 12 62'); | ||||
|         'Lancement', 7); | ||||
|  | ||||
|  | ||||
| INSERT INTO entrepreneurs (ecole, filiere, status_snee, id_entrepreneur) VALUES | ||||
| ('ENSEIRB-MATMECA', 'INFO', TRUE, 1), | ||||
| ('ENSC', 'Cognitique', TRUE, 2), | ||||
| ('ENSEIRB-MATMECA', 'MATMECA', FALSE, 3), | ||||
| ('SupOptique', 'Classique', TRUE, 4), | ||||
| ('ENSEGID', 'Géoscience', FALSE, 5), | ||||
| ('ENSMAC', 'Matériaux composites - Mécanique', FALSE, 6); | ||||
| INSERT INTO entrepreneur (school, course, snee_status, id_entrepreneur, id_project_participation, id_project_proposed) | ||||
| VALUES ('ENSEIRB-MATMECA', 'INFO', TRUE, 1, 4, 4), | ||||
|        ('ENSC', 'Cognitique', TRUE, 2, 2, null), | ||||
|        ('ENSEIRB-MATMECA', 'MATMECA', FALSE, 3, 3, 3), | ||||
|        ('SupOptique', 'Classique', TRUE, 4, 1, 1), | ||||
|        ('ENSEGID', 'Géoscience', FALSE, 5, 1, null), | ||||
|        ('ENSMAC', 'Matériaux composites - Mécanique', FALSE, 6, 2, 2); | ||||
|  | ||||
| INSERT INTO sections (titre, contenu_section, date_modification) VALUES | ||||
| ('Problème', 'les problèmes...', TO_TIMESTAMP('15-JAN-2025 09:30:20', 'DD-MON-YYYY, HH24:MI:SS')), | ||||
| ('Segment de client', 'Le segment AB passant le client n°8 est de longueur 32mm. | ||||
|     Le segment BC a quant à lui un longueur de 28mm. Quelle la longueur du segment AC ?', TO_TIMESTAMP('12-OCT-2022 17:47:38', 'DD-MON-YYYY, HH24:MI:SS')), | ||||
| ('Proposition de valeur unique', '''Son prix est de 2594€'' ''Ah oui c''est unique en effet', TO_TIMESTAMP('25-MAY-2024 11:12:04', 'DD-MON-YYYY, HH24:MI:SS')), | ||||
| ('Solution', 'Un problème ? Une solution', TO_TIMESTAMP('08-FEB-2024 10:17:53', 'DD-MON-YYYY, HH24:MI:SS')), | ||||
| ('Canaux', 'Ici nous avons la Seine, là-bas le Rhin, oh et plus loin le canal de Suez', TO_TIMESTAMP('19-JUL-2023 19:22:45', 'DD-MON-YYYY, HH24:MI:SS')), | ||||
| ('Sources de revenus', 'Y''en n''a pas on est pas payé. Enfin y''a du café quoi', TO_TIMESTAMP('12-JAN-2025 11:40:26', 'DD-MON-YYYY, HH24:MI:SS')), | ||||
| ('Structure des coûts', '''Ah oui là ça va faire au moins 1000€ par mois'', Eirbware', TO_TIMESTAMP('06-FEB-2025 13:04:06', 'DD-MON-YYYY, HH24:MI:SS')), | ||||
| ('Indicateurs clés', 'On apprend les clés comme des badges, ça se fait', TO_TIMESTAMP('05-FEB-2025 12:42:38', 'DD-MON-YYYY, HH24:MI:SS')), | ||||
| ('Avantages concurrentiel', 'On est meilleur', TO_TIMESTAMP('23-APR-2024 16:24:02', 'DD-MON-YYYY, HH24:MI:SS')); | ||||
|  | ||||
| INSERT INTO rendez_vous (date_rdv, heure_rdv, duree_rdv, lieu_rdv, sujet_rdv) VALUES | ||||
| (TO_DATE('24-DEC-2023', 'DD-MON-YYYY'), '00:00:00', '00:37:53', 'À la maison', 'Ouvrir les cadeaux'), | ||||
| (TO_DATE('15-AUG-2024', 'DD-MON-YYYY'), '22:35:00', '00:12:36', 'Sur les quais ou dans un champ probablement', 'BOUM BOUM les feux d''artifices (on fête quoi déjà ?)'), | ||||
| (TO_DATE('28-FEB-2023', 'DD-MON-YYYY'), '14:20:00', '00:20:00', 'Salle TD 15', 'Ah mince c''est pas une année bissextile !'), | ||||
| (TO_DATE('23-JAN-2024', 'DD-MON-YYYY'), '12:56:27', '11:03:33', 'Là où le vent nous porte', 'Journée la plus importante de l''année'), | ||||
| (TO_DATE('25-AUG-2025', 'DD-MON-YYYY'), '00:09:00', '01:00:00', 'Euh c''est par où l''amphi 56 ?', 'Rentrée scolaire (il fait trop froid c''est quoi ça on est en août)'); | ||||
| INSERT INTO section_cell (title, content_section_cell, modification_date, id_project) | ||||
| VALUES ('Problème', 'les problèmes...', TO_TIMESTAMP('15-JAN-2025 09:30:20', 'DD-MON-YYYY, HH24:MI:SS'), 2), | ||||
|        ('Segment de client', 'Le segment AB passant le client n°8 est de longueur 32mm. | ||||
|     Le segment BC a quant à lui un longueur de 28mm. Quelle la longueur du segment AC ?', | ||||
|         TO_TIMESTAMP('12-OCT-2022 17:47:38', 'DD-MON-YYYY, HH24:MI:SS'), 3), | ||||
|        ('Proposition de valeur unique', '''Son prix est de 2594€'' ''Ah oui c''est unique en effet', | ||||
|         TO_TIMESTAMP('25-MAY-2024 11:12:04', 'DD-MON-YYYY, HH24:MI:SS'), 2), | ||||
|        ('Solution', 'Un problème ? Une solution', TO_TIMESTAMP('08-FEB-2024 10:17:53', 'DD-MON-YYYY, HH24:MI:SS'), 1), | ||||
|        ('Canaux', 'Ici nous avons la Seine, là-bas le Rhin, oh et plus loin le canal de Suez', | ||||
|         TO_TIMESTAMP('19-JUL-2023 19:22:45', 'DD-MON-YYYY, HH24:MI:SS'), 4), | ||||
|        ('Sources de revenus', 'Y''en n''a pas on est pas payé. Enfin y''a du café quoi', | ||||
|         TO_TIMESTAMP('12-JAN-2025 11:40:26', 'DD-MON-YYYY, HH24:MI:SS'), 1), | ||||
|        ('Structure des coûts', '''Ah oui là ça va faire au moins 1000€ par mois'', Eirbware', | ||||
|         TO_TIMESTAMP('06-FEB-2025 13:04:06', 'DD-MON-YYYY, HH24:MI:SS'), 3), | ||||
|        ('Indicateurs clés', 'On apprend les clés comme des badges, ça se fait', | ||||
|         TO_TIMESTAMP('05-FEB-2025 12:42:38', 'DD-MON-YYYY, HH24:MI:SS'), 4), | ||||
|        ('Avantages concurrentiel', 'On est meilleur', TO_TIMESTAMP('23-APR-2024 16:24:02', 'DD-MON-YYYY, HH24:MI:SS'), | ||||
|         2); | ||||
|  | ||||
| INSERT INTO comptes_rendus (contenu_compte_rendu) VALUES | ||||
| ('Ah oui ça c''est super, ah ouais j''aime bien, bien vu de penser à ça'), | ||||
| ('Bonne réunion'), | ||||
| ('Ouais, j''ai rien compris mais niquel on fait comme vous avez dit'), | ||||
| ('Non non ça va pas du tout ce que tu me proposes, faut tout refaire'), | ||||
| ('Réponse de la DSI : non'), | ||||
| ('Trop dommage qu''Apple ait sorti leur logiciel avant nous, on avait la même idée et tout on aurait tellement pu leur faire de la concurrence'); | ||||
| INSERT INTO appointment (appointment_date, appointment_time, appointment_duration, appointment_place, | ||||
|                          appointment_subject) | ||||
| VALUES (TO_DATE('24-DEC-2023', 'DD-MON-YYYY'), '00:00:00', '00:37:53', 'À la maison', 'Ouvrir les cadeaux'), | ||||
|        (TO_DATE('15-AUG-2024', 'DD-MON-YYYY'), '22:35:00', '00:12:36', 'Sur les quais ou dans un champ probablement', | ||||
|         'BOUM BOUM les feux d''artifices (on fête quoi déjà ?)'), | ||||
|        (TO_DATE('28-FEB-2023', 'DD-MON-YYYY'), '14:20:00', '00:20:00', 'Salle TD 15', | ||||
|         'Ah mince c''est pas une année bissextile !'), | ||||
|        (TO_DATE('23-JAN-2024', 'DD-MON-YYYY'), '12:56:27', '11:03:33', 'Là où le vent nous porte', | ||||
|         'Journée la plus importante de l''année'), | ||||
|        (TO_DATE('25-AUG-2025', 'DD-MON-YYYY'), '00:09:00', '01:00:00', 'Euh c''est par où l''amphi 56 ?', | ||||
|         'Rentrée scolaire (il fait trop froid c''est quoi ça on est en août)'); | ||||
|  | ||||
| INSERT INTO report (report_content, id_appointment) | ||||
| VALUES ('Ah oui ça c''est super, ah ouais j''aime bien, bien vu de penser à ça', 1), | ||||
|        ('Bonne réunion', 3), | ||||
|        ('Ouais, j''ai rien compris mais niquel on fait comme vous avez dit', 3), | ||||
|        ('Non non ça va pas du tout ce que tu me proposes, faut tout refaire', 4), | ||||
|        ('Réponse de la DSI : non', 2), | ||||
|        ('Trop dommage qu''Apple ait sorti leur logiciel avant nous, on avait la même idée et tout on aurait tellement pu leur faire de la concurrence', | ||||
|         5); | ||||
|  | ||||
| INSERT INTO annotation (comment, id_administrator, id_section_cell) | ||||
| VALUES ('faut changer ça hein', 7, 5), | ||||
|        ('??? sérieusement, vous pensez que c''est une bonne idée ?', 7, 7), | ||||
|        ('ok donc ça c''est votre business plan, bah glhf la team', 7, 2); | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1 +1,2 @@ | ||||
| DROP TABLE IF EXISTS administrateurs, projets, utilisateurs, entrepreneurs, sections, rendez_vous, comptes_rendus, concerner CASCADE; | ||||
| DROP TABLE IF EXISTS administrateurs, projets, utilisateurs, entrepreneurs, sections, rendez_vous, comptes_rendus, concerner CASCADE; | ||||
| DROP TABLE IF EXISTS administrator, project, user_inpulse, entrepreneur, section_cell, appointment, make_appointment, report, annotation, concern CASCADE; | ||||
| @@ -1,134 +0,0 @@ | ||||
| DROP TABLE IF EXISTS projets CASCADE; | ||||
| DROP TABLE IF EXISTS utilisateurs CASCADE; | ||||
| DROP TABLE IF EXISTS entrepreneurs CASCADE; | ||||
| DROP TABLE IF EXISTS administrateurs CASCADE; | ||||
| DROP TABLE IF EXISTS sections CASCADE; | ||||
| DROP TABLE IF EXISTS rendez_vous CASCADE; | ||||
| DROP TABLE IF EXISTS comptes_rendus CASCADE; | ||||
| DROP TABLE IF EXISTS concerner CASCADE; | ||||
| DROP TABLE IF EXISTS formes CASCADE; | ||||
|  | ||||
| CREATE TABLE projets | ||||
| ( | ||||
|     id_projet     SERIAL NOT NULL, | ||||
|     nom_projet    VARCHAR(255), | ||||
|     logo          BYTEA, | ||||
|     date_creation DATE, | ||||
|     status_projet VARCHAR(255), | ||||
|     CONSTRAINT pk_projet PRIMARY KEY (id_projet) | ||||
| ); | ||||
|  | ||||
| CREATE TABLE utilisateurs | ||||
| ( | ||||
| id_utilisateur      SERIAL    NOT NULL, | ||||
| nom_utilisateur     VARCHAR(255)      , | ||||
| prenom_utilisateur  VARCHAR(255)      , | ||||
| mail_principal      VARCHAR(255)      , | ||||
| mail_secondaire     VARCHAR(255)      , | ||||
| numero_telephone    VARCHAR(20)       , | ||||
| CONSTRAINT pk_utilisateur PRIMARY KEY (id_utilisateur) ); | ||||
|  | ||||
| CREATE TABLE entrepreneurs | ||||
| ( | ||||
|     id_entrepreneur SERIAL REFERENCES utilisateurs (id_utilisateur), | ||||
|     ecole           VARCHAR(255), | ||||
|     filiere         VARCHAR(255), | ||||
|     status_snee     BOOLEAN, | ||||
|     CONSTRAINT pk_entrepreneur PRIMARY KEY (id_entrepreneur) | ||||
| ); | ||||
|  | ||||
| CREATE TABLE administrateurs | ||||
| ( | ||||
|     id_administrateur SERIAL REFERENCES utilisateurs (id_utilisateur), | ||||
|     CONSTRAINT pk_administrateur PRIMARY KEY (id_administrateur) | ||||
| ); | ||||
|  | ||||
| CREATE TABLE sections | ||||
| ( | ||||
|     id_section        SERIAL NOT NULL, | ||||
|     titre             VARCHAR(255), | ||||
|     contenu_section   TEXT, | ||||
|     date_modification TIMESTAMP, | ||||
|     CONSTRAINT pk_section PRIMARY KEY (id_section) | ||||
| ); | ||||
|  | ||||
| CREATE TABLE rendez_vous | ||||
| ( | ||||
|     id_rdv    SERIAL NOT NULL, | ||||
|     date_rdv  DATE, | ||||
|     heure_rdv TIME, | ||||
|     duree_rdv TIME, | ||||
|     lieu_rdv  VARCHAR(255), | ||||
|     sujet_rdv TEXT, | ||||
|     CONSTRAINT pk_rdv PRIMARY KEY (id_rdv) | ||||
| ); | ||||
|  | ||||
| CREATE TABLE comptes_rendus | ||||
| ( | ||||
|     id_compte_rendu      SERIAL NOT NULL, | ||||
|     contenu_compte_rendu TEXT, | ||||
|     CONSTRAINT pk_compte_rendu PRIMARY KEY (id_compte_rendu) | ||||
| ); | ||||
|  | ||||
| CREATE TABLE concerner | ||||
| ( | ||||
|     id_section SERIAL REFERENCES sections (id_section), | ||||
|     id_rdv     SERIAL REFERENCES sections (id_rdv), | ||||
|     CONSTRAINT pk_concerner PRIMARY KEY (id_section, id_rdv) | ||||
| ); | ||||
|  | ||||
|  | ||||
| ALTER TABLE projets | ||||
|     ADD CONSTRAINT fk1_projet FOREIGN KEY (id_administrateur) | ||||
|         REFERENCES administrateurs (id_administrateur) | ||||
|         ON DELETE CASCADE; | ||||
|  | ||||
| ALTER TABLE projets | ||||
|     ADD CONSTRAINT fk2_projet FOREIGN KEY (id_entrepreneur_participation) | ||||
|         REFERENCES entrepreneurs (id_entrepreneur) | ||||
|         ON DELETE CASCADE; | ||||
|  | ||||
| ALTER TABLE entrepreneurs | ||||
|     ADD CONSTRAINT fk1_entrepreneur FOREIGN KEY (id_projet_propose) | ||||
|         REFERENCES projets (id_projet) | ||||
|         ON DELETE CASCADE; | ||||
|  | ||||
| ALTER TABLE sections | ||||
|     ADD CONSTRAINT fk1_section FOREIGN KEY (id_projet) | ||||
|         REFERENCES projets (id_projet) | ||||
|         ON DELETE CASCADE; | ||||
|  | ||||
| ALTER TABLE sections | ||||
|     ADD CONSTRAINT fk2_section FOREIGN KEY (id_administrateur) | ||||
|         REFERENCES administrateurs (id_administrateur) | ||||
|         ON DELETE CASCADE; | ||||
|  | ||||
| ALTER TABLE rendez-vous | ||||
|     ADD CONSTRAINT fk1_rdv FOREIGN KEY (id_entrepreneur) | ||||
|     REFERENCES entrepreneurs (id_entrepreneur) | ||||
|     ON | ||||
| DELETE | ||||
| CASCADE; | ||||
|  | ||||
| ALTER TABLE rendez-vous | ||||
|     ADD CONSTRAINT fk2_rdv FOREIGN KEY (id_administrateur) | ||||
|     REFERENCES administrateurs (id_administrateur) | ||||
|     ON | ||||
| DELETE | ||||
| CASCADE; | ||||
|  | ||||
| ALTER TABLE comptes-rendus | ||||
|     ADD CONSTRAINT fk1_compte_rendu FOREIGN KEY (id_rdv) | ||||
|     REFERENCES rendez_vous (id_rdv) | ||||
|     ON | ||||
| DELETE | ||||
| CASCADE; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -0,0 +1,224 @@ | ||||
| package enseirb.myinpulse; | ||||
|  | ||||
| import static enseirb.myinpulse.model.ProjectDecisionValue.*; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
|  | ||||
| import enseirb.myinpulse.model.Administrator; | ||||
| import enseirb.myinpulse.model.Entrepreneur; | ||||
| import enseirb.myinpulse.model.Project; | ||||
| import enseirb.myinpulse.model.ProjectDecision; | ||||
| import enseirb.myinpulse.service.AdminApiService; | ||||
| import enseirb.myinpulse.service.database.AdministratorService; | ||||
| import enseirb.myinpulse.service.database.EntrepreneurService; | ||||
| import enseirb.myinpulse.service.database.ProjectService; | ||||
|  | ||||
| import org.junit.jupiter.api.BeforeAll; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| import org.springframework.web.server.ResponseStatusException; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| @SpringBootTest | ||||
| @Transactional | ||||
| public class AdminApiServiceTest { | ||||
|     private static long administratorid; | ||||
|     private static Administrator administrator; | ||||
|     private static Entrepreneur entrepreneur; | ||||
|     @Autowired private AdminApiService adminApiService; | ||||
|     @Autowired private ProjectService projectService; | ||||
|  | ||||
|     @BeforeAll | ||||
|     static void setup( | ||||
|             @Autowired AdministratorService administratorService, | ||||
|             @Autowired ProjectService projectService, | ||||
|             @Autowired EntrepreneurService entrepreneurService) { | ||||
|         administratorService.addAdministrator( | ||||
|                 new Administrator( | ||||
|                         "admin", | ||||
|                         "admin", | ||||
|                         "testAdminEmpty@example.com", | ||||
|                         "testAdmin@example.com", | ||||
|                         "")); | ||||
|         administrator = | ||||
|                 administratorService.addAdministrator( | ||||
|                         new Administrator( | ||||
|                                 "admin2", | ||||
|                                 "admin2", | ||||
|                                 "testAdminFull@example.com", | ||||
|                                 "testAdmin@example.com", | ||||
|                                 "")); | ||||
|         administratorid = administrator.getIdUser(); | ||||
|         entrepreneur = | ||||
|                 new Entrepreneur( | ||||
|                         "JeSuisUnEntrepreneurDeCompet", | ||||
|                         "EtUé", | ||||
|                         "Entrepreneur@inpulse.com", | ||||
|                         "mail2", | ||||
|                         "phone", | ||||
|                         "Ensimag    nan jdeconne ENSEIRB (-matmeca mais on s'en fout)", | ||||
|                         "info ofc", | ||||
|                         false); | ||||
|         entrepreneurService.addEntrepreneur(entrepreneur); | ||||
|         projectService.addNewProject( | ||||
|                 new Project( | ||||
|                         "sampleProjectAdminApiService", | ||||
|                         null, | ||||
|                         LocalDate.now(), | ||||
|                         ACTIVE, | ||||
|                         administratorService.getAdministratorByPrimaryMain( | ||||
|                                 "testAdminFull@example.com"))); | ||||
|     } | ||||
|  | ||||
|     private <T> List<T> IterableToList(Iterable<T> iterable) { | ||||
|         List<T> l = new ArrayList<>(); | ||||
|         iterable.forEach(l::add); | ||||
|         return l; | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void getProjectOfAdminIsEmpty() { | ||||
|         Iterable<Project> projects = | ||||
|                 adminApiService.getProjectsOfAdmin("testAdminEmpty@example.com"); | ||||
|         assertEquals(0, IterableToList(projects).size()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void getProjectOfInexistantAdminFails() { | ||||
|         String nonExistentAdminEmail = "testInexistantAdmin@example.com"; | ||||
|  | ||||
|         assertThrows( | ||||
|                 ResponseStatusException.class, | ||||
|                 () -> { | ||||
|                     adminApiService.getProjectsOfAdmin(nonExistentAdminEmail); | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void getProjectOfAdminNotEmpty() { | ||||
|         Iterable<Project> projects = | ||||
|                 adminApiService.getProjectsOfAdmin("testAdminFull@example.com"); | ||||
|         List<Project> l = IterableToList(projects); | ||||
|         assertEquals(1, l.size()); | ||||
|         Project p = l.getFirst(); | ||||
|         assertEquals(p.getProjectName(), "sampleProjectAdminApiService"); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void getPendingProjectsEmpty() { | ||||
|         assertEquals(0, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void getPendingProjectsNotEmpty() { | ||||
|         this.projectService.addNewProject( | ||||
|                 new Project( | ||||
|                         "PendingProjectAdminApiService1", null, LocalDate.now(), PENDING, null)); | ||||
|         this.projectService.addNewProject( | ||||
|                 new Project( | ||||
|                         "PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null)); | ||||
|         Iterable<Project> pendingProjects = this.adminApiService.getPendingProjects(); | ||||
|         List<Project> pendingProjectsList = IterableToList(pendingProjects); | ||||
|         assertEquals(2, pendingProjectsList.size()); | ||||
|         assertTrue( | ||||
|                 List.of("PendingProjectAdminApiService1", "PendingProjectAdminApiService2") | ||||
|                         .contains(pendingProjectsList.getFirst().getProjectName())); | ||||
|         assertTrue( | ||||
|                 List.of("PendingProjectAdminApiService1", "PendingProjectAdminApiService2") | ||||
|                         .contains(pendingProjectsList.getLast().getProjectName())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void validateInexistantProject() { | ||||
|         ProjectDecision d = new ProjectDecision(-1, 0, 1); | ||||
|         assertThrows(ResponseStatusException.class, () -> this.adminApiService.validateProject(d)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void validateExistantProject() { | ||||
|         Project p = | ||||
|                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||
|         this.projectService.addNewProject(p); | ||||
|         assertEquals(PENDING, p.getProjectStatus()); | ||||
|         ProjectDecision d = new ProjectDecision(p.getIdProject(), administratorid, 1); | ||||
|         this.adminApiService.validateProject(d); | ||||
|         assertEquals(ACTIVE, p.getProjectStatus()); | ||||
|  | ||||
|         // Check if the project was really updated in the database | ||||
|         assertEquals(0, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void refuseExistantProject() { | ||||
|         Project p = | ||||
|                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||
|         this.projectService.addNewProject(p); | ||||
|         assertEquals(PENDING, p.getProjectStatus()); | ||||
|         ProjectDecision d = new ProjectDecision(p.getIdProject(), administratorid, 0); | ||||
|         this.adminApiService.validateProject(d); | ||||
|         assertEquals(REJECTED, p.getProjectStatus()); | ||||
|  | ||||
|         // Check if the project was really updated in the database | ||||
|         assertEquals(0, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void addProject() { | ||||
|         assertEquals(0, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||
|         Project p1 = | ||||
|                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||
|         this.adminApiService.addNewProject(p1); | ||||
|  | ||||
|         assertEquals(1, IterableToList(this.adminApiService.getPendingProjects()).size()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void addProjectToAdmin() { | ||||
|         assertEquals(0, administrator.getListProject().size()); | ||||
|         Project p1 = new Project("assProjectToAdmin", null, LocalDate.now(), ACTIVE, administrator); | ||||
|         this.adminApiService.addNewProject(p1); | ||||
|         assertEquals(1, administrator.getListProject().size()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void addProjectToUser() { | ||||
|         assertNull(entrepreneur.getProjectParticipation()); | ||||
|         Project p1 = | ||||
|                 new Project("assProjectToAdmin", null, LocalDate.now(), ACTIVE, null, entrepreneur); | ||||
|         this.adminApiService.addNewProject(p1); | ||||
|         assertEquals(p1, entrepreneur.getProjectParticipation()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void addProjectWithManyUsers() { | ||||
|         Entrepreneur e1 = new Entrepreneur(); | ||||
|         Entrepreneur e2 = new Entrepreneur(); | ||||
|         Entrepreneur e3 = new Entrepreneur(); | ||||
|         assertNull(e1.getProjectParticipation()); | ||||
|         assertNull(e2.getProjectParticipation()); | ||||
|         assertNull(e3.getProjectParticipation()); | ||||
|         Project p1 = new Project("assProjectToAdmin", null, LocalDate.now(), ACTIVE, null, null); | ||||
|         p1.updateListEntrepreneurParticipation(e1); | ||||
|         p1.updateListEntrepreneurParticipation(e2); | ||||
|         p1.updateListEntrepreneurParticipation(e3); | ||||
|         this.adminApiService.addNewProject(p1); | ||||
|         assertEquals(p1, e1.getProjectParticipation()); | ||||
|         assertEquals(p1, e2.getProjectParticipation()); | ||||
|         assertEquals(p1, e3.getProjectParticipation()); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     void addDuplicateProject() { | ||||
|         Project p1 = | ||||
|                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||
|         Project p2 = | ||||
|                 new Project("PendingProjectAdminApiService2", null, LocalDate.now(), PENDING, null); | ||||
|         this.adminApiService.addNewProject(p1); | ||||
|         assertThrows(ResponseStatusException.class, () -> this.adminApiService.addNewProject(p2)); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,6 @@ | ||||
| package enseirb.myinpulse; | ||||
|  | ||||
| import org.junit.jupiter.api.DisplayName; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
|  | ||||
| @@ -7,5 +8,6 @@ import org.springframework.boot.test.context.SpringBootTest; | ||||
| class MyinpulseApplicationTests { | ||||
|  | ||||
|     @Test | ||||
|     @DisplayName("contextLoad => Test if the context can load, i.e. the application can start") | ||||
|     void contextLoads() {} | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								MyINPulse-back/src/test/resources/application.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								MyINPulse-back/src/test/resources/application.properties
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| spring.datasource.driver-class-name=org.h2.Driver | ||||
| spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 | ||||
| spring.datasource.username=sa | ||||
| spring.datasource.password=sa | ||||
| spring.sql.init.mode=never | ||||
| spring.application.name=myinpulse-test | ||||
| spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://localhost:7080/realms/test/protocol/openid-connect/certs | ||||
| spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:7080/realms/test | ||||
| spring.jpa.hibernate.ddl-auto=update | ||||
| logging.pattern.console=%d{yyyy-MMM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n | ||||
							
								
								
									
										22
									
								
								config/.env.dev
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								config/.env.dev
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| POSTGRES_DB=postgres_db | ||||
| POSTGRES_USER=postgres | ||||
| POSTGRES_PASSWORD=postgres_db_user_password | ||||
|  | ||||
| KEYCLOAK_ADMIN=admin | ||||
| KEYCLOAK_ADMIN_PASSWORD=admin | ||||
| KEYCLOAK_HOSTNAME=localhost | ||||
| KEYCLOAK_DB=keycloak_db | ||||
| KEYCLOAK_USER=keycloak_db_user | ||||
| KEYCLOAK_PASSWORD=keycloak_db_user_password | ||||
|  | ||||
| BACKEND_DB=backend_db | ||||
| BACKEND_USER=backend_db_user | ||||
| BACKEND_PASSWORD=backend_db_user_password | ||||
|  | ||||
| DATABASE_URL=localhost:5433 | ||||
|  | ||||
| VITE_KEYCLOAK_URL=http://localhost:7080 | ||||
| VITE_KEYCLOAK_CLIENT_ID=myinpulse-dev | ||||
| VITE_KEYCLOAK_REALM=test | ||||
| VITE_APP_URL=http://localhost:5173 | ||||
| VITE_BACKEND_URL=http://localhost:8081/ | ||||
							
								
								
									
										12
									
								
								documentation/Doc.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								documentation/Doc.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| Format des comptes rendus de réunion : | ||||
| Texte organisé par bullet point, chaque bullet point est séparé par "//" pour pouvoir être correctement généré. | ||||
|  | ||||
| Exemple : | ||||
| Le texte "// blablabla // oui bonjour" | ||||
| donne le résultat | ||||
|  | ||||
| Point n°1 : | ||||
|   blablabla | ||||
|  | ||||
| Point n°2 : | ||||
|   oui bonjour | ||||
							
								
								
									
										0
									
								
								front/Dockerfile
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								front/Dockerfile
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										63
									
								
								front/MyINPulse-front/fake_data/db.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								front/MyINPulse-front/fake_data/db.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| { | ||||
|   "entrepreneurs": [ | ||||
|     { "id": 1, "name": "Alice", "email": "alice@example.com" }, | ||||
|     { "id": 2, "name": "Bob", "email": "bob@example.com" }, | ||||
|     { "id": 3, "name": "Charlie", "email": "charlie@example.com" } | ||||
|   ], | ||||
|   "data": [ | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 1, | ||||
|       "title_text": "1. Problème", | ||||
|       "description": "3 problèmes essentiels à résoudre pour le client" | ||||
|     }, | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 2, | ||||
|       "title_text": "2. Segments", | ||||
|       "description": "Les segments de clientèle visés" | ||||
|     }, | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 3, | ||||
|       "title_text": "3. Valeur", | ||||
|       "description": "La proposition de valeur" | ||||
|     }, | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 4, | ||||
|       "title_text": "4. Solution", | ||||
|       "description": "Les solutions proposées" | ||||
|     }, | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 5, | ||||
|       "title_text": "5. Avantage", | ||||
|       "description": "Les avantages concurrentiels" | ||||
|     }, | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 6, | ||||
|       "title_text": "6. Canaux", | ||||
|       "description": "Les canaux de distribution" | ||||
|     }, | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 7, | ||||
|       "title_text": "7. Indicateurs", | ||||
|       "description": "Les indicateurs clés de performance" | ||||
|     }, | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 8, | ||||
|       "title_text": "8. Coûts", | ||||
|       "description": "Les coûts associés" | ||||
|     }, | ||||
|     { | ||||
|       "projectId": 1, | ||||
|       "title": 9, | ||||
|       "title_text": "9. Revenus", | ||||
|       "description": "Les sources de revenus" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										2
									
								
								front/MyINPulse-front/fake_data/open.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								front/MyINPulse-front/fake_data/open.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| #!/usr/bin/bash | ||||
| json-server --watch db.json --port 5000 | ||||
							
								
								
									
										10
									
								
								front/MyINPulse-front/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								front/MyINPulse-front/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -10,6 +10,7 @@ | ||||
|       "dependencies": { | ||||
|         "axios": "^1.7.9", | ||||
|         "cors": "^2.8.5", | ||||
|         "jwt-decode": "^4.0.0", | ||||
|         "keycloak-js": "^26.1.0", | ||||
|         "pinia": "^2.3.1", | ||||
|         "pinia-plugin-persistedstate": "^4.2.0", | ||||
| @@ -3588,6 +3589,15 @@ | ||||
|         "graceful-fs": "^4.1.6" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/jwt-decode": { | ||||
|       "version": "4.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", | ||||
|       "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", | ||||
|       "license": "MIT", | ||||
|       "engines": { | ||||
|         "node": ">=18" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/keycloak-js": { | ||||
|       "version": "26.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.1.0.tgz", | ||||
|   | ||||
| @@ -18,7 +18,8 @@ | ||||
|     "pinia": "^2.3.1", | ||||
|     "pinia-plugin-persistedstate": "^4.2.0", | ||||
|     "vue": "^3.5.13", | ||||
|     "vue-router": "^4.5.0" | ||||
|     "vue-router": "^4.5.0", | ||||
|     "jwt-decode": "^4.0.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@playwright/test": "^1.49.1", | ||||
|   | ||||
| @@ -1,47 +1,16 @@ | ||||
| <script setup lang="ts"> | ||||
| import { RouterView } from "vue-router"; | ||||
| import { /*RouterLink,*/ RouterView } from 'vue-router' | ||||
| import ErrorWrapper from "@/views/errorWrapper.vue"; | ||||
| import ProjectComponent from "@/components/ProjectComponent.vue"; | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|     <HeaderComponent /> | ||||
|     <error-wrapper></error-wrapper> | ||||
|     <div id="main"> | ||||
|         <ProjectComponent | ||||
|             v-for="(project, index) in projects" | ||||
|             :key="index" | ||||
|             :project-name="project.name" | ||||
|         /> | ||||
|     </div> | ||||
|  | ||||
| <Header /> | ||||
|     <ErrorWrapper /> | ||||
|     <!--<RouterLink to="/">Home</RouterLink> | --> | ||||
|     <!--<RouterLink to="/canvas">Canvas</RouterLink> --> | ||||
|     <RouterView /> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import HeaderComponent from "@/components/HeaderComponent.vue"; | ||||
|  | ||||
| export default { | ||||
|     name: "App", | ||||
|     components: { | ||||
|         HeaderComponent, | ||||
|     }, | ||||
|     data() { | ||||
|         return { | ||||
|             projects: [ | ||||
|                 { | ||||
|                     name: "Projet Alpha", | ||||
|                     //link: './project-alpha.html', | ||||
|                     //members: ['Alice', 'Bob', 'Charlie'], | ||||
|                 }, | ||||
|                 { | ||||
|                     name: "Projet Beta", | ||||
|                     //link: './project-beta.html', | ||||
|                     //members: ['David', 'Eve', 'Frank'], | ||||
|                 }, | ||||
|             ], | ||||
|         }; | ||||
|     }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped></style> | ||||
|   | ||||
							
								
								
									
										102
									
								
								front/MyINPulse-front/src/components/AddProjectForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								front/MyINPulse-front/src/components/AddProjectForm.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| <template> | ||||
|     <form class="add-project-form" @submit.prevent="submitProject"> | ||||
|       <h2>Ajouter un projet</h2> | ||||
|    | ||||
|       <div class="form-group"> | ||||
|         <label for="projectName">Nom du projet</label> | ||||
|         <input | ||||
|           id="projectName" | ||||
|           v-model="project.projectName" | ||||
|           type="text" | ||||
|           required | ||||
|         /> | ||||
|       </div> | ||||
|    | ||||
|       <div class="form-group"> | ||||
|         <label for="creationDate">Date de création</label> | ||||
|         <input | ||||
|           id="creationDate" | ||||
|           v-model="project.creationDate" | ||||
|           type="text" | ||||
|           placeholder="JJ-MM-AAAA" | ||||
|           required | ||||
|         /> | ||||
|       </div> | ||||
|    | ||||
|       <div class="form-group"> | ||||
|         <label for="logo">Logo</label> | ||||
|         <input | ||||
|           id="logo" | ||||
|           v-model="project.logo" | ||||
|           type="text" | ||||
|           placeholder="(à discuter)" | ||||
|         /> | ||||
|       </div> | ||||
|    | ||||
|       <button type="submit">Ajouter</button> | ||||
|     </form> | ||||
|   </template> | ||||
|    | ||||
|   <script setup lang="ts"> | ||||
|   import { ref } from "vue"; | ||||
|   import { postApi } from "@/services/api.ts";  | ||||
|    | ||||
|   const project = ref({ | ||||
|     idProject: 0, | ||||
|     projectName: "", | ||||
|     creationDate: "", | ||||
|     logo: "to be discussed not yet fixed", | ||||
|   }); | ||||
|    | ||||
|   function submitProject() { | ||||
|     postApi("/admin/projects/add", project.value); | ||||
|   } | ||||
|   </script> | ||||
|    | ||||
|   <style scoped> | ||||
|   .add-project-form { | ||||
|     max-width: 500px; | ||||
|     margin: 0 auto; | ||||
|     padding: 20px; | ||||
|     background: #fff; | ||||
|     border-radius: 10px; | ||||
|     box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | ||||
|   } | ||||
|    | ||||
|   h2 { | ||||
|     margin-bottom: 20px; | ||||
|     font-size: 24px; | ||||
|     color: #333; | ||||
|   } | ||||
|    | ||||
|   .form-group { | ||||
|     margin-bottom: 15px; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|   } | ||||
|    | ||||
|   label { | ||||
|     font-weight: bold; | ||||
|     margin-bottom: 5px; | ||||
|   } | ||||
|    | ||||
|   input { | ||||
|     padding: 8px; | ||||
|     border-radius: 5px; | ||||
|     border: 1px solid #ccc; | ||||
|   } | ||||
|    | ||||
|   button { | ||||
|     background-color: #4caf50; | ||||
|     color: white; | ||||
|     padding: 10px 15px; | ||||
|     border: none; | ||||
|     border-radius: 5px; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|    | ||||
|   button:hover { | ||||
|     background-color: #45a049; | ||||
|   } | ||||
|   </style> | ||||
|    | ||||
							
								
								
									
										75
									
								
								front/MyINPulse-front/src/components/Agenda.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								front/MyINPulse-front/src/components/Agenda.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| <template> | ||||
|     <div id="agenda"> | ||||
|         <h3>Rendez-vous</h3> | ||||
|         <table> | ||||
|         <tbody> | ||||
|             <tr v-for=" (p, index) in projectRDV" :key="index" > | ||||
|                 <td>{{ p.projectName }} </td> <td>{{ p.date }}</td> <td>{{ p.lieu }}</td> | ||||
|             </tr> | ||||
|         </tbody> | ||||
|         </table> | ||||
|     </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
|     import { defineProps } from "vue"; | ||||
|  | ||||
|     interface rendezVous{ | ||||
|         projectName: string, | ||||
|         date: string, | ||||
|         lieu: string, | ||||
|     } | ||||
|  | ||||
|     const props = defineProps<{ | ||||
|         projectRDV: rendezVous[] | ||||
|     }>(); | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
|  #agenda {    | ||||
|     padding: 20px; | ||||
|   } | ||||
|  | ||||
|   /* Table Styling */ | ||||
|  table { | ||||
|     width: 100%; | ||||
|     border-collapse: collapse; | ||||
|     font-family: Arial, sans-serif; | ||||
|     text-align: left; | ||||
|     margin-top: 20px; | ||||
|     border: 1px solid #ccc; | ||||
|   } | ||||
|    | ||||
|   /* Header Row (if exists) */ | ||||
|   th { | ||||
|     background-color: #f4f4f4; | ||||
|     padding: 12px; | ||||
|     font-weight: bold; | ||||
|     border: 1px solid #ccc; | ||||
|   } | ||||
|    | ||||
|   /* Table Body Rows */ | ||||
|   tbody tr { | ||||
|     border-bottom: 1px solid #ddd; | ||||
|     transition: background-color 0.2s ease; /* Smooth hover effect */ | ||||
|   } | ||||
|    | ||||
|   tbody tr:hover { | ||||
|     background-color: #f9f9f9; /* Highlight row on hover */ | ||||
|   } | ||||
|    | ||||
|   /* Cells Styling */ | ||||
|   td { | ||||
|     padding: 10px; | ||||
|     border: 1px solid #eee; | ||||
|     font-size: 14px; | ||||
|     vertical-align: middle; /* Align text to middle */ | ||||
|   } | ||||
|    | ||||
|   /* First Column Styling */ | ||||
|   td:first-child { | ||||
|     text-align: center; | ||||
|     width: 50px; /* Adjust width as needed */ | ||||
|   } | ||||
|   | ||||
| </style> | ||||
							
								
								
									
										173
									
								
								front/MyINPulse-front/src/components/LoginComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								front/MyINPulse-front/src/components/LoginComponent.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| <script lang="ts" setup> | ||||
| import { onMounted, ref } from "vue"; | ||||
| import { useRouter } from "vue-router"; | ||||
| import {jwtDecode} from "jwt-decode"; // i hope this doesn't break the code later | ||||
| import { store } from "../main.ts"; | ||||
| import { callApi } from "@/services/api.ts"; | ||||
|  | ||||
| const router = useRouter(); | ||||
|  | ||||
| type TokenPayload = { | ||||
|   realm_access?: { | ||||
|     roles?: string[]; | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| const customRequest = ref(''); | ||||
|  | ||||
| onMounted(() => { | ||||
|   if (store.authenticated && store.user.token) { | ||||
|     try { | ||||
|       const decoded = jwtDecode<TokenPayload>(store.user.token); | ||||
|       const roles = decoded.realm_access?.roles || []; | ||||
|  | ||||
|       if (roles.includes("MyINPulse-admin")) { | ||||
|         router.push("/"); | ||||
|       } else if (roles.includes("entrepreneur")) { | ||||
|         router.push("/entrepreneur"); | ||||
|       } | ||||
|     } catch (err) { | ||||
|       console.error("Failed to decode token", err); | ||||
|     } | ||||
|   } | ||||
| }); | ||||
| </script> | ||||
|  | ||||
|  | ||||
| <template> | ||||
|     <error-wrapper></error-wrapper> | ||||
|     <div class="auth-container"> | ||||
|       <div class="auth-card"> | ||||
|         <h1>Bienvenue</h1> | ||||
|  | ||||
|         <div class="status" :class="store.authenticated ? 'success' : 'error'"> | ||||
|           <p> | ||||
|             {{ store.authenticated ? '✅ Authenticated' : '❌ Not Authenticated' }} | ||||
|           </p> | ||||
|         </div> | ||||
|  | ||||
|         <div class="actions"> | ||||
|           <button @click="store.login">Login</button> | ||||
|           <button @click="store.logout">Logout</button> | ||||
|           <button @click="store.signup">Signup-admin</button> | ||||
|           <button @click="store.signup">Signup-Entrepreneur</button> | ||||
|           <button @click="store.refreshUserToken">Refresh Token</button> | ||||
|         </div> | ||||
|  | ||||
|         <div v-if="store.authenticated" class="token-section" > | ||||
|           <p><strong>Access Token:</strong></p> | ||||
|           <pre>{{ store.user.token }}</pre> | ||||
|  | ||||
|           <p><strong>Refresh Token:</strong></p> | ||||
|           <pre>{{ store.user.refreshToken }}</pre> | ||||
|         </div> | ||||
|  | ||||
|         <div class="api-calls"> | ||||
|           <h2>Test API Calls</h2> | ||||
|           <button @click="callApi('random')">Call Entrepreneur API</button> | ||||
|           <button @click="callApi('random2')">Call Admin API</button> | ||||
|           <button @click="callApi('unauth/dev')">Call Unauth API</button> | ||||
|  | ||||
|           <div class="custom-call"> | ||||
|             <input v-model="customRequest" placeholder="Custom endpoint" /> | ||||
|             <button @click="callApi(customRequest)">Call</button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
| </template> | ||||
|  | ||||
| <style scoped> | ||||
| .auth-container { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
|   padding: 3rem 1rem; | ||||
|   min-height: 100vh; | ||||
|   background-color: #eef1f5; | ||||
|   font-family: Arial, sans-serif; | ||||
| } | ||||
|  | ||||
| .auth-card { | ||||
|   background: white; | ||||
|   padding: 2rem; | ||||
|   border-radius: 12px; | ||||
|   box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); | ||||
|   width: 100%; | ||||
|   max-width: 600px; | ||||
| } | ||||
|  | ||||
| h1 { | ||||
|   text-align: center; | ||||
|   margin-bottom: 1rem; | ||||
|   color: #333; | ||||
| } | ||||
|  | ||||
| .status { | ||||
|   text-align: center; | ||||
|   margin-bottom: 1.5rem; | ||||
|   font-weight: bold; | ||||
| } | ||||
| .success { | ||||
|   color: green; | ||||
| } | ||||
| .error { | ||||
|   color: red; | ||||
| } | ||||
|  | ||||
| .actions { | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 1rem; | ||||
|   justify-content: center; | ||||
|   margin-bottom: 1.5rem; | ||||
| } | ||||
|  | ||||
| .actions button { | ||||
|   padding: 0.6rem 1rem; | ||||
|   background-color: #4a90e2; | ||||
|   border: none; | ||||
|   color: white; | ||||
|   border-radius: 8px; | ||||
|   cursor: pointer; | ||||
|   transition: background-color 0.2s; | ||||
| } | ||||
| .actions button:hover { | ||||
|   background-color: #357abd; | ||||
| } | ||||
|  | ||||
| .token-section pre { | ||||
|   background: #f6f8fa; | ||||
|   padding: 0.5rem; | ||||
|   overflow-x: auto; | ||||
|   border: 1px solid #ddd; | ||||
|   border-radius: 6px; | ||||
|   margin-bottom: 1rem; | ||||
|   font-size: 0.85rem; | ||||
| } | ||||
|  | ||||
| .api-calls { | ||||
|   margin-top: 2rem; | ||||
| } | ||||
| .api-calls h2 { | ||||
|   margin-bottom: 1rem; | ||||
|   color: #444; | ||||
|   font-size: 1.1rem; | ||||
| } | ||||
| .api-calls button { | ||||
|   margin-right: 0.5rem; | ||||
|   margin-bottom: 0.5rem; | ||||
| } | ||||
|  | ||||
| .custom-call { | ||||
|   margin-top: 1rem; | ||||
|   display: flex; | ||||
|   gap: 0.5rem; | ||||
| } | ||||
| .custom-call input { | ||||
|   flex: 1; | ||||
|   padding: 0.5rem; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 6px; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										149
									
								
								front/MyINPulse-front/src/components/PendingProjectComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								front/MyINPulse-front/src/components/PendingProjectComponent.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | ||||
| <template> | ||||
|     <div class="project"> | ||||
|         <div class="project-header"> | ||||
|             <div class="project-title"> | ||||
|                 <h2>{{ projectName }}</h2> | ||||
|                 <p>Projet mis le: {{ creationDate }}</p> | ||||
|             </div> | ||||
|         <div class="project-button"> | ||||
|             <button id="accept" @click="acceptProject">Accepter</button> | ||||
|             <button id="refus" @click="refuseProject">Refuser</button> | ||||
|         </div> | ||||
|     </div> | ||||
|     </div> | ||||
|  | ||||
| </template> | ||||
|  | ||||
|  | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { defineProps } from "vue"; | ||||
| import { postApi } from "@/services/api"; | ||||
| import { addNewMessage, color } from "@/services/popupDisplayer"; | ||||
|  | ||||
| const props = defineProps<{ | ||||
|   projectName: string; | ||||
|   creationDate: string; | ||||
| }>(); | ||||
|  | ||||
| const URI = "/admin/projects/pending/decision"; | ||||
|  | ||||
| const sendDecision = (decision: "true" | "false") => { | ||||
|   postApi( | ||||
|     URI, | ||||
|     { | ||||
|       projectName: props.projectName, | ||||
|       decision, | ||||
|     }, | ||||
|     () => { | ||||
|       addNewMessage( | ||||
|         `Projet ${props.projectName} ${decision === "true" ? "accepté" : "refusé"}`, | ||||
|         color.Green | ||||
|       ); | ||||
|     }, | ||||
|     (err) => { | ||||
|       addNewMessage(`Erreur lors de la décision`, color.Red); | ||||
|       console.error(err); | ||||
|     } | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const acceptProject = () => sendDecision("true"); | ||||
| const refuseProject = () => sendDecision("false"); | ||||
| </script> | ||||
|  | ||||
|  | ||||
|  | ||||
| <style scoped> | ||||
| .project { | ||||
|   background: linear-gradient(to right, #f4f4f4, #ffffff); | ||||
|   border: 1px solid #ddd; | ||||
|   border-radius: 10px; | ||||
|   padding: 20px; | ||||
|   margin: 20px 0; | ||||
|   box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | ||||
|   font-family: Arial, sans-serif; | ||||
| } | ||||
|  | ||||
| /* Header Styling */ | ||||
| .project-header { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: flex-start; | ||||
| } | ||||
|  | ||||
| .project-title { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
| } | ||||
|  | ||||
| .project-title h2 { | ||||
|   font-size: 20px; | ||||
|   color: #333; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .project-title p { | ||||
|   font-size: 14px; | ||||
|   color: #777; | ||||
|   margin-top: 4px; | ||||
| } | ||||
|  | ||||
| /* Button Container */ | ||||
| .project-buttons { | ||||
|   display: flex; | ||||
|   gap: 10px; | ||||
| } | ||||
|  | ||||
| #accept { | ||||
|   background-color: #45a049; | ||||
| } | ||||
|  | ||||
| #refus { | ||||
|   background-color: red; | ||||
| } | ||||
|  | ||||
| button { | ||||
|   padding: 10px 15px; | ||||
|   color: white; | ||||
|   border: none; | ||||
|   cursor: pointer; | ||||
|   border-radius: 5px; | ||||
| } | ||||
|  | ||||
| button:hover { | ||||
|   transform: scale(1.05); | ||||
| } | ||||
|  | ||||
| #accept:hover { | ||||
|   background-color: #3e8e41; | ||||
| } | ||||
|  | ||||
| #refus:hover { | ||||
|   background-color: darkred; | ||||
| } | ||||
|  | ||||
| /* Project Body (unchanged) */ | ||||
| .project-body { | ||||
|   margin-top: 15px; | ||||
| } | ||||
|  | ||||
| .project-body p { | ||||
|   font-size: 16px; | ||||
|   color: #555; | ||||
|   margin-bottom: 10px; | ||||
| } | ||||
|  | ||||
| .project-body ul { | ||||
|   list-style-type: disc; | ||||
|   margin: 0; | ||||
|   padding-left: 20px; | ||||
| } | ||||
|  | ||||
| .project-body ul li { | ||||
|   font-size: 14px; | ||||
|   color: #666; | ||||
|   line-height: 1.6; | ||||
| } | ||||
|  | ||||
| </style> | ||||
| @@ -1,21 +1,130 @@ | ||||
| <template> | ||||
|     <div class="project"> | ||||
|     <div class="project" @click="goToLink" > | ||||
|         <div class="project-header"> | ||||
|             <h2>{{ projectName }}</h2> | ||||
|             <h2 >{{ projectName }}</h2> | ||||
|             <div class="project-buttons"> | ||||
|                 <button class="contact-btn">Contact</button> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="project-body">    | ||||
|             <ul> | ||||
|                 <li v-for="(name, index) in listName" :key="index">{{ name }}</li> | ||||
|             </ul> | ||||
|         </div> | ||||
|     </div> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import type { PropType } from "vue"; | ||||
|  | ||||
| export default { | ||||
|     name: "ProjectComponent", | ||||
|     props: { | ||||
|         projectName: { | ||||
|             type: Object as PropType<string>, | ||||
|             required: true, | ||||
|         }, | ||||
|     }, | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { defineProps } from "vue"; | ||||
| import { useRouter } from 'vue-router' | ||||
|  | ||||
|  | ||||
| const props = defineProps<{ | ||||
|     projectName: string; | ||||
|     listName: string[]; | ||||
|     projectLink: string; | ||||
| }>(); | ||||
|  | ||||
| const router = useRouter(); | ||||
|  | ||||
| const goToLink = () => { | ||||
|   if (props.projectLink) { | ||||
|     router.push(props.projectLink);0 | ||||
|   } | ||||
|   | ||||
| }; | ||||
| </script> | ||||
|  | ||||
|  | ||||
| <style scoped> | ||||
| .project { | ||||
|     background: linear-gradient(to right, #f4f4f4, #ffffff); | ||||
|     border: 1px solid #ddd; | ||||
|     border-radius: 10px; | ||||
|     padding: 20px; | ||||
|     margin: 20px 0; | ||||
|     box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | ||||
|     font-family: Arial, sans-serif; | ||||
|   } | ||||
|    | ||||
|   /* Header Styling */ | ||||
|   .project-header { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|   } | ||||
|    | ||||
|   .project-header h2 { | ||||
|     font-size: 20px; | ||||
|     color: #333; | ||||
|     margin: 0; | ||||
|   } | ||||
|    | ||||
|   /* Button Container */ | ||||
|   .project-buttons { | ||||
|     display: flex; | ||||
|     gap: 10px; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   .info-btn { | ||||
|     background-color: #4CAF50; | ||||
|     color: #fff; | ||||
|   } | ||||
|    | ||||
|   .info-btn:hover { | ||||
|     background-color: #45a049; | ||||
|     transform: scale(1.05); | ||||
|   } | ||||
|    | ||||
|   .contact-btn { | ||||
|     background-color: #007BFF; | ||||
|     color: #fff; | ||||
|   } | ||||
|    | ||||
|   .contact-btn:hover { | ||||
|     background-color: #0056b3; | ||||
|     transform: scale(1.05); | ||||
|   } | ||||
|    | ||||
|  | ||||
|  | ||||
|  | ||||
|   .project-body { | ||||
|     margin-top: 15px; | ||||
|   } | ||||
|    | ||||
|   .project-body p { | ||||
|     font-size: 16px; | ||||
|     color: #555; | ||||
|     margin-bottom: 10px; | ||||
|   } | ||||
|    | ||||
|   .project-body ul { | ||||
|     list-style-type: disc; | ||||
|     margin: 0; | ||||
|     padding-left: 20px; | ||||
|   } | ||||
|    | ||||
|   .project-body ul li { | ||||
|     font-size: 14px; | ||||
|     color: #666; | ||||
|     line-height: 1.6; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   button { | ||||
|   padding: 10px 15px; | ||||
|   background-color: #007bff; | ||||
|   color: white; | ||||
|   border: none; | ||||
|   cursor: pointer; | ||||
|   border-radius: 5px; | ||||
| } | ||||
|   button:hover { | ||||
|     background-color: #0056b3; | ||||
|   } | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										396
									
								
								front/MyINPulse-front/src/components/canvas/CanvasItem.vue
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										396
									
								
								front/MyINPulse-front/src/components/canvas/CanvasItem.vue
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,396 @@ | ||||
| <template> | ||||
|   <div :class="['cell', { expanded }]" @click="handleClick"> | ||||
|     <h3 class="fs-5 fw-medium">{{ titleText }}</h3> | ||||
|  | ||||
|     <div v-for="(desc, index) in currentDescriptions" :key="index" class="section-bloc"> | ||||
|  | ||||
| <!-- ADMIN --------------------------------------------------------------------------------------------> | ||||
|  | ||||
|       <template v-if="IS_ADMIN"> | ||||
|         <div class="description"> | ||||
|           <p class="m-0">{{ desc }}</p> | ||||
|         </div> | ||||
|       </template> | ||||
|        | ||||
| <!-- ENTREP -------------------------------------------------------------------------------------------> | ||||
|        | ||||
|       <template v-if="!IS_ADMIN"> | ||||
|         <!-- Mode affichage --> | ||||
|         <template v-if="!isEditing[index]"> | ||||
|           <div class="description"> | ||||
|             <p class="m-0">{{ desc }}</p> | ||||
|           </div> | ||||
|           <div class="button-container"> | ||||
|             <button v-if="expanded" class="edit-button" @click.stop="startEditing(index)">Éditer</button> | ||||
|           </div> | ||||
|         </template> | ||||
|  | ||||
|         <!-- Mode édition --> | ||||
|         <template v-else> | ||||
|           <textarea v-model="editedDescriptions[index]" class="edit-input"></textarea> | ||||
|           <div class="button-container"> | ||||
|             <button class="save-button" @click.stop="saveEdit(index)">Enregistrer</button> | ||||
|             <button class="cancel-button" @click.stop="cancelEdit(index)">Annuler</button> | ||||
|           </div> | ||||
|         </template> | ||||
|       </template> | ||||
|     </div> | ||||
| <!----------------------------------------------------------------------------------------------------> | ||||
|     <template v-if="expanded"> | ||||
|       <div class="canvas-exit-hint"> | ||||
|         Cliquez n'importe où pour quitter le canvas | ||||
|       </div> | ||||
|     </template> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref, defineProps, onMounted } from "vue"; | ||||
| import axios from "axios"; | ||||
| import { axiosInstance } from "@/services/api.ts"; | ||||
|  | ||||
| const IS_MOCK_MODE = true;  | ||||
|  | ||||
| const props = defineProps<{ | ||||
|   projectId: number; | ||||
|   title: number; | ||||
|   titleText: string; | ||||
|   description: string; | ||||
|   is_admin: number; | ||||
| }>(); | ||||
|  | ||||
| const IS_ADMIN = props.is_admin; | ||||
|  | ||||
| const expanded = ref(false); | ||||
| const currentDescriptions = ref<string[]>([]); | ||||
| currentDescriptions.value[0] = props.description; | ||||
| const editedDescriptions = ref<string[]>([]); | ||||
| const isEditing = ref<boolean[]>([]); | ||||
|  | ||||
| onMounted(() => { | ||||
|   fetchData(props.projectId, props.title, "NaN", IS_MOCK_MODE); | ||||
| }); | ||||
|  | ||||
|  | ||||
| /* FOR LOCAL DATABASE | ||||
| const fetchData = async () => { | ||||
|   try { | ||||
|     const response = await axios.get("http://localhost:5000/data"); // Met à jour l'URL | ||||
|     if (response.data.length > 0) { | ||||
|       currentDescription.value = response.data[0].canva_data; | ||||
|       editedDescription.value = response.data[0].canva_data; | ||||
|     } else { | ||||
|       console.warn("Aucune donnée reçue."); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.error("Erreur lors de la récupération des données :", error); | ||||
|   } | ||||
| }; | ||||
| */ | ||||
|  | ||||
| // Fonction fetchData avec possibilité d'utiliser le mock | ||||
| /* FOR FETCHING WITH AXIOS DIRECTLY | ||||
| const fetchData = async (projectId: number, title: number, date: string, useMock = false) => { | ||||
|   try { | ||||
|     const responseData = useMock | ||||
|       ? await mockFetch(projectId, title, date) | ||||
|       : (await axios.get<{ txt: string }[]>( | ||||
|           `http://localhost:5000/shared/projects/lcsection/${projectId}/${title}/${date}` | ||||
|         )).data; | ||||
|     if (responseData.length > 0) { | ||||
|       currentDescriptions.value = responseData.map((item) => item.txt); | ||||
|       editedDescriptions.value = [...currentDescriptions.value]; | ||||
|       isEditing.value = Array(responseData.length).fill(false); | ||||
|     } else { | ||||
|       console.warn("Aucune donnée reçue."); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.error("Erreur lors de la récupération des données :", error); | ||||
|   } | ||||
| }; | ||||
| */ | ||||
|  | ||||
| // Fonction fetchData avec possibilité d'utiliser le mock | ||||
| const fetchData = async (projectId: number, title: number, date: string, useMock = false) => { | ||||
|   try { | ||||
|     const responseData = useMock | ||||
|       ? await mockFetch(projectId, title, date) | ||||
|       : (await axiosInstance.get<{ txt: string }[]>( | ||||
|           `/shared/projects/lcsection/${projectId}/${title}/${date}` | ||||
|         )).data; | ||||
|  | ||||
|     if (responseData.length > 0) { | ||||
|       currentDescriptions.value = responseData.map((item) => item.txt); | ||||
|       editedDescriptions.value = [...currentDescriptions.value]; | ||||
|       isEditing.value = Array(responseData.length).fill(false); | ||||
|     } else { | ||||
|       console.warn("Aucune donnée reçue."); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.error("Erreur lors de la récupération des données :", error); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // Fonction de simulation de l'API | ||||
| const mockFetch = async (projectId: number, title: number, date: string) => { | ||||
|   console.log(`Mock fetch pour projectId: ${projectId}, title: ${title}, date: ${date}`); | ||||
|  | ||||
|   return new Promise<{ txt: string }[]>((resolve) => { | ||||
|     setTimeout(() => { | ||||
|       resolve([ | ||||
|       {txt: "Ceci est une description 1 pour tester le front."}, | ||||
|       {txt: "Deuxième description."}, | ||||
|       {txt: "Troisième description."} | ||||
|       ]); | ||||
|     }, 500); // Simule un délai réseau de 500ms | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| // Utilisation du mock dans handleClick pour tester sans serveur | ||||
| const handleClick = async () => { | ||||
|   if (!expanded.value) { | ||||
|     await fetchData(props.projectId, props.title, "NaN", IS_MOCK_MODE); | ||||
|   } else if (!isEditing.value.includes(true)) { | ||||
|     // Réinitialiser les descriptions si aucune édition n'est en cours | ||||
|     currentDescriptions.value = [props.description]; | ||||
|     editedDescriptions.value = [props.description]; | ||||
|   } | ||||
|  | ||||
|   if (!isEditing.value.includes(true)) { | ||||
|     expanded.value = !expanded.value; | ||||
|   } | ||||
| }; | ||||
|  | ||||
|  | ||||
| const startEditing = (index: number) => { | ||||
|   isEditing.value[index] = true; | ||||
| }; | ||||
|  | ||||
| /* | ||||
| const saveEdit = async (index: number) => { | ||||
|   try { | ||||
|     const id = index + 1; // À adapter selon l'ID réel des données | ||||
|     await axios.put(`http://localhost:5000/data/${id}`, { | ||||
|       canva_data: editedDescriptions.value[index] | ||||
|     }); | ||||
|  | ||||
|     // Mettre à jour l'affichage local après la mise à jour réussie | ||||
|     currentDescriptions.value[index] = editedDescriptions.value[index]; | ||||
|     isEditing.value[index] = false; | ||||
|   } catch (error) { | ||||
|     console.error("Erreur lors de la mise à jour des données :", error); | ||||
|   } | ||||
| }; | ||||
| */ | ||||
|  | ||||
| const saveEdit = async (index: number) => { | ||||
|   if (IS_MOCK_MODE) { | ||||
|     await mockSaveEdit(index); | ||||
|   } else { | ||||
|     try { | ||||
|       const id = index + 1; | ||||
|       await axios.put(`http://localhost:5000/data/${id}`, { | ||||
|         canva_data: editedDescriptions.value[index] | ||||
|       }); | ||||
|  | ||||
|       // Mettre à jour l'affichage local après la mise à jour réussie | ||||
|       currentDescriptions.value[index] = editedDescriptions.value[index]; | ||||
|       isEditing.value[index] = false; | ||||
|     } catch (error) { | ||||
|       console.error("Erreur lors de la mise à jour des données :", error); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // Fonction de mock pour l'enregistrement | ||||
| const mockSaveEdit = async (index: number) => { | ||||
|   try { | ||||
|     const id = index + 1; | ||||
|     console.log(`Mock save pour l'ID ${id} avec la description : ${editedDescriptions.value[index]}`); | ||||
|  | ||||
|     await new Promise((resolve) => setTimeout(resolve, 500)); // Simulation de délai réseau | ||||
|  | ||||
|     // Mettre à jour l'affichage local après la mise à jour réussie | ||||
|     currentDescriptions.value[index] = editedDescriptions.value[index]; | ||||
|     isEditing.value[index] = false; | ||||
|   } catch (error) { | ||||
|     console.error("Erreur lors de la mise à jour des données mockées :", error); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const cancelEdit = (index: number) => { | ||||
|   editedDescriptions.value[index] = currentDescriptions.value[index]; | ||||
|   isEditing.value[index] = false; | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| @import "@/components/canvas/style-project.css"; | ||||
|  | ||||
|  | ||||
| .cell { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   text-align: center; | ||||
|   transition: all 0.3s ease; | ||||
|   cursor: pointer; | ||||
|   box-shadow: 0 4px 5px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
|  | ||||
|  | ||||
| .expanded-content { | ||||
|   justify-content: flex-start !important; | ||||
| } | ||||
|  | ||||
| .cell:not(.expanded):hover { | ||||
|   transform: scale(1.05); | ||||
|   box-shadow: 0 8px 9px rgba(0, 0, 0, 0.2); | ||||
| } | ||||
|  | ||||
| .cell h3 { | ||||
|   font-size: 15px; | ||||
|   font-weight: 500; | ||||
|   font-family: 'Arial', sans-serif; | ||||
| } | ||||
|  | ||||
| .p { | ||||
|   font-size: 10px; | ||||
|   color: #666; | ||||
|   font-family: 'Arial', sans-serif; | ||||
| } | ||||
|  | ||||
| .expanded { | ||||
|   padding-top: 10%; | ||||
|   position: fixed; | ||||
|   top: 0; | ||||
|   left: 0; | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   background: white; | ||||
|   z-index: 10; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: flex-start; | ||||
|   box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); | ||||
| } | ||||
|  | ||||
|  | ||||
| .description { | ||||
|   display: flex; | ||||
|   align-items: center;  | ||||
|   justify-content: center; | ||||
|   text-align: center; | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   font-size: 16px; | ||||
|   margin-top: 10px; | ||||
|   margin-left: 2%; | ||||
|   margin-right: 4%; | ||||
| } | ||||
|  | ||||
| .description + .p { | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| .edit-input { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   padding: 10px; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 5px; | ||||
|   margin-top: 10px; | ||||
|   box-sizing: border-box; | ||||
|   margin-left: 2%; | ||||
| } | ||||
|  | ||||
|  | ||||
| .button-container { | ||||
|   display: block; | ||||
|   margin-top: 20px; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
|   gap: 10px; | ||||
|   padding-right: 1%; | ||||
| } | ||||
|  | ||||
|  | ||||
| .section-bloc ,.editing-section-bloc { | ||||
|   width: 100%; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
|   display: flex; | ||||
|   margin-right: 10%; | ||||
|   margin: 10px; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| .edit-button { | ||||
|   width: 100px; | ||||
|   height: 40px; | ||||
|   border: none; | ||||
|   border-radius: 5px; | ||||
|   cursor: pointer; | ||||
|   transition: background 0.3s ease; | ||||
|   font-size: 12px; | ||||
|   margin-right: 20px; | ||||
| } | ||||
|  | ||||
| .save-button, .cancel-button { | ||||
|   width: 100px; | ||||
|   height: 40px; | ||||
|   border: none; | ||||
|   border-radius: 5px; | ||||
|   cursor: pointer; | ||||
|   transition: background 0.3s ease; | ||||
|   font-size: 12px; | ||||
|   margin-bottom: 5px; | ||||
| } | ||||
|  | ||||
| .edit-button { | ||||
|   background-color: #007bff; | ||||
|   color: white; | ||||
| } | ||||
|  | ||||
| .save-button { | ||||
|   background-color: #28a745; | ||||
|   color: white; | ||||
| } | ||||
|  | ||||
| .cancel-button { | ||||
|   background-color: #dc3545; | ||||
|   color: white; | ||||
| } | ||||
|  | ||||
| .edit-button:hover { | ||||
|   background-color: #0056b3; | ||||
| } | ||||
|  | ||||
| .save-button:hover { | ||||
|   background-color: #218838; | ||||
| } | ||||
|  | ||||
| .cancel-button:hover { | ||||
|   background-color: #c82333; | ||||
| } | ||||
|  | ||||
| .canvas-exit-hint { | ||||
|   font-size: 0.75rem; | ||||
|   color: #666; | ||||
|   position: fixed; | ||||
|   bottom: 10px; | ||||
|   left: 0; | ||||
|   width: 100%; | ||||
|   text-align: center; | ||||
|   z-index: 1000; | ||||
| } | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										218
									
								
								front/MyINPulse-front/src/components/canvas/HeaderCanvas.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								front/MyINPulse-front/src/components/canvas/HeaderCanvas.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,218 @@ | ||||
| <template> | ||||
|   <header class="header"> | ||||
|     <img src="../icons/logo inpulse.png" alt="INPulse Logo" class="logo" /> | ||||
|  | ||||
|     <div class="header-actions"> | ||||
|       <div class="dropdown-wrapper"> | ||||
|         <button class="contact-button" @click="toggleDropdown">Contact</button> | ||||
|         <div class="contact-dropdown" :class="{ 'dropdown-visible': isDropdownOpen }"> | ||||
|           <button @click="contactAll">Contacter tous</button> | ||||
|           <button | ||||
|             v-for="(email, index) in entrepreneurEmails" | ||||
|             :key="index" | ||||
|             @click="contactSingle(email)" | ||||
|           > | ||||
|             {{ email }} | ||||
|           </button> | ||||
|         </div> | ||||
|       </div> | ||||
|       <RouterLink to="/" class="return-button">Retour</RouterLink> | ||||
|     </div> | ||||
|   </header> | ||||
| </template> | ||||
|  | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref, onMounted } from "vue"; | ||||
| import axios from "axios"; | ||||
|  | ||||
| const IS_MOCK_MODE = true; | ||||
|  | ||||
| const props = defineProps<{ | ||||
|   projectId: number; | ||||
| }>(); | ||||
|  | ||||
| type Entrepreneur = { | ||||
|   idUser: number; | ||||
|   userSurname: string; | ||||
|   userName: string; | ||||
|   primaryMail: string; | ||||
|   secondaryMail: string; | ||||
|   phoneNumber: string; | ||||
|   school: string; | ||||
|   course: string; | ||||
|   sneeStatus: boolean; | ||||
| }; | ||||
|  | ||||
| const isDropdownOpen = ref(false); | ||||
| const entrepreneurEmails = ref<string[]>([]); | ||||
|  | ||||
| const toggleDropdown = () => { | ||||
|   isDropdownOpen.value = !isDropdownOpen.value; | ||||
|   console.log("Dropdown toggled:", isDropdownOpen.value); | ||||
| }; | ||||
|  | ||||
| const fetchEntrepreneurs = async (projectId: number, useMock = IS_MOCK_MODE) => { | ||||
|   try { | ||||
|     const responseData: Entrepreneur[] = useMock | ||||
|       ? await mockFetchEntrepreneurs(projectId) | ||||
|       : (await axios.get(`http://localhost:5000/shared/projects/entrepreneurs/${projectId}`)).data; | ||||
|  | ||||
|     if (responseData.length > 0) { | ||||
|       entrepreneurEmails.value = responseData.map((item: Entrepreneur) => item.primaryMail); | ||||
|     } else { | ||||
|       console.warn("Aucun entrepreneur trouvé."); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.error("Erreur lors de la récupération des entrepreneurs :", error); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // Fonction de simulation de l'API | ||||
| const mockFetchEntrepreneurs = async (projectId :number) => { | ||||
|   console.log(`Mock fetch pour projectId: ${projectId}`); | ||||
|  | ||||
|   return new Promise((resolve) => { | ||||
|     setTimeout(() => { | ||||
|       resolve([ | ||||
|         { | ||||
|           idUser: 1, | ||||
|           userSurname: "Doe", | ||||
|           userName: "John", | ||||
|           primaryMail: "john.doe@example.com", | ||||
|           secondaryMail: "johndoe@backup.com", | ||||
|           phoneNumber: "612345678", | ||||
|           school: "ENSEIRB", | ||||
|           course: "Info", | ||||
|           sneeStatus: false | ||||
|         }, | ||||
|         { | ||||
|           idUser: 2, | ||||
|           userSurname: "Smith", | ||||
|           userName: "Jane", | ||||
|           primaryMail: "jane.smith@example.com", | ||||
|           secondaryMail: "janesmith@backup.com", | ||||
|           phoneNumber: "698765432", | ||||
|           school: "ENSEIRB", | ||||
|           course: "Info", | ||||
|           sneeStatus: true | ||||
|         } | ||||
|       ]); | ||||
|     }, 500); | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| const contactAll = () => { | ||||
|   const allEmails = entrepreneurEmails.value.join(", "); | ||||
|   navigator.clipboard.writeText(allEmails) | ||||
|     .then(() => { | ||||
|       alert("Tous les emails copiés dans le presse-papiers !"); | ||||
|       window.open("https://partage.bordeaux-inp.fr/", "_blank"); | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       console.error("Erreur lors de la copie :", err); | ||||
|     }); | ||||
| }; | ||||
|  | ||||
| const contactSingle = (email: string) => { | ||||
|   navigator.clipboard.writeText(email) | ||||
|     .then(() => { | ||||
|       alert(`Adresse copiée : ${email}`); | ||||
|       window.open("https://partage.bordeaux-inp.fr/", "_blank"); | ||||
|     }) | ||||
|     .catch(err => { | ||||
|       console.error("Erreur lors de la copie :", err); | ||||
|     }); | ||||
| }; | ||||
|  | ||||
|  | ||||
| const copyToClipboard = (email: string) => { | ||||
|   navigator.clipboard.writeText(email).then(() => { | ||||
|     alert(`Adresse copiée : ${email}`); | ||||
|   }).catch(err => { | ||||
|     console.error("Erreur lors de la copie :", err); | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| onMounted(() => fetchEntrepreneurs(props.projectId, IS_MOCK_MODE)); | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| @import "@/components/canvas/style-project.css"; | ||||
|  | ||||
| .header { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   padding: 15px 30px; | ||||
|   background-color: #f9f9f9; | ||||
|   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
|  | ||||
| .logo { | ||||
|   height: 50px; | ||||
| } | ||||
|  | ||||
| .header-actions { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   gap: 20px; | ||||
|   position: relative; | ||||
| } | ||||
|  | ||||
| .contact-button, | ||||
| .return-button { | ||||
|   background-color: #009CDE; | ||||
|   color: white; | ||||
|   border: none; | ||||
|   padding: 10px 15px; | ||||
|   cursor: pointer; | ||||
|   font-size: 14px; | ||||
|   border-radius: 5px; | ||||
|   text-decoration: none; | ||||
|   transition: background-color 0.2s ease; | ||||
|   font-family: Arial, sans-serif; | ||||
| } | ||||
|  | ||||
| .return-button:hover, | ||||
| .contact-button:hover { | ||||
|   background-color: #007bad; | ||||
| } | ||||
|  | ||||
|  | ||||
| .contact-dropdown { | ||||
|   position: absolute; | ||||
|   top: 100%; | ||||
|   left: 0; | ||||
|   background-color: #000; | ||||
|   color: white; | ||||
|   box-shadow: 0px 4px 8px rgba(255, 255, 255, 0.2); | ||||
|   border-radius: 8px; | ||||
|   padding: 10px; | ||||
|   margin-top: 5px; | ||||
|   z-index: 1000; | ||||
|   min-width: 200px; | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .contact-dropdown button { | ||||
|   display: block; | ||||
|   width: 100%; | ||||
|   padding: 5px; | ||||
|   text-align: left; | ||||
|   border: none; | ||||
|   background: none; | ||||
|   cursor: pointer; | ||||
|   color: white; | ||||
| } | ||||
|  | ||||
| .contact-dropdown button:hover { | ||||
|   background-color: #009CDE; | ||||
| } | ||||
|  | ||||
| .contact-dropdown.dropdown-visible { | ||||
|   display: block; | ||||
| } | ||||
|  | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										82
									
								
								front/MyINPulse-front/src/components/canvas/LeanCanvas.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								front/MyINPulse-front/src/components/canvas/LeanCanvas.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| <template> | ||||
|   <div class="canvas container-fluid">   | ||||
|     <CanvasItem | ||||
|       v-for="(item, index) in items" | ||||
|       :key="index" | ||||
|       :title="item.title" | ||||
|       :titleText="item.title_text" | ||||
|       :description="item.description" | ||||
|       :project-id="item.projectId" | ||||
|       :class="['canvas-item', item.class, 'card', 'shadow', 'p-3']" | ||||
|       :is_admin=is_admin | ||||
|     /> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref, onMounted } from "vue"; | ||||
| import CanvasItem from "@/components/canvas/CanvasItem.vue"; | ||||
|  | ||||
| const props = defineProps<{ | ||||
|   is_admin: number; | ||||
| }>(); | ||||
|  | ||||
| const items = ref([ | ||||
|   { projectId: 1, title: 1, title_text: "1. Problème", description: "3 problèmes essentiels à résoudre pour le client", class: "Probleme" }, | ||||
|   { projectId: 1, title: 2, title_text: "2. Segments", description: "Les segments de clientèle visés", class: "Segments" }, | ||||
|   { projectId: 1, title: 3, title_text: "3. Valeur", description: "La proposition de valeur", class: "Valeur" }, | ||||
|   { projectId: 1, title: 4, title_text: "4. Solution", description: "Les solutions proposées", class: "Solution" }, | ||||
|   { projectId: 1, title: 5, title_text: "5. Avantage", description: "Les avantages concurrentiels", class: "Avantage" }, | ||||
|   { projectId: 1, title: 6, title_text: "6. Canaux", description: "Les canaux de distribution", class: "Canaux" }, | ||||
|   { projectId: 1, title: 7, title_text: "7. Indicateurs", description: "Les indicateurs clés de performance", class: "Indicateurs" }, | ||||
|   { projectId: 1, title: 8, title_text: "8. Coûts", description: "Les coûts associés", class: "Couts" }, | ||||
|   { projectId: 1, title: 9, title_text: "9. Revenus", description: "Les sources de revenus", class: "Revenus" } | ||||
| ]); | ||||
|  | ||||
| onMounted(() => { | ||||
|   const bootstrapCss = document.createElement('link') | ||||
|   bootstrapCss.rel = 'stylesheet' | ||||
|   bootstrapCss.href = 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css' | ||||
|   bootstrapCss.integrity = 'sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+Fpc+NC' | ||||
|   bootstrapCss.crossOrigin = 'anonymous' | ||||
|   document.head.appendChild(bootstrapCss) | ||||
|  | ||||
|   const bootstrapJs = document.createElement('script') | ||||
|   bootstrapJs.src = 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js' | ||||
|   bootstrapJs.integrity = 'sha384-mQ93S0EhrF4Z1nM+fTflmYf0DyzsY5j7F5H3WlClDD6H3WUJh6kxBkF3GDW8n1j6' | ||||
|   bootstrapJs.crossOrigin = 'anonymous' | ||||
|   document.body.appendChild(bootstrapJs) | ||||
| }) | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| @import "@/components/canvas/style-project.css"; | ||||
|  | ||||
| .canvas { | ||||
|   display: grid; | ||||
|   grid-template-columns: repeat(10, 1fr); | ||||
|   grid-template-rows: repeat(6, 1fr); | ||||
|   gap: 12px; | ||||
|   padding: 30px; | ||||
|   /*background-color: #f8f9fa;*/ | ||||
|   position: relative; | ||||
|   height: 90vh; | ||||
|   overflow: auto; | ||||
| } | ||||
|  | ||||
| .Probleme { grid-column: 1 / 3; grid-row: 1 / 5; } | ||||
| .Segments { grid-column: 9 / 11; grid-row: 1 / 5; } | ||||
| .Valeur { grid-column: 5 / 7; grid-row: 1 / 5; } | ||||
| .Solution { grid-column: 3 / 5; grid-row: 1 / 3; } | ||||
| .Avantage { grid-column: 7 / 9; grid-row: 1 / 3; } | ||||
| .Canaux { grid-column: 7 / 9; grid-row: 3 / 5; } | ||||
| .Indicateurs { grid-column: 3 / 5; grid-row: 3 / 5; } | ||||
| .Couts { grid-column: 1 / 6; grid-row: 5 / 7; } | ||||
| .Revenus { grid-column: 6 / 11; grid-row: 5 / 7; } | ||||
|  | ||||
| .canvas-item { | ||||
|   /*background-color: white;*/ | ||||
|   border: 1px solid #dee2e6; | ||||
|   border-radius: 0.5rem; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										156
									
								
								front/MyINPulse-front/src/components/canvas/style-project.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								front/MyINPulse-front/src/components/canvas/style-project.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| body { | ||||
|     font-family: Arial, sans-serif; | ||||
|     margin: 0; | ||||
|     padding: 10px; | ||||
|   } | ||||
|    | ||||
|   .row { | ||||
|     display: flex; | ||||
|   } | ||||
|    | ||||
|   .cell { | ||||
|     flex: 1; | ||||
|     border: 1px solid #ddd; | ||||
|     padding: 10px; | ||||
|     text-align: center; | ||||
|     background-color: #f1f1f1; | ||||
|   } | ||||
|    | ||||
|   .produit { | ||||
|     background-color: #f9e4e4; | ||||
|   } | ||||
|    | ||||
|   .marche { | ||||
|     background-color: #e4f1f9; | ||||
|   } | ||||
|    | ||||
|   .valeur { | ||||
|     background-color: #f9f4e4; | ||||
|   } | ||||
|    | ||||
|   h3 { | ||||
|     margin: 0; | ||||
|     font-size: 18px; | ||||
|     color: #333; | ||||
|   } | ||||
|    | ||||
|   p { | ||||
|     margin: 5px 0 0; | ||||
|     font-size: 14px; | ||||
|   } | ||||
|    | ||||
|  | ||||
|   body { | ||||
|     font-family: Arial, sans-serif; | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     background-color: #f9f9f9; | ||||
|   } | ||||
|  | ||||
|   h1 img { | ||||
|     height: 80px; | ||||
|     margin: 40px; | ||||
|     text-align: center; | ||||
|   } | ||||
|  | ||||
|   .row { | ||||
|     display: flex; | ||||
|     margin-bottom: 10px; | ||||
|   } | ||||
|  | ||||
|   #ade { | ||||
|     max-width: 1200px; | ||||
|     margin: 20px auto; | ||||
|     padding: 20px; | ||||
|     text-align: center; | ||||
|     background-color: #e8f5e9; | ||||
|     border: 2px solid #4caf50; | ||||
|     border-radius: 10px; | ||||
|   } | ||||
|  | ||||
|   #ade h3 { | ||||
|     color: #2e7d32; | ||||
|   } | ||||
|  | ||||
|   #ade p { | ||||
|     margin: 10px 0; | ||||
|     font-size: 16px; | ||||
|     color: #333; | ||||
|   } | ||||
|   header { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|     padding: 10px 20px; | ||||
|     background-color: #fff; | ||||
|     border-bottom: 2px solid #ddd; | ||||
|   } | ||||
|  | ||||
|   header img { | ||||
|     height: 60px; | ||||
|   } | ||||
|  | ||||
|   header .contact-menu { | ||||
|     position: relative; | ||||
|   } | ||||
|  | ||||
|   .contact-button, .return { | ||||
|     padding: 10px 15px; | ||||
|     border: none; | ||||
|     border-radius: 4px; | ||||
|     background-color: #2196f3; | ||||
|     color: #fff; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|  .contact-button:hover, .return:hover { | ||||
|     background-color: #1976d2; | ||||
|   } | ||||
|  | ||||
|   /* Dropdown styling */ | ||||
|   .contact-dropdown { | ||||
|     position: absolute; | ||||
|     right: 0; | ||||
|     top: 50px; | ||||
|     display: none; | ||||
|     flex-direction: column; | ||||
|     gap: 10px; | ||||
|     padding: 15px; | ||||
|     background-color: #fff; | ||||
|     border: 1px solid #ddd; | ||||
|     border-radius: 8px; | ||||
|     box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | ||||
|     z-index: 10; | ||||
|   } | ||||
|  | ||||
|   .contact-dropdown button { | ||||
|     padding: 8px 12px; | ||||
|     border: none; | ||||
|     border-radius: 4px; | ||||
|     background-color: #4caf50; | ||||
|     color: #fff; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   .contact-dropdown button:hover { | ||||
|     background-color: #388e3c; | ||||
|   } | ||||
|  | ||||
|   .return { | ||||
|     background-color: #f44336; | ||||
|   } | ||||
|  | ||||
|   .return:hover { | ||||
|     background-color: #d32f2f; | ||||
|   } | ||||
|  | ||||
|   .header-buttons { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     gap: 15px; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   a{ | ||||
|     color: white; | ||||
|   } | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 39 KiB | 
| @@ -26,6 +26,52 @@ keycloakService.CallInit(() => { | ||||
|         console.error(e); | ||||
|         createApp(App).mount("#app"); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| }) | ||||
|  | ||||
| // this shit made by me so i can run the canva vue app | ||||
| //createApp(App).use(router).mount('#app'); | ||||
|  | ||||
| // TODO: fix the comment | ||||
| /* | ||||
| function tokenInterceptor () { | ||||
|     axios.interceptors.request.use(config => { | ||||
|         const keycloak = useKeycloak() | ||||
|         if (keycloak.authenticated) { | ||||
|             // Note that this is a simple example. | ||||
|             // you should be careful not to leak tokens to third parties. | ||||
|             // in this example the token is added to all usage of axios. | ||||
|             config.headers.Authorization = `Bearer ${keycloak.token}` | ||||
|         } | ||||
|         return config | ||||
|     }, error => { | ||||
|         console.error("tokenInterceptor: Rejected") | ||||
|         return Promise.reject(error) | ||||
|     }) | ||||
| } | ||||
| */ | ||||
|  | ||||
| /* | ||||
| app.use(VueKeyCloak,{ | ||||
|     onReady: (keycloak) => { | ||||
|         console.log("Ready !") | ||||
|         tokenInterceptor() | ||||
|     }, | ||||
|     init: { | ||||
|         onLoad: 'login-required', | ||||
|         checkLoginIframe: false, | ||||
|  | ||||
|     }, | ||||
|  | ||||
|     config: { | ||||
|         realm: 'test', | ||||
|         url: 'http://localhost:7080', | ||||
|         clientId: 'myinpulse' | ||||
|     } | ||||
| }  ); | ||||
| */ | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| export { store }; | ||||
|   | ||||
							
								
								
									
										14
									
								
								front/MyINPulse-front/src/plugins/authStore.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								front/MyINPulse-front/src/plugins/authStore.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| // file: src/plugins/authStore.js | ||||
|  | ||||
| import { useAuthStore } from "@/stores/authStore.ts"; | ||||
| import keycloakService from '@/services/keycloak'; | ||||
| // Setup auth store as a plugin so it can be accessed globally in our FE | ||||
| const authStorePlugin = { | ||||
|     install(app: any, option: any) { | ||||
|         const store = useAuthStore(option.pinia); | ||||
|         app.config.globalProperties.$store = store; | ||||
|         keycloakService.CallInitStore(store); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export default authStorePlugin; | ||||
| @@ -1,17 +1,40 @@ | ||||
| import { createRouter, createWebHistory } from "vue-router"; | ||||
|  | ||||
| const router = createRouter({ | ||||
|     history: createWebHistory(import.meta.env.BASE_URL), | ||||
|     routes: [ | ||||
|         { | ||||
|             path: "/test", | ||||
|             name: "test", | ||||
|             // route level code-splitting | ||||
|             // this generates a separate chunk (About.[hash].js) for this route | ||||
|             // which is lazy-loaded when the route is visited. | ||||
|             component: () => import("../views/testComponent.vue"), | ||||
|         }, | ||||
|     ], | ||||
| }); | ||||
|   history: createWebHistory(import.meta.env.BASE_URL), | ||||
|   routes: [ | ||||
|     { | ||||
|       path: '/test', | ||||
|       name: 'test', | ||||
|       // route level code-splitting | ||||
|       // this generates a separate chunk (About.[hash].js) for this route | ||||
|       // which is lazy-loaded when the route is visited. | ||||
|       component: () => import('../views/testComponent.vue'), | ||||
|     }, | ||||
|     { | ||||
|       path: '/login', | ||||
|       name: 'login', | ||||
|       component: () => import('../components/LoginComponent.vue'), | ||||
|     }, | ||||
|     { | ||||
|       path: '/', | ||||
|       name: 'Admin-main', | ||||
|       component: () => import('../views/AdminMain.vue'), | ||||
|     }, | ||||
|  | ||||
| // route pour les canvas (made by adnane), in fact the two vue apps are separated for now   | ||||
|     { | ||||
|       path: '/canvas', | ||||
|       name: 'canvas', | ||||
|       component: () => import('../views/CanvasView.vue'), | ||||
|     }, | ||||
|  | ||||
|     { | ||||
|       path: '/signup', | ||||
|       name: 'signup', | ||||
|       component: () => import('../views/EntrepSignUp.vue'), | ||||
|     }, | ||||
|   ], | ||||
| }) | ||||
|  | ||||
| export default router; | ||||
|   | ||||
| @@ -65,4 +65,28 @@ function callApi( | ||||
|         ); | ||||
| } | ||||
|  | ||||
| export { callApi }; | ||||
| function postApi( | ||||
|     endpoint: string, | ||||
|     data: any, | ||||
|     onSuccessHandler?: (response: AxiosResponse) => void, | ||||
|     onErrorHandler?: (error: AxiosError) => void | ||||
| ): void { | ||||
|     axiosInstance | ||||
|         .post(endpoint, data) | ||||
|         .then(onSuccessHandler ?? defaultApiSuccessHandler) | ||||
|         .catch(onErrorHandler ?? defaultApiErrorHandler); | ||||
| } | ||||
|  | ||||
| function deleteApi( | ||||
|     endpoint: string, | ||||
|     onSuccessHandler?: (response: AxiosResponse) => void, | ||||
|     onErrorHandler?: (error: AxiosError) => void | ||||
| ): void { | ||||
|     axiosInstance | ||||
|         .delete(endpoint) | ||||
|         .then(onSuccessHandler ?? defaultApiSuccessHandler) | ||||
|         .catch(onErrorHandler ?? defaultApiErrorHandler); | ||||
| } | ||||
|  | ||||
|  | ||||
| export { axiosInstance, callApi, postApi, deleteApi }; | ||||
|   | ||||
| @@ -54,7 +54,7 @@ const useAuthStore = defineStore("storeAuth", { | ||||
|         async logout() { | ||||
|             try { | ||||
|                 await keycloakService.CallLogout( | ||||
|                     import.meta.env.VITE_APP_URL + "/test" | ||||
|                     import.meta.env.VITE_APP_URL + "/login" //redirect to login page instead of test... | ||||
|                 ); | ||||
|                 await this.clearUserData(); | ||||
|             } catch (error) { | ||||
|   | ||||
							
								
								
									
										139
									
								
								front/MyINPulse-front/src/views/AdminMain.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								front/MyINPulse-front/src/views/AdminMain.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| <template> | ||||
|     <Header /> | ||||
|     <error-wrapper></error-wrapper> | ||||
|     <div id="container">   | ||||
|       <div id="main"> | ||||
|         <h3> Projet en cours </h3> | ||||
|           <ProjectComp  | ||||
|             v-for="(project, index) in projects"  | ||||
|             :key="index" | ||||
|             :project-name="project.name" | ||||
|             :list-name="project.members" | ||||
|             :project-link="project.link" | ||||
|           /> | ||||
|  | ||||
|         <div id ="main"> | ||||
|           <h3> Projet en attente </h3> | ||||
|            | ||||
|           <PendingProjectComponent | ||||
|             v-for="( project, index) in pendingProjects" | ||||
|             :key="index" | ||||
|             :project-name="project.name" | ||||
|             :creation-date="project.creationDate" | ||||
|           /> | ||||
|         </div>  | ||||
|  | ||||
|          | ||||
|       </div>   | ||||
|        | ||||
|       <Agenda :project-r-d-v="rendezVous" /> | ||||
|     </div> | ||||
|     <AddProjectForm/> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref, onMounted } from "vue"; | ||||
| import { callApi } from "@/services/api"; | ||||
|  | ||||
| import Header from "../components/HeaderComponent.vue"; | ||||
| import Agenda from "../components/Agenda.vue"; | ||||
| import ProjectComp from "../components/ProjectComponent.vue"; | ||||
| import PendingProjectComponent from "@/components/PendingProjectComponent.vue"; | ||||
| import AddProjectForm from "@/components/AddProjectForm.vue"; | ||||
|  | ||||
| const PORT = "8081"; | ||||
| const URI = `http://localhost:${PORT}`; | ||||
|  | ||||
| //const projects = ref<{ name: string; link: string; members: string[] }[]>([]); | ||||
|  | ||||
| /* const fetchProjects = () => { | ||||
|   callApi( | ||||
|     `${URI}/admin/projects`, | ||||
|     async (response) => { | ||||
|       console.log(response); | ||||
|       const projectList = response.data; | ||||
|  | ||||
|       const projectPromises = projectList.map((project: any) => { | ||||
|         return new Promise(async (resolve) => { | ||||
|           callApi( | ||||
|             `${URI}/shared/projects/entrepreneurs/${project.idProject}`, | ||||
|             (memberResponse) => { | ||||
|               const members = memberResponse.data.map((m: any) => m.userName); | ||||
|               resolve({ | ||||
|                 name: project.projectName, | ||||
|                 link: `/project/${project.idProject}`, | ||||
|                 members, | ||||
|               }); | ||||
|             }, | ||||
|             () => { | ||||
|               // Error fetching members, still resolve with empty members | ||||
|               resolve({ | ||||
|                 name: project.projectName, | ||||
|                 link: `/project/${project.idProject}`, | ||||
|                 members: [], | ||||
|               }); | ||||
|             } | ||||
|           ); | ||||
|         }); | ||||
|       }); | ||||
|  | ||||
|       projects.value = await Promise.all(projectPromises); | ||||
|     }, | ||||
|     (error) => { | ||||
|       console.error("Error fetching projects:", error); | ||||
|     } | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| onMounted(fetchProjects); | ||||
|  */ | ||||
|  | ||||
|  | ||||
| const projects = ref([ | ||||
|   { | ||||
|     name: "Projet Alpha", | ||||
|     link: "/canvas", // to test | ||||
|     members: ["Alice", "Bob", "Charlie"], | ||||
|   }, | ||||
|   { | ||||
|     name: "Projet Beta", | ||||
|     link: "./canvas", // to test | ||||
|     members: ["David", "Eve", "Frank"], | ||||
|   }, | ||||
| ]); | ||||
|  | ||||
|  | ||||
| const pendingProjects = ref ([ | ||||
|   { name: "l'eau", creationDate: "26-02-2024" }, | ||||
|   { name: "l'air", creationDate: "09-03-2023" }, | ||||
| ]) | ||||
|  | ||||
| const rendezVous = ref([ | ||||
|   { projectName: "Projet Alpha", date: "2025-03-10", lieu: "P106" }, | ||||
|   { projectName: "Projet Beta", date: "2025-04-15", lieu: "Td10" }, | ||||
| ]); | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
|  | ||||
| #container { | ||||
|     margin: 0; | ||||
|     display: grid; | ||||
|     grid-template-columns: 3fr 1fr; /* Main body takes 3/4, agenda 1/4 */ | ||||
|     height: 100vh; /* Full viewport height */ | ||||
| } | ||||
|  | ||||
| button { | ||||
|   padding: 10px 15px; | ||||
|   background-color: #007bff; | ||||
|   color: white; | ||||
|   border: none; | ||||
|   cursor: pointer; | ||||
|   border-radius: 5px; | ||||
| } | ||||
| button:hover { | ||||
|   background-color: #0056b3; | ||||
| } | ||||
|  | ||||
| </style> | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user