mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-04 01:41:27 +00:00
153 lines
5.0 KiB
JavaScript
153 lines
5.0 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { getGravatarUrl } from '@/utils/gravatar'; // Assurez-vous que cette fonction est définie pour générer les URLs Gravatar
|
|
import { getRightStr } from '@/utils/rights'; // Fonction existante pour récupérer le nom des rôles
|
|
import logger from '@/utils/logger';
|
|
|
|
export default function RecipientInput({
|
|
label,
|
|
recipients,
|
|
setRecipients,
|
|
searchRecipients, // Fonction pour effectuer la recherche
|
|
establishmentId, // ID de l'établissement
|
|
required = false, // Ajout de la prop required avec valeur par défaut
|
|
}) {
|
|
const [inputValue, setInputValue] = useState('');
|
|
const [suggestions, setSuggestions] = useState([]);
|
|
const [selectedIndex, setSelectedIndex] = useState(-1);
|
|
|
|
const handleInputChange = async (e) => {
|
|
const value = e.target.value;
|
|
setInputValue(value);
|
|
|
|
if (value.trim() !== '') {
|
|
try {
|
|
const results = await searchRecipients(establishmentId, value);
|
|
setSuggestions(results);
|
|
} catch (error) {
|
|
logger.error('Erreur lors de la recherche des destinataires:', error);
|
|
setSuggestions([]);
|
|
}
|
|
} else {
|
|
setSuggestions([]);
|
|
}
|
|
};
|
|
|
|
const handleKeyDown = (e) => {
|
|
if (e.key === 'Enter') {
|
|
e.preventDefault();
|
|
if (selectedIndex >= 0 && selectedIndex < suggestions.length) {
|
|
handleSuggestionClick(suggestions[selectedIndex]);
|
|
} else {
|
|
const trimmedValue = inputValue.trim();
|
|
if (trimmedValue && !recipients.includes(trimmedValue)) {
|
|
setRecipients([...recipients, trimmedValue]);
|
|
setInputValue('');
|
|
setSuggestions([]);
|
|
}
|
|
}
|
|
} else if (e.key === 'ArrowDown') {
|
|
e.preventDefault();
|
|
setSelectedIndex((prevIndex) =>
|
|
prevIndex < suggestions.length - 1 ? prevIndex + 1 : 0
|
|
);
|
|
} else if (e.key === 'ArrowUp') {
|
|
e.preventDefault();
|
|
setSelectedIndex((prevIndex) =>
|
|
prevIndex > 0 ? prevIndex - 1 : suggestions.length - 1
|
|
);
|
|
}
|
|
};
|
|
|
|
const handleSuggestionClick = (suggestion) => {
|
|
if (!recipients.includes(suggestion.email)) {
|
|
setRecipients([...recipients, suggestion.email]);
|
|
}
|
|
setInputValue('');
|
|
setSuggestions([]);
|
|
};
|
|
|
|
const handleRemoveRecipient = (email) => {
|
|
setRecipients(recipients.filter((recipient) => recipient !== email));
|
|
};
|
|
|
|
return (
|
|
<div className="mb-4">
|
|
<label className="block text-sm font-medium text-gray-700">
|
|
{label}
|
|
{required && <span className="text-red-500 ml-1">*</span>}
|
|
</label>
|
|
<div
|
|
className={`
|
|
mt-1 flex flex-wrap items-center gap-2 border rounded-md
|
|
border-gray-200 hover:border-gray-400 focus-within:border-gray-500
|
|
transition-colors
|
|
`}
|
|
>
|
|
{recipients.map((email, index) => (
|
|
<div
|
|
key={index}
|
|
className="flex items-center bg-gray-100 text-gray-700 px-2 py-1 rounded-full"
|
|
>
|
|
<img
|
|
src={getGravatarUrl(email)}
|
|
alt={email}
|
|
className="w-6 h-6 rounded-full mr-2"
|
|
/>
|
|
<span className="mr-2">{email}</span>
|
|
<button
|
|
type="button"
|
|
onClick={() => handleRemoveRecipient(email)}
|
|
className="text-gray-500 hover:text-gray-700"
|
|
>
|
|
×
|
|
</button>
|
|
</div>
|
|
))}
|
|
<input
|
|
type="text"
|
|
value={inputValue}
|
|
onChange={handleInputChange}
|
|
onKeyDown={handleKeyDown}
|
|
placeholder="Rechercher des destinataires"
|
|
className="flex-1 px-3 py-2 block w-full sm:text-sm border-none focus:ring-0 outline-none rounded-md"
|
|
required={required}
|
|
/>
|
|
</div>
|
|
{suggestions.length > 0 && (
|
|
<ul className="border rounded mt-2 bg-white shadow">
|
|
{suggestions.map((suggestion, index) => (
|
|
<li
|
|
key={suggestion.id}
|
|
className={`p-2 cursor-pointer ${
|
|
index === selectedIndex ? 'bg-gray-200' : ''
|
|
}`}
|
|
onClick={() => handleSuggestionClick(suggestion)}
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<img
|
|
src={getGravatarUrl(suggestion.email)}
|
|
alt={suggestion.email}
|
|
className="w-8 h-8 rounded-full"
|
|
/>
|
|
<div>
|
|
<p className="font-medium">
|
|
{suggestion.first_name && suggestion.last_name
|
|
? `${suggestion.first_name} ${suggestion.last_name}`
|
|
: suggestion.email}
|
|
</p>
|
|
<p className="text-sm text-gray-500">{suggestion.email}</p>
|
|
<p className="text-xs text-gray-400">
|
|
{suggestion.roles
|
|
.map((role) => getRightStr(role.role_type) || 'Inconnu')
|
|
.join(', ')}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|