front_foundation #5
@ -7,8 +7,8 @@ import ErrorWrapper from "@/views/errorWrapper.vue";
|
|||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
|
|||||||
<ErrorWrapper />
|
<ErrorWrapper />
|
||||||
<RouterLink to="/">Home</RouterLink> |
|
<!--<RouterLink to="/">Home</RouterLink> | -->
|
||||||
piair
commented
Vous êtes sur qu'il faut laisser ça, je pense que ça devrait être inclus dans RouterView Vous êtes sur qu'il faut laisser ça, je pense que ça devrait être inclus dans RouterView
|
|||||||
<RouterLink to="/canvas">Canvas</RouterLink>
|
<!--<RouterLink to="/canvas">Canvas</RouterLink> -->
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -35,9 +35,12 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!---------------------------------------------------------------------------------------------------->
|
<!---------------------------------------------------------------------------------------------------->
|
||||||
|
<template v-if="expanded">
|
||||||
|
<div class="canvas-exit-hint">
|
||||||
|
Cliquez n'importe où pour quitter le canvas
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -107,9 +110,9 @@ const mockFetch = async (projectId: number, title: number, date: string) => {
|
|||||||
return new Promise<{ txt: string }[]>((resolve) => {
|
return new Promise<{ txt: string }[]>((resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resolve([
|
resolve([
|
||||||
{ txt: "Ceci est une description 1 pour tester the damn front, Why are u still reading dumbass this is just some nonsense sentence XD" },
|
{txt: "Ceci est une description 1 pour tester le front. Franchement, si tu es encore en train de lire, c’est probablement que tu veux t'assurer que tout s’affiche bien même avec un texte bien long. Allez, encore quelques mots inutiles pour bien remplir la ligne et tester les retours à la ligne. Bravo champion."},
|
||||||
{ txt: "Ceci est une description 1 pour tester the damn front, Bruh are u still here?" },
|
{txt: "Deuxième description : elle est là pour t’aider à tester le comportement du composant avec du texte plus dense. Peut-être même avec quelques caractères spéciaux, tiens : éèàçù$#@! Et si on faisait semblant d’avoir du contenu sérieux ? Non, toujours pas."},
|
||||||
{ txt: "Ceci est une description 1 pour tester the damn front, .-. BRUH" }
|
{txt: "Troisième description, probablement inutile mais bon, on continue pour la forme. À ce stade, tu testes sûrement si le champ de texte peut supporter un pavé sans exploser. Spoiler alert : si t'as tout bien codé, ça devrait aller. Sinon, bah... débogue. Courage."}
|
||||||
]);
|
]);
|
||||||
}, 500); // Simule un délai réseau de 500ms
|
}, 500); // Simule un délai réseau de 500ms
|
||||||
});
|
});
|
||||||
@ -118,7 +121,7 @@ const mockFetch = async (projectId: number, title: number, date: string) => {
|
|||||||
// Utilisation du mock dans handleClick pour tester sans serveur
|
// Utilisation du mock dans handleClick pour tester sans serveur
|
||||||
const handleClick = async () => {
|
const handleClick = async () => {
|
||||||
if (!expanded.value) {
|
if (!expanded.value) {
|
||||||
await fetchData(props.projectId, props.title, "NaN", IS_MOCK_MODE); // true pour activer le mock
|
await fetchData(props.projectId, props.title, "NaN", IS_MOCK_MODE);
|
||||||
} else if (!isEditing.value.includes(true)) {
|
} else if (!isEditing.value.includes(true)) {
|
||||||
// Réinitialiser les descriptions si aucune édition n'est en cours
|
// Réinitialiser les descriptions si aucune édition n'est en cours
|
||||||
currentDescriptions.value = [props.description];
|
currentDescriptions.value = [props.description];
|
||||||
@ -152,7 +155,6 @@ const saveEdit = async (index: number) => {
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Utilisation de `mockSaveEdit` au lieu de `saveEdit` dans `handleClick` ou tout autre endroit
|
|
||||||
const saveEdit = async (index: number) => {
|
const saveEdit = async (index: number) => {
|
||||||
if (IS_MOCK_MODE) {
|
if (IS_MOCK_MODE) {
|
||||||
await mockSaveEdit(index);
|
await mockSaveEdit(index);
|
||||||
@ -175,10 +177,9 @@ const saveEdit = async (index: number) => {
|
|||||||
// Fonction de mock pour l'enregistrement
|
// Fonction de mock pour l'enregistrement
|
||||||
const mockSaveEdit = async (index: number) => {
|
const mockSaveEdit = async (index: number) => {
|
||||||
try {
|
try {
|
||||||
const id = index + 1; // À adapter selon l'ID réel des données
|
const id = index + 1;
|
||||||
console.log(`Mock save pour l'ID ${id} avec la description : ${editedDescriptions.value[index]}`);
|
console.log(`Mock save pour l'ID ${id} avec la description : ${editedDescriptions.value[index]}`);
|
||||||
|
|
||||||
// Simuler un délai d'enregistrement comme une requête réseau
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500)); // Simulation de délai réseau
|
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
|
// Mettre à jour l'affichage local après la mise à jour réussie
|
||||||
@ -198,6 +199,9 @@ const cancelEdit = (index: number) => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
@import "@/components/canvas/style-project.css";
|
@import "@/components/canvas/style-project.css";
|
||||||
|
|
||||||
|
#marque {
|
||||||
|
|
||||||
|
}
|
||||||
.cell {
|
.cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -221,7 +225,6 @@ const cancelEdit = (index: number) => {
|
|||||||
.cell h3 {
|
.cell h3 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
/*margin-bottom: 10px;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cell p {
|
.cell p {
|
||||||
@ -247,9 +250,9 @@ const cancelEdit = (index: number) => {
|
|||||||
|
|
||||||
.description {
|
.description {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center; /* Centre verticalement */
|
align-items: center;
|
||||||
justify-content: center; /* Centre horizontalement */
|
justify-content: center;
|
||||||
text-align: center; /* Centre le texte à l'intérieur */
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@ -344,4 +347,15 @@ const cancelEdit = (index: number) => {
|
|||||||
background-color: #c82333;
|
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>
|
</style>
|
@ -1,19 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<header>
|
<header class="header">
|
||||||
<img src="../icons/logo inpulse.png" alt="INPulse Logo">
|
<img src="../icons/logo inpulse.png" alt="INPulse Logo" class="logo" />
|
||||||
<div class="header-buttons">
|
|
||||||
<div class="menu">
|
<div class="header-actions">
|
||||||
|
<div class="dropdown-wrapper">
|
||||||
<button class="contact-button" @click="toggleDropdown">Contact</button>
|
<button class="contact-button" @click="toggleDropdown">Contact</button>
|
||||||
<div class="contact-dropdown" v-bind:class="{ 'dropdown-visible': isDropdownOpen }">
|
<div class="contact-dropdown" :class="{ 'dropdown-visible': isDropdownOpen }">
|
||||||
<button @click="contactAll">Contact All</button>
|
<button @click="contactAll">Contacter tous</button>
|
||||||
<button v-for="(email, index) in entrepreneurEmails" :key="index">
|
<button v-for="(email, index) in entrepreneurEmails" :key="index">
|
||||||
{{ email }}
|
{{ email }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
mohamed_maoulainine marked this conversation as resolved
Outdated
piair
commented
plutôt utiliser des routerLink au lieu de href plutôt utiliser des routerLink au lieu de href
https://stackoverflow.com/questions/52675885/when-to-use-router-link-vs-a
|
|||||||
<button class="return-button">
|
|
||||||
<RouterLink to="/">Return to list project</RouterLink>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<RouterLink to="/" class="return-button">Retour</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
@ -23,76 +23,138 @@
|
|||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
const IS_MOCK_MODE = true;
|
||||||
|
|
||||||
mohamed_maoulainine marked this conversation as resolved
Outdated
piair
commented
Vérifier que le type de données renvoyé par le backend correspond bien à ca (ce n'est pas le cas). Vérifier que le type de données renvoyé par le backend correspond bien à ca (ce n'est pas le cas).
|
|||||||
|
const props = defineProps<{
|
||||||
|
projectId: number;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
type Entrepreneur = {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
primaryMail: string;
|
||||||
|
};
|
||||||
|
|
||||||
mohamed_maoulainine marked this conversation as resolved
Outdated
piair
commented
il faut pas Hardcoder une addresse, elle est dans le fichier .env. Dans tout les cas, cette adresse ne devrait pas être là. il faut pas Hardcoder une addresse, elle est dans le fichier .env. Dans tout les cas, cette adresse ne devrait pas être là.
piair
commented
je viens de voir le message de commit, c'est en effet logique d'utiliser cette donnée. Par contre je suis pas sur que ce soit la bonne méthode pour faire des tests, c'est a discuter. Il serait bien d'appeler mock-data au lieu de fake-data je viens de voir le message de commit, c'est en effet logique d'utiliser cette donnée. Par contre je suis pas sur que ce soit la bonne méthode pour faire des tests, c'est a discuter.
Il serait bien d'appeler mock-data au lieu de fake-data
|
|||||||
const isDropdownOpen = ref(false);
|
const isDropdownOpen = ref(false);
|
||||||
const entrepreneurEmails = ref([]);
|
const entrepreneurEmails = ref([]);
|
||||||
|
|
||||||
const toggleDropdown = () => {
|
const toggleDropdown = () => {
|
||||||
isDropdownOpen.value = !isDropdownOpen.value;
|
isDropdownOpen.value = !isDropdownOpen.value;
|
||||||
console.log("Dropdown toggled:", isDropdownOpen.value); // for debug purposes
|
console.log("Dropdown toggled:", isDropdownOpen.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchEntrepreneurs = async () => {
|
|
||||||
|
const fetchEntrepreneurs = async (projectId :number, useMock = IS_MOCK_MODE) => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get("http://localhost:5000/entrepreneurs");
|
const responseData = useMock
|
||||||
entrepreneurEmails.value = response.data.map((e: { email: string }) => e.email);
|
? await mockFetchEntrepreneurs(projectId)
|
||||||
|
: (await axios.get(`http://localhost:5000/shared/projects/entrepreneurs/${projectId}`)).data;
|
||||||
|
|
||||||
|
if (responseData.length > 0) {
|
||||||
|
entrepreneurEmails.value = responseData.map((item) => item.primaryMail);
|
||||||
|
} else {
|
||||||
|
console.warn("Aucun entrepreneur trouvé.");
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Erreur lors de la récupération des entrepreneurs:", 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 contactAll = () => {
|
||||||
alert("Contacter tous les entrepreneurs : " + entrepreneurEmails.value.join(", "));
|
alert("Contacter tous les entrepreneurs : " + entrepreneurEmails.value.join(", "));
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(fetchEntrepreneurs);
|
onMounted(() => fetchEntrepreneurs(props.projectId, IS_MOCK_MODE));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@import "@/components/canvas/style-project.css";
|
@import "@/components/canvas/style-project.css";
|
||||||
|
|
||||||
header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
padding: 10px;
|
padding: 15px 30px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-buttons {
|
.logo {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu {
|
.contact-button,
|
||||||
display: flex;
|
.return-button {
|
||||||
flex-direction: column;
|
background-color: #009CDE;
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-button, .return-button {
|
|
||||||
background-color: #000;
|
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 10px;
|
padding: 10px 15px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-align: center;
|
border-radius: 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.return-button a {
|
.return-button:hover,
|
||||||
color: white;
|
.contact-button:hover {
|
||||||
text-decoration: none;
|
background-color: #007bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-dropdown {
|
.contact-dropdown {
|
||||||
display: none;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: white;
|
top: 100%;
|
||||||
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
|
left: 0;
|
||||||
|
background-color: #000;
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0px 4px 8px rgba(255, 255, 255, 0.2);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
|
min-width: 200px;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-dropdown button {
|
.contact-dropdown button {
|
||||||
@ -103,18 +165,17 @@ header {
|
|||||||
border: none;
|
border: none;
|
||||||
background: none;
|
background: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-dropdown button:hover {
|
.contact-dropdown button:hover {
|
||||||
background-color: #f0f0f0;
|
background-color: #009CDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-visible {
|
.contact-dropdown.dropdown-visible {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
header img {
|
|
||||||
width: 100px;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user
Il faut laisser ça, cela permet d'afficher les messages d'erreurs par desssus le contenu.