Checkpoint: Réorganisation complète de la modal des rappels : largeur optimisée (50vw), labels et champs sur une seule ligne horizontale pour Configuration générale et Timing d'envoi, pièces jointes compactes avec icône et textes alignés, 4 zones colorées distinctes, espacement optimisé pour écran 24 pouces
This commit is contained in:
@@ -116,28 +116,25 @@ export function FileUpload({ value, onChange, accept, maxSize = 10, label = "Pi
|
||||
|
||||
{!value && !uploading ? (
|
||||
<label className="block">
|
||||
<div className="relative border-2 border-dashed rounded-xl p-6 text-center cursor-pointer transition-all duration-300 ease-in-out border-gray-300 bg-gray-50 hover:border-blue-400 hover:bg-blue-50">
|
||||
<div className="space-y-3">
|
||||
<div className="mx-auto w-14 h-14 bg-gradient-to-br from-blue-100 to-purple-100 rounded-full flex items-center justify-center">
|
||||
<FileText className="w-7 h-7 text-blue-600" />
|
||||
<div className="relative border-2 border-dashed rounded-xl p-4 cursor-pointer transition-all duration-300 ease-in-out border-gray-300 bg-gray-50 hover:border-blue-400 hover:bg-blue-50">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-12 h-12 bg-gradient-to-br from-blue-100 to-purple-100 rounded-full flex items-center justify-center flex-shrink-0">
|
||||
<FileText className="w-6 h-6 text-blue-600" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-gray-700 mb-1">
|
||||
Cliquez pour choisir un fichier
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-gray-700">
|
||||
Cliquez pour choisir un fichier <span className="text-xs text-gray-500 font-normal">ou glissez-déposez</span>
|
||||
</p>
|
||||
<p className="text-xs text-gray-500">
|
||||
ou glissez-déposez votre fichier ici
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center justify-center gap-2 text-xs text-gray-400">
|
||||
{accept && (
|
||||
<span className="px-2 py-1 bg-white rounded-full border border-gray-200">
|
||||
{accept}
|
||||
<div className="flex items-center gap-2 text-xs text-gray-400 mt-1">
|
||||
{accept && (
|
||||
<span className="px-2 py-0.5 bg-white rounded-full border border-gray-200">
|
||||
{accept}
|
||||
</span>
|
||||
)}
|
||||
<span className="px-2 py-0.5 bg-white rounded-full border border-gray-200">
|
||||
Max {maxSize} Mo
|
||||
</span>
|
||||
)}
|
||||
<span className="px-2 py-1 bg-white rounded-full border border-gray-200">
|
||||
Max {maxSize} Mo
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -586,7 +586,7 @@ export default function AdminRappels() {
|
||||
|
||||
{/* Dialog de création */}
|
||||
<Dialog open={isCreateOpen} onOpenChange={setIsCreateOpen}>
|
||||
<DialogContent className="max-w-2xl">
|
||||
<DialogContent className="!max-w-[2000px] w-[50vw]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Créer un nouveau rappel</DialogTitle>
|
||||
<DialogDescription>
|
||||
@@ -594,104 +594,116 @@ export default function AdminRappels() {
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="templateType">Template d'email utilisé *</Label>
|
||||
<Select
|
||||
value={formData.templateType}
|
||||
onValueChange={handleTemplateTypeChange}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Sélectionnez un type de rappel" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{TEMPLATE_TYPES.map((template) => (
|
||||
<SelectItem key={template.value} value={template.value}>
|
||||
{template.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Le template d'email correspondant sera utilisé pour l'envoi
|
||||
</p>
|
||||
</div>
|
||||
{/* Zone 1: Template + Nom + Rappel actif */}
|
||||
<div className="border-l-4 border-blue-500 pl-4 py-2 bg-blue-50/50 rounded-r">
|
||||
<h3 className="text-sm font-semibold text-blue-700 mb-2">Configuration générale</h3>
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="flex items-center gap-2 flex-1">
|
||||
<Label htmlFor="templateType" className="whitespace-nowrap">Template *</Label>
|
||||
<Select
|
||||
value={formData.templateType}
|
||||
onValueChange={handleTemplateTypeChange}
|
||||
>
|
||||
<SelectTrigger className="flex-1">
|
||||
<SelectValue placeholder="Sélectionnez un type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{TEMPLATE_TYPES.map((template) => (
|
||||
<SelectItem key={template.value} value={template.value}>
|
||||
{template.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="nom">Nom du rappel *</Label>
|
||||
<Input
|
||||
id="nom"
|
||||
value={formData.nom}
|
||||
onChange={(e) => setFormData({ ...formData, nom: e.target.value })}
|
||||
placeholder="Ex: Rappel automatique J-7"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 flex-1">
|
||||
<Label htmlFor="nom" className="whitespace-nowrap">Nom *</Label>
|
||||
<Input
|
||||
id="nom"
|
||||
value={formData.nom}
|
||||
onChange={(e) => setFormData({ ...formData, nom: e.target.value })}
|
||||
placeholder="Ex: Rappel J-7"
|
||||
className="flex-1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>Timing d'envoi *</Label>
|
||||
<div className="flex gap-4">
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="timing"
|
||||
value="pre_formation"
|
||||
checked={formData.timing === "pre_formation"}
|
||||
onChange={(e) => setFormData({ ...formData, timing: e.target.value as "pre_formation" | "post_formation" })}
|
||||
className="w-4 h-4"
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
id="actif"
|
||||
checked={formData.actif}
|
||||
onCheckedChange={(checked) => setFormData({ ...formData, actif: checked })}
|
||||
/>
|
||||
<span>Pré-formation</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="timing"
|
||||
value="post_formation"
|
||||
checked={formData.timing === "post_formation"}
|
||||
onChange={(e) => setFormData({ ...formData, timing: e.target.value as "pre_formation" | "post_formation" })}
|
||||
className="w-4 h-4"
|
||||
/>
|
||||
<span>Post-formation</span>
|
||||
</label>
|
||||
<Label htmlFor="actif" className="cursor-pointer whitespace-nowrap">Rappel actif</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="joursAvant">
|
||||
{formData.timing === "pre_formation"
|
||||
? "Nombre de jours avant la séquence *"
|
||||
: "Nombre de jours après la séquence *"}
|
||||
</Label>
|
||||
<Input
|
||||
id="joursAvant"
|
||||
type="number"
|
||||
min="1"
|
||||
value={formData.joursAvant}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, joursAvant: parseInt(e.target.value) || 1 })
|
||||
}
|
||||
placeholder="Ex: 7"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{formData.timing === "pre_formation"
|
||||
? "Le rappel sera envoyé ce nombre de jours avant le début de la séquence"
|
||||
: "Le rappel sera envoyé ce nombre de jours après la fin de la séquence"}
|
||||
</p>
|
||||
{/* Zone 2: Timing d'envoi */}
|
||||
<div className="border-l-4 border-green-500 pl-4 py-2 bg-green-50/50 rounded-r">
|
||||
<h3 className="text-sm font-semibold text-green-700 mb-2">Timing d'envoi</h3>
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<Label className="whitespace-nowrap">Type *</Label>
|
||||
<div className="flex gap-4">
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="timing"
|
||||
value="pre_formation"
|
||||
checked={formData.timing === "pre_formation"}
|
||||
onChange={(e) => setFormData({ ...formData, timing: e.target.value as "pre_formation" | "post_formation" })}
|
||||
className="w-4 h-4"
|
||||
/>
|
||||
<span>Pré-formation</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="timing"
|
||||
value="post_formation"
|
||||
checked={formData.timing === "post_formation"}
|
||||
onChange={(e) => setFormData({ ...formData, timing: e.target.value as "pre_formation" | "post_formation" })}
|
||||
className="w-4 h-4"
|
||||
/>
|
||||
<span>Post-formation</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 flex-1">
|
||||
<Label htmlFor="joursAvant" className="whitespace-nowrap">
|
||||
{formData.timing === "pre_formation" ? "Jours avant *" : "Jours après *"}
|
||||
</Label>
|
||||
<Input
|
||||
id="joursAvant"
|
||||
type="number"
|
||||
min="1"
|
||||
value={formData.joursAvant}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, joursAvant: parseInt(e.target.value) || 1 })
|
||||
}
|
||||
placeholder="Ex: 7"
|
||||
className="w-24"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Label htmlFor="heureEnvoi" className="whitespace-nowrap">Heure *</Label>
|
||||
<Input
|
||||
id="heureEnvoi"
|
||||
type="time"
|
||||
value={formData.heureEnvoi}
|
||||
onChange={(e) => setFormData({ ...formData, heureEnvoi: e.target.value })}
|
||||
className="w-32"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="heureEnvoi">Heure d'envoi *</Label>
|
||||
<Input
|
||||
id="heureEnvoi"
|
||||
type="time"
|
||||
value={formData.heureEnvoi}
|
||||
onChange={(e) => setFormData({ ...formData, heureEnvoi: e.target.value })}
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
L'heure à laquelle le rappel sera envoyé chaque jour
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>Dates de formation concernées (optionnel)</Label>
|
||||
{/* Zone 3: Dates concernées */}
|
||||
<div className="border-l-4 border-purple-500 pl-4 py-2 bg-purple-50/50 rounded-r">
|
||||
<h3 className="text-sm font-semibold text-purple-700 mb-3">Dates de formation concernées</h3>
|
||||
<DateFormationMultiSelect
|
||||
sequences={sequences?.map(seq => ({
|
||||
id: seq.id,
|
||||
@@ -709,29 +721,26 @@ export default function AdminRappels() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FileUpload
|
||||
label="Pièce jointe 1 (optionnel)"
|
||||
value={formData.fichier}
|
||||
onChange={(fichier) => setFormData({ ...formData, fichier })}
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png"
|
||||
maxSize={10}
|
||||
/>
|
||||
{/* Zone 4: Pièces jointes */}
|
||||
<div className="border-l-4 border-orange-500 pl-4 py-2 bg-orange-50/50 rounded-r">
|
||||
<h3 className="text-sm font-semibold text-orange-700 mb-2">Pièces jointes</h3>
|
||||
<div className="space-y-3">
|
||||
<FileUpload
|
||||
label="Pièce jointe 1 (optionnel)"
|
||||
value={formData.fichier}
|
||||
onChange={(fichier) => setFormData({ ...formData, fichier })}
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png"
|
||||
maxSize={10}
|
||||
/>
|
||||
|
||||
<FileUpload
|
||||
label="Pièce jointe 2 (optionnel)"
|
||||
value={formData.fichier2}
|
||||
onChange={(fichier2) => setFormData({ ...formData, fichier2 })}
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png"
|
||||
maxSize={10}
|
||||
/>
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch
|
||||
id="actif"
|
||||
checked={formData.actif}
|
||||
onCheckedChange={(checked) => setFormData({ ...formData, actif: checked })}
|
||||
/>
|
||||
<Label htmlFor="actif">Rappel actif</Label>
|
||||
<FileUpload
|
||||
label="Pièce jointe 2 (optionnel)"
|
||||
value={formData.fichier2}
|
||||
onChange={(fichier2) => setFormData({ ...formData, fichier2 })}
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png"
|
||||
maxSize={10}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
@@ -747,7 +756,7 @@ export default function AdminRappels() {
|
||||
|
||||
{/* Dialog de modification */}
|
||||
<Dialog open={isEditOpen} onOpenChange={setIsEditOpen}>
|
||||
<DialogContent className="max-w-2xl">
|
||||
<DialogContent className="!max-w-[2000px] w-[50vw]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Modifier le rappel</DialogTitle>
|
||||
<DialogDescription>
|
||||
@@ -755,98 +764,116 @@ export default function AdminRappels() {
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-templateType">Template d'email utilisé *</Label>
|
||||
<Select
|
||||
value={formData.templateType}
|
||||
onValueChange={handleTemplateTypeChange}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Sélectionnez un type de rappel" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{TEMPLATE_TYPES.map((template) => (
|
||||
<SelectItem key={template.value} value={template.value}>
|
||||
{template.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
{/* Zone 1: Template + Nom + Rappel actif */}
|
||||
<div className="border-l-4 border-blue-500 pl-4 py-2 bg-blue-50/50 rounded-r">
|
||||
<h3 className="text-sm font-semibold text-blue-700 mb-2">Configuration générale</h3>
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="flex items-center gap-2 flex-1">
|
||||
<Label htmlFor="edit-templateType" className="whitespace-nowrap">Template *</Label>
|
||||
<Select
|
||||
value={formData.templateType}
|
||||
onValueChange={handleTemplateTypeChange}
|
||||
>
|
||||
<SelectTrigger className="flex-1">
|
||||
<SelectValue placeholder="Sélectionnez un type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{TEMPLATE_TYPES.map((template) => (
|
||||
<SelectItem key={template.value} value={template.value}>
|
||||
{template.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-nom">Nom du rappel *</Label>
|
||||
<Input
|
||||
id="edit-nom"
|
||||
value={formData.nom}
|
||||
onChange={(e) => setFormData({ ...formData, nom: e.target.value })}
|
||||
placeholder="Ex: Rappel automatique J-7"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 flex-1">
|
||||
<Label htmlFor="edit-nom" className="whitespace-nowrap">Nom *</Label>
|
||||
<Input
|
||||
id="edit-nom"
|
||||
value={formData.nom}
|
||||
onChange={(e) => setFormData({ ...formData, nom: e.target.value })}
|
||||
placeholder="Ex: Rappel J-7"
|
||||
className="flex-1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>Timing d'envoi *</Label>
|
||||
<div className="flex gap-4">
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="edit-timing"
|
||||
value="pre_formation"
|
||||
checked={formData.timing === "pre_formation"}
|
||||
onChange={(e) => setFormData({ ...formData, timing: e.target.value as "pre_formation" | "post_formation" })}
|
||||
className="w-4 h-4"
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
id="edit-actif"
|
||||
checked={formData.actif}
|
||||
onCheckedChange={(checked) => setFormData({ ...formData, actif: checked })}
|
||||
/>
|
||||
<span>Pré-formation</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="edit-timing"
|
||||
value="post_formation"
|
||||
checked={formData.timing === "post_formation"}
|
||||
onChange={(e) => setFormData({ ...formData, timing: e.target.value as "pre_formation" | "post_formation" })}
|
||||
className="w-4 h-4"
|
||||
/>
|
||||
<span>Post-formation</span>
|
||||
</label>
|
||||
<Label htmlFor="edit-actif" className="cursor-pointer whitespace-nowrap">Rappel actif</Label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-joursAvant">
|
||||
{formData.timing === "pre_formation"
|
||||
? "Nombre de jours avant la séquence *"
|
||||
: "Nombre de jours après la séquence *"}
|
||||
</Label>
|
||||
<Input
|
||||
id="edit-joursAvant"
|
||||
type="number"
|
||||
min="1"
|
||||
value={formData.joursAvant}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, joursAvant: parseInt(e.target.value) || 1 })
|
||||
}
|
||||
placeholder="Ex: 7"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{formData.timing === "pre_formation"
|
||||
? "Le rappel sera envoyé ce nombre de jours avant le début de la séquence"
|
||||
: "Le rappel sera envoyé ce nombre de jours après la fin de la séquence"}
|
||||
</p>
|
||||
{/* Zone 2: Timing d'envoi */}
|
||||
<div className="border-l-4 border-green-500 pl-4 py-2 bg-green-50/50 rounded-r">
|
||||
<h3 className="text-sm font-semibold text-green-700 mb-2">Timing d'envoi</h3>
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<Label className="whitespace-nowrap">Type *</Label>
|
||||
<div className="flex gap-4">
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="edit-timing"
|
||||
value="pre_formation"
|
||||
checked={formData.timing === "pre_formation"}
|
||||
onChange={(e) => setFormData({ ...formData, timing: e.target.value as "pre_formation" | "post_formation" })}
|
||||
className="w-4 h-4"
|
||||
/>
|
||||
<span>Pré-formation</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
name="edit-timing"
|
||||
value="post_formation"
|
||||
checked={formData.timing === "post_formation"}
|
||||
onChange={(e) => setFormData({ ...formData, timing: e.target.value as "pre_formation" | "post_formation" })}
|
||||
className="w-4 h-4"
|
||||
/>
|
||||
<span>Post-formation</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 flex-1">
|
||||
<Label htmlFor="edit-joursAvant" className="whitespace-nowrap">
|
||||
{formData.timing === "pre_formation" ? "Jours avant *" : "Jours après *"}
|
||||
</Label>
|
||||
<Input
|
||||
id="edit-joursAvant"
|
||||
type="number"
|
||||
min="1"
|
||||
value={formData.joursAvant}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, joursAvant: parseInt(e.target.value) || 1 })
|
||||
}
|
||||
placeholder="Ex: 7"
|
||||
className="w-24"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<Label htmlFor="edit-heureEnvoi" className="whitespace-nowrap">Heure *</Label>
|
||||
<Input
|
||||
id="edit-heureEnvoi"
|
||||
type="time"
|
||||
value={formData.heureEnvoi}
|
||||
onChange={(e) => setFormData({ ...formData, heureEnvoi: e.target.value })}
|
||||
className="w-32"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="edit-heureEnvoi">Heure d'envoi *</Label>
|
||||
<Input
|
||||
id="edit-heureEnvoi"
|
||||
type="time"
|
||||
value={formData.heureEnvoi}
|
||||
onChange={(e) => setFormData({ ...formData, heureEnvoi: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label>Dates de formation concernées (optionnel)</Label>
|
||||
{/* Zone 3: Dates concernées */}
|
||||
<div className="border-l-4 border-purple-500 pl-4 py-2 bg-purple-50/50 rounded-r">
|
||||
<h3 className="text-sm font-semibold text-purple-700 mb-3">Dates de formation concernées</h3>
|
||||
<DateFormationMultiSelect
|
||||
sequences={sequences?.map(seq => ({
|
||||
id: seq.id,
|
||||
@@ -864,29 +891,26 @@ export default function AdminRappels() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FileUpload
|
||||
label="Pièce jointe 1 (optionnel)"
|
||||
value={formData.fichier}
|
||||
onChange={(fichier) => setFormData({ ...formData, fichier })}
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png"
|
||||
maxSize={10}
|
||||
/>
|
||||
{/* Zone 4: Pièces jointes */}
|
||||
<div className="border-l-4 border-orange-500 pl-4 py-2 bg-orange-50/50 rounded-r">
|
||||
<h3 className="text-sm font-semibold text-orange-700 mb-2">Pièces jointes</h3>
|
||||
<div className="space-y-3">
|
||||
<FileUpload
|
||||
label="Pièce jointe 1 (optionnel)"
|
||||
value={formData.fichier}
|
||||
onChange={(fichier) => setFormData({ ...formData, fichier })}
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png"
|
||||
maxSize={10}
|
||||
/>
|
||||
|
||||
<FileUpload
|
||||
label="Pièce jointe 2 (optionnel)"
|
||||
value={formData.fichier2}
|
||||
onChange={(fichier2) => setFormData({ ...formData, fichier2 })}
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png"
|
||||
maxSize={10}
|
||||
/>
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch
|
||||
id="edit-actif"
|
||||
checked={formData.actif}
|
||||
onCheckedChange={(checked) => setFormData({ ...formData, actif: checked })}
|
||||
/>
|
||||
<Label htmlFor="edit-actif">Rappel actif</Label>
|
||||
<FileUpload
|
||||
label="Pièce jointe 2 (optionnel)"
|
||||
value={formData.fichier2}
|
||||
onChange={(fichier2) => setFormData({ ...formData, fichier2 })}
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png"
|
||||
maxSize={10}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
|
||||
3
todo.md
3
todo.md
@@ -1482,3 +1482,6 @@
|
||||
- [x] Afficher immédiatement le nom du fichier sélectionné dans la boîte de dialogue
|
||||
|
||||
- [x] Appliquer la même ergonomie de boîte de dialogue pour les pièces jointes des rappels
|
||||
|
||||
- [ ] Réorganiser la boîte de dialogue des rappels pour réduire la hauteur et élargir la largeur
|
||||
- [x] Déployer la réorganisation complète de la modal des rappels sur le VPS
|
||||
|
||||
Reference in New Issue
Block a user