mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-04 04:01:27 +00:00
feat: Messagerie WIP [#17]
This commit is contained in:
144
Front-End/src/components/RecipientInput.js
Normal file
144
Front-End/src/components/RecipientInput.js
Normal file
@ -0,0 +1,144 @@
|
||||
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
|
||||
|
||||
export default function RecipientInput({
|
||||
label,
|
||||
recipients,
|
||||
setRecipients,
|
||||
searchRecipients, // Fonction pour effectuer la recherche
|
||||
establishmentId, // ID de l'établissement
|
||||
}) {
|
||||
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) {
|
||||
console.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.some((r) => r.email === trimmedValue)) {
|
||||
setRecipients([...recipients, { email: 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.some((r) => r.email === suggestion.email)) {
|
||||
setRecipients([...recipients, suggestion]);
|
||||
}
|
||||
setInputValue('');
|
||||
setSuggestions([]);
|
||||
};
|
||||
|
||||
const handleRemoveRecipient = (email) => {
|
||||
setRecipients(recipients.filter((recipient) => recipient.email !== email));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700">{label}</label>
|
||||
<div className="flex flex-wrap items-center gap-2 p-2 border rounded">
|
||||
{recipients.map((recipient, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center bg-gray-100 text-gray-700 px-2 py-1 rounded-full"
|
||||
>
|
||||
<img
|
||||
src={getGravatarUrl(recipient.email)}
|
||||
alt={recipient.email}
|
||||
className="w-6 h-6 rounded-full mr-2"
|
||||
/>
|
||||
<span className="mr-2">
|
||||
{recipient.first_name && recipient.last_name
|
||||
? `${recipient.first_name} ${recipient.last_name}`
|
||||
: recipient.email}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleRemoveRecipient(recipient.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 p-1 outline-none"
|
||||
/>
|
||||
</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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user