Compare commits
No commits in common. "05a56dc022f5cce355b2fe2311977023e5d41382" and "be7381586162089572857c4d643f0bee3c407b8e" have entirely different histories.
05a56dc022
...
be73815861
@ -1,9 +1,9 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="">
|
<html lang="">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Vite App</title>
|
<title>Vite App</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -43,15 +43,6 @@ class SectionCell {
|
|||||||
set modificationDate(value: string | undefined) {
|
set modificationDate(value: string | undefined) {
|
||||||
this._modificationDate = value;
|
this._modificationDate = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
toPlainObject() {
|
|
||||||
return {
|
|
||||||
idSectionCell: this._idSectionCell,
|
|
||||||
sectionId: this._sectionId,
|
|
||||||
contentSectionCell: this._contentSectionCell,
|
|
||||||
modificationDate: this._modificationDate,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SectionCell;
|
export default SectionCell;
|
||||||
|
@ -6,32 +6,37 @@
|
|||||||
|
|
||||||
<template v-if="expanded">
|
<template v-if="expanded">
|
||||||
<div class="explain">
|
<div class="explain">
|
||||||
<p>{{ description }}</p>
|
<p>
|
||||||
|
{{ description }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="description-wrapper custom-flow">
|
<div class="description-wrapper custom-flow">
|
||||||
<div
|
<div
|
||||||
v-for="(desc, index) in currentDescriptions"
|
v-for="(desc, index) in currentDescriptions"
|
||||||
:key="desc.idSectionCell || index"
|
:key="index"
|
||||||
:class="[
|
:class="[
|
||||||
'section-bloc',
|
'section-bloc',
|
||||||
index % 2 === 0 ? 'from-left' : 'from-right',
|
index % 2 === 0 ? 'from-left' : 'from-right',
|
||||||
]"
|
]"
|
||||||
|
class="section-bloc"
|
||||||
>
|
>
|
||||||
<!-- ADMIN -------------------------------------------------------------------------------------------->
|
<!-- ADMIN -------------------------------------------------------------------------------------------->
|
||||||
|
|
||||||
<template v-if="IS_ADMIN">
|
<template v-if="IS_ADMIN">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p class="m-0">{{ desc.contentSectionCell }}</p>
|
<p class="m-0">{{ desc }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- ENTREP ------------------------------------------------------------------------------------------->
|
<!-- ENTREP ------------------------------------------------------------------------------------------->
|
||||||
<template v-else>
|
|
||||||
|
<template v-if="!IS_ADMIN">
|
||||||
<!-- Mode affichage -->
|
<!-- Mode affichage -->
|
||||||
<template v-if="!isEditing[index]">
|
<template v-if="!isEditing[index]">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p class="m-0">{{ desc.contentSectionCell }}</p>
|
<p class="m-0">{{ desc }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
<button
|
<button
|
||||||
@ -48,9 +53,7 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="edit-row">
|
<div class="edit-row">
|
||||||
<textarea
|
<textarea
|
||||||
v-model="
|
v-model="editedDescriptions[index]"
|
||||||
editedDescriptions[index].contentSectionCell
|
|
||||||
"
|
|
||||||
class="edit-input"
|
class="edit-input"
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
@ -71,7 +74,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<!---------------------------------------------------------------------------------------------------->
|
||||||
<template v-if="expanded">
|
<template v-if="expanded">
|
||||||
<div class="canvas-exit-hint">
|
<div class="canvas-exit-hint">
|
||||||
Cliquez n'importe où pour quitter le canvas (terminez
|
Cliquez n'importe où pour quitter le canvas (terminez
|
||||||
@ -84,10 +87,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, defineProps, onMounted } from "vue";
|
import { ref, defineProps, onMounted } from "vue";
|
||||||
import { getSectionCellsByDate } from "@/api_tmp.ts";
|
import axios from "axios";
|
||||||
import SectionCell from "@/ApiClasses/SectionCell.ts";
|
import { axiosInstance } from "@/services/api.ts";
|
||||||
import { addSectionCell } from "@/api_tmp.ts";
|
|
||||||
import type { AxiosResponse, AxiosError } from "axios";
|
const IS_MOCK_MODE = true;
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
projectId: number;
|
projectId: number;
|
||||||
@ -97,125 +100,86 @@ const props = defineProps<{
|
|||||||
isAdmin: number;
|
isAdmin: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const IS_MOCK_MODE = false;
|
|
||||||
const IS_ADMIN = props.isAdmin;
|
const IS_ADMIN = props.isAdmin;
|
||||||
|
|
||||||
const expanded = ref(false);
|
const expanded = ref(false);
|
||||||
const currentDescriptions = ref<SectionCell[]>([]);
|
const currentDescriptions = ref<string[]>([]);
|
||||||
const editedDescriptions = ref<SectionCell[]>([]);
|
currentDescriptions.value[0] = props.description;
|
||||||
|
const editedDescriptions = ref<string[]>([]);
|
||||||
const isEditing = ref<boolean[]>([]);
|
const isEditing = ref<boolean[]>([]);
|
||||||
|
|
||||||
function getCurrentFormattedDate(): string {
|
|
||||||
const now = new Date();
|
|
||||||
const year = now.getFullYear();
|
|
||||||
const month = String(now.getMonth() + 1).padStart(2, '0'); // +1 car janvier = 0
|
|
||||||
const day = String(now.getDate()).padStart(2, '0');
|
|
||||||
const hours = String(now.getHours()).padStart(2, '0');
|
|
||||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
|
||||||
|
|
||||||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchData(props.projectId, props.title, getCurrentFormattedDate(), IS_MOCK_MODE);
|
fetchData(props.projectId, props.title, "NaN", IS_MOCK_MODE);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fonctions
|
/* FOR LOCAL DATABASE
|
||||||
const startEditing = (index: number) => {
|
const fetchData = async () => {
|
||||||
isEditing.value[index] = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const cancelEdit = (index: number) => {
|
|
||||||
editedDescriptions.value[index].contentSectionCell =
|
|
||||||
currentDescriptions.value[index].contentSectionCell;
|
|
||||||
isEditing.value[index] = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveEdit = (index: number) => {
|
|
||||||
currentDescriptions.value[index].contentSectionCell =
|
|
||||||
editedDescriptions.value[index].contentSectionCell;
|
|
||||||
isEditing.value[index] = false;
|
|
||||||
|
|
||||||
if (!IS_MOCK_MODE){
|
|
||||||
addSectionCell(currentDescriptions.value[index],
|
|
||||||
(response) => {
|
|
||||||
console.log("Modification enregistrée avec succès :", response.data);
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.error("Erreur lors de l'enregistrement :", error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const handleClick = () => {
|
|
||||||
if (expanded.value) {
|
|
||||||
const editingInProgress = isEditing.value.some((edit) => edit);
|
|
||||||
if (!editingInProgress) {
|
|
||||||
expanded.value = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
expanded.value = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// fetchData
|
|
||||||
const handleFetchSuccess = (sectionCells: SectionCell[]) => {
|
|
||||||
currentDescriptions.value = sectionCells;
|
|
||||||
editedDescriptions.value = sectionCells.map(
|
|
||||||
(cell) => new SectionCell({
|
|
||||||
idSectionCell: cell.idSectionCell,
|
|
||||||
sectionId: cell.sectionId,
|
|
||||||
contentSectionCell: cell.contentSectionCell,
|
|
||||||
modificationDate: cell.modificationDate, })
|
|
||||||
);
|
|
||||||
isEditing.value = Array(sectionCells.length).fill(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFetchError = (error: unknown) => {
|
|
||||||
console.error("Erreur lors de la récupération des données :", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchData = async ( projectId: number, title: number, date: string, useMock = false ) => {
|
|
||||||
try {
|
try {
|
||||||
if (useMock) {
|
const response = await axios.get("http://localhost:5000/data"); // Met à jour l'URL
|
||||||
const responseData = await mockFetch(projectId, title, date);
|
if (response.data.length > 0) {
|
||||||
handleFetchSuccess(responseData);
|
currentDescription.value = response.data[0].canva_data;
|
||||||
|
editedDescription.value = response.data[0].canva_data;
|
||||||
} else {
|
} else {
|
||||||
await new Promise<void>((resolve, reject) => {
|
console.warn("Aucune donnée reçue.");
|
||||||
getSectionCellsByDate( projectId, title, date,
|
|
||||||
(response: AxiosResponse) => {
|
|
||||||
const data = response.data;
|
|
||||||
|
|
||||||
if (Array.isArray(data) && data.length > 0) {
|
|
||||||
const sectionCells = data.map((cellData) => new SectionCell({
|
|
||||||
idSectionCell: cellData.idSectionCell,
|
|
||||||
sectionId: cellData.sectionId,
|
|
||||||
contentSectionCell: cellData.contentSectionCell,
|
|
||||||
modificationDate:
|
|
||||||
cellData.modificationDate, })
|
|
||||||
);
|
|
||||||
handleFetchSuccess(sectionCells);
|
|
||||||
} else {
|
|
||||||
console.warn( "Aucune donnée reçue ou format inattendu :", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve();
|
|
||||||
},
|
|
||||||
(error: AxiosError) => {
|
|
||||||
handleFetchError(error);
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleFetchError(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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockFetch = async ( projectId: number, title: number, date: string ): Promise<SectionCell[]> => {
|
// Fonction de simulation de l'API
|
||||||
|
const mockFetch = async (projectId: number, title: number, date: string) => {
|
||||||
console.log(
|
console.log(
|
||||||
`Mock fetch pour projectId: ${projectId}, title: ${title}, date: ${date}`
|
`Mock fetch pour projectId: ${projectId}, title: ${title}, date: ${date}`
|
||||||
);
|
);
|
||||||
@ -269,16 +233,95 @@ const mockFetch = async ( projectId: number, title: number, date: string ): Prom
|
|||||||
// On extrait les descriptions pour la section demandée
|
// On extrait les descriptions pour la section demandée
|
||||||
const section = leanCanvasData[title] || ["Aucune donnée disponible."];
|
const section = leanCanvasData[title] || ["Aucune donnée disponible."];
|
||||||
|
|
||||||
// On crée des instances de SectionCell
|
// On garde tous les éléments, dans l'ordre
|
||||||
const result = section.map(
|
const result = section.map((txt) => ({ txt }));
|
||||||
(txt, index) => new SectionCell({ idSectionCell: index + 1, sectionId: title,
|
|
||||||
contentSectionCell: txt, modificationDate: date, })
|
|
||||||
);
|
|
||||||
|
|
||||||
return new Promise<SectionCell[]>((resolve) => {
|
return new Promise<{ txt: string }[]>((resolve) => {
|
||||||
setTimeout(() => resolve(result), 500);
|
setTimeout(() => resolve(result), 500);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
//FOR LOCAL HOST
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -154,6 +154,16 @@ const contactSingle = (email: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
const copyToClipboard = (email: string) => {
|
||||||
|
navigator.clipboard.writeText(email).then(() => {
|
||||||
|
alert(`Adresse copiée : ${email}`);
|
||||||
|
}).catch(err => {
|
||||||
|
console.error("Erreur lors de la copie :", err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
// Cacher le menu si on clique en dehors
|
// Cacher le menu si on clique en dehors
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
if (
|
if (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user