Checkpoint: Ajout d'un éditeur de texte riche (React Quill) pour formater facilement le contenu des emails (gras, italique, listes, couleurs, liens). Ajout de 7 boutons pour insérer rapidement des variables dynamiques : {{nomApprenant}}, {{prenomApprenant}}, {{nomFormation}}, {{nomSequence}}, {{dateDebut}}, {{lieu}}, {{formateur}}. La prévisualisation affiche le contenu HTML formaté en temps réel.

This commit is contained in:
Manus Sandbox
2025-11-23 15:36:56 -05:00
parent 3de0e39350
commit e16bdb22a1
4 changed files with 305 additions and 10 deletions

View File

@@ -1,4 +1,6 @@
import { useState, useEffect } from "react";
import { useState, useEffect, useRef } from "react";
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import { trpc } from "@/lib/trpc";
import DashboardLayout from "@/components/DashboardLayout";
import { Button } from "@/components/ui/button";
@@ -20,7 +22,7 @@ import {
SelectValue,
} from "@/components/ui/select";
import { toast } from "sonner";
import { Mail, Eye, Save, RotateCcw } from "lucide-react";
import { Mail, Eye, Save, RotateCcw, Plus } from "lucide-react";
export default function AdminEmailTemplates() {
const [selectedType, setSelectedType] = useState<string>("inscription");
@@ -311,15 +313,96 @@ export default function AdminEmailTemplates() {
<div>
<Label htmlFor="bodyContent">Corps du message</Label>
<Textarea
id="bodyContent"
value={formData.bodyContent}
onChange={(e) => setFormData({ ...formData, bodyContent: e.target.value })}
placeholder="Contenu principal de l'email...\n\nVous pouvez utiliser des variables : {{nomApprenant}}, {{nomFormation}}, {{nomSequence}}, etc."
rows={8}
/>
{/* Boutons de variables dynamiques */}
<div className="flex flex-wrap gap-2 mb-2">
<Button
type="button"
variant="outline"
size="sm"
onClick={() => setFormData({ ...formData, bodyContent: formData.bodyContent + '{{nomApprenant}}' })}
>
<Plus className="h-3 w-3 mr-1" />
Nom apprenant
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => setFormData({ ...formData, bodyContent: formData.bodyContent + '{{prenomApprenant}}' })}
>
<Plus className="h-3 w-3 mr-1" />
Prénom apprenant
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => setFormData({ ...formData, bodyContent: formData.bodyContent + '{{nomFormation}}' })}
>
<Plus className="h-3 w-3 mr-1" />
Nom formation
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => setFormData({ ...formData, bodyContent: formData.bodyContent + '{{nomSequence}}' })}
>
<Plus className="h-3 w-3 mr-1" />
Nom séquence
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => setFormData({ ...formData, bodyContent: formData.bodyContent + '{{dateDebut}}' })}
>
<Plus className="h-3 w-3 mr-1" />
Date début
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => setFormData({ ...formData, bodyContent: formData.bodyContent + '{{lieu}}' })}
>
<Plus className="h-3 w-3 mr-1" />
Lieu
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => setFormData({ ...formData, bodyContent: formData.bodyContent + '{{formateur}}' })}
>
<Plus className="h-3 w-3 mr-1" />
Formateur
</Button>
</div>
{/* Éditeur WYSIWYG */}
<div className="border rounded-md">
<ReactQuill
theme="snow"
value={formData.bodyContent}
onChange={(value) => setFormData({ ...formData, bodyContent: value })}
placeholder="Contenu principal de l'email...\n\nVous pouvez utiliser des variables : {{nomApprenant}}, {{nomFormation}}, {{nomSequence}}, etc."
modules={{
toolbar: [
[{ 'header': [1, 2, 3, false] }],
['bold', 'italic', 'underline', 'strike'],
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'color': [] }, { 'background': [] }],
['link'],
['clean']
]
}}
style={{ minHeight: '200px' }}
/>
</div>
<p className="text-xs text-muted-foreground mt-1">
Le contenu du corps du message. Laissez vide pour utiliser le contenu par défaut.
Le contenu du corps du message. Utilisez les boutons ci-dessus pour insérer des variables dynamiques.
</p>
</div>