3. Interface Utilisateur
Création d'un chat interactif
10-15 min
Interface Utilisateur pour ChatGPT : Création d’un Chat Interactif
Introduction
Dans ce module, nous allons créer une interface utilisateur moderne et réactive pour interagir avec l’API ChatGPT. Nous utiliserons React pour construire notre interface, mais les concepts peuvent être adaptés à d’autres frameworks.
Configuration du Projet
Installation des Dépendances
npm create vite@latest chatgpt-ui -- --template react
cd chatgpt-ui
npm install openai axios @chakra-ui/react @emotion/react @emotion/styled framer-motion
Structure du Projet
chatgpt-ui/
├── src/
│ ├── components/
│ │ ├── ChatWindow.jsx
│ │ ├── MessageInput.jsx
│ │ └── Message.jsx
│ ├── hooks/
│ │ └── useChatGPT.js
│ ├── App.jsx
│ └── main.jsx
└── .env
Création des Composants
1. Le Hook useChatGPT
// src/hooks/useChatGPT.js
import { useState } from 'react';
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: import.meta.env.VITE_OPENAI_API_KEY
});
export function useChatGPT() {
const [messages, setMessages] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const sendMessage = async (content) => {
try {
setIsLoading(true);
// Ajouter le message de l'utilisateur
const userMessage = { role: 'user', content };
setMessages(prev => [...prev, userMessage]);
// Appeler l'API ChatGPT
const completion = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [
{ role: "system", content: "Vous êtes un assistant utile." },
...messages,
userMessage
],
});
// Ajouter la réponse de l'assistant
const assistantMessage = completion.choices[0].message;
setMessages(prev => [...prev, assistantMessage]);
return assistantMessage;
} catch (error) {
console.error('Erreur lors de l\'envoi du message:', error);
throw error;
} finally {
setIsLoading(false);
}
};
return {
messages,
isLoading,
sendMessage
};
}
2. Le Composant Message
// src/components/Message.jsx
import { Box, Text } from '@chakra-ui/react';
export function Message({ role, content }) {
const isUser = role === 'user';
return (
<Box
bg={isUser ? 'blue.500' : 'gray.100'}
color={isUser ? 'white' : 'black'}
p={4}
borderRadius="lg"
maxW="80%"
alignSelf={isUser ? 'flex-end' : 'flex-start'}
mb={4}
>
<Text>{content}</Text>
</Box>
);
}
3. Le Composant MessageInput
// src/components/MessageInput.jsx
import { useState } from 'react';
import { Input, Button, HStack } from '@chakra-ui/react';
export function MessageInput({ onSend, isLoading }) {
const [message, setMessage] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (message.trim()) {
onSend(message);
setMessage('');
}
};
return (
<form onSubmit={handleSubmit}>
<HStack>
<Input
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Tapez votre message..."
disabled={isLoading}
/>
<Button
type="submit"
colorScheme="blue"
isLoading={isLoading}
loadingText="Envoi..."
>
Envoyer
</Button>
</HStack>
</form>
);
}
4. Le Composant ChatWindow
// src/components/ChatWindow.jsx
import { VStack, Box } from '@chakra-ui/react';
import { Message } from './Message';
import { MessageInput } from './MessageInput';
import { useChatGPT } from '../hooks/useChatGPT';
export function ChatWindow() {
const { messages, isLoading, sendMessage } = useChatGPT();
return (
<Box
w="full"
maxW="container.md"
mx="auto"
h="100vh"
p={4}
display="flex"
flexDirection="column"
>
<VStack
flex={1}
overflowY="auto"
spacing={4}
mb={4}
align="stretch"
>
{messages.map((message, index) => (
<Message
key={index}
role={message.role}
content={message.content}
/>
))}
</VStack>
<MessageInput
onSend={sendMessage}
isLoading={isLoading}
/>
</Box>
);
}
5. Le Composant App
// src/App.jsx
import { ChakraProvider } from '@chakra-ui/react';
import { ChatWindow } from './components/ChatWindow';
function App() {
return (
<ChakraProvider>
<ChatWindow />
</ChakraProvider>
);
}
export default App;
Gestion de l’État et des Conversations
Notre implémentation utilise le hook useState
pour gérer l’état local des messages. Pour une application plus complexe, vous pourriez vouloir utiliser :
- Redux ou Context API pour la gestion globale de l’état
- Local Storage pour persister les conversations
- WebSocket pour une communication en temps réel
Améliorations Possibles
- Persistance des Données
// Sauvegarder les messages dans le localStorage
const saveMessages = (messages) => {
localStorage.setItem('chatMessages', JSON.stringify(messages));
};
// Charger les messages au démarrage
const loadMessages = () => {
const saved = localStorage.getItem('chatMessages');
return saved ? JSON.parse(saved) : [];
};
- Gestion des Erreurs
const [error, setError] = useState(null);
// Dans le hook useChatGPT
try {
// ... code existant
} catch (error) {
setError(error.message);
// Afficher un message d'erreur à l'utilisateur
}
- Typage des Messages
// Dans le composant Message
const getMessageStyle = (role) => {
switch (role) {
case 'user':
return { bg: 'blue.500', color: 'white' };
case 'assistant':
return { bg: 'gray.100', color: 'black' };
case 'system':
return { bg: 'green.100', color: 'black' };
default:
return {};
}
};
Prochaines Étapes
Dans le prochain module, nous explorerons :
- L’optimisation des performances
- La gestion avancée du contexte
- L’implémentation de fonctionnalités supplémentaires (historique, export, etc.)
Commentaires
Les commentaires sont alimentés par GitHub Discussions
Connectez-vous avec GitHub pour participer à la discussion