0%
Interface Utilisateur pour ChatGPT : Création d'un Chat Interactif

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

  1. 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) : [];
};
  1. 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
}
  1. 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.)

Ressources Supplémentaires

Commentaires

Les commentaires sont alimentés par GitHub Discussions

Connectez-vous avec GitHub pour participer à la discussion

Lien copié !