├── .gitattributes └── base-chatbot ├── frontend ├── index.html ├── script.js └── style.css └── backend └── config.php /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /base-chatbot/frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Mini Chatbot 13 | 14 | 15 | 16 | 17 |
18 |
19 | 21 | 22 |
23 |
24 | 25 |
26 | 37 |
38 |

39 |

Wait a moment

40 |
41 | 44 |
45 |
46 |
AI Chatbot 47 | 48 |
49 |
50 |
Offline
51 | 52 |
53 |
54 |
55 | 56 | 57 |
58 | 59 |
60 |
61 |
62 | 63 |
64 | 65 | 66 | 67 |
68 | 69 | 70 |
71 |
72 | 73 |
74 |
75 |
76 |
77 | 78 | 79 |
80 | 82 |
83 | 84 |
85 |
86 | 87 |
88 |
89 |
90 | 91 |
92 | 93 | 94 |
95 |
96 |
97 | 98 | 99 | -------------------------------------------------------------------------------- /base-chatbot/backend/config.php: -------------------------------------------------------------------------------- 1 | function generate_chat_response( $last_prompt, $conversation_history ) { 2 | 3 | // OpenAI API URL and key 4 | $api_url = 'https://api.openai.com/v1/chat/completions'; 5 | $api_key = 'sk-XXX'; // Replace with your actual API key 6 | 7 | // Headers for the OpenAI API 8 | $headers = [ 9 | 'Content-Type' => 'application/json', 10 | 'Authorization' => 'Bearer ' . $api_key 11 | ]; 12 | 13 | // Add the last prompt to the conversation history 14 | $conversation_history[] = [ 15 | 'role' => 'system', 16 | 'content' => 'Answer questions only related to digital marketing, otherwise, say I dont know' 17 | ]; 18 | 19 | $conversation_history[] = [ 20 | 'role' => 'user', 21 | 'content' => $last_prompt 22 | ]; 23 | 24 | // Body for the OpenAI API 25 | $body = [ 26 | 'model' => 'gpt-3.5-turbo', // You can change the model if needed 27 | 'messages' => $conversation_history, 28 | 'temperature' => 0.7 // You can adjust this value based on desired creativity 29 | ]; 30 | 31 | // Args for the WordPress HTTP API 32 | $args = [ 33 | 'method' => 'POST', 34 | 'headers' => $headers, 35 | 'body' => json_encode($body), 36 | 'timeout' => 120 37 | ]; 38 | 39 | // Send the request 40 | $response = wp_remote_request($api_url, $args); 41 | 42 | // Handle the response 43 | if (is_wp_error($response)) { 44 | return $response->get_error_message(); 45 | } else { 46 | $response_body = wp_remote_retrieve_body($response); 47 | $data = json_decode($response_body, true); 48 | 49 | if (json_last_error() !== JSON_ERROR_NONE) { 50 | return [ 51 | 'success' => false, 52 | 'message' => 'Invalid JSON in API response', 53 | 'result' => '' 54 | ]; 55 | } elseif (!isset($data['choices'])) { 56 | return [ 57 | 'success' => false, 58 | 'message' => 'API request failed. Response: ' . $response_body, 59 | 'result' => '' 60 | ]; 61 | } else { 62 | $content = $data['choices'][0]['message']['content']; 63 | return [ 64 | 'success' => true, 65 | 'message' => 'Response Generated', 66 | 'result' => $content 67 | ]; 68 | } 69 | } 70 | } 71 | 72 | function generate_dummy_response( $last_prompt, $conversation_history ) { 73 | // Dummy static response 74 | $dummy_response = array( 75 | 'success' => true, 76 | 'message' => 'done', 77 | 'result' => "here is my reply" 78 | ); 79 | 80 | // Return the dummy response as an associative array 81 | return $dummy_response; 82 | } 83 | 84 | function handle_chat_bot_request( WP_REST_Request $request ) { 85 | $last_prompt = $request->get_param('last_prompt'); 86 | $conversation_history = $request->get_param('conversation_history'); 87 | 88 | $response = generate_chat_response($last_prompt, $conversation_history); 89 | return $response; 90 | } 91 | 92 | function load_chat_bot_base_configuration(WP_REST_Request $request) { 93 | // You can retrieve user data or other dynamic information here 94 | $user_avatar_url = "https://learnwithhasan.com/wp-content/uploads/2023/09/pngtree-businessman-user-avatar-wearing-suit-with-red-tie-png-image_5809521.png"; // Implement this function 95 | $bot_image_url = "https://learnwithhasan.com/wp-content/uploads/2023/12/site-logo-mobile.png"; // Implement this function 96 | 97 | $response = array( 98 | 'botStatus' => 0, 99 | 'StartUpMessage' => "Hi, How are you?", 100 | 'fontSize' => '16', 101 | 'userAvatarURL' => $user_avatar_url, 102 | 'botImageURL' => $bot_image_url, 103 | // Adding the new field 104 | 'commonButtons' => array( 105 | array( 106 | 'buttonText' => 'I want your help!!!', 107 | 'buttonPrompt' => 'I have a question about your courses' 108 | ), 109 | array( 110 | 'buttonText' => 'I want a Discount', 111 | 'buttonPrompt' => 'I want a discount' 112 | ) 113 | 114 | ) 115 | 116 | ); 117 | 118 | $response = new WP_REST_Response($response, 200); 119 | 120 | return $response; 121 | } 122 | 123 | add_action( 'rest_api_init', function () { 124 | register_rest_route( 'myapi/v1', '/chat-bot/', array( 125 | 'methods' => 'POST', 126 | 'callback' => 'handle_chat_bot_request', 127 | 'permission_callback' => '__return_true' 128 | ) ); 129 | 130 | register_rest_route('myapi/v1', '/chat-bot-config', array( 131 | 'methods' => 'GET', 132 | 'callback' => 'load_chat_bot_base_configuration', 133 | )); 134 | } ); 135 | -------------------------------------------------------------------------------- /base-chatbot/frontend/script.js: -------------------------------------------------------------------------------- 1 | const apiUrl = 'http://ai-chatbot.local/wp-json/myapi/v1/chat-bot/'; 2 | const botConfigurationUrl = 'http://ai-chatbot.local/wp-json/myapi/v1/chat-bot-config'; 3 | const copyButtons = document.querySelectorAll('.lwh-open-cbot .copy-button'); 4 | const button = document.querySelector('.lwh-open-cbot #submit-btn'); 5 | let messageInput = document.querySelector('.lwh-open-cbot #message'); 6 | let content = []; 7 | let botConfigData = ''; 8 | let conversationTranscript = []; 9 | 10 | function lwhOpenCbotToggleChat() { 11 | const chatWindow = document.querySelector(".lwh-open-cbot .chat"); 12 | chatWindow.classList.toggle('show'); 13 | if(chatWindow.classList.contains('show')){ 14 | document.querySelector(".lwh-open-cbot .custom-chatbot").style.zIndex = '9999' 15 | } 16 | else{ 17 | document.querySelector(".lwh-open-cbot .custom-chatbot").style.zIndex = '9998' 18 | } 19 | } 20 | 21 | function lwhOpenCbotonFormSubmit(event, userMessage) { 22 | event.preventDefault(); 23 | if(button.disabled == true) return 24 | let message; 25 | if(userMessage == undefined){ 26 | message = messageInput.value.trim(); 27 | document.querySelector(".lwh-open-cbot .startup-btns").style.display = "none"; 28 | } 29 | else{ 30 | message = userMessage; 31 | } 32 | content.push({ 33 | role: 'user', 34 | message: message, 35 | }); 36 | let timestamp = new Date().toLocaleString(); 37 | conversationTranscript.push({ 38 | sender: 'user', 39 | time: timestamp, 40 | message: message, 41 | }); 42 | data = ""; 43 | if (message !== '') { 44 | lwhOpenCbotaddMessage('user', message); 45 | messageInput.value = ''; 46 | lwhOpenCbotaddTypingAnimation('ai'); 47 | lwhOpenCbotfetchData() 48 | } 49 | } 50 | 51 | function lwhOpenCbotaddMessage(sender, message) { 52 | let chatMessagesContainer = document.querySelector('.lwh-open-cbot .chat__messages'); 53 | let messageContainer = document.createElement('div'); 54 | messageContainer.classList.add('chat__messages__' + sender); 55 | let messageDiv = document.createElement('div'); 56 | messageDiv.innerHTML = ` 57 | ${sender === 'ai' ? 58 | ` 59 |
60 | bot-image 63 |
64 | ` 65 | : "" 66 | } 67 |

${message} 68 |

69 | ${sender === 'user' ? 70 | ` 71 |
72 | avatar 75 |
76 | ` 77 | : "" 78 | } 79 | `; 80 | messageContainer.appendChild(messageDiv); 81 | chatMessagesContainer.appendChild(messageContainer); 82 | chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight; 83 | } 84 | 85 | function lwhOpenCbotaddTypingAnimation(sender) { 86 | let chatMessagesContainer = document.querySelector('.lwh-open-cbot .chat__messages'); 87 | let typingContainer = document.createElement('div'); 88 | typingContainer.classList.add('chat__messages__' + sender); 89 | let typingAnimationDiv = document.createElement('div'); 90 | typingAnimationDiv.classList.add('typing-animation'); 91 | typingAnimationDiv.innerHTML = ` 92 |
93 | 96 |
97 |

98 | 99 | 100 | 101 | 102 | 103 |

104 | `; 105 | typingContainer.appendChild(typingAnimationDiv); 106 | chatMessagesContainer.appendChild(typingContainer); 107 | chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight; 108 | } 109 | 110 | function lwhOpenCbotreplaceTypingAnimationWithMessage(sender, message) { 111 | let chatMessagesContainer = document.querySelector('.lwh-open-cbot .chat__messages'); 112 | let typingContainer = document.querySelector('.lwh-open-cbot .chat__messages__' + sender + ':last-child'); 113 | if (typingContainer) { 114 | let messageContainer = document.createElement('div'); 115 | messageContainer.classList.add('chat__messages__' + sender); 116 | messageContainer.classList.add('chat_messages_ai'); 117 | let messageDiv = document.createElement('div'); 118 | messageDiv.innerHTML = ` 119 | ${sender === 'ai' ? 120 | ` 121 |
122 | bot-image 125 |
126 | ` 127 | : "" 128 | } 129 |

130 | ${sender === 'user' ? 131 | ` 132 |
133 | avatar 136 |
137 | ` 138 | : "" 139 | } 140 | `; 141 | messageContainer.appendChild(messageDiv); 142 | typingContainer.parentNode.replaceChild(messageContainer, typingContainer); 143 | const typingEffectElement = messageDiv.querySelector(".typing-effect"); 144 | let index = 0; 145 | const typingInterval = setInterval(() => { 146 | typingEffectElement.textContent += message[index]; 147 | index++; 148 | if (index === message.length) { 149 | clearInterval(typingInterval); 150 | typingEffectElement.insertAdjacentHTML('beforeend', `copied`); 151 | chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight; 152 | } 153 | }, 5); 154 | chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight; 155 | } 156 | } 157 | 158 | function lwhOpenCbotremoveTypingAnimation() { 159 | let typingAnimationDivs = document.querySelectorAll('.lwh-open-cbot .typing-animation'); 160 | typingAnimationDivs.forEach(function (typingAnimationDiv) { 161 | let chatMessagesAiDiv = typingAnimationDiv.closest('.chat__messages__ai'); 162 | if (chatMessagesAiDiv) { 163 | chatMessagesAiDiv.parentNode.removeChild(chatMessagesAiDiv); 164 | } 165 | }); 166 | } 167 | 168 | copyButtons.forEach(button => { 169 | button.addEventListener('click', function (event) { 170 | const codeElement = this.parentNode.nextElementSibling.querySelector('code'); 171 | const codeText = codeElement.textContent; 172 | navigator.clipboard.writeText(codeText).then(function () { 173 | event.target.innerText = "Copied"; 174 | setTimeout(() => { 175 | event.target.innerText = "Copy"; 176 | }, 2000); 177 | }).catch(function (error) { 178 | console.error('Error copying code: ', error); 179 | }); 180 | }); 181 | }); 182 | 183 | function lwhOpenCbotcopyText(event) { 184 | const paragraph = event.target.closest('p'); 185 | const clone = paragraph.cloneNode(true); 186 | clone.querySelectorAll('.copy-text').forEach(elem => { 187 | elem.parentNode.removeChild(elem); 188 | }); 189 | const textToCopy = clone.textContent.trim(); 190 | navigator.clipboard.writeText(textToCopy) 191 | .then(() => { 192 | const copiedSpan = event.target.nextElementSibling; 193 | copiedSpan.style.display = 'block'; 194 | setTimeout(() => { 195 | copiedSpan.style.display = 'none'; 196 | }, 2000); 197 | }) 198 | .catch(error => { 199 | console.error('Error copying text: ', error); 200 | }); 201 | } 202 | 203 | async function lwhOpenCbotfetchData() { 204 | button.disabled = true; 205 | try { 206 | response = await fetch(apiUrl, { 207 | method: 'POST', 208 | headers: { 209 | 'Content-Type': 'application/json' 210 | }, 211 | body: JSON.stringify({ 212 | "last_prompt": content[content.length - 1].message, 213 | "conversation_history": content.map(item => ({ 214 | "role": item.role, 215 | "content": item.message 216 | })) 217 | }) 218 | }); 219 | if (response.ok) { 220 | data = await response.json(); 221 | console.log(data, "Data from api"); 222 | button.disabled = false; 223 | if (!data.success) { 224 | lwhOpenCbotremoveTypingAnimation() 225 | lwhOpenCbotshowPopup('Oops! Something went wrong!', '#991a1a'); 226 | throw new Error("Something went wrong. Please Try Again!"); 227 | } 228 | } else { 229 | lwhOpenCbotshowPopup('Oops! Something went wrong!', '#991a1a'); 230 | throw new Error("Request failed. Please try again!"); 231 | } 232 | content.push({ 233 | role: 'assistant', 234 | message: data.result, 235 | }); 236 | let timestamp = new Date().toLocaleString(); 237 | conversationTranscript.push({ 238 | sender: 'bot', 239 | time: timestamp, 240 | message: data.result, 241 | }); 242 | lwhOpenCbotreplaceTypingAnimationWithMessage('ai', data.result); 243 | } catch (error) { 244 | lwhOpenCbotremoveTypingAnimation(); 245 | lwhOpenCbotshowPopup('Oops! Something went wrong!', '#991a1a'); 246 | console.error('There was a problem with the fetch operation:', error); 247 | return; 248 | } 249 | } 250 | 251 | async function lwhOpenCbotfetchBotConfiguration() { 252 | const chatMessagesContainer = document.querySelector(".lwh-open-cbot .chat__messages"); 253 | document.querySelector(".lwh-open-cbot .loading").style.display = 'flex'; 254 | chatMessagesContainer.innerHTML = ''; 255 | let startupBtnsDiv = document.createElement('div'); 256 | startupBtnsDiv.classList.add('startup-btns'); 257 | chatMessagesContainer.appendChild(startupBtnsDiv); 258 | let botResponse = '' 259 | try { 260 | botResponse = await fetch(botConfigurationUrl); 261 | if (botResponse.ok) { 262 | botConfigData = await botResponse.json(); 263 | console.log(botConfigData, "Data from api"); 264 | chatMessagesContainer.style.fontSize = `${botConfigData.fontSize}px`; 265 | let startupBtns='' 266 | const startupBtnContainer = document.querySelector('.lwh-open-cbot .startup-btns'); 267 | botConfigData.commonButtons.forEach(btn => { 268 | startupBtns += `

${btn.buttonText}

`; 269 | }); 270 | startupBtnContainer.innerHTML = startupBtns; 271 | if (botConfigData.botStatus == 1) { 272 | document.querySelector(".lwh-open-cbot .chat__status").innerHTML = ` Online`; 273 | document.querySelector(".lwh-open-cbot .chat__status").querySelector("span").style.background = "#68D391"; 274 | } 275 | 276 | document.querySelector(".lwh-open-cbot .loading").style.display = 'none'; 277 | lwhOpenCbotaddMessage('ai', botConfigData.StartUpMessage); 278 | content.push({ 279 | role: 'assistant', 280 | message: botConfigData.StartUpMessage, 281 | }); 282 | let timestamp = new Date().toLocaleString(); 283 | conversationTranscript.push({ 284 | sender: 'bot', 285 | time: timestamp, 286 | message: botConfigData.StartUpMessage, 287 | }); 288 | } else { 289 | document.querySelector(".lwh-open-cbot .loading").style.display = 'none'; 290 | lwhOpenCbotshowPopup('Oops! Something went wrong!', '#991a1a'); 291 | throw new Error("Request failed. Please try again!"); 292 | } 293 | } catch (error) { 294 | lwhOpenCbotshowPopup('Oops! Something went wrong!', '#991a1a'); 295 | button.disabled = true 296 | console.error('There was a problem with the fetch operation:', error); 297 | return; 298 | } 299 | } 300 | 301 | function lwhOpenCbotshowPopup(val, color) { 302 | button.disabled = false; 303 | const popup = document.querySelector('.lwh-open-cbot .popup'); 304 | popup.style.display = 'block'; 305 | popup.style.opacity = 1; 306 | const innerPopup = popup.querySelector('p'); 307 | innerPopup.innerText = val; 308 | innerPopup.style.color = color; 309 | popup.classList.add('popup-animation'); 310 | setTimeout(() => { 311 | popup.classList.remove('popup-animation'); 312 | popup.style.display = 'none'; 313 | popup.style.opacity = 0; 314 | }, 3000); 315 | } 316 | 317 | 318 | function lwhOpenCbothandleStartupBtnClick(event){ 319 | const startupBtnContainer = event.target.parentNode; 320 | startupBtnContainer.style.display = 'none'; 321 | } 322 | 323 | lwhOpenCbotfetchBotConfiguration(); 324 | -------------------------------------------------------------------------------- /base-chatbot/frontend/style.css: -------------------------------------------------------------------------------- 1 | .lwh-open-cbot, .lwh-open-cbot :root { 2 | --chatbot-width: 350px; 3 | --chatbot-font-family: 'Segoe UI'; 4 | --chatbot-image-position-bottom: 5%; 5 | --chatbot-image-position-right: 3%; 6 | --chatbot-position-bottom: 6%; 7 | --chatbot-position-right: 10%; 8 | --chatbot-height:60vh; 9 | --chatbot-border-color: #E4E3E3; 10 | --chatbot-primary-color: #2B2A66; 11 | --chatbot-secondary-color: #2c2b8e; 12 | --chatbot-hover-color: #1e8ece; 13 | --chatbot-bg-color: #F1F1F1; 14 | --chatbot-scrollbar-track-color: #f3f3f3; 15 | --chatbot-scrollbar-thumb-color: #d7d7d7; 16 | --chatbot-scrollbar-thumb-hover-color: #949494; 17 | --chatbot-button-disabled-color: grey; 18 | --chatbot-popup-bg-color: #fff; 19 | --chatbot-dot-color: grey; 20 | } 21 | 22 | .lwh-open-cbot *, 23 | .lwh-open-cbot *::after, 24 | .lwh-open-cbot *::before, 25 | .lwh-open-cbot *:focus { 26 | box-sizing: border-box; 27 | margin: 0; 28 | padding: 0; 29 | } 30 | 31 | .lwh-open-cbot *:focus { 32 | box-shadow: none; 33 | } 34 | 35 | 36 | .lwh-open-cbot .custom-chatbot { 37 | width: var(--chatbot-width); 38 | font-family: var(--chatbot-font-family); 39 | position: fixed; 40 | bottom: var(--chatbot-position-bottom); 41 | right: var(--chatbot-position-right); 42 | overflow: hidden; 43 | z-index: 9998; 44 | } 45 | 46 | .lwh-open-cbot .custom-chatbot .chat__messages__ai a { 47 | color: var(--chatbot-primary-color); 48 | text-decoration: none; 49 | } 50 | 51 | .lwh-open-cbot .chat { 52 | background-color: white; 53 | position: relative; 54 | z-index: 9999; 55 | border: 1.5px solid var(--chatbot-border-color); 56 | border-radius: 12px; 57 | opacity: 0; 58 | transform: translateY(100%); 59 | transition: opacity 0.5s ease-in-out, transform 0.5s ease-in-out, display 0s linear 0.5s; 60 | } 61 | 62 | .lwh-open-cbot .chat.show { 63 | opacity: 1; 64 | transform: translateY(0); 65 | transition-delay: 0s; 66 | } 67 | 68 | .lwh-open-cbot .custom-chatbot__image { 69 | position: fixed; 70 | right: var(--chatbot-image-position-right); 71 | bottom: var(--chatbot-image-position-bottom); 72 | z-index: 9999; 73 | cursor: pointer; 74 | } 75 | 76 | .lwh-open-cbot .custom-chatbot button { 77 | border: none; 78 | background: none; 79 | } 80 | 81 | .lwh-open-cbot .custom-chatbot button>i { 82 | color: var(--chatbot-primary-color); 83 | font-size: 18px; 84 | } 85 | 86 | .lwh-open-cbot .custom-chatbot button:hover i { 87 | color: var(--chatbot-hover-color); 88 | cursor: pointer; 89 | } 90 | 91 | .lwh-open-cbot .custom-chatbot input[type='text'] { 92 | border: none; 93 | outline: none; 94 | padding: 0; 95 | box-shadow: none !important; 96 | } 97 | 98 | .lwh-open-cbot .chat__header { 99 | display: flex; 100 | justify-content: space-between; 101 | border-bottom: 1.5px solid var(--chatbot-border-color); 102 | padding: 12px 10px; 103 | align-items: flex-start; 104 | position: relative; 105 | z-index: 1; 106 | } 107 | 108 | .lwh-open-cbot .chat__header>div:nth-child(1)>div:nth-child(2) { 109 | display: flex; 110 | align-items: end; 111 | gap: 1rem; 112 | margin-top: 4px; 113 | } 114 | 115 | .lwh-open-cbot .chat__header .chat__new { 116 | font-size: 11px; 117 | font-weight: 500; 118 | padding: 3px 6px 4px 6px; 119 | background-color: var(--chatbot-primary-color); 120 | color: white; 121 | cursor: pointer; 122 | border-radius: 4px; 123 | } 124 | 125 | .lwh-open-cbot .chat__header .chat__new:hover { 126 | background-color: var(--chatbot-hover-color); 127 | } 128 | 129 | .lwh-open-cbot .chat__header>div:nth-child(2) { 130 | display: flex; 131 | gap: 0.5rem; 132 | align-items: center; 133 | } 134 | 135 | .lwh-open-cbot .chat__export i, 136 | .lwh-open-cbot .chat__close-icon i { 137 | display: block; 138 | } 139 | 140 | .lwh-open-cbot .chat__export i:hover, 141 | .lwh-open-cbot .chat__close-icon i:hover, 142 | .lwh-open-cbot .copy-text i:hover, 143 | .lwh-open-cbot .feedback-btn:hover, 144 | .lwh-open-cbot .feedback__modal-close:hover { 145 | color: var(--chatbot-hover-color); 146 | cursor: pointer; 147 | } 148 | 149 | .lwh-open-cbot .chat__export { 150 | font-size: 12px; 151 | cursor: pointer; 152 | width: -moz-fit-content; 153 | width: fit-content; 154 | margin-left: -1px; 155 | } 156 | 157 | .lwh-open-cbot .chat__title { 158 | font-weight: 500; 159 | font-size: 18px; 160 | } 161 | 162 | .lwh-open-cbot .chat__title span { 163 | font-size: 12px; 164 | } 165 | 166 | .lwh-open-cbot .chat__status { 167 | font-size: 14px; 168 | font-weight: 500; 169 | color: rgba(0, 0, 0, 0.6); 170 | display: flex; 171 | gap: 6px; 172 | align-items: center; 173 | margin-top: 4px; 174 | } 175 | 176 | .lwh-open-cbot .chat__status span { 177 | background-color: #68D391; 178 | background-color: #acacac; 179 | width: 8px; 180 | height: 8px; 181 | display: block; 182 | border-radius: 100px; 183 | } 184 | 185 | .lwh-open-cbot .chat__close-icon { 186 | cursor: pointer; 187 | position: relative; 188 | z-index: 1; 189 | } 190 | 191 | .lwh-open-cbot .chat__messages { 192 | padding: 12px 10px 0 10px; 193 | display: flex; 194 | flex-direction: column; 195 | gap: 16px; 196 | height: var(--chatbot-height); 197 | overflow-y: auto; 198 | position: relative; 199 | } 200 | 201 | .lwh-open-cbot .chat__messages::-webkit-scrollbar, 202 | .lwh-open-cbot .chat__messages__ai code::-webkit-scrollbar { 203 | width: 3px; 204 | height: 5px; 205 | } 206 | 207 | .lwh-open-cbot .chat__messages::-webkit-scrollbar-track, 208 | .lwh-open-cbot .chat__messages__ai code::-webkit-scrollbar-track { 209 | background: var(--chatbot-scrollbar-track-color); 210 | } 211 | 212 | .lwh-open-cbot .chat__messages::-webkit-scrollbar-thumb, 213 | .lwh-open-cbot .chat__messages__ai code::-webkit-scrollbar-thumb { 214 | background: var(--chatbot-scrollbar-thumb-color); 215 | border-radius: 100px; 216 | } 217 | 218 | .lwh-open-cbot .chat__messages::-webkit-scrollbar-thumb:hover, 219 | .lwh-open-cbot .chat__messages__ai code::-webkit-scrollbar-thumb:hover { 220 | background: var(--chatbot-scrollbar-thumb-hover-color); 221 | } 222 | 223 | .lwh-open-cbot .chat__messages__user, 224 | .lwh-open-cbot .chat__messages__ai { 225 | display: flex; 226 | gap: 6px; 227 | flex-direction: column; 228 | width: calc(100% - 38px); 229 | } 230 | 231 | .lwh-open-cbot .chat__messages__user { 232 | align-self: flex-end; 233 | } 234 | 235 | .lwh-open-cbot .chat__messages__user>div { 236 | align-items: end; 237 | align-self: flex-end; 238 | } 239 | 240 | .lwh-open-cbot .chat__messages__ai>div, 241 | .lwh-open-cbot .chat__messages__user>div { 242 | display: flex; 243 | gap: 0.5rem; 244 | } 245 | 246 | .lwh-open-cbot .chat__messages__ai p { 247 | background-color: var(--chatbot-bg-color); 248 | padding: 6px 12px; 249 | border-radius: 0px 8px 8px 8px; 250 | width: -moz-fit-content; 251 | width: fit-content; 252 | align-self: flex-start; 253 | display: flex; 254 | justify-content: space-between; 255 | gap: 0.5rem; 256 | position: relative; 257 | padding-right: 20px; 258 | } 259 | 260 | .lwh-open-cbot .chat__messages__ai .code-snippet { 261 | background-color: rgb(27, 27, 27); 262 | border-radius: 8px; 263 | } 264 | 265 | .lwh-open-cbot .chat__messages__ai pre { 266 | display: flex; 267 | overflow: hidden; 268 | } 269 | 270 | .lwh-open-cbot .chat__messages__ai code { 271 | display: block; 272 | padding: 10px; 273 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 274 | color: #f8f8f8; 275 | overflow-x: auto; 276 | word-break: normal; 277 | word-spacing: normal; 278 | white-space: pre; 279 | align-self: flex-start; 280 | text-align: left; 281 | } 282 | 283 | .lwh-open-cbot .snippet-header { 284 | background: rgb(164, 164, 164); 285 | border-radius: 8px 8px 0 0; 286 | padding: 6px 12px; 287 | } 288 | 289 | .lwh-open-cbot .snippet-header button { 290 | cursor: pointer; 291 | color: rgb(55 55 55); 292 | font-weight: 600; 293 | } 294 | 295 | .lwh-open-cbot .chat__messages__ai img:not(.bot-image) { 296 | padding: 6px 12px; 297 | border-radius: 0px 8px 8px 8px; 298 | align-self: flex-start; 299 | border: 1.5px solid var(--chatbot-bg-color); 300 | max-width: 160px; 301 | } 302 | 303 | .lwh-open-cbot .chat__messages__user p { 304 | background-color: var(--chatbot-primary-color); 305 | padding: 6px 12px; 306 | border-radius: 8px 8px 0px 8px; 307 | color: white; 308 | width: -moz-fit-content; 309 | width: fit-content; 310 | align-self: flex-end; 311 | } 312 | 313 | .lwh-open-cbot .chat__messages__user img:not(.avatar-image) { 314 | padding: 6px 12px; 315 | border-radius: 8px 8px 0px 8px; 316 | align-self: flex-end; 317 | border: 1.5px solid var(--chatbot-primary-color); 318 | max-width: 160px; 319 | } 320 | 321 | .lwh-open-cbot .chat__input-area { 322 | padding: 12px 10px; 323 | position: relative; 324 | z-index: 1; 325 | } 326 | 327 | .lwh-open-cbot .chat__input-area>form { 328 | border: 2px solid var(--chatbot-border-color); 329 | border-radius: 10px; 330 | padding: 8px 10px; 331 | } 332 | 333 | .lwh-open-cbot .chat__input-area>form>div { 334 | display: flex; 335 | gap: 6px; 336 | align-items: center; 337 | } 338 | 339 | .lwh-open-cbot .chat__input-area .input { 340 | display: flex; 341 | gap: 6px; 342 | width: 100%; 343 | align-items: center; 344 | } 345 | 346 | .lwh-open-cbot .chat__input-area .input label { 347 | font-size: 12px; 348 | opacity: 0.7; 349 | } 350 | 351 | .lwh-open-cbot .chat__input-area .input label:hover { 352 | color: var(--chatbot-secondary-color); 353 | cursor: pointer; 354 | opacity: 1; 355 | } 356 | 357 | .lwh-open-cbot .chat__input-area .input>div:nth-child(1), 358 | .lwh-open-cbot .chat__input-area .input input { 359 | width: 100%; 360 | font-size: 16px; 361 | } 362 | 363 | .lwh-open-cbot .custom-chatbot button[disabled] i { 364 | cursor: not-allowed; 365 | color: var(--chatbot-button-disabled-color); 366 | } 367 | 368 | .lwh-open-cbot .popup { 369 | display: none; 370 | width: 100%; 371 | position: absolute; 372 | background-color: var(--chatbot-popup-bg-color); 373 | padding: 12px; 374 | border-radius: 4px; 375 | top: 1%; 376 | opacity: 0; 377 | font-weight: 500; 378 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); 379 | z-index: 2; 380 | } 381 | 382 | .lwh-open-cbot .popup-animation { 383 | animation: slideInRight 0.5s ease forwards, fadeOut 2s ease forwards 3s; 384 | } 385 | 386 | .lwh-open-cbot .popup p { 387 | color: var(--chatbot-popup-text-color); 388 | } 389 | 390 | .lwh-open-cbot .popup .close-btn { 391 | position: absolute; 392 | top: 5px; 393 | right: 5px; 394 | cursor: pointer; 395 | } 396 | 397 | @keyframes slideUp { 398 | from { 399 | transform: translateY(100%); 400 | opacity: 0; 401 | } 402 | to { 403 | transform: translateY(0); 404 | opacity: 1; 405 | } 406 | } 407 | 408 | @keyframes slideInRight { 409 | from { 410 | transform: translateX(100%); 411 | opacity: 0; 412 | } 413 | to { 414 | transform: translateX(0); 415 | opacity: 1; 416 | } 417 | } 418 | 419 | @keyframes fadeOut { 420 | from { 421 | opacity: 1; 422 | } 423 | to { 424 | opacity: 0; 425 | } 426 | } 427 | 428 | @keyframes blink { 429 | 50% { 430 | fill: transparent; 431 | } 432 | } 433 | 434 | .lwh-open-cbot .dot { 435 | animation: 1s blink infinite; 436 | fill: var(--chatbot-dot-color); 437 | } 438 | 439 | .lwh-open-cbot .dot:nth-child(2) { 440 | animation-delay: 250ms; 441 | } 442 | 443 | .lwh-open-cbot .dot:nth-child(3) { 444 | animation-delay: 500ms; 445 | } 446 | 447 | .lwh-open-cbot .loading { 448 | position: absolute; 449 | top: 0; 450 | display: flex; 451 | flex-direction: column; 452 | width: 100%; 453 | height: 100%; 454 | justify-content: center; 455 | align-items: center; 456 | text-align: center; 457 | font-size: 20px; 458 | } 459 | 460 | .lwh-open-cbot .copy-text { 461 | cursor: pointer; 462 | font-size: 12px; 463 | position: absolute; 464 | top: 4px; 465 | right: 4px; 466 | } 467 | 468 | .lwh-open-cbot .copy-text span { 469 | display: none; 470 | position: absolute; 471 | background-color: white; 472 | border-radius: 4px; 473 | padding: 0px 6px 1px 6px; 474 | color: black; 475 | border: 1px solid var(--chatbot-border-color); 476 | } 477 | 478 | .lwh-open-cbot .avatar-image { 479 | display: block; 480 | } 481 | 482 | .lwh-open-cbot .startup-btns { 483 | display: flex; 484 | flex-wrap: wrap; 485 | gap: 6px; 486 | position: absolute; 487 | bottom: 0; 488 | } 489 | 490 | .lwh-open-cbot .startup-btns p { 491 | padding: 6px 10px; 492 | border: 1px solid var(--chatbot-border-color); 493 | border-radius: 4px; 494 | width: -moz-fit-content; 495 | width: fit-content; 496 | cursor: pointer; 497 | } 498 | 499 | .lwh-open-cbot .startup-btns p:hover { 500 | background-color: var(--chatbot-hover-color); 501 | color: white; 502 | } 503 | 504 | .lwh-open-cbot .feedback-form { 505 | background: white; 506 | border-radius: 4px; 507 | box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.2); 508 | position: absolute; 509 | width: 100%; 510 | top: 50%; 511 | left: 50%; 512 | transform: translate(-50%, -50%); 513 | z-index: 1; 514 | padding: 0.8rem; 515 | display: flex; 516 | flex-direction: column; 517 | justify-content: space-between; 518 | display: none; 519 | } 520 | 521 | .lwh-open-cbot .feedback-form.show { 522 | display: flex; 523 | } 524 | 525 | .lwh-open-cbot .feedback-header { 526 | display: flex; 527 | justify-content: space-between; 528 | align-items: flex-start; 529 | padding: 0 0 0.8rem 0; 530 | } 531 | 532 | .lwh-open-cbot .feedback-form form { 533 | display: flex; 534 | flex-direction: column; 535 | align-items: baseline; 536 | } 537 | 538 | .lwh-open-cbot .feedback-form textarea { 539 | width: 100%; 540 | border: 2px solid var(--chatbot-border-color); 541 | outline: none; 542 | padding: 6px; 543 | font-size: 16px; 544 | } 545 | 546 | .lwh-open-cbot .feedback-form button { 547 | background: var(--chatbot-primary-color); 548 | padding: 0.7rem; 549 | color: white; 550 | cursor: pointer; 551 | margin-top: 0.5rem; 552 | font-size: 14px; 553 | font-weight: 400; 554 | } 555 | 556 | .lwh-open-cbot .feedback-form button[disabled] { 557 | cursor: not-allowed; 558 | background-color: var(--chatbot-button-disabled-color) !important; 559 | } 560 | 561 | .lwh-open-cbot .feedback-form button:hover { 562 | background: var(--chatbot-hover-color); 563 | } 564 | 565 | .lwh-open-cbot .footer-area { 566 | padding: 0 10px 10px 10px; 567 | font-size: 11px; 568 | display: none; 569 | } 570 | 571 | .lwh-open-cbot .footer-area a { 572 | text-decoration: none; 573 | } 574 | 575 | @media (max-width: 679px) { 576 | .lwh-open-cbot .custom-chatbot { 577 | position: fixed; 578 | top: 50%; 579 | left: 50%; 580 | transform: translate(-50%, -50%); 581 | right: auto; 582 | bottom: auto; 583 | } 584 | } 585 | --------------------------------------------------------------------------------