Compare commits
	
		
			21 Commits
		
	
	
		
			eed4e6f855
			...
			front_test
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a1322c64ca | |||
| 8394bf02f2 | |||
| 
						 | 
					f48b570494 | ||
| 
						 | 
					0733f8d5af | ||
| 
						 | 
					8071c01c5d | ||
| 4ee3d9bc44 | |||
| d75d45e204 | |||
| 
						 | 
					9f3754776f | ||
| 651fb2b1a1 | |||
| 
						 | 
					aa5988ce75 | ||
| 
						 | 
					9ae18e1e4b | ||
| 22ebb0e1f4 | |||
| 09e4b3262f | |||
| 6a3d4239ab | |||
| 9d71c93b5b | |||
| 
						 | 
					5145b833ae | ||
| 
						 | 
					4080cee818 | ||
| 
						 | 
					f4d73654d1 | ||
| 4fda5513a9 | |||
| 32407b0e8f | |||
| b30e1196f4 | 
							
								
								
									
										10
									
								
								front/MyINPulse-front/fake_data/db.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								front/MyINPulse-front/fake_data/db.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "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": [
 | 
				
			||||||
 | 
					      { "canva_data": "this is a fake data to test api" }
 | 
				
			||||||
 | 
					  ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										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
 | 
				
			||||||
@@ -4,47 +4,12 @@ import ErrorWrapper from "@/views/errorWrapper.vue";
 | 
				
			|||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <Header />
 | 
					
 | 
				
			||||||
  <error-wrapper></error-wrapper>
 | 
					<Header />
 | 
				
			||||||
  <div id="main">
 | 
					    <RouterLink to="/">Home</RouterLink> |
 | 
				
			||||||
      <ProjectComp 
 | 
					    <RouterLink to="/canvas">Canvas</RouterLink>
 | 
				
			||||||
        v-for="(project, index) in projects" 
 | 
					    <RouterView />
 | 
				
			||||||
        :key="index"
 | 
					 | 
				
			||||||
        :projectName="project.name"
 | 
					 | 
				
			||||||
      />
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  <RouterView />
 | 
					 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style scoped>
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					 | 
				
			||||||
import Header from "@/components/Header.vue";
 | 
					 | 
				
			||||||
import ProjectComp from "@/components/Project-comp.vue";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  name: 'App',
 | 
					 | 
				
			||||||
  components: {
 | 
					 | 
				
			||||||
    Header,
 | 
					 | 
				
			||||||
    ProjectComp,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  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>
 | 
					 | 
				
			||||||
							
								
								
									
										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>
 | 
				
			||||||
@@ -1,18 +1,129 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div class="project">
 | 
					    <div @click="goToLink" class="project">
 | 
				
			||||||
        <div class="project-header">
 | 
					        <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>
 | 
				
			||||||
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
export default {
 | 
					import { defineProps } from "vue";
 | 
				
			||||||
    name: 'Project',
 | 
					import { useRouter } from 'vue-router'
 | 
				
			||||||
    props: {
 | 
					
 | 
				
			||||||
        projectName: String,
 | 
					
 | 
				
			||||||
    }
 | 
					const props = defineProps<{
 | 
				
			||||||
 | 
					    projectName: string;
 | 
				
			||||||
 | 
					    listName: string[];
 | 
				
			||||||
 | 
					    projectLink: string;
 | 
				
			||||||
 | 
					}>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const goToLink = () => {
 | 
				
			||||||
 | 
					  if (props.projectLink) {
 | 
				
			||||||
 | 
					    router.push(props.projectLink);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					  button:hover {
 | 
				
			||||||
 | 
					    background-color: #0056b3;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										88
									
								
								front/MyINPulse-front/src/components/canvas/CanvasItem.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								front/MyINPulse-front/src/components/canvas/CanvasItem.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div :class="['cell', { expanded }]"
 | 
				
			||||||
 | 
					    @click="toggleExpand"
 | 
				
			||||||
 | 
					    :style="{ justifyContent: expanded ? 'flex-start' : 'center' }"> <!-- Looking for finding a way 
 | 
				
			||||||
 | 
					                                                          to make this style in the toggleExpand event -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <h3>{{ title }}</h3>
 | 
				
			||||||
 | 
					      <p>{{ currentDescription }}</p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { ref, defineProps, onMounted } from "vue";
 | 
				
			||||||
 | 
					import axios from "axios";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps<{  
 | 
				
			||||||
 | 
					    title: string;
 | 
				
			||||||
 | 
					    description: string;
 | 
				
			||||||
 | 
					}>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const expanded = ref(false);
 | 
				
			||||||
 | 
					const currentDescription = ref(props.description);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const fetchData = async () => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const response = await axios.get("http://localhost:5000/data"); // Update the URL if needed
 | 
				
			||||||
 | 
					    currentDescription.value = response.data[0].canva_data;
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.error("Erreur lors de la récupération des données :", error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const toggleExpand = async () => {
 | 
				
			||||||
 | 
					  if (!expanded.value) {
 | 
				
			||||||
 | 
					    await fetchData();
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    currentDescription.value = props.description;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  expanded.value = !expanded.value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.cell:not(.expanded):hover {
 | 
				
			||||||
 | 
					  transform: scale(1.05);
 | 
				
			||||||
 | 
					  box-shadow: 0 8px 9px rgba(0, 0, 0, 0.2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.cell h3 {
 | 
				
			||||||
 | 
					    font-size: 20px;
 | 
				
			||||||
 | 
					    font-weight: 500;
 | 
				
			||||||
 | 
					    /*margin-bottom: 10px;*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.cell p {
 | 
				
			||||||
 | 
					    font-size: 14px;
 | 
				
			||||||
 | 
					    color: #666;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.expanded {
 | 
				
			||||||
 | 
					  position: fixed;
 | 
				
			||||||
 | 
						top: 0;
 | 
				
			||||||
 | 
						left: 0;
 | 
				
			||||||
 | 
						width: 100%;
 | 
				
			||||||
 | 
						height: 100%;
 | 
				
			||||||
 | 
						background: white;
 | 
				
			||||||
 | 
						z-index: 10;
 | 
				
			||||||
 | 
						display: flex;
 | 
				
			||||||
 | 
						align-items: center;
 | 
				
			||||||
 | 
						justify-content: center;
 | 
				
			||||||
 | 
						box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										120
									
								
								front/MyINPulse-front/src/components/canvas/HeaderCanvas.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								front/MyINPulse-front/src/components/canvas/HeaderCanvas.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <header>
 | 
				
			||||||
 | 
					    <img src="../icons/logo inpulse.png" alt="INPulse Logo">
 | 
				
			||||||
 | 
					    <div class="header-buttons">
 | 
				
			||||||
 | 
					      <div class="menu">
 | 
				
			||||||
 | 
					        <button class="contact-button" @click="toggleDropdown">Contact</button>
 | 
				
			||||||
 | 
					        <div class="contact-dropdown" v-bind:class="{ 'dropdown-visible': isDropdownOpen }">
 | 
				
			||||||
 | 
					          <button @click="contactAll">Contact All</button>
 | 
				
			||||||
 | 
					          <button v-for="(email, index) in entrepreneurEmails" :key="index">
 | 
				
			||||||
 | 
					            {{ email }}
 | 
				
			||||||
 | 
					          </button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <button class="return-button">
 | 
				
			||||||
 | 
					            <RouterLink to="/">Return to list project</RouterLink>
 | 
				
			||||||
 | 
					        </button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </header>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					import { ref, onMounted } from "vue";
 | 
				
			||||||
 | 
					import axios from "axios";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const isDropdownOpen = ref(false);
 | 
				
			||||||
 | 
					const entrepreneurEmails = ref([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const toggleDropdown = () => {
 | 
				
			||||||
 | 
					  isDropdownOpen.value = !isDropdownOpen.value;
 | 
				
			||||||
 | 
					  console.log("Dropdown toggled:", isDropdownOpen.value); // for debug purposes
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const fetchEntrepreneurs = async () => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const response = await axios.get("http://localhost:5000/entrepreneurs");
 | 
				
			||||||
 | 
					    entrepreneurEmails.value = response.data.map(e => e.email);
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.error("Erreur lors de la récupération des entrepreneurs:", error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const contactAll = () => {
 | 
				
			||||||
 | 
					  alert("Contacter tous les entrepreneurs : " + entrepreneurEmails.value.join(", "));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(fetchEntrepreneurs);
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					@import "@/components/canvas/style-project.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					header {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: space-between;
 | 
				
			||||||
 | 
					  align-items: flex-start;
 | 
				
			||||||
 | 
					  padding: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.header-buttons {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: flex-start;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.menu {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					  gap: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.contact-button, .return-button {
 | 
				
			||||||
 | 
					  background-color: #000;
 | 
				
			||||||
 | 
					  color: white;
 | 
				
			||||||
 | 
					  border: none;
 | 
				
			||||||
 | 
					  padding: 10px;
 | 
				
			||||||
 | 
					  cursor: pointer;
 | 
				
			||||||
 | 
					  font-size: 14px;
 | 
				
			||||||
 | 
					  text-align: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.return-button a {
 | 
				
			||||||
 | 
					  color: white;
 | 
				
			||||||
 | 
					  text-decoration: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.contact-dropdown {
 | 
				
			||||||
 | 
					  display: none;
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  background-color: white;
 | 
				
			||||||
 | 
					  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
 | 
				
			||||||
 | 
					  border-radius: 8px;
 | 
				
			||||||
 | 
					  padding: 10px;
 | 
				
			||||||
 | 
					  margin-top: 5px;
 | 
				
			||||||
 | 
					  z-index: 1000;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.contact-dropdown button {
 | 
				
			||||||
 | 
					  display: block;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  padding: 5px;
 | 
				
			||||||
 | 
					  text-align: left;
 | 
				
			||||||
 | 
					  border: none;
 | 
				
			||||||
 | 
					  background: none;
 | 
				
			||||||
 | 
					  cursor: pointer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.contact-dropdown button:hover {
 | 
				
			||||||
 | 
					  background-color: #f0f0f0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.dropdown-visible {
 | 
				
			||||||
 | 
					  display: block;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					header img {
 | 
				
			||||||
 | 
					  width: 100px;
 | 
				
			||||||
 | 
					  height: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										56
									
								
								front/MyINPulse-front/src/components/canvas/LeanCanvas.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								front/MyINPulse-front/src/components/canvas/LeanCanvas.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="canvas">
 | 
				
			||||||
 | 
					    <CanvasItem
 | 
				
			||||||
 | 
					      v-for="(item, index) in items"
 | 
				
			||||||
 | 
					      :key="index"
 | 
				
			||||||
 | 
					      :title="item.title"
 | 
				
			||||||
 | 
					      :description="item.description"
 | 
				
			||||||
 | 
					      :class="item.class"
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { ref } from "vue";
 | 
				
			||||||
 | 
					import CanvasItem from "@/components/canvas/CanvasItem.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const items = ref([
 | 
				
			||||||
 | 
					  { title: "1. Problème", description: "3 problèmes essentiels à résoudre pour le client", class: "Probleme" },
 | 
				
			||||||
 | 
					  { title: "2. Segments", description: "Les segments de clientèle visés", class: "Segments" },
 | 
				
			||||||
 | 
					  { title: "3. Valeur", description: "La proposition de valeur", class: "Valeur" },
 | 
				
			||||||
 | 
					  { title: "4. Solution", description: "Les solutions proposées", class: "Solution" },
 | 
				
			||||||
 | 
					  { title: "5. Avantage", description: "Les avantages concurrentiels", class: "Avantage" },
 | 
				
			||||||
 | 
					  { title: "6. Canaux", description: "Les canaux de distribution", class: "Canaux" },
 | 
				
			||||||
 | 
					  { title: "7. Indicateurs", description: "Les indicateurs clés de performance", class: "Indicateurs" },
 | 
				
			||||||
 | 
					  { title: "8. Coûts", description: "Les coûts associés", class: "Couts" },
 | 
				
			||||||
 | 
					  { title: "9. Revenus", description: "Les sources de revenus", class: "Revenus" }
 | 
				
			||||||
 | 
					]);
 | 
				
			||||||
 | 
					</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: 10px;
 | 
				
			||||||
 | 
					  padding: 10px;
 | 
				
			||||||
 | 
					  max-width: 1200px;
 | 
				
			||||||
 | 
					  margin: 20px auto;
 | 
				
			||||||
 | 
					  background-color: #fff; 
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  height: 80vh;
 | 
				
			||||||
 | 
					  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; }
 | 
				
			||||||
 | 
					</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  | 
@@ -29,6 +29,47 @@ keycloakService.CallInit(() => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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'
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}  );
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,19 @@ const router = createRouter({
 | 
				
			|||||||
      // which is lazy-loaded when the route is visited.
 | 
					      // which is lazy-loaded when the route is visited.
 | 
				
			||||||
      component: () => import('../views/test.vue'),
 | 
					      component: () => import('../views/test.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'),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										68
									
								
								front/MyINPulse-front/src/views/AdminMain.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								front/MyINPulse-front/src/views/AdminMain.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <Header />
 | 
				
			||||||
 | 
					    <error-wrapper></error-wrapper>
 | 
				
			||||||
 | 
					    <div id="container"> 
 | 
				
			||||||
 | 
					      <div id="main">
 | 
				
			||||||
 | 
					          <ProjectComp 
 | 
				
			||||||
 | 
					            v-for="(project, index) in projects" 
 | 
				
			||||||
 | 
					            :key="index"
 | 
				
			||||||
 | 
					            :projectName="project.name"
 | 
				
			||||||
 | 
					            :listName="project.members"
 | 
				
			||||||
 | 
					            :projectLink="project.link"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					      <Agenda :projectRDV="rendezVous" />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import Header from '../components/Header.vue';
 | 
				
			||||||
 | 
					import Agenda from "../components/Agenda.vue"
 | 
				
			||||||
 | 
					import ProjectComp from '../components/Project-comp.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { ref } from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 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>
 | 
				
			||||||
							
								
								
									
										17
									
								
								front/MyINPulse-front/src/views/CanvasView.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								front/MyINPulse-front/src/views/CanvasView.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <header>
 | 
				
			||||||
 | 
					        <HeaderCanvas />
 | 
				
			||||||
 | 
					      </header>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      <h1>Page Canvas</h1>
 | 
				
			||||||
 | 
					      <LeanCanvas />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import HeaderCanvas from '../components/canvas/HeaderCanvas.vue';
 | 
				
			||||||
 | 
					import LeanCanvas from '../components/canvas/LeanCanvas.vue';
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
@@ -3,7 +3,7 @@ import {store} from "../main.ts";
 | 
				
			|||||||
import {callApi} from "@/services/api.ts";
 | 
					import {callApi} from "@/services/api.ts";
 | 
				
			||||||
import ErrorModal from "@/components/errorModal.vue";
 | 
					import ErrorModal from "@/components/errorModal.vue";
 | 
				
			||||||
import {errorList} from "@/services/popupDisplayer.ts";
 | 
					import {errorList} from "@/services/popupDisplayer.ts";
 | 
				
			||||||
import TempModal from "@/components/temp-modal.vue";
 | 
					//import TempModal from "@/components/temp-modal.vue";
 | 
				
			||||||
import ErrorWrapper from "@/App.vue";
 | 
					import ErrorWrapper from "@/App.vue";
 | 
				
			||||||
function addResToTable(id: any){
 | 
					function addResToTable(id: any){
 | 
				
			||||||
  return (req: any) => {
 | 
					  return (req: any) => {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								tests/example.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								tests/example.spec.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					// @ts-check
 | 
				
			||||||
 | 
					import { test, expect } from '@playwright/test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('has title', async ({ page }) => {
 | 
				
			||||||
 | 
					  await page.goto('https://playwright.dev/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Expect a title "to contain" a substring.
 | 
				
			||||||
 | 
					  await expect(page).toHaveTitle(/Playwright/);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('get started link', async ({ page }) => {
 | 
				
			||||||
 | 
					  await page.goto('https://playwright.dev/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Click the get started link.
 | 
				
			||||||
 | 
					  await page.getByRole('link', { name: 'Get started' }).click();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Expects page to have a heading with the name of Installation.
 | 
				
			||||||
 | 
					  await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										123
									
								
								tests/front.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								tests/front.spec.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					import { test,expect } from '@playwright/test'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('Title Page',async({page}) =>{
 | 
				
			||||||
 | 
					    await page.goto('http://localhost:5173/')
 | 
				
			||||||
 | 
					    await expect(page).toHaveTitle(/Vite App/)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('Navigation between pages', async ({ page }) => {
 | 
				
			||||||
 | 
					  // Aller à la page d'accueil
 | 
				
			||||||
 | 
					  await page.goto('http://localhost:5173/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Vérifier que l'URL a changé pour la page Canvas
 | 
				
			||||||
 | 
					  await page.click('text=Canvas');
 | 
				
			||||||
 | 
					  await expect(page).toHaveURL(/canvas/);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Vérifier que l'URL a changé pour la page Home
 | 
				
			||||||
 | 
					  await page.click('text=Home');
 | 
				
			||||||
 | 
					  await expect(page).toHaveURL(/\//);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					test.describe('Tests de la Page Canvas', () => {
 | 
				
			||||||
 | 
					test('Vérifier que tous les blocs Canvas sont affichés', async ({ page }) => {
 | 
				
			||||||
 | 
					  // Aller à la page Canvas
 | 
				
			||||||
 | 
					  await page.goto('http://localhost:5173/canvas');
 | 
				
			||||||
 | 
					  await expect(page.locator('h1')).toHaveText('Page Canvas');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const sections = [
 | 
				
			||||||
 | 
					        '1. Problème', '2. Segments', '3. Valeur', '4. Solution',
 | 
				
			||||||
 | 
					        '5. Avantage', '6. Canaux', '7. Indicateurs', '8. Coûts', '9. Revenus'
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (const section of sections) {
 | 
				
			||||||
 | 
					        await expect(page.locator(`text=${section}`)).toBeVisible();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('Vérifier le contenu de la page Canvas', async ({ page }) => {
 | 
				
			||||||
 | 
					  await page.goto('http://localhost:5173/canvas');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Attendre le chargement des éléments
 | 
				
			||||||
 | 
					  await page.waitForSelector('.canvas');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Vérifier le titre
 | 
				
			||||||
 | 
					  await expect(page.locator('h1')).toHaveText('Page Canvas');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Nouveau sélecteur plus précis
 | 
				
			||||||
 | 
					  const canvasItems = page.locator('.canvas > div'); // Sélectionne les div directes dans .canvas
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Vérifier le nombre d'éléments
 | 
				
			||||||
 | 
					  await expect(canvasItems).toHaveCount(9);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Contenu attendu
 | 
				
			||||||
 | 
					  const expectedContent = [
 | 
				
			||||||
 | 
					    { title: '1. Problème', description: '3 problèmes essentiels à résoudre pour le client' },
 | 
				
			||||||
 | 
					    { title: '2. Segments', description: 'Les segments de clientèle visés' },
 | 
				
			||||||
 | 
					    { title: '3. Valeur', description: 'La proposition de valeur' },
 | 
				
			||||||
 | 
					    { title: '4. Solution', description: 'Les solutions proposées' },
 | 
				
			||||||
 | 
					    { title: '5. Avantage', description: 'Les avantages concurrentiels' },
 | 
				
			||||||
 | 
					    { title: '6. Canaux', description: 'Les canaux de distribution' },
 | 
				
			||||||
 | 
					    { title: '7. Indicateurs', description: 'Les indicateurs clés de performance' },
 | 
				
			||||||
 | 
					    { title: '8. Coûts', description: 'Les coûts associés' },
 | 
				
			||||||
 | 
					    { title: '9. Revenus', description: 'Les sources de revenus' }
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Vérifier chaque élément
 | 
				
			||||||
 | 
					  for (let i = 0; i < expectedContent.length; i++) {
 | 
				
			||||||
 | 
					    const item = canvasItems.nth(i);
 | 
				
			||||||
 | 
					    await expect(item.locator('h3')).toHaveText(expectedContent[i].title);
 | 
				
			||||||
 | 
					    await expect(item.locator('p')).toHaveText(expectedContent[i].description);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test.describe('Tests de la page Home', () => {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  test('Vérifier la présence des projets', async ({ page }) => {
 | 
				
			||||||
 | 
					      await page.goto('http://localhost:5173');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Vérifier les titres des projets avec getByRole pour éviter les doublons
 | 
				
			||||||
 | 
					      await expect(page.getByRole('heading', { name: 'Projet Alpha' })).toBeVisible();
 | 
				
			||||||
 | 
					      await expect(page.getByRole('heading', { name: 'Projet Beta' })).toBeVisible();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  test('Vérifier les membres des projets', async ({ page }) => {
 | 
				
			||||||
 | 
					      await page.goto('http://localhost:5173');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const membresAlpha = ['Alice', 'Bob', 'Charlie'];
 | 
				
			||||||
 | 
					      const membresBeta = ['David', 'Eve', 'Frank'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (const membre of membresAlpha) {
 | 
				
			||||||
 | 
					          await expect(page.getByText(membre)).toBeVisible();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      for (const membre of membresBeta) {
 | 
				
			||||||
 | 
					          await expect(page.getByText(membre)).toBeVisible();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  test('Vérifier les boutons Contact', async ({ page }) => {
 | 
				
			||||||
 | 
					      await page.goto('http://localhost:5173');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Vérifier que les boutons "Contact" existent et sont visibles
 | 
				
			||||||
 | 
					      const contactButtons = await page.locator('button:has-text("Contact")').count();
 | 
				
			||||||
 | 
					      expect(contactButtons).toBe(2); // Vérifie qu'il y a bien 2 boutons Contact
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  test('Vérifier la table des rendez-vous', async ({ page }) => {
 | 
				
			||||||
 | 
					      await page.goto('http://localhost:5173');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await expect(page.getByRole('heading', { name: 'Rendez-vous' })).toBeVisible();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Vérifier la première ligne du tableau
 | 
				
			||||||
 | 
					      await expect(page.locator('table').getByRole('cell', { name: 'Projet Alpha' })).toBeVisible();
 | 
				
			||||||
 | 
					      await expect(page.getByText('2025-03-10')).toBeVisible();
 | 
				
			||||||
 | 
					      await expect(page.getByText('P106')).toBeVisible();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Vérifier la deuxième ligne du tableau
 | 
				
			||||||
 | 
					      await expect(page.locator('table').getByRole('cell', { name: 'Projet Beta' })).toBeVisible();
 | 
				
			||||||
 | 
					      await expect(page.getByText('2025-04-15')).toBeVisible();
 | 
				
			||||||
 | 
					      await expect(page.getByText('Td10')).toBeVisible();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
		Reference in New Issue
	
	Block a user