Checkpoint: Correction du bug d'émargement formateur bloqué sur la saisie d'email
- Ajout de la détection automatique formateur/apprenant dans EmargementScan.tsx - Nouvelle procédure tRPC getSequenceByToken pour récupérer les infos de séquence - Interface adaptée selon le type d'utilisateur (apprenant ou formateur) - Déploiement réussi sur le VPS de production Le système détecte maintenant automatiquement si l'email correspond à un apprenant ou un formateur, et affiche l'interface appropriée pour chaque cas.
This commit is contained in:
@@ -1,177 +0,0 @@
|
||||
/**
|
||||
* Génération d'aperçus d'emails avec données réelles
|
||||
*/
|
||||
|
||||
import * as db from "./db";
|
||||
import { generateEmailFromTemplate } from "./emailTemplateGenerator";
|
||||
|
||||
export interface EmailPreviewParams {
|
||||
sequenceId: number;
|
||||
type: 'teaser' | 'rappel' | 'rappel_j1';
|
||||
apprenantId?: number; // Si non fourni, prendre le premier apprenant inscrit
|
||||
}
|
||||
|
||||
export async function generateEmailPreview(params: EmailPreviewParams): Promise<{
|
||||
html: string;
|
||||
subject: string;
|
||||
recipient: {
|
||||
email: string;
|
||||
nom: string;
|
||||
prenom: string;
|
||||
};
|
||||
}> {
|
||||
// Récupérer la séquence
|
||||
const sequence = await db.getSequenceById(params.sequenceId);
|
||||
if (!sequence) {
|
||||
throw new Error('Séquence non trouvée');
|
||||
}
|
||||
|
||||
// Récupérer la formation
|
||||
const formation = await db.getFormationById(sequence.formationId);
|
||||
if (!formation) {
|
||||
throw new Error('Formation non trouvée');
|
||||
}
|
||||
|
||||
// Récupérer les dates
|
||||
const dates = await db.getDatesBySequence(sequence.id);
|
||||
if (dates.length === 0) {
|
||||
throw new Error('Aucune date trouvée pour cette séquence');
|
||||
}
|
||||
|
||||
// Récupérer le formateur si disponible
|
||||
let formateurNom: string | undefined;
|
||||
if (sequence.formateurId) {
|
||||
const formateur = await db.getFormateurById(sequence.formateurId);
|
||||
formateurNom = formateur?.nom;
|
||||
}
|
||||
|
||||
// Récupérer un apprenant inscrit
|
||||
const inscriptions = await db.getInscriptionsBySequence(params.sequenceId);
|
||||
const confirmedInscriptions = inscriptions.filter(i => i.inscription.statut === 'confirmee' && i.apprenant);
|
||||
|
||||
if (confirmedInscriptions.length === 0) {
|
||||
throw new Error('Aucun apprenant confirmé trouvé pour cette séquence');
|
||||
}
|
||||
|
||||
// Utiliser l'apprenant spécifié ou le premier de la liste
|
||||
let selectedInscription = confirmedInscriptions[0];
|
||||
if (params.apprenantId) {
|
||||
const found = confirmedInscriptions.find(i => i.apprenant!.id === params.apprenantId);
|
||||
if (found) {
|
||||
selectedInscription = found;
|
||||
}
|
||||
}
|
||||
|
||||
const apprenant = selectedInscription.apprenant!;
|
||||
|
||||
// Préparer les données pour l'email
|
||||
const fonctionLabel = apprenant.fonction === 'directeur' ? 'Directeur' :
|
||||
apprenant.fonction === 'chef_service' ? 'Chef de service' : '';
|
||||
const salutation = fonctionLabel ? `${fonctionLabel} ${apprenant.prenom} ${apprenant.nom}` : apprenant.prenom;
|
||||
|
||||
const datesHTML = dates.map(date => `
|
||||
<div class="date-item">
|
||||
<strong>Date ${date.ordre} :</strong> ${new Date(date.dateDebut).toLocaleDateString('fr-FR', {
|
||||
weekday: 'long',
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
})}
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
// Générer le contenu selon le type
|
||||
let content: string;
|
||||
let subject: string;
|
||||
|
||||
if (params.type === 'teaser') {
|
||||
content = `
|
||||
<h2>Votre formation approche !</h2>
|
||||
<p>Bonjour ${salutation},</p>
|
||||
|
||||
<p>Nous sommes ravis de vous accueillir prochainement pour la formation <strong>${formation.nom}</strong>.</p>
|
||||
|
||||
<div class="info-box">
|
||||
<p><strong>Séquence :</strong> ${sequence.nom}</p>
|
||||
<h4>Dates :</h4>
|
||||
${datesHTML}
|
||||
${sequence.lieu ? `<p><strong>Lieu :</strong> ${sequence.lieu}</p>` : ''}
|
||||
${formateurNom ? `<p><strong>Formateur :</strong> ${formateurNom}</p>` : ''}
|
||||
</div>
|
||||
|
||||
<p>Préparez-vous à vivre une expérience enrichissante qui vous permettra de développer vos compétences managériales.</p>
|
||||
|
||||
<p>À très bientôt !</p>
|
||||
`;
|
||||
subject = `Votre formation ${formation.nom} approche !`;
|
||||
} else if (params.type === 'rappel') {
|
||||
// Rappel J-7
|
||||
content = `
|
||||
<h2>Rappel : Votre formation commence bientôt !</h2>
|
||||
<p>Bonjour ${salutation},</p>
|
||||
|
||||
<p>Nous vous rappelons que votre formation <strong>${formation.nom}</strong> commence dans une semaine.</p>
|
||||
|
||||
<div class="info-box">
|
||||
<p><strong>Séquence :</strong> ${sequence.nom}</p>
|
||||
<h4>Dates :</h4>
|
||||
${datesHTML}
|
||||
${sequence.lieu ? `<p><strong>Lieu :</strong> ${sequence.lieu}</p>` : ''}
|
||||
${formateurNom ? `<p><strong>Formateur :</strong> ${formateurNom}</p>` : ''}
|
||||
</div>
|
||||
|
||||
<p>N'oubliez pas d'apporter le matériel nécessaire et de vous présenter à l'heure indiquée.</p>
|
||||
|
||||
<p>À très bientôt !</p>
|
||||
`;
|
||||
subject = `Rappel J-7 : Formation ${formation.nom}`;
|
||||
} else {
|
||||
// Rappel J-1
|
||||
content = `
|
||||
<h2>Rappel : Votre formation commence demain !</h2>
|
||||
<p>Bonjour ${salutation},</p>
|
||||
|
||||
<p>Nous vous rappelons que votre formation <strong>${formation.nom}</strong> commence <strong>demain</strong>.</p>
|
||||
|
||||
<div class="info-box">
|
||||
<p><strong>Séquence :</strong> ${sequence.nom}</p>
|
||||
<h4>Dates :</h4>
|
||||
${datesHTML}
|
||||
${sequence.lieu ? `<p><strong>Lieu :</strong> ${sequence.lieu}</p>` : ''}
|
||||
${formateurNom ? `<p><strong>Formateur :</strong> ${formateurNom}</p>` : ''}
|
||||
</div>
|
||||
|
||||
<p><strong>Merci de vous présenter à l'heure indiquée.</strong></p>
|
||||
<p>N'oubliez pas d'apporter le matériel nécessaire.</p>
|
||||
|
||||
<p>À demain !</p>
|
||||
`;
|
||||
subject = `Rappel J-1 : Formation ${formation.nom} - C'est demain !`;
|
||||
}
|
||||
|
||||
// Préparer les variables
|
||||
const variables = {
|
||||
nomApprenant: apprenant.nom,
|
||||
prenomApprenant: apprenant.prenom,
|
||||
nomFormation: formation.nom,
|
||||
nomSequence: sequence.nom,
|
||||
dateDebut: new Date(dates[0].dateDebut).toLocaleDateString('fr-FR'),
|
||||
dateFin: new Date(dates[dates.length - 1].dateFin).toLocaleDateString('fr-FR'),
|
||||
datesHTML: datesHTML, // Ajouter le HTML des dates
|
||||
lieu: sequence.lieu || '',
|
||||
formateur: formateurNom || '',
|
||||
};
|
||||
|
||||
// Générer le HTML final avec le template
|
||||
const html = await generateEmailFromTemplate(params.type === 'teaser' ? 'teaser' : 'rappel', content, variables);
|
||||
|
||||
return {
|
||||
html,
|
||||
subject,
|
||||
recipient: {
|
||||
email: apprenant.email,
|
||||
nom: apprenant.nom,
|
||||
prenom: apprenant.prenom,
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user