Files
2026-02-02 17:32:58 -05:00

110 lines
3.3 KiB
TypeScript

/**
* Module de génération de fichiers ICS (iCalendar) pour les invitations Outlook
*/
interface ICSEvent {
summary: string;
description?: string;
location: string;
startDate: Date;
endDate: Date;
attendeeEmail: string;
attendeeName: string;
organizerEmail?: string;
organizerName?: string;
}
/**
* Formate une date au format iCalendar (YYYYMMDDTHHMMSSZ)
*/
function formatICSDate(date: Date): string {
const year = date.getUTCFullYear();
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
const day = String(date.getUTCDate()).padStart(2, '0');
const hours = String(date.getUTCHours()).padStart(2, '0');
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
const seconds = String(date.getUTCSeconds()).padStart(2, '0');
return `${year}${month}${day}T${hours}${minutes}${seconds}Z`;
}
/**
* Génère un UID unique pour l'événement
*/
function generateUID(): string {
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}@itinova.com`;
}
/**
* Échappe les caractères spéciaux pour le format ICS
*/
function escapeICS(text: string): string {
return text
.replace(/\\/g, '\\\\')
.replace(/;/g, '\\;')
.replace(/,/g, '\\,')
.replace(/\n/g, '\\n');
}
/**
* Génère un fichier ICS pour une invitation Outlook
*/
export function generateICS(event: ICSEvent): string {
const now = new Date();
const uid = generateUID();
const icsContent = [
'BEGIN:VCALENDAR',
'VERSION:2.0',
'PRODID:-//Itinova//Formation Manager//FR',
'CALSCALE:GREGORIAN',
'METHOD:REQUEST',
'BEGIN:VEVENT',
`UID:${uid}`,
`DTSTAMP:${formatICSDate(now)}`,
`DTSTART:${formatICSDate(event.startDate)}`,
`DTEND:${formatICSDate(event.endDate)}`,
`SUMMARY:${escapeICS(event.summary)}`,
event.description ? `DESCRIPTION:${escapeICS(event.description)}` : '',
`LOCATION:${escapeICS(event.location)}`,
'STATUS:CONFIRMED',
'TRANSP:OPAQUE', // Marque comme "occupé" dans le calendrier
'SEQUENCE:0',
`ORGANIZER;CN=${escapeICS(event.organizerName || 'Formation Itinova')}:mailto:${event.organizerEmail || 'formation@itinova.com'}`,
`ATTENDEE;CN=${escapeICS(event.attendeeName)};RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:${event.attendeeEmail}`,
'BEGIN:VALARM',
'TRIGGER:-P1D', // Rappel 1 jour avant
'ACTION:DISPLAY',
`DESCRIPTION:Rappel: ${escapeICS(event.summary)}`,
'END:VALARM',
'END:VEVENT',
'END:VCALENDAR',
].filter(line => line !== '').join('\r\n');
return icsContent;
}
/**
* Génère un fichier ICS pour une session de formation
*/
export function generateFormationICS(params: {
formationNom: string;
sessionNom: string;
dateDebut: Date;
dateFin: Date;
lieu: string;
apprenantNom: string;
apprenantPrenom: string;
apprenantEmail: string;
}): string {
return generateICS({
summary: `Formation: ${params.formationNom} - ${params.sessionNom}`,
description: `Vous êtes inscrit à la formation "${params.formationNom}".\n\nSession: ${params.sessionNom}\n\nMerci de vous présenter à l'heure indiquée.`,
location: params.lieu,
startDate: params.dateDebut,
endDate: params.dateFin,
attendeeEmail: params.apprenantEmail,
attendeeName: `${params.apprenantPrenom} ${params.apprenantNom}`,
});
}