Compare commits
2 Commits
front_test
...
ac19d33bdb
Author | SHA1 | Date | |
---|---|---|---|
ac19d33bdb | |||
3d4d5b90d1 |
@ -1,10 +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": [
|
|
||||||
{ "canva_data": "this is a fake data to test api" }
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
json-server --watch db.json --port 5000
|
|
@ -4,12 +4,47 @@ import ErrorWrapper from "@/views/errorWrapper.vue";
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<Header />
|
||||||
<Header />
|
<error-wrapper></error-wrapper>
|
||||||
<RouterLink to="/">Home</RouterLink> |
|
<div id="main">
|
||||||
<RouterLink to="/canvas">Canvas</RouterLink>
|
<ProjectComp
|
||||||
<RouterView />
|
v-for="(project, index) in projects"
|
||||||
|
: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>
|
@ -1,75 +0,0 @@
|
|||||||
<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,129 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div @click="goToLink" class="project">
|
<div 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 setup lang="ts">
|
<script lang="ts">
|
||||||
import { defineProps } from "vue";
|
export default {
|
||||||
import { useRouter } from 'vue-router'
|
name: 'Project',
|
||||||
|
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;
|
|
||||||
}
|
}
|
||||||
button:hover {
|
</script>
|
||||||
background-color: #0056b3;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -1,88 +0,0 @@
|
|||||||
<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>
|
|
@ -1,120 +0,0 @@
|
|||||||
<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>
|
|
@ -1,56 +0,0 @@
|
|||||||
<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>
|
|
@ -1,156 +0,0 @@
|
|||||||
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: 39 KiB After Width: | Height: | Size: 5.1 KiB |
@ -29,47 +29,6 @@ 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,19 +11,6 @@ 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'),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
<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>
|
|
@ -1,17 +0,0 @@
|
|||||||
<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) => {
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
// @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();
|
|
||||||
});
|
|
@ -1,123 +0,0 @@
|
|||||||
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