front_foundation #9
@ -1,63 +0,0 @@
|
|||||||
{
|
|
||||||
"entrepreneurs": [
|
|
||||||
{ "id": 1, "name": "Alice", "email": "alice@example.com" },
|
|
||||||
{ "id": 2, "name": "Bob", "email": "bob@example.com" },
|
|
||||||
{ "id": 3, "name": "Charlie", "email": "charlie@example.com" }
|
|
||||||
],
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 1,
|
|
||||||
"title_text": "1. Problème",
|
|
||||||
"description": "3 problèmes essentiels à résoudre pour le client"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 2,
|
|
||||||
"title_text": "2. Segments",
|
|
||||||
"description": "Les segments de clientèle visés"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 3,
|
|
||||||
"title_text": "3. Valeur",
|
|
||||||
"description": "La proposition de valeur"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 4,
|
|
||||||
"title_text": "4. Solution",
|
|
||||||
"description": "Les solutions proposées"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 5,
|
|
||||||
"title_text": "5. Avantage",
|
|
||||||
"description": "Les avantages concurrentiels"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 6,
|
|
||||||
"title_text": "6. Canaux",
|
|
||||||
"description": "Les canaux de distribution"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 7,
|
|
||||||
"title_text": "7. Indicateurs",
|
|
||||||
"description": "Les indicateurs clés de performance"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 8,
|
|
||||||
"title_text": "8. Coûts",
|
|
||||||
"description": "Les coûts associés"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectId": 1,
|
|
||||||
"title": 9,
|
|
||||||
"title_text": "9. Revenus",
|
|
||||||
"description": "Les sources de revenus"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
json-server --watch db.json --port 5000
|
|
@ -1,6 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<header>
|
<header>
|
||||||
<img src="./icons/logo inpulse.png" alt="INPulse" />
|
<a
|
||||||
|
href="https://www.bordeaux-inp.fr/fr/lincubateur-bordeaux-inpulse"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<img src="./icons/logo inpulse.png" alt="INPulse Logo" class="logo" />
|
||||||
|
</a>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { useRouter } from "vue-router";
|
|||||||
import { jwtDecode } from "jwt-decode"; // i hope this doesn't break the code later
|
import { jwtDecode } from "jwt-decode"; // i hope this doesn't break the code later
|
||||||
import { store } from "../main.ts";
|
import { store } from "../main.ts";
|
||||||
import { callApi } from "@/services/api.ts";
|
import { callApi } from "@/services/api.ts";
|
||||||
|
import Header from "@/components/HeaderComponent.vue";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
type TokenPayload = {
|
type TokenPayload = {
|
||||||
@ -43,6 +43,7 @@ const callApiWithLoading = async (path: string) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<Header />
|
||||||
<error-wrapper></error-wrapper>
|
<error-wrapper></error-wrapper>
|
||||||
<div class="auth-container">
|
<div class="auth-container">
|
||||||
<div class="auth-card">
|
<div class="auth-card">
|
||||||
|
@ -2,67 +2,72 @@
|
|||||||
<div :class="['cell', { expanded }]" @click="handleClick">
|
<div :class="['cell', { expanded }]" @click="handleClick">
|
||||||
<h3 class="fs-5 fw-medium">{{ titleText }}</h3>
|
<h3 class="fs-5 fw-medium">{{ titleText }}</h3>
|
||||||
|
|
||||||
<div
|
<div class="tooltip-explain">{{ description }}</div>
|
||||||
v-for="(desc, index) in currentDescriptions"
|
|
||||||
:key="index"
|
|
||||||
class="section-bloc"
|
|
||||||
>
|
|
||||||
<!-- ADMIN -------------------------------------------------------------------------------------------->
|
|
||||||
|
|
||||||
<template v-if="IS_ADMIN">
|
|
||||||
<div class="description">
|
|
||||||
<p class="m-0">{{ desc }}</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- ENTREP ------------------------------------------------------------------------------------------->
|
|
||||||
|
|
||||||
<template v-if="!IS_ADMIN">
|
|
||||||
<!-- Mode affichage -->
|
|
||||||
<template v-if="!isEditing[index]">
|
|
||||||
<div class="description">
|
|
||||||
<p class="m-0">{{ desc }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="button-container">
|
|
||||||
<button
|
|
||||||
v-if="expanded"
|
|
||||||
class="edit-button"
|
|
||||||
@click.stop="startEditing(index)"
|
|
||||||
>
|
|
||||||
Éditer
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- Mode édition -->
|
|
||||||
<template v-else>
|
|
||||||
<textarea
|
|
||||||
v-model="editedDescriptions[index]"
|
|
||||||
class="edit-input"
|
|
||||||
></textarea>
|
|
||||||
<div class="button-container">
|
|
||||||
<button
|
|
||||||
class="save-button"
|
|
||||||
@click.stop="saveEdit(index)"
|
|
||||||
>
|
|
||||||
Enregistrer
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="cancel-button"
|
|
||||||
@click.stop="cancelEdit(index)"
|
|
||||||
>
|
|
||||||
Annuler
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<!---------------------------------------------------------------------------------------------------->
|
|
||||||
<template v-if="expanded">
|
<template v-if="expanded">
|
||||||
<div class="canvas-exit-hint">
|
<div class="explain">
|
||||||
Cliquez n'importe où pour quitter le canvas
|
<p>
|
||||||
</div>
|
{{ description }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<div class="description-wrapper custom-flow">
|
||||||
|
<div
|
||||||
|
v-for="(desc, index) in currentDescriptions"
|
||||||
|
:key="index"
|
||||||
|
:class="['section-bloc', index % 2 === 0 ? 'from-left' : 'from-right']"
|
||||||
|
class="section-bloc"
|
||||||
|
>
|
||||||
|
<!-- ADMIN -------------------------------------------------------------------------------------------->
|
||||||
|
|
||||||
|
<template v-if="IS_ADMIN">
|
||||||
|
<div class="description">
|
||||||
|
<p class="m-0">{{ desc }}</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- ENTREP ------------------------------------------------------------------------------------------->
|
||||||
|
|
||||||
|
<template v-if="!IS_ADMIN">
|
||||||
|
<!-- Mode affichage -->
|
||||||
|
<template v-if="!isEditing[index]">
|
||||||
|
<div class="description">
|
||||||
|
<p class="m-0">{{ desc }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="button-container">
|
||||||
|
<button
|
||||||
|
v-if="expanded"
|
||||||
|
class="edit-button"
|
||||||
|
@click.stop="startEditing(index)"
|
||||||
|
>
|
||||||
|
Éditer
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Mode édition -->
|
||||||
|
<template v-else>
|
||||||
|
<div class="edit-row">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<!---------------------------------------------------------------------------------------------------->
|
||||||
|
<template v-if="expanded">
|
||||||
|
<div class="canvas-exit-hint">
|
||||||
|
Cliquez n'importe où pour quitter le canvas (terminez d'abord vos modifications)
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -165,24 +170,72 @@ const mockFetch = async (projectId: number, title: number, date: string) => {
|
|||||||
`Mock fetch pour projectId: ${projectId}, title: ${title}, date: ${date}`
|
`Mock fetch pour projectId: ${projectId}, title: ${title}, date: ${date}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const leanCanvasData: Record<number, string[]> = {
|
||||||
|
1: [
|
||||||
|
"Les clients ont du mal à trouver des produits écoresponsables abordables.",
|
||||||
|
"Le processus d'achat en ligne est trop complexe.",
|
||||||
|
"Manque de transparence sur l’origine des produits.",
|
||||||
|
"Peu d’alternatives locales et durables sur le marché."
|
||||||
|
],
|
||||||
|
2: [
|
||||||
|
"Jeunes urbains engagés dans la cause écologique.",
|
||||||
|
"Familles à revenu moyen voulant consommer responsable.",
|
||||||
|
"Entreprises soucieuses de leur empreinte carbone."
|
||||||
|
],
|
||||||
|
3: [
|
||||||
|
"Une plateforme centralisée avec des produits écologiques certifiés.",
|
||||||
|
"Un service client humain et réactif.",
|
||||||
|
"Livraison éco-responsable avec suivi."
|
||||||
|
],
|
||||||
|
4: [
|
||||||
|
"Application intuitive avec suggestions personnalisées.",
|
||||||
|
"Emballages recyclables et réutilisables.",
|
||||||
|
],
|
||||||
|
5: [
|
||||||
|
"Algorithme exclusif de recommandations durables.",
|
||||||
|
"Forte communauté engagée sur les réseaux.",
|
||||||
|
],
|
||||||
|
6: [
|
||||||
|
"Canaux digitaux : réseaux sociaux, SEO.",
|
||||||
adnane marked this conversation as resolved
Outdated
|
|||||||
|
"Partenariats avec influenceurs écoresponsables.",
|
||||||
|
"Boutique physique en pop-up stores."
|
||||||
|
],
|
||||||
adnane marked this conversation as resolved
Outdated
piair
commented
axios again axios again
piair
commented
And the path is not right And the path is not right
|
|||||||
|
7: [
|
||||||
|
"Taux de rétention client mensuel.",
|
||||||
|
"Taux de satisfaction utilisateur (NPS)."
|
||||||
|
],
|
||||||
|
8: [
|
||||||
|
"Coût du développement logiciel initial.",
|
||||||
|
"Campagnes publicitaires et communication.",
|
||||||
|
"Frais logistiques (emballages, transport)."
|
||||||
|
],
|
||||||
|
9: [
|
||||||
|
"Ventes directes sur la plateforme.",
|
||||||
|
"Abonnement mensuel premium pour livraison gratuite.",
|
||||||
|
"Revenus via partenariats de marque."
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// On extrait les descriptions pour la section demandée
|
||||||
|
const section = leanCanvasData[title] || ["Aucune donnée disponible."];
|
||||||
|
|
||||||
adnane marked this conversation as resolved
Outdated
piair
commented
same same
|
|||||||
|
// On garde tous les éléments, dans l'ordre
|
||||||
|
const result = section.map((txt) => ({ txt }));
|
||||||
|
|
||||||
return new Promise<{ txt: string }[]>((resolve) => {
|
return new Promise<{ txt: string }[]>((resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => resolve(result), 500);
|
||||||
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
|
// 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);
|
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];
|
||||||
editedDescriptions.value = [props.description];
|
editedDescriptions.value = [props.description];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,6 +309,20 @@ const cancelEdit = (index: number) => {
|
|||||||
editedDescriptions.value[index] = currentDescriptions.value[index];
|
editedDescriptions.value[index] = currentDescriptions.value[index];
|
||||||
isEditing.value[index] = false;
|
isEditing.value[index] = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const randomStyle = () => {
|
||||||
|
const offsetX = Math.floor(Math.random() * 20) - 10; // entre -10 et +10px
|
||||||
|
const offsetY = Math.floor(Math.random() * 20) - 10;
|
||||||
|
return {
|
||||||
|
transform: `translate(${offsetX}px, ${offsetY}px)`,
|
||||||
|
transition: 'transform 0.3s ease',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const styleClasses = ['float-up', 'float-left', 'float-right', 'wiggle', 'tilt'];
|
||||||
|
const getRandomClass = () => {
|
||||||
|
return styleClasses[Math.floor(Math.random() * styleClasses.length)];
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -276,6 +343,27 @@ const cancelEdit = (index: number) => {
|
|||||||
justify-content: flex-start !important;
|
justify-content: flex-start !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltip-explain {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 101%; /* au-dessus de la carte */
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
border-radius: 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell:not(.expanded):hover .tooltip-explain {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
.cell:not(.expanded):hover {
|
.cell:not(.expanded):hover {
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
box-shadow: 0 8px 9px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 8px 9px rgba(0, 0, 0, 0.2);
|
||||||
@ -309,16 +397,11 @@ const cancelEdit = (index: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
display: flex;
|
font-size: 5px;
|
||||||
align-items: center;
|
color: #333;
|
||||||
justify-content: center;
|
word-break: break-word;
|
||||||
text-align: center;
|
width: 90%;
|
||||||
width: 100%;
|
margin: 5px 0;
|
||||||
height: 100%;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-left: 2%;
|
|
||||||
margin-right: 4%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.description + .p {
|
.description + .p {
|
||||||
@ -330,14 +413,18 @@ const cancelEdit = (index: number) => {
|
|||||||
.edit-input {
|
.edit-input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
min-height: 100px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-left: 2%;
|
margin-left: 2%;
|
||||||
|
max-height: none;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.button-container {
|
.button-container {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
@ -347,7 +434,25 @@ const cancelEdit = (index: number) => {
|
|||||||
padding-right: 1%;
|
padding-right: 1%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-bloc,
|
.section-bloc {
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
font-family: "Arial", sans-serif;
|
||||||
|
color: #333;
|
||||||
|
word-break: break-word;
|
||||||
|
flex-shrink: 0;
|
||||||
|
cursor: default;
|
||||||
|
|
||||||
|
max-width: 100%;
|
||||||
|
width: fit-content;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.editing-section-bloc {
|
.editing-section-bloc {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -368,6 +473,10 @@ const cancelEdit = (index: number) => {
|
|||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.description p {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.save-button,
|
.save-button,
|
||||||
.cancel-button {
|
.cancel-button {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
@ -417,4 +526,86 @@ const cancelEdit = (index: number) => {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.description-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
max-height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
max-height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.custom-flow {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||||
|
grid-auto-rows: min-content;
|
||||||
|
grid-auto-flow: dense;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-up { transform: translateY(-10px); }
|
||||||
|
.float-left { transform: translateX(-10px); }
|
||||||
|
.float-right { transform: translateX(10px); }
|
||||||
|
.wiggle { transform: rotate(1deg); }
|
||||||
|
.tilt { transform: rotate(-1deg); }
|
||||||
|
|
||||||
|
.from-left {
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.from-right {
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-bloc.from-left {
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-bloc.from-right {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.explain {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #444; /* gris doux pour le texte */
|
||||||
|
background-color: #f9f9f9; /* fond léger pour contraster */
|
||||||
|
padding: 7px;
|
||||||
|
border-left: 4px solid #0d6efd; /* petite bande à gauche type "info" */
|
||||||
|
border-right: 4px solid #0d6efd;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-family: "Segoe UI", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
adnane marked this conversation as resolved
piair
commented
Doesn't this header overlap with the main app canvas ? Doesn't this header overlap with the main app canvas ?
|
|||||||
<header class="header">
|
<header class="header">
|
||||||
<img src="../icons/logo inpulse.png" alt="INPulse Logo" class="logo" />
|
<a
|
||||||
|
href="https://www.bordeaux-inp.fr/fr/lincubateur-bordeaux-inpulse"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
<img src="../icons/logo inpulse.png" alt="INPulse Logo" class="logo" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<div ref="dropdownRef" class="dropdown-wrapper">
|
<div ref="dropdownRef" class="dropdown-wrapper">
|
||||||
|
@ -112,16 +112,24 @@ onMounted(() => {
|
|||||||
|
|
||||||
.canvas {
|
.canvas {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(10, 1fr);
|
grid-template-columns: repeat(10, minmax(0, 1fr));
|
||||||
grid-template-rows: repeat(6, 1fr);
|
grid-auto-rows: min-content;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
/*background-color: #f8f9fa;*/
|
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 90vh;
|
height: auto; /* autorise la hauteur à s'ajuster selon le contenu */
|
||||||
overflow: auto;
|
max-height: none; /* enlève la limite de hauteur */
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: visible; /* autorise le débordement visible */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.canvas {
|
||||||
|
grid-template-columns: repeat(1, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.Probleme {
|
.Probleme {
|
||||||
grid-column: 1 / 3;
|
grid-column: 1 / 3;
|
||||||
grid-row: 1 / 5;
|
grid-row: 1 / 5;
|
||||||
@ -164,4 +172,33 @@ onMounted(() => {
|
|||||||
border: 1px solid #dee2e6;
|
border: 1px solid #dee2e6;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Probleme {
|
||||||
|
background-color: #ffdddd;
|
||||||
|
}
|
||||||
|
.Segments {
|
||||||
|
background-color: #ddffdd;
|
||||||
|
}
|
||||||
|
.Valeur {
|
||||||
|
background-color: #ddddff;
|
||||||
|
}
|
||||||
|
.Solution {
|
||||||
|
background-color: #fff0b3;
|
||||||
|
}
|
||||||
|
.Avantage {
|
||||||
|
background-color: #d1c4e9;
|
||||||
|
}
|
||||||
|
.Canaux {
|
||||||
|
background-color: #b2ebf2;
|
||||||
|
}
|
||||||
|
.Indicateurs {
|
||||||
|
background-color: #ffe082;
|
||||||
|
}
|
||||||
|
.Couts {
|
||||||
|
background-color: #ffcdd2;
|
||||||
|
}
|
||||||
|
.Revenus {
|
||||||
|
background-color: #c8e6c9;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<header>
|
<header>
|
||||||
<HeaderCanvas :project-id="1" />
|
<HeaderCanvas :project-id="1" />
|
||||||
@ -6,13 +7,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="page-title">PAGE CANVAS</h1>
|
<h1 class="page-title">PAGE CANVAS</h1>
|
||||||
|
|
||||||
<p class="canvas-help-text">
|
<p class="canvas-help-text">
|
||||||
Cliquez sur un champ du tableau pour afficher son contenu en détail
|
Cliquez sur un champ du tableau pour afficher son contenu en détail
|
||||||
ci-dessous.
|
ci-dessous.
|
||||||
</p>
|
</p>
|
||||||
<LeanCanvas :is-admin="isAdmin" />
|
<LeanCanvas :is-admin="isAdmin" />
|
||||||
|
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
<p>
|
<p>
|
||||||
Responsable :
|
Responsable :
|
||||||
@ -26,7 +25,7 @@
|
|||||||
<a href="tel:{{ admin.phoneNumber }}">{{
|
<a href="tel:{{ admin.phoneNumber }}">{{
|
||||||
admin.phoneNumber
|
admin.phoneNumber
|
||||||
}}</a>
|
}}</a>
|
||||||
</p>
|
</p> <div class="main"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -138,4 +137,13 @@ onMounted(() => {
|
|||||||
.info-box a:hover {
|
.info-box a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.canvas-help-text {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:last-child {
|
||||||
|
margin-bottom: 60px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user
Ce saveEdit utile étant donnée celle définie en dessous ?