agenda + parcourir
This commit is contained in:
parent
8d62ebf0af
commit
66338ee020
@ -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 qu’on 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 (lundi→dimanche) 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();
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user