fix: with prettier
Some checks failed
Format / formatting (push) Successful in 6s
Build / build (push) Successful in 42s
CI / build (push) Failing after 10s
Format / formatting (pull_request) Successful in 5s

This commit is contained in:
Mohamed Maoulainine Maoulainine
2025-04-21 19:01:15 +02:00
parent e20556ed0f
commit c60fb8945b
17 changed files with 1414 additions and 1286 deletions

View File

@ -1,47 +1,69 @@
<template>
<div :class="['cell', { expanded }]" @click="handleClick">
<h3 class="fs-5 fw-medium">{{ titleText }}</h3>
<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">
<div
v-for="(desc, index) in currentDescriptions"
:key="index"
class="section-bloc"
>
<!-- ADMIN -------------------------------------------------------------------------------------------->
<!-- ADMIN -------------------------------------------------------------------------------------------->
<template v-if="IS_ADMIN">
<div class="description">
<p class="m-0">{{ desc }}</p>
</div>
</template>
<template v-if="IS_ADMIN">
<div class="description">
<p class="m-0">{{ desc }}</p>
<!-- 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>
<!-- 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 v-if="expanded">
<div class="canvas-exit-hint">
Cliquez n'importe où pour quitter le canvas
</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">
@ -49,14 +71,14 @@ import { ref, defineProps, onMounted } from "vue";
import axios from "axios";
import { axiosInstance } from "@/services/api.ts";
const IS_MOCK_MODE = true;
const IS_MOCK_MODE = true;
const props = defineProps<{
projectId: number;
title: number;
titleText: string;
description: string;
isAdmin: number;
projectId: number;
title: number;
titleText: string;
description: string;
isAdmin: number;
}>();
const IS_ADMIN = props.isAdmin;
@ -68,10 +90,9 @@ const editedDescriptions = ref<string[]>([]);
const isEditing = ref<boolean[]>([]);
onMounted(() => {
fetchData(props.projectId, props.title, "NaN", IS_MOCK_MODE);
fetchData(props.projectId, props.title, "NaN", IS_MOCK_MODE);
});
/* FOR LOCAL DATABASE
const fetchData = async () => {
try {
@ -111,59 +132,67 @@ const fetchData = async (projectId: number, title: number, date: string, useMock
*/
// 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;
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.");
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);
}
} 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}`);
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
});
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 (!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;
}
if (!isEditing.value.includes(true)) {
expanded.value = !expanded.value;
}
};
const startEditing = (index: number) => {
isEditing.value[index] = true;
isEditing.value[index] = true;
};
/*
@ -184,213 +213,208 @@ const saveEdit = async (index: number) => {
*/
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]
});
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);
// 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]}`);
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
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);
}
// 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;
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);
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;
justify-content: flex-start !important;
}
.cell:not(.expanded):hover {
transform: scale(1.05);
box-shadow: 0 8px 9px rgba(0, 0, 0, 0.2);
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;
font-size: 15px;
font-weight: 500;
font-family: "Arial", sans-serif;
}
.p {
font-size: 10px;
color: #666;
font-family: 'Arial', sans-serif;
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);
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%;
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;
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%;
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%;
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;
.section-bloc,
.editing-section-bloc {
width: 100%;
justify-content: center;
align-items: center;
display: flex;
margin-right: 10%;
margin: 10px;
}
.edit-button {
background-color: #007bff;
color: white;
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;
background-color: #28a745;
color: white;
}
.cancel-button {
background-color: #dc3545;
color: white;
background-color: #dc3545;
color: white;
}
.edit-button:hover {
background-color: #0056b3;
background-color: #0056b3;
}
.save-button:hover {
background-color: #218838;
background-color: #218838;
}
.cancel-button:hover {
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;
font-size: 0.75rem;
color: #666;
position: fixed;
bottom: 10px;
left: 0;
width: 100%;
text-align: center;
z-index: 1000;
}
</style>
</style>