nmdx-portfolio / components /chat-widget.js
dodey917's picture
Create a modern, high-end UX/UI designer portfolio website with the following features and requirements:
ca5829a verified
class CustomChatWidget extends HTMLElement {
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
.chat-widget {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 999;
}
.chat-bubble {
width: 60px;
height: 60px;
background: linear-gradient(135deg, #9333ea, #3b82f6);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 4px 20px rgba(147, 51, 234, 0.4);
transition: all 0.3s ease;
position: relative;
}
.chat-bubble:hover {
transform: scale(1.1);
box-shadow: 0 6px 30px rgba(147, 51, 234, 0.6);
}
.chat-bubble .notification {
position: absolute;
top: -5px;
right: -5px;
background: #ef4444;
color: white;
width: 20px;
height: 20px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
}
.chat-window {
position: absolute;
bottom: 80px;
right: 0;
width: 380px;
height: 500px;
background: #1a1a2e;
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
display: none;
flex-direction: column;
border: 1px solid rgba(147, 51, 234, 0.3);
overflow: hidden;
}
.chat-window.open {
display: flex;
animation: slideUp 0.3s ease;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.chat-header {
background: linear-gradient(135deg, #9333ea, #3b82f6);
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.chat-header h3 {
color: white;
font-size: 1.1rem;
font-weight: 600;
}
.chat-header .status {
display: flex;
align-items: center;
gap: 0.5rem;
color: white;
font-size: 0.875rem;
}
.status-dot {
width: 8px;
height: 8px;
background: #10b981;
border-radius: 50%;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 1rem;
background: #111827;
}
.message {
margin-bottom: 1rem;
display: flex;
gap: 0.5rem;
}
.message.bot {
flex-direction: row;
}
.message.user {
flex-direction: row-reverse;
}
.message-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
.message.bot .message-avatar {
background: linear-gradient(135deg, #9333ea, #3b82f6);
}
.message.user .message-avatar {
background: #374151;
}
.message-content {
max-width: 70%;
padding: 0.75rem;
border-radius: 12px;
font-size: 0.875rem;
line-height: 1.5;
}
.message.bot .message-content {
background: #374151;
color: white;
border-bottom-left-radius: 4px;
}
.message.user .message-content {
background: #9333ea;
color: white;
border-bottom-right-radius: 4px;
}
.typing-indicator {
display: none;
align-items: center;
gap: 0.25rem;
}
.typing-indicator.active {
display: flex;
}
.typing-dot {
width: 8px;
height: 8px;
background: #6b7280;
border-radius: 50%;
animation: typing 1.4s infinite;
}
.typing-dot:nth-child(2) {
animation-delay: 0.2s;
}
.typing-dot:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes typing {
0%, 60%, 100% {
transform: translateY(0);
}
30% {
transform: translateY(-10px);
}
}
.chat-input {
padding: 1rem;
background: #1a1a2e;
border-top: 1px solid rgba(147, 51, 234, 0.2);
}
.chat-input-container {
display: flex;
gap: 0.5rem;
}
.chat-input input {
flex: 1;
padding: 0.75rem;
background: #374151;
border: 1px solid rgba(147, 51, 234, 0.3);
border-radius: 8px;
color: white;
font-size: 0.875rem;
outline: none;
transition: all 0.3s ease;
}
.chat-input input:focus {
border-color: #9333ea;
box-shadow: 0 0 0 2px rgba(147, 51, 234, 0.1);
}
.chat-input button {
padding: 0.75rem 1rem;
background: linear-gradient(135deg, #9333ea, #3b82f6);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
}
.chat-input button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(147, 51, 234, 0.4);
}
.chat-input button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
@media (max-width: 640px) {
.chat-window {
width: calc(100vw - 40px);
right: -10px;
left: -10px;
}
}
</style>
<div class="chat-widget">
<div class="chat-bubble" onclick="toggleChat()">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
</svg>
<span class="notification">1</span>
</div>
<div class="chat-window" id="chatWindow">
<div class="chat-header">
<h3>NMDX Assistant</h3>
<div class="status">
<span class="status-dot"></span>
<span>Online</span>
</div>
</div>
<div class="chat-messages" id="chatMessages">
<div class="message bot">
<div class="message-avatar">πŸ€–</div>
<div class="message-content">
Hi! Welcome to NMDX! πŸ‘‹ I'm here to help you find the perfect service for your needs. What can I assist you with today?
</div>
</div>
</div>
<div class="typing-indicator" id="typingIndicator">
<div class="typing-dot"></div>
<div class="typing-dot"></div>
<div class="typing-dot"></div>
</div>
<div class="chat-input">
<div class="chat-input-container">
<input type="text" id="chatInput" placeholder="Type your message..." onkeypress="handleChatKeyPress(event)">
<button onclick="sendMessage()" id="sendBtn">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="22" y1="2" x2="11" y2="13"></line>
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
</svg>
Send
</button>
</div>
</div>
</div>
</div>
`;
}
}
// Global chat functions
window.toggleChat = function() {
const chatWindow = document.querySelector('custom-chat-widget').shadowRoot.getElementById('chatWindow');
chatWindow.classList.toggle('open');
// Remove notification when opened
if (chatWindow.classList.contains('open')) {
const notification = document.querySelector('custom-chat-widget').shadowRoot.querySelector('.notification');
notification.style.display = 'none';
}
};
window.sendMessage = function() {
const chatInput = document.querySelector('custom-chat-widget').shadowRoot.getElementById('chatInput');
const message = chatInput.value.trim();
if (!message) return;
const chatMessages = document.querySelector('custom-chat-widget').shadowRoot.getElementById('chatMessages');
const typingIndicator = document.querySelector('custom-chat-widget').shadowRoot.getElementById('typingIndicator');
// Add user message
const userMessage = document.createElement('div');
userMessage.className = 'message user';
userMessage.innerHTML = `
<div class="message-avatar">πŸ‘€</div>
<div class="message-content">${message}</div>
`;
chatMessages.appendChild(userMessage);
// Clear input
chatInput.value = '';
// Show typing indicator
typingIndicator.classList.add('active');
// Simulate bot response
setTimeout(() => {
typingIndicator.classList.remove('active');
const botResponse = getBotResponse(message);
const botMessage = document.createElement('div');
botMessage.className = 'message bot';
botMessage.innerHTML = `
<div class="message-avatar">πŸ€–</div>
<div class="message-content">${botResponse}</div>
`;
chatMessages.appendChild(botMessage);
// Scroll to bottom
chatMessages.scrollTop = chatMessages.scrollHeight;
}, 1500);
// Scroll to bottom
chatMessages.scrollTop = chatMessages.scrollHeight;
};
window.handleChatKeyPress = function(event) {
if (event.key === 'Enter') {
sendMessage();
}
};
function getBotResponse(message) {
const lowerMessage = message.toLowerCase();
if (lowerMessage.includes('telegram')) {
return "Our Telegram promotion services are top-notch! We can help you grow your channel with targeted campaigns, influencer partnerships, and community engagement strategies. Would you like to know more about our Telegram Ads or Community Management services?";
} else if (lowerMessage.includes('token') || lowerMessage.includes('crypto')) {
return "Great choice for token promotion! We offer comprehensive crypto marketing solutions including token launches, community building, and strategic partnerships. Our team has helped raise millions for various projects. What type of token are you promoting?";
} else if (lowerMessage.includes('app')) {
return "For app promotion and development, we've got you covered! From ASO optimization to viral marketing campaigns, we'll help your app reach millions of users. Are you looking to promote an existing app or develop a new one?";
} else if (lowerMessage.includes('youtube') || lowerMessage.includes('video')) {
return "YouTube promotion is our specialty! We can help you grow your channel, increase views, and build a loyal subscriber base through organic and paid strategies. What type of content do you create?";
} else if (lowerMessage.includes('price') || lowerMessage.includes('cost')) {
return "Our pricing varies based on your specific needs and goals. We offer customized packages for every budget. Would you like to schedule a free consultation to discuss your requirements and get a personalized quote?";
} else if (lowerMessage.includes('contact') || lowerMessage.includes('talk')) {
return "I'd be happy to connect you with our team! You can fill out the contact form below, or I can collect some basic information here to get started. Which service interests you most?";
} else {
return "I'd be happy to help you with our digital marketing services! We specialize in Telegram promotion, token marketing, app development, and much more. What specific service are you interested in learning about?";
}
}
customElements.define('custom-chat-widget', CustomChatWidget);