agenda + parcourir

This commit is contained in:
Omar El Alaoui El Ismaili 2025-04-09 03:39:27 +02:00
parent 8d62ebf0af
commit 66338ee020

View File

@ -1,5 +1,10 @@
<template>
<div class="ade-agenda-container">
<!-- Import ICS -->
<div style="margin-bottom: 15px; text-align: center;">
<input type="file" @change="handleFileUpload" accept=".ics" />
</div>
<!-- Le tableau ADE en haut, inchangé -->
<table class="ade-table">
<thead>
@ -29,61 +34,40 @@
</thead>
<tbody>
<!-- Lignes pour les créneaux horaires -->
<tr v-for="(slot, slotIndex) in timeSlots" :key="slotIndex">
<td class="time-col">
{{ slot.start }} - {{ slot.end }}
</td>
<td class="time-col">{{ slot.start }} - {{ slot.end }}</td>
<td
v-for="(day, dayIndex) in daysOfWeek"
:key="dayIndex"
class="agenda-cell"
>
<!-- On affiche les events qui commencent pile sur ce créneau -->
<div
v-for="(evt, eIndex) in eventsForSlot(day, slot)"
:key="eIndex"
class="event-card"
:style="eventStyle(evt)"
>
<div class="event-title">
{{ evt.title }}
</div>
<div class="event-info">
{{ evt.start }} - {{ evt.end }}
</div>
<div class="event-title">{{ evt.title }}</div>
<div class="event-info">{{ evt.start }} - {{ evt.end }}</div>
</div>
</td>
</tr>
</tbody>
</table>
<!-- Barre d'onglets en bas, AVEC flèches gauche/droite -->
<div class="week-tabs">
<!-- Flèche "précédent" -->
<button
class="arrow-btn"
@click="prevPage"
:disabled="startIndex === 0"
>
</button>
<!-- Onglets affichés : seulement 'weeksToShow' semaines, via displayedWeeks -->
<button class="arrow-btn" @click="prevPage" :disabled="startIndex === 0"></button>
<button
v-for="(week, idx) in displayedWeeks"
:key="idx"
class="week-tab-button"
@click="goToWeek(week.monday)"
>
<!-- Affiche Sxx + JJ/MM, par ex. "S14 31/03" -->
S{{ week.isoWeek }} {{ formatDDMM(week.monday) }}
</button>
<!-- Flèche "suivant" -->
<button
class="arrow-btn"
@click="nextPage"
<button
class="arrow-btn"
@click="nextPage"
:disabled="startIndex + weeksToShow >= allWeeks.length"
>
@ -93,19 +77,15 @@
</template>
<script>
/**
* Calcule le numéro de semaine ISO pour une date donnée (1-53).
*/
function getIsoWeekNumber(date) {
const tempDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
const dayNum = tempDate.getUTCDay() || 7;
const dayNum = tempDate.getUTCDay() || 7;
tempDate.setUTCDate(tempDate.getUTCDate() + 4 - dayNum);
const yearStart = new Date(Date.UTC(tempDate.getUTCFullYear(), 0, 1));
return Math.ceil(((tempDate - yearStart) / 86400000 + 1) / 7);
}
function formatDate(dateObj) {
// "2025-04-01"
const yyyy = dateObj.getFullYear();
const mm = String(dateObj.getMonth() + 1).padStart(2, "0");
const dd = String(dateObj.getDate()).padStart(2, "0");
@ -115,12 +95,10 @@ function formatDate(dateObj) {
export default {
name: "AdeLikeAgenda",
data() {
const currentMonday = new Date(2025, 2, 31); // Lundi 31/03/2025
const currentMonday = new Date(2025, 2, 31);
return {
currentMonday,
resourceName: "El Alaoui El Ismaili Omar",
// Créneaux horaires
timeSlots: [
{ start: "08:00", end: "08:30" },
{ start: "08:30", end: "09:00" },
@ -147,102 +125,13 @@ export default {
{ start: "19:00", end: "19:30" },
{ start: "19:30", end: "20:00" },
],
// Exemples d'événements
events: [
{
day: "2025-03-31",
start: "09:30",
end: "10:40",
title: "Systèmes d'exploitation DS",
color: "#f44", // ex. rouge
},
{
day: "2025-03-31",
start: "10:40",
end: "11:15",
title: "Systèmes d'exploitation (suite)",
color: "#f44",
},
{
day: "2025-04-01",
start: "08:00",
end: "09:00",
title: "2A ESPAGNOL GPE 1",
color: "#f6f112",
},
{
day: "2025-04-01",
start: "09:00",
end: "10:10",
title: "Projet de Génie Logiciel",
color: "#ffe",
},
{
day: "2025-04-01",
start: "14:00",
end: "16:00",
title: "INFO ANGLAIS TOEIC",
color: "#0bc",
},
{
day: "2025-04-02",
start: "11:00",
end: "12:20",
title: "Intelligence artificielle",
color: "#ff7",
},
{
day: "2025-04-02",
start: "10:20",
end: "12:20",
title: "Projet Sys. exploitation",
color: "#f4a",
},
{
day: "2025-04-03",
start: "08:10",
end: "10:10",
title: "Projet de Réseaux",
color: "#aff",
},
{
day: "2025-04-04",
start: "14:00",
end: "16:00",
title: "Programmation Fonct.",
color: "#cca",
},
{
day: "2025-04-05",
start: "16:10",
end: "18:10",
title: "TD Intelligence Art.",
color: "#fa4",
},
{
day: "2025-04-06",
start: "13:00",
end: "14:00",
title: "À planifier",
color: "#ddd",
},
],
/* Tableau complet de semaines quon veut afficher dans la barre du bas. */
events: [],
allWeeks: [],
/* On affiche 7 semaines à la fois. */
weeksToShow: 7,
/* Index de la première semaine affichée dans la barre. */
startIndex: 0,
};
},
computed: {
/**
* daysOfWeek : 7 jours (lundidimanche) depuis currentMonday
*/
daysOfWeek() {
const result = [];
for (let i = 0; i < 7; i++) {
@ -252,88 +141,50 @@ export default {
}
return result;
},
/**
* isoWeekNumber : ex. 14 pour 31/03/2025.
*/
isoWeekNumber() {
return getIsoWeekNumber(this.currentMonday);
},
/**
* Les semaines réellement affichées dans la barre (7 à la fois).
*/
displayedWeeks() {
return this.allWeeks.slice(this.startIndex, this.startIndex + this.weeksToShow);
},
},
methods: {
/**
* Crée la liste allWeeks pour X semaines (par ex. 15),
* depuis la date initiale currentMonday.
*/
initWeeks() {
// On définit par ex. 15 semaines à partir de currentMonday
const totalCount = 15;
const baseDate = new Date(this.currentMonday);
// Pour s'assurer qu'on part du lundi "31/03/2025" dans allWeeks[0]
// (ou un autre point de départ si tu veux).
// Sinon, tu peux partir d'une autre date plus ancienne.
for (let i = 0; i < totalCount; i++) {
const temp = new Date(baseDate);
temp.setDate(baseDate.getDate() + i * 7);
this.allWeeks.push({
monday: temp,
isoWeek: getIsoWeekNumber(temp),
});
}
},
/**
* Retourne les événements (ou un seul) pour un jour + créneau.
*/
eventsForSlot(dayDate, slot) {
const dayStr = formatDate(dayDate);
const dayStr = formatDate(dayDate);
return this.events.filter(
(evt) => evt.day === dayStr && evt.start === slot.start
);
},
/**
* Style d'un event (couleur, etc.)
*/
eventStyle(evt) {
return {
backgroundColor: evt.color || "#cef",
};
},
/**
* Format "dd/mm/yyyy"
*/
formatDateShort(dateObj) {
const dd = String(dateObj.getDate()).padStart(2, "0");
const mm = String(dateObj.getMonth() + 1).padStart(2, "0");
const yyyy = dateObj.getFullYear();
return `${dd}/${mm}/${yyyy}`;
},
/**
* Format "JJ/MM" (sans l'année)
*/
formatDDMM(dateObj) {
const dd = String(dateObj.getDate()).padStart(2, "0");
const mm = String(dateObj.getMonth() + 1).padStart(2, "0");
return `${dd}/${mm}`;
},
/**
* Renvoie "Lundi", "Mardi", etc.
*/
weekdayLabel(dateObj) {
const dayIndex = dateObj.getDay();
const dayIndex = dateObj.getDay();
const labels = [
"Dimanche",
"Lundi",
@ -345,10 +196,6 @@ export default {
];
return labels[dayIndex];
},
/**
* Aller à la semaine week.monday dans le planning
*/
goToWeek(mondayDate) {
this.currentMonday = new Date(
mondayDate.getFullYear(),
@ -356,24 +203,69 @@ export default {
mondayDate.getDate()
);
},
/* Flèche gauche : on recule le startIndex si possible */
prevPage() {
if (this.startIndex > 0) {
this.startIndex--;
}
if (this.startIndex > 0) this.startIndex--;
},
nextPage() {
if (this.startIndex + this.weeksToShow < this.allWeeks.length) this.startIndex++;
},
/* Flèche droite : on avance le startIndex si on peut encore afficher plus */
nextPage() {
if (this.startIndex + this.weeksToShow < this.allWeeks.length) {
this.startIndex++;
// 💡 NOUVELLE MÉTHODE : lecture .ics
handleFileUpload(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
const content = e.target.result;
this.parseICS(content);
};
reader.readAsText(file);
},
parseICS(text) {
const lines = text.split(/\r?\n/);
let currentEvent = null;
const events = [];
for (const line of lines) {
if (line === "BEGIN:VEVENT") {
currentEvent = {};
} else if (line === "END:VEVENT") {
if (currentEvent) events.push(currentEvent);
currentEvent = null;
} else if (currentEvent) {
if (line.startsWith("DTSTART")) {
currentEvent.start = this.parseICSTime(line);
} else if (line.startsWith("DTEND")) {
currentEvent.end = this.parseICSTime(line);
} else if (line.startsWith("SUMMARY")) {
currentEvent.title = line.split(":")[1] || "Sans titre";
}
}
}
this.events = events.map((e) => ({
title: e.title,
day: e.start.date,
start: e.start.time,
end: e.end.time,
color: "#acf",
}));
},
parseICSTime(line) {
const match = line.match(/:(\d{8})T(\d{4})/);
if (!match) return { date: "", time: "" };
const dateStr = match[1];
const timeStr = match[2];
return {
date: `${dateStr.slice(0, 4)}-${dateStr.slice(4, 6)}-${dateStr.slice(6, 8)}`,
time: `${timeStr.slice(0, 2)}:${timeStr.slice(2, 4)}`,
};
},
},
/**
* Au montage, on initialise la liste allWeeks
*/
mounted() {
this.initWeeks();
},