chore: Initial Commit

feat: Gestion des inscriptions [#1]
feat(frontend): Création des vues pour le paramétrage de l'école [#2]
feat: Gestion du login [#6]
fix: Correction lors de la migration des modèle [#8]
feat: Révision du menu principal [#9]
feat: Ajout d'un footer [#10]
feat: Création des dockers compose pour les environnements de
développement et de production [#12]
doc(ci): Mise en place de Husky et d'un suivi de version automatique [#14]
This commit is contained in:
Luc SORIGNET
2024-11-18 10:02:58 +01:00
committed by N3WT DE COMPET
commit af0cd1c840
228 changed files with 22694 additions and 0 deletions

View File

@ -0,0 +1,106 @@
'use client'
import React, { useState, useRef, useEffect } from 'react';
import { SendHorizontal } from 'lucide-react';
const contacts = [
{ id: 1, name: 'Facturation', profilePic: 'https://i.pravatar.cc/32' },
{ id: 2, name: 'Enseignant 1', profilePic: 'https://i.pravatar.cc/32' },
{ id: 3, name: 'Contact', profilePic: 'https://i.pravatar.cc/32' },
];
export default function MessageriePage() {
const [selectedContact, setSelectedContact] = useState(null);
const [messages, setMessages] = useState({});
const [newMessage, setNewMessage] = useState('');
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};
useEffect(() => {
scrollToBottom();
}, [messages]);
const handleSendMessage = () => {
if (newMessage.trim() && selectedContact) {
const contactMessages = messages[selectedContact.id] || [];
setMessages({
...messages,
[selectedContact.id]: [...contactMessages, { id: contactMessages.length + 1, text: newMessage, date: new Date() }],
});
setNewMessage('');
simulateContactResponse(selectedContact.id);
}
};
const handleKeyPress = (event) => {
if (event.key === 'Enter') {
handleSendMessage();
}
};
const simulateContactResponse = (contactId) => {
setTimeout(() => {
setMessages((prevMessages) => {
const contactMessages = prevMessages[contactId] || [];
return {
...prevMessages,
[contactId]: [...contactMessages, { id: contactMessages.length + 2, text: 'Réponse automatique', isResponse: true, date: new Date() }],
};
});
}, 2000);
};
return (
<div className="flex" style={{ height: 'calc(100vh - 128px )' }}> {/* Utilisation de calc pour soustraire la hauteur de l'entête */}
<div className="w-1/4 border-r border-gray-200 p-4 overflow-y-auto h-full ">
{contacts.map((contact) => (
<div
key={contact.id}
className={`p-2 cursor-pointer ${selectedContact?.id === contact.id ? 'bg-gray-200' : ''}`}
onClick={() => setSelectedContact(contact)}
>
<img src={contact.profilePic} alt={`${contact.name}'s profile`} className="w-8 h-8 rounded-full inline-block mr-2" />
{contact.name}
</div>
))}
</div>
<div className="flex-1 flex flex-col h-full">
<div className="flex-1 overflow-y-auto p-4 h-full">
{selectedContact && (messages[selectedContact.id] || []).map((message) => (
<div
key={message.id}
className={`mb-2 p-2 rounded max-w-xs ${message.isResponse ? 'bg-gray-200 justify-self-end' : 'bg-emerald-200 justify-self-start'}`}
style={{ borderRadius: message.isResponse ? '20px 20px 0 20px' : '20px 20px 20px 0', minWidth: '25%' }}
>
<div className="flex items-center mb-1">
<img src={selectedContact.profilePic} alt={`${selectedContact.name}'s profile`} className="w-8 h-8 rounded-full inline-block mr-2" />
<span className="text-xs text-gray-600">{selectedContact.name}</span>
<span className="text-xs text-gray-400 ml-2">{new Date(message.date).toLocaleTimeString()}</span>
</div>
{message.text}
</div>
))}
<div ref={messagesEndRef} />
</div>
<div className="p-4 border-t border-gray-200 flex">
<input
type="text"
value={newMessage}
onChange={(e) => setNewMessage(e.target.value)}
className="w-full p-2 border border-gray-300 rounded"
placeholder="Écrire un message..."
onKeyDown={handleKeyPress}
/>
<button
onClick={handleSendMessage}
className="p-2 bg-emerald-500 text-white rounded mr-2"
>
<SendHorizontal />
</button>
</div>
</div>
</div>
);
}