Chatbot Tailwind

🏷️ Extraits & Composants HTML 📅 07/04/2026 22:00:00 👤 Mezgani Said
Tailwind Chatbot List Tailwind Design Template Html Integration List Ai

Chatbot Tailwind optimisées pour la visualisation et l'interaction. Composants modernes et responsive.

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <meta name="copyright" content="MEZGANI Said" />
  <meta name="author" content="AngularForAll" />
  <meta name="robots" content="noindex, nofollow" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Snippet Chatboot Tailwind 2026 23040040 | AngularForAll</title>
<!-- Tailwind CSS via CDN (v3) -->
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- Police plus moderne -->
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
  <style>
    * { font-family: 'Inter', system-ui, sans-serif; }
    
    /* Animation typing personnalisée */
    @keyframes typingPulse {
      0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
      30% { transform: translateY(-6px); opacity: 1; }
    }
    .typing-dot {
      animation: typingPulse 1.2s infinite ease-in-out;
    }
    .typing-dot:nth-child(2) { animation-delay: 0.2s; }
    .typing-dot:nth-child(3) { animation-delay: 0.4s; }
    
    /* Animation apparition messages */
    @keyframes fadeInUp {
      from { opacity: 0; transform: translateY(8px); }
      to { opacity: 1; transform: translateY(0); }
    }
    .message-animation {
      animation: fadeInUp 0.25s ease-out;
    }
    
    /* Scrollbar fine */
    .chat-body::-webkit-scrollbar { width: 5px; }
    .chat-body::-webkit-scrollbar-track { background: transparent; }
    .chat-body::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
  </style>
</head>
<body class="bg-slate-50 min-h-screen">

<!-- Contenu de démonstration -->
<div class="container mx-auto px-4 py-12 max-w-4xl">
  <div class="text-center">
    <h1 class="text-4xl md:text-5xl font-semibold text-slate-800 mb-3">🤖 Assistant Virtuel</h1>
    <p class="text-lg text-slate-600">Cliquez sur l'icône en bas à droite pour discuter avec notre chatbot Tailwind.</p>
    <div class="mt-8 p-8 bg-white rounded-3xl shadow-sm border border-slate-100">
      <svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto text-blue-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
        <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
      </svg>
      <p class="mt-4 text-slate-600">Posez une question sur nos services, les tarifs ou le support.</p>
    </div>
  </div>
</div>

<!-- ========== WIDGET CHATBOT TAILWIND ========== -->
<div class="fixed bottom-6 right-6 z-50 flex flex-col items-end">
  
  <!-- Fenêtre de chat (cachée par défaut) -->
  <div id="chatWindow" class="hidden w-[360px] max-w-[calc(100vw-2rem)] bg-white rounded-3xl shadow-2xl border border-slate-200/80 overflow-hidden mb-4 transition-all">
    
    <!-- Header -->
    <div class="bg-gradient-to-br from-blue-600 to-blue-700 text-white px-5 py-4 flex items-center justify-between">
      <div class="flex items-center gap-3">
        <div class="w-10 h-10 bg-white rounded-full flex items-center justify-center text-blue-600 font-bold text-xl shadow-md">
          <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
            <path stroke-linecap="round" stroke-linejoin="round" d="M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0112 15a9.065 9.065 0 00-6.23-.693L5 14.5m14.8.8l1.402 1.402c-.009.673-.315 1.297-.832 1.745M4.198 15.3L2.796 16.702c.009.673.315 1.297.832 1.745M18 12a6 6 0 11-12 0 6 6 0 0112 0z" />
          </svg>
        </div>
        <div>
          <h6 class="font-semibold text-[15px] leading-tight">SupportBot</h6>
          <div class="flex items-center gap-1 text-white/80 text-xs mt-0.5">
            <span class="inline-block w-2 h-2 bg-green-400 rounded-full"></span>
            <span>En ligne · répond en ~1min</span>
          </div>
        </div>
      </div>
      <button id="closeChatBtn" class="w-8 h-8 rounded-full bg-white/20 hover:bg-white/30 flex items-center justify-center transition">
        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
          <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
        </svg>
      </button>
    </div>

    <!-- Body (messages) -->
    <div id="chatBody" class="chat-body h-[380px] overflow-y-auto p-4 bg-slate-50/80 flex flex-col gap-3">
      <!-- Message initial bot -->
      <div class="flex max-w-[85%] self-start message-animation">
        <div class="bg-white border border-slate-200 rounded-2xl rounded-bl-md px-4 py-2.5 text-sm shadow-sm text-slate-700">
          👋 Bonjour ! Je suis l'assistant virtuel. Comment puis-je vous aider aujourd'hui ?
        </div>
      </div>
      <!-- Les autres messages injectés ici -->
    </div>

    <!-- Footer avec input -->
    <div class="bg-white border-t border-slate-200 p-3 flex items-center gap-2">
      <input type="text" id="chatInput" placeholder="Écrivez votre message..." autocomplete="off"
             class="flex-1 bg-slate-100 border border-slate-200 rounded-full px-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/30 focus:border-blue-400 focus:bg-white transition">
      <button id="sendMessageBtn" class="w-11 h-11 bg-blue-600 hover:bg-blue-700 rounded-full flex items-center justify-center text-white shadow-md hover:shadow-lg transition transform hover:scale-[1.02]">
        <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
          <path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5" />
        </svg>
      </button>
    </div>
  </div>

  <!-- Bouton toggle principal -->
  <button id="toggleChatBtn" class="w-[60px] h-[60px] bg-blue-600 hover:bg-blue-700 rounded-full flex items-center justify-center text-white shadow-lg shadow-blue-600/30 hover:shadow-xl hover:shadow-blue-600/40 transition-all border-2 border-white/30">
    <svg id="toggleIcon" xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
      <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
    </svg>
  </button>
</div>

<script>
  (function() {
    'use strict';

    // Éléments DOM
    const chatWindow = document.getElementById('chatWindow');
    const toggleBtn = document.getElementById('toggleChatBtn');
    const closeBtn = document.getElementById('closeChatBtn');
    const chatBody = document.getElementById('chatBody');
    const chatInput = document.getElementById('chatInput');
    const sendBtn = document.getElementById('sendMessageBtn');
    const toggleIcon = document.getElementById('toggleIcon');

    // Icônes SVG (pour basculer entre bulle et croix)
    const chatIconSVG = `<path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />`;
    const closeIconSVG = `<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />`;

    // Fonctions utilitaires
    function openChat() {
      chatWindow.classList.remove('hidden');
      toggleIcon.innerHTML = closeIconSVG;
      setTimeout(() => chatInput.focus(), 50);
    }

    function closeChat() {
      chatWindow.classList.add('hidden');
      toggleIcon.innerHTML = chatIconSVG;
    }

    function toggleChat() {
      chatWindow.classList.contains('hidden') ? openChat() : closeChat();
    }

    function scrollToBottom() {
      chatBody.scrollTop = chatBody.scrollHeight;
    }

    function escapeHtml(text) {
      const div = document.createElement('div');
      div.textContent = text;
      return div.innerHTML;
    }

    // Ajouter message utilisateur
    function addUserMessage(text) {
      const msgDiv = document.createElement('div');
      msgDiv.className = 'flex max-w-[85%] self-end message-animation';
      msgDiv.innerHTML = `<div class="bg-blue-600 text-white rounded-2xl rounded-br-md px-4 py-2.5 text-sm shadow-sm">${escapeHtml(text)}</div>`;
      chatBody.appendChild(msgDiv);
      scrollToBottom();
    }

    // Ajouter message bot
    function addBotMessage(text) {
      const msgDiv = document.createElement('div');
      msgDiv.className = 'flex max-w-[85%] self-start message-animation';
      msgDiv.innerHTML = `<div class="bg-white border border-slate-200 rounded-2xl rounded-bl-md px-4 py-2.5 text-sm shadow-sm text-slate-700">${escapeHtml(text)}</div>`;
      chatBody.appendChild(msgDiv);
      scrollToBottom();
    }

    // Indicateur "typing..."
    function addTypingIndicator() {
      const typingDiv = document.createElement('div');
      typingDiv.className = 'flex self-start';
      typingDiv.id = 'typingIndicator';
      typingDiv.innerHTML = `
        <div class="bg-white border border-slate-200 rounded-2xl rounded-bl-md px-4 py-3 flex gap-1.5 items-center">
          <span class="typing-dot w-2 h-2 bg-slate-400 rounded-full"></span>
          <span class="typing-dot w-2 h-2 bg-slate-400 rounded-full"></span>
          <span class="typing-dot w-2 h-2 bg-slate-400 rounded-full"></span>
        </div>
      `;
      chatBody.appendChild(typingDiv);
      scrollToBottom();
      return typingDiv;
    }

    function removeTypingIndicator() {
      const el = document.getElementById('typingIndicator');
      if (el) el.remove();
    }

    // Logique de réponse du bot
    function getBotResponse(userMsg) {
      const msg = userMsg.toLowerCase().trim();
      if (msg.includes('bonjour') || msg.includes('salut') || msg.includes('hello')) 
        return "Bonjour ! 😊 Comment puis-je vous aider ?";
      if (msg.includes('prix') || msg.includes('tarif') || msg.includes('coût')) 
        return "Nos tarifs varient selon les services. Le forfait de base commence à 29€/mois. Souhaitez-vous plus de détails ?";
      if (msg.includes('horaire') || msg.includes('ouverture')) 
        return "Notre équipe est disponible du lundi au vendredi, de 9h à 18h. Le support par chat est ouvert 24/7.";
      if (msg.includes('contact') || msg.includes('téléphone') || msg.includes('email')) 
        return "📞 Vous pouvez nous joindre au +33 1 23 45 67 89 ou par email à support@exemple.fr";
      if (msg.includes('merci')) 
        return "Avec plaisir ! N'hésitez pas si vous avez d'autres questions. 🌟";
      if (msg.includes('aide') || msg.includes('help')) 
        return "Je peux vous renseigner sur : tarifs, horaires, contact, ou assistance technique. Dites-moi ce dont vous avez besoin.";
      if (msg.includes('tech') || msg.includes('bug') || msg.includes('problème')) 
        return "Je suis désolé que vous rencontriez un souci. Pouvez-vous décrire le problème plus précisément ? Je vais vous guider.";
      return "Intéressant ! Je suis un chatbot de démonstration. Pour le moment, je peux répondre à des questions sur les tarifs, horaires, contact ou assistance. Dites-m'en plus 😊";
    }

    function simulateBotReply(userText) {
      const typingEl = addTypingIndicator();
      const delay = Math.floor(Math.random() * 900) + 800;
      setTimeout(() => {
        removeTypingIndicator();
        addBotMessage(getBotResponse(userText));
      }, delay);
    }

    function handleSendMessage() {
      const text = chatInput.value.trim();
      if (!text) return;
      addUserMessage(text);
      chatInput.value = '';
      simulateBotReply(text);
    }

    // Événements
    toggleBtn.addEventListener('click', toggleChat);
    closeBtn.addEventListener('click', closeChat);
    sendBtn.addEventListener('click', handleSendMessage);
    
    chatInput.addEventListener('keypress', (e) => {
      if (e.key === 'Enter') {
        e.preventDefault();
        handleSendMessage();
      }
    });

    document.addEventListener('keydown', (e) => {
      if (e.key === 'Escape' && !chatWindow.classList.contains('hidden')) {
        closeChat();
      }
    });

    // Auto-scroll quand la fenêtre s'ouvre
    const observer = new MutationObserver(() => {
      if (!chatWindow.classList.contains('hidden')) scrollToBottom();
    });
    observer.observe(chatWindow, { attributes: true, attributeFilter: ['class'] });

  })();
</script>

</body>
</html>

Ouvrir cet aperçu dans un nouvel onglet du navigateur

🔗 Ouvrir dans le navigateur