[ Root System Explorer ]
Location:
Root
/
home
/
u456045770
/
domains
/
srmeshop.in
/
public_html
/
admin
/
chat
+ Folder
+ File
Upload
Editing: messages.php
<?php // Enable full error visibility error_reporting(E_ALL); ini_set('display_errors', 1); require_once '../config.php'; if (!isset($_SESSION['userdata']['id'])) { die('<div class="alert alert-warning text-center p-4"> <h5>Please Login</h5> <p>You must be logged in to use chat.</p> </div>'); } $current_user_id = (int)$_SESSION['userdata']['id']; $current_user_name = trim(($_SESSION['userdata']['firstname'] ?? '') . ' ' . ($_SESSION['userdata']['lastname'] ?? '')); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Chats</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <style> :root { --whatsapp-green: #25D366; --whatsapp-light-green: #DCF8C6; --whatsapp-gray: #ECE5DD; --whatsapp-dark-gray: #3C3C3C; --whatsapp-light-gray: #F0F0F0; --whatsapp-blue: #34B7F1; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; background: var(--whatsapp-gray); margin: 0; padding: 0; height: 100vh; } /* Mobile Responsive Styles */ .chat-container { height: calc(100vh - 60px); max-width: 1400px; margin: 0 auto; margin-top: 60px; /* Account for fixed navbar */ position: relative; overflow: hidden; } /* Desktop layout - both sidebar and chat area visible */ @media (min-width: 992px) { .chat-container.desktop-layout { display: flex; } .sidebar { display: flex !important; width: 30%; } .chat-area { display: flex !important; width: 70%; } .mobile-back-btn { display: none !important; } .mobile-chat-header { display: none !important; } } /* Mobile layout - only one panel visible at a time */ @media (max-width: 991px) { .chat-container.mobile-layout { display: flex; transition: transform 0.3s ease; position: relative; height: 100%; } .sidebar { width: 100%; min-width: 100%; position: absolute; top: 0; left: 0; height: 100%; transition: transform 0.3s ease; z-index: 10; } .chat-area { width: 100%; min-width: 100%; position: absolute; top: 0; left: 0; height: 100%; transition: transform 0.3s ease; transform: translateX(100%); z-index: 20; } .chat-area.active { transform: translateX(0); } .sidebar.hidden { transform: translateX(-100%); } .mobile-back-btn { display: inline-flex !important; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; border: none; background: transparent; color: #666; font-size: 20px; cursor: pointer; margin-right: 10px; flex-shrink: 0; } /* Simple CSS-only solution */ @media (max-width: 991px) { .mobile-back-arrow { display: inline-flex !important; align-items: center; } .desktop-brand { display: none !important; } } .mobile-chat-header { display: flex !important; align-items: center; padding: 10px 15px; background: #f0f2f5; border-bottom: 1px solid #e0e0e0; position: sticky; top: 0; z-index: 30; } .desktop-chat-header { display: none !important; } .nav-links { display: none; } .filter-tabs { overflow-x: auto; white-space: nowrap; -webkit-overflow-scrolling: touch; } .filter-tab { flex-shrink: 0; } .chat-avatar { width: 45px; height: 45px; font-size: 18px; } .chat-name { font-size: 15px; } .chat-time { font-size: 11px; } .message { max-width: 85%; } } /* Tablet layout */ @media (min-width: 768px) and (max-width: 991px) { .sidebar { width: 40%; } .chat-area { width: 60%; } } /* Mobile Chat Header */ .mobile-chat-header { display: none; } /* Current chat info adjustments for mobile */ .current-chat-info h6 { margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Mobile Loading State */ .mobile-loading { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(255, 255, 255, 0.9); display: flex; align-items: center; justify-content: center; z-index: 9999; display: none; } .mobile-loading.active { display: flex; } /* Clear search button */ #clearSearchBtn { display: none; } /* Ensure inputs are mobile-friendly */ .message-input, #searchChat { font-size: 16px !important; /* Prevents zoom on iOS */ } /* Top Navigation Bar */ .top-navbar { background: white; border-bottom: 1px solid #e0e0e0; padding: 0 15px; height: 60px; display: flex; align-items: center; justify-content: space-between; box-shadow: 0 1px 3px rgba(0,0,0,0.1); } .nav-brand { font-weight: 600; font-size: 18px; color: #25D366; text-decoration: none; } .nav-links { display: flex; align-items: center; gap: 20px; } .nav-link { color: #666; text-decoration: none; font-size: 14px; display: flex; align-items: center; gap: 5px; padding: 8px 12px; border-radius: 5px; transition: all 0.3s ease; } .nav-link:hover { background: #f5f5f5; color: #25D366; } .nav-link.active { color: #25D366; font-weight: 500; } .nav-link i { font-size: 16px; } .chat-container { height: calc(100vh - 60px); max-width: 1400px; margin: 0 auto; } /* Left Sidebar */ .sidebar { width: 30%; background: white; border-right: 1px solid #e0e0e0; height: 100%; display: flex; flex-direction: column; } .sidebar-header { background: #f0f2f5; padding: 10px 15px; border-bottom: 1px solid #e0e0e0; } .user-avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--whatsapp-green); color: white; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 18px; } .search-box { background: white; border-radius: 8px; padding: 8px 15px; margin: 10px 15px; display: flex; align-items: center; border: 1px solid #e0e0e0; } .search-box input { border: none; outline: none; width: 100%; margin-left: 10px; font-size: 14px; } .filter-tabs { display: flex; padding: 0 15px; margin-bottom: 10px; border-bottom: 1px solid #e0e0e0; } .filter-tab { padding: 8px 15px; font-size: 14px; color: #666; cursor: pointer; border-bottom: 2px solid transparent; } .filter-tab.active { color: var(--whatsapp-green); border-bottom-color: var(--whatsapp-green); font-weight: 500; } .chat-list { flex: 1; overflow-y: auto; } .chat-item { display: flex; padding: 12px 15px; border-bottom: 1px solid #f0f0f0; cursor: pointer; transition: background 0.2s; } .chat-item:hover { background: #f5f5f5; } .chat-item.active { background: #e6f7ff; } .chat-avatar { width: 50px; height: 50px; border-radius: 50%; background: #ddd; color: #666; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 20px; margin-right: 15px; } .chat-info { flex: 1; min-width: 0; } .chat-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; } .chat-name { font-weight: 500; font-size: 16px; color: #333; } .chat-time { font-size: 12px; color: #999; } .chat-preview { font-size: 14px; color: #666; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .unread-badge { background: var(--whatsapp-green); color: white; font-size: 12px; padding: 2px 8px; border-radius: 10px; margin-left: 5px; } /* Right Chat Area */ .chat-area { width: 70%; background: var(--whatsapp-gray); height: 100%; display: flex; flex-direction: column; } .chat-area-header { background: #f0f2f5; padding: 10px 15px; border-bottom: 1px solid #e0e0e0; display: flex; align-items: center; justify-content: space-between; } .current-chat-info { display: flex; align-items: center; } .chat-area-actions { display: flex; gap: 15px; } .action-btn { background: none; border: none; color: #666; font-size: 18px; cursor: pointer; } .messages-container { flex: 1; padding: 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; } .message-date { text-align: center; margin: 20px 0; color: #999; font-size: 12px; position: relative; } .message-date span { background: rgba(255,255,255,0.8); padding: 5px 15px; border-radius: 15px; } .message { max-width: 70%; padding: 8px 12px; border-radius: 8px; margin-bottom: 5px; position: relative; word-wrap: break-word; } .message.received { background: white; border-radius: 0 8px 8px 8px; align-self: flex-start; box-shadow: 0 1px 2px rgba(0,0,0,0.1); } .message.sent { background: var(--whatsapp-light-green); border-radius: 8px 0 8px 8px; align-self: flex-end; box-shadow: 0 1px 2px rgba(0,0,0,0.1); } .message-time { font-size: 11px; color: #999; text-align: right; margin-top: 5px; display: flex; align-items: center; justify-content: flex-end; gap: 5px; } .message.sent .message-time { color: #666; } .message-input-area { background: #f0f2f5; padding: 10px 15px; display: flex; align-items: center; gap: 10px; } .message-input { flex: 1; background: white; border: none; border-radius: 20px; padding: 10px 20px; font-size: 14px; outline: none; } .send-btn { background: var(--whatsapp-green); border: none; width: 40px; height: 40px; border-radius: 50%; color: white; cursor: pointer; display: flex; align-items: center; justify-content: center; } .empty-chat { display: flex; align-items: center; justify-content: center; height: 100%; text-align: center; color: #999; } /* Scrollbar */ ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { background: #f1f1f1; } ::-webkit-scrollbar-thumb { background: #c1c1c1; border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: #a8a8a8; } /* Dropdown Menu */ .dropdown-menu { min-width: 200px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); border: 1px solid #e0e0e0; } .dropdown-item { padding: 8px 15px; font-size: 14px; } .dropdown-item i { width: 20px; margin-right: 10px; } .dropdown-item:hover { background: #f5f5f5; } .dropdown-divider { margin: 5px 0; } /* Modal */ .modal-content { border-radius: 10px; border: none; box-shadow: 0 5px 20px rgba(0,0,0,0.1); } .modal-header { border-bottom: 1px solid #e0e0e0; padding: 15px 20px; } .modal-body { padding: 20px; } .modal-footer { border-top: 1px solid #e0e0e0; padding: 15px 20px; } .btn-outline-danger { border-color: #dc3545; color: #dc3545; } .btn-outline-danger:hover { background: #dc3545; color: white; } .chat-avatar { position: relative; } .chat-avatar::after { content: ''; position: absolute; bottom: 2px; right: 2px; width: 8px; height: 8px; border-radius: 50%; border: 1px solid white; } .chat-avatar.online::after { background: #25D366; } .chat-avatar.offline::after { background: #ccc; } .chat-avatar.admin::after { background: #FF6B6B; content: 'A'; font-size: 6px; color: white; display: flex; align-items: center; justify-content: center; } </style> </head> <body> <!-- Top Navigation Bar --> <nav class="top-navbar"> <div> <!-- Always show left arrow on mobile --> <a href="messages.php" class="nav-brand"> <i class="fas fa-sms" me-2"></i> Messages </a> </div> <div class="nav-links"> <a href="https://youtrips.in/" class="nav-link"> <i class="fas fa-mountain"></i> Youtrips </a> <a href="https://srmeshop.in" class="nav-link"> <i class="fas fa-basket"></i> SRM Eshop </a> <a href="/?page=packages&r=<?php echo md5(8) ?>" class="nav-link"> <i class="fas fa-suitcase-rolling"></i> China Tour </a> </div> </nav> <!-- Main Chat Container --> <div class="chat-container d-flex"> <!-- Left Sidebar --> <div class="sidebar"> <!-- Sidebar Header --> <div class="sidebar-header d-flex align-items-center justify-content-between"> <div class="d-flex align-items-center"> <div class="user-avatar me-3"> <?php echo strtoupper(substr($current_user_name, 0, 1)); ?> </div> <div> <h5 class="mb-0" style="font-size: 16px; font-weight: 500;">YouChat</h5> </div> </div> <div class="d-flex gap-3"> <button class="btn btn-link text-muted p-0"> <i class="fas fa-search"></i> </button> <div class="dropdown"> <button class="btn btn-link text-muted p-0" type="button" data-bs-toggle="dropdown"> <i class="fas fa-ellipsis-v"></i> </button> <ul class="dropdown-menu dropdown-menu-end"> <li><a class="dropdown-item" href="#"><i class="fas fa-user-plus"></i> New chat</a></li> <li><a class="dropdown-item" href="#"><i class="fas fa-users"></i> New group</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item" href="#"><i class="fas fa-cog"></i> Settings</a></li> </ul> </div> </div> </div> <!-- Search Box --> <div class="search-box"> <i class="fas fa-search text-muted"></i> <input type="text" id="searchChat" placeholder="Search or start new chat" onkeyup="searchChats()"> </div> <!-- Filter Tabs --> <div class="filter-tabs"> <div class="filter-tab active" onclick="filterChats('all')">All</div> <div class="filter-tab" onclick="filterChats('unread')">Unread</div> <div class="filter-tab" onclick="filterChats('favorites')">Favourites</div> <div class="filter-tab" onclick="filterChats('elite')">Elite</div> </div> <!-- Chat List --> <div class="chat-list" id="chatList"> <!-- Chat items will be loaded here --> <div class="text-center py-5 text-muted"> <i class="fas fa-comments fa-2x mb-3"></i> <p>Loading conversations...</p> </div> </div> </div> <!-- Right Chat Area --> <div class="chat-area"> <!-- Chat Area Header (Hidden when no chat selected) --> <div class="chat-area-header" id="chatHeader" style="display: none;"> <div class="current-chat-info"> <div class="chat-avatar me-3" id="currentChatAvatar"></div> <div> <h6 class="mb-0" id="currentChatName"></h6> <small class="text-muted" id="currentChatStatus">Last seen today at 3:18 pm</small> </div> </div> <div class="chat-area-actions"> <button class="action-btn" onclick="toggleFavorite()"> <i class="far fa-star" id="favoriteIcon"></i> </button> <div class="dropdown"> <button class="action-btn" type="button" data-bs-toggle="dropdown"> <i class="fas fa-ellipsis-v"></i> </button> <ul class="dropdown-menu dropdown-menu-end"> <li><a class="dropdown-item" href="#" onclick="viewContactInfo()"><i class="fas fa-info-circle"></i> Contact info</a></li> <li><a class="dropdown-item" href="#" onclick="clearChat()"><i class="fas fa-trash"></i> Clear chat</a></li> <li><a class="dropdown-item" href="#" onclick="deleteChat()"><i class="fas fa-times-circle"></i> Delete chat</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item text-danger" href="#" onclick="blockChat()"><i class="fas fa-ban"></i> Block</a></li> <li><a class="dropdown-item text-danger" href="#" onclick="reportChat()"><i class="fas fa-flag"></i> Report</a></li> </ul> </div> </div> </div> <!-- Messages Container --> <div class="messages-container" id="messagesContainer"> <div class="empty-chat" id="emptyChat"> <div> <i class="fas fa-comments fa-3x mb-3 text-muted"></i> <h4 class="text-muted mb-2">Chat to know more!</h4> <p class="text-muted">Select a conversation to start chatting</p> </div> </div> </div> <!-- Message Input Area --> <div class="message-input-area" id="messageInputArea" style="display: none;"> <button class="btn btn-link text-muted"> <i class="fas fa-paperclip"></i> </button> <input type="text" class="message-input" id="messageInput" placeholder="Type a message..."> <button class="send-btn" onclick="sendMessage()"> <i class="fas fa-paper-plane"></i> </button> </div> </div> </div> <!-- Clear Chat Modal --> <div class="modal fade" id="clearChatModal" tabindex="-1"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Clear Chat</h5> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body"> <p>Are you sure you want to clear this chat? This will delete all messages in this conversation.</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> <button type="button" class="btn btn-danger" onclick="confirmClearChat()">Clear Chat</button> </div> </div> </div> </div> <!-- Delete Chat Modal --> <div class="modal fade" id="deleteChatModal" tabindex="-1"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Delete Chat</h5> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body"> <p>Are you sure you want to delete this chat? This will permanently remove all messages and the conversation.</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> <button type="button" class="btn btn-danger" onclick="confirmDeleteChat()">Delete Chat</button> </div> </div> </div> </div> <!-- Block Chat Modal --> <div class="modal fade" id="blockChatModal" tabindex="-1"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Block User</h5> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body"> <p>Are you sure you want to block <span id="blockUserName"></span>? You will no longer receive messages from this user.</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> <button type="button" class="btn btn-outline-danger" onclick="confirmBlockChat()">Block</button> </div> </div> </div> </div> <!-- Bootstrap JS --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script> <script> // Global variables let currentUserId = <?php echo json_encode(isset($_SESSION['userdata']['id']) ? $_SESSION['userdata']['id'] : 0); ?>; let currentUserName = '<?php echo addslashes(trim(($_SESSION['userdata']['firstname'] ?? '') . ' ' . ($_SESSION['userdata']['lastname'] ?? ''))); ?>'; let activeChatId = null; let activeChatName = ''; let allChats = []; let filteredChats = []; // Abort controllers let activeFetchController = null; let sendMessageController = null; // Add these mobile-specific variables at the top let isMobile = window.innerWidth <= 991; let currentView = 'sidebar'; // Mobile detection and layout setup function checkMobile() { const oldIsMobile = isMobile; isMobile = window.innerWidth <= 991; if (oldIsMobile !== isMobile) { setupLayout(); } } function setupLayout() { const container = document.getElementById('chatContainer'); const sidebar = document.getElementById('sidebar'); const chatArea = document.getElementById('chatArea'); if (!container || !sidebar || !chatArea) return; if (isMobile) { container.classList.remove('desktop-layout'); container.classList.add('mobile-layout'); sidebar.classList.remove('hidden'); chatArea.classList.remove('active'); currentView = 'sidebar'; } else { container.classList.remove('mobile-layout'); container.classList.add('desktop-layout'); sidebar.classList.remove('hidden'); chatArea.classList.remove('active'); } } // Mobile navigation functions function showSidebar() { if (!isMobile) return; const sidebar = document.getElementById('sidebar'); const chatArea = document.getElementById('chatArea'); if (sidebar) { sidebar.classList.remove('hidden'); setTimeout(() => { sidebar.style.transform = 'translateX(0)'; }, 10); } if (chatArea) { chatArea.classList.remove('active'); chatArea.style.transform = 'translateX(100%)'; } currentView = 'sidebar'; } function showChatArea() { if (!isMobile) return; const sidebar = document.getElementById('sidebar'); const chatArea = document.getElementById('chatArea'); if (sidebar) { sidebar.classList.add('hidden'); sidebar.style.transform = 'translateX(-100%)'; } if (chatArea) { chatArea.classList.add('active'); setTimeout(() => { chatArea.style.transform = 'translateX(0)'; }, 10); } currentView = 'chat'; } function backToConversations() { if (!isMobile) return; showSidebar(); // Update chat list active state updateActiveChat(null); } // Update the openChat function to handle mobile view function openChat(chatId, chatName) { console.log('Opening chat:', { chatId, chatName, activeChatId, currentUserId, isMobile }); // Prevent re-opening the same chat if (activeChatId === chatId) { console.log('Chat already active'); return; } // Cancel any ongoing fetch requests if (activeFetchController) { activeFetchController.abort(); } // Create new AbortController for this request activeFetchController = new AbortController(); const signal = activeFetchController.signal; // Mark previous chat as read before switching if (activeChatId) { markAsRead(activeChatId); } // Set new active chat immediately activeChatId = chatId; activeChatName = chatName; // Update UI immediately const chatHeader = document.getElementById('chatHeader'); const emptyChat = document.getElementById('emptyChat'); const messageInputArea = document.getElementById('messageInputArea'); if (chatHeader) chatHeader.style.display = 'flex'; if (emptyChat) emptyChat.style.display = 'none'; if (messageInputArea) messageInputArea.style.display = 'flex'; // Update chat header immediately updateChatHeader(chatId, chatName); // Update chat list active state immediately updateActiveChat(chatId); // Clear previous messages and show loading const messagesContainer = document.getElementById('messagesContainer'); if (messagesContainer) { messagesContainer.innerHTML = ` <div class="text-center py-5"> <div class="spinner-border text-primary mb-3" role="status"> <span class="visually-hidden">Loading...</span> </div> <p class="text-muted">Loading messages...</p> </div> `; } // Focus on message input setTimeout(() => { const messageInput = document.getElementById('messageInput'); if (messageInput) messageInput.focus(); }, 100); // Load messages with abort signal loadMessages(signal); // On mobile, switch to chat area if (isMobile) { setTimeout(() => { showChatArea(); }, 100); } } // Update resetChatUI function for mobile function resetChatUI() { activeChatId = null; activeChatName = ''; if (isMobile) { showSidebar(); } const chatHeader = document.getElementById('chatHeader'); const emptyChat = document.getElementById('emptyChat'); const messageInputArea = document.getElementById('messageInputArea'); const messagesContainer = document.getElementById('messagesContainer'); if (chatHeader) chatHeader.style.display = 'none'; if (emptyChat) emptyChat.style.display = 'flex'; if (messageInputArea) messageInputArea.style.display = 'none'; if (messagesContainer) { messagesContainer.innerHTML = ` <div class="empty-chat" id="emptyChat"> <div> <i class="fas fa-comments fa-3x mb-3 text-muted"></i> <h4 class="text-muted mb-2">Chat to know more!</h4> <p class="text-muted">Select a conversation to start chatting</p> </div> </div> `; } // Update chat list active state updateActiveChat(null); } // Add event listener for mobile back arrow in navbar document.addEventListener('DOMContentLoaded', function() { const mobileBackArrow = document.querySelector('.nav-brand'); if (mobileBackArrow) { mobileBackArrow.addEventListener('click', function(e) { if (isMobile && currentView === 'chat' && activeChatId) { e.preventDefault(); backToConversations(); } // Otherwise, the link will work normally }); } }); // Update initializeChat function function initializeChat() { console.log('Initializing chat system...'); console.log('Current User:', { id: currentUserId, name: currentUserName, isAdmin: isCurrentUserAdmin(), isMobile: isMobile }); // Set up layout based on screen size setupLayout(); // Add resize listener window.addEventListener('resize', checkMobile); // Load conversations initially loadConversations(); // Set up event listeners const messageInput = document.getElementById('messageInput'); if (messageInput) { messageInput.addEventListener('keypress', function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); // Focus on message input when chat is opened messageInput.addEventListener('focus', function() { if (activeChatId) { // Mark as read when user starts typing markAsRead(activeChatId); } }); } // Auto-refresh every 30 seconds setInterval(() => { if (activeChatId) { loadMessages(); } loadConversations(); }, 30000); // Add keyboard shortcuts (desktop only) if (!isMobile) { document.addEventListener('keydown', function(e) { // Ctrl/Cmd + K to focus search if ((e.ctrlKey || e.metaKey) && e.key === 'k') { e.preventDefault(); const searchInput = document.getElementById('searchChat'); if (searchInput) searchInput.focus(); } // Escape to clear search if (e.key === 'Escape') { const searchInput = document.getElementById('searchChat'); if (searchInput === document.activeElement && searchInput.value) { searchInput.value = ''; searchChats(); } } }); } } // Check if user is admin function isCurrentUserAdmin() { return currentUserId === 'admin' || currentUserId === 0 || <?php echo isset($_SESSION['userdata']['login_type']) && in_array($_SESSION['userdata']['login_type'], [54, 55, 56, 57, 58]) ? 'true' : 'false'; ?>; } // Helper functions function escapeHtml(text) { if (!text) return ''; const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function formatTime(dateString) { try { const date = new Date(dateString); const now = new Date(); const diffMs = now - date; const diffHours = diffMs / (1000 * 60 * 60); if (diffHours < 24) { return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } else if (diffHours < 48) { return 'Yesterday ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } else { return date.toLocaleDateString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); } } catch (e) { return ''; } } function formatRelativeTime(dateString) { try { const date = new Date(dateString); const now = new Date(); const diffMs = now - date; const diffMins = Math.floor(diffMs / 60000); const diffHours = Math.floor(diffMs / 3600000); const diffDays = Math.floor(diffMs / 86400000); if (diffMins < 1) return 'Just now'; if (diffMins < 60) return `${diffMins}m ago`; if (diffHours < 24) return `${diffHours}h ago`; if (diffDays < 7) return `${diffDays}d ago`; return date.toLocaleDateString([], { month: 'short', day: 'numeric' }); } catch (e) { return ''; } } // Get avatar color based on ID function getAvatarColor(id) { const colors = [ '#FF6B6B', '#4ECDC4', '#FFD166', '#06D6A0', '#118AB2', '#EF476F', '#FF9A76', '#0D4C92', '#00B7A8', '#3D5A80', '#FF9A8B', '#A78BFA', '#FBBF24', '#34D399', '#60A5FA', '#F472B6', '#818CF8', '#F59E0B', '#10B981', '#3B82F6' ]; // If id is 'admin', use a special color if (id === 'admin' || id === 'Admin') { return '#FF6B6B'; // Red color for admin } // Convert string to number for consistent color let numId = 0; if (typeof id === 'string') { for (let i = 0; i < id.length; i++) { numId += id.charCodeAt(i); } } else { numId = parseInt(id) || 0; } return colors[numId % colors.length]; } // Load conversations function loadConversations() { console.log('Loading conversations...'); fetch('chat_actions.php?action=get_conversations') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log('Conversations data:', data); if (data.error) { showError('chatList', data.error); return; } allChats = data; filteredChats = [...data]; displayChats(data); // If there's an active chat, update its unread count if (activeChatId) { const activeChat = data.find(chat => (chat.id === 'admin' && activeChatId === 'admin') || parseInt(chat.id) === parseInt(activeChatId) ); if (activeChat) { updateActiveChatBadge(activeChatId, activeChat.unread_count); } } }) .catch(error => { console.error('Error loading conversations:', error); showError('chatList', 'Failed to load conversations. Please check your connection.'); }); } // Display chat list function displayChats(chats) { const chatList = document.getElementById('chatList'); if (!chatList) return; if (!chats || chats.length === 0) { chatList.innerHTML = ` <div class="text-center py-5 text-muted"> <i class="fas fa-comments fa-2x mb-3"></i> <p>No conversations yet</p> <small>Start a new chat to begin messaging</small> </div> `; return; } let html = ''; chats.forEach(chat => { // Determine if this chat is active let isActive = false; if (activeChatId === 'admin' && chat.id === 'admin') { isActive = true; } else if (parseInt(activeChatId) === parseInt(chat.id)) { isActive = true; } const unreadBadge = chat.unread_count > 0 ? `<span class="unread-badge">${chat.unread_count}</span>` : ''; // Truncate long last messages let lastMessage = 'No messages yet'; if (chat.last_message) { lastMessage = chat.last_message.length > 40 ? chat.last_message.substring(0, 40) + '...' : chat.last_message; } // Get avatar initials const avatarText = chat.name ? chat.name.charAt(0).toUpperCase() : '?'; const avatarColor = getAvatarColor(chat.id); // Determine if this is admin const isAdminChat = chat.id === 'admin'; // Escape chat name for HTML const escapedChatName = escapeHtml(chat.name); html += ` <div class="chat-item ${isActive ? 'active' : ''}" onclick="openChat('${chat.id}', '${escapedChatName}')" data-chat-id="${chat.id}" data-chat-name="${escapedChatName}"> <div class="chat-avatar" style="background: ${avatarColor};"> ${avatarText} ${isAdminChat ? '<span style="position: absolute; bottom: -2px; right: -2px; background: #FF6B6B; color: white; border-radius: 50%; width: 16px; height: 16px; font-size: 10px; display: flex; align-items: center; justify-content: center; border: 2px solid white;">A</span>' : ''} </div> <div class="chat-info"> <div class="chat-header"> <span class="chat-name"> ${escapedChatName} ${unreadBadge} </span> <span class="chat-time">${chat.last_message_time ? formatRelativeTime(chat.last_message_time) : ''}</span> </div> <div class="chat-preview"> ${escapeHtml(lastMessage)} </div> ${chat.is_elite ? '<small style="color: #FFD700;"><i class="fas fa-crown"></i> Elite Member</small>' : ''} </div> </div> `; }); chatList.innerHTML = html; } // Show error message function showError(elementId, message) { const element = document.getElementById(elementId); if (element) { element.innerHTML = ` <div class="alert alert-danger m-3"> <i class="fas fa-exclamation-triangle me-2"></i> ${escapeHtml(message)} <button onclick="loadConversations()" class="btn btn-sm btn-outline-danger ms-2">Retry</button> </div> `; } } // Reset active chat UI function resetActiveChatUI() { const messagesContainer = document.getElementById('messagesContainer'); const messageInput = document.getElementById('messageInput'); const currentChatName = document.getElementById('currentChatName'); const currentChatStatus = document.getElementById('currentChatStatus'); const favoriteIcon = document.getElementById('favoriteIcon'); if (messagesContainer) messagesContainer.innerHTML = ''; if (messageInput) messageInput.value = ''; if (currentChatName) currentChatName.textContent = 'Loading...'; if (currentChatStatus) currentChatStatus.textContent = ''; if (favoriteIcon) favoriteIcon.className = 'far fa-star'; } // Update chat header function updateChatHeader(chatId, chatName) { const avatarElement = document.getElementById('currentChatAvatar'); const currentChatName = document.getElementById('currentChatName'); if (!avatarElement || !currentChatName) return; const avatarText = chatName.charAt(0).toUpperCase(); const avatarColor = getAvatarColor(chatId); avatarElement.textContent = avatarText; avatarElement.style.background = avatarColor; avatarElement.style.width = '40px'; avatarElement.style.height = '40px'; avatarElement.style.borderRadius = '50%'; avatarElement.style.display = 'flex'; avatarElement.style.alignItems = 'center'; avatarElement.style.justifyContent = 'center'; avatarElement.style.fontWeight = 'bold'; avatarElement.style.fontSize = '18px'; avatarElement.style.color = 'white'; currentChatName.textContent = chatName; // Update status updateChatStatus(chatId); } // Update chat status function updateChatStatus(chatId) { const statusElement = document.getElementById('currentChatStatus'); if (!statusElement) return; // For admin, always show as available if (chatId === 'admin') { statusElement.textContent = 'Available'; statusElement.style.color = '#25D366'; return; } // For regular users, simulate status const isOnline = Math.random() > 0.3; // 70% chance of being online for demo if (isOnline) { statusElement.textContent = 'Online'; statusElement.style.color = '#25D366'; } else { const lastSeen = new Date(); lastSeen.setHours(lastSeen.getHours() - Math.floor(Math.random() * 24)); statusElement.textContent = `Last seen ${formatRelativeTime(lastSeen.toISOString())}`; statusElement.style.color = '#999'; } } // Open chat conversation - FIXED VERSION function openChat(chatId, chatName) { console.log('Opening chat:', { chatId, chatName, activeChatId, currentUserId }); // Prevent re-opening the same chat if (activeChatId === chatId) { console.log('Chat already active'); return; } // Cancel any ongoing fetch requests if (activeFetchController) { activeFetchController.abort(); } // Create new AbortController for this request activeFetchController = new AbortController(); const signal = activeFetchController.signal; // Mark previous chat as read before switching if (activeChatId) { markAsRead(activeChatId); } // Set new active chat immediately activeChatId = chatId; activeChatName = chatName; // Update UI immediately const chatHeader = document.getElementById('chatHeader'); const emptyChat = document.getElementById('emptyChat'); const messageInputArea = document.getElementById('messageInputArea'); if (chatHeader) chatHeader.style.display = 'flex'; if (emptyChat) emptyChat.style.display = 'none'; if (messageInputArea) messageInputArea.style.display = 'flex'; // Update chat header immediately updateChatHeader(chatId, chatName); // Update chat list active state immediately updateActiveChat(chatId); // Clear previous messages and show loading const messagesContainer = document.getElementById('messagesContainer'); if (messagesContainer) { messagesContainer.innerHTML = ` <div class="text-center py-5"> <div class="spinner-border text-primary mb-3" role="status"> <span class="visually-hidden">Loading...</span> </div> <p class="text-muted">Loading messages...</p> </div> `; } // Focus on message input setTimeout(() => { const messageInput = document.getElementById('messageInput'); if (messageInput) messageInput.focus(); }, 100); // Load messages with abort signal loadMessages(signal); } // Update active chat in list function updateActiveChat(chatId) { document.querySelectorAll('.chat-item').forEach(item => { item.classList.remove('active'); const itemChatId = item.getAttribute('data-chat-id'); // Handle admin comparison if (chatId === 'admin' && itemChatId === 'admin') { item.classList.add('active'); } else if (parseInt(itemChatId) === parseInt(chatId)) { item.classList.add('active'); } }); } // Update unread badge for active chat function updateActiveChatBadge(chatId, unreadCount) { const chatItem = document.querySelector(`.chat-item[data-chat-id="${chatId}"]`); if (chatItem) { const badge = chatItem.querySelector('.unread-badge'); if (badge) { if (unreadCount > 0) { badge.textContent = unreadCount; } else { badge.remove(); } } else if (unreadCount > 0) { const nameElement = chatItem.querySelector('.chat-name'); if (nameElement) { nameElement.innerHTML += `<span class="unread-badge">${unreadCount}</span>`; } } } } // Load messages for current chat - FIXED VERSION function loadMessages(signal = null) { const container = document.getElementById('messagesContainer'); if (!container || !activeChatId) { console.error('No active chat ID or container not found'); if (container) { container.innerHTML = ` <div class="alert alert-warning m-3"> <i class="fas fa-exclamation-triangle me-2"></i> Please select a conversation </div> `; } return; } console.log('Loading messages for chat:', activeChatId); // Encode chat ID for URL const chatIdParam = encodeURIComponent(activeChatId); const fetchOptions = {}; if (signal) { fetchOptions.signal = signal; } fetch(`chat_actions.php?action=get_messages&chat_id=${chatIdParam}`, fetchOptions) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log('Messages data:', data); // Check if this response is still relevant (user hasn't switched chats) if (!activeChatId || !container) return; if (data.error) { console.error('Error loading messages:', data.error); container.innerHTML = ` <div class="alert alert-warning m-3">${escapeHtml(data.error)}</div> `; return; } let html = ''; let currentDate = ''; if (!data || data.length === 0) { html = ` <div class="text-center py-5 text-muted"> <i class="fas fa-comment-alt fa-3x mb-3"></i> <p>No messages yet</p> <small>Start the conversation!</small> </div> `; } else { data.forEach(msg => { // Check if date changed const messageDate = msg.created_at ? msg.created_at.split(' ')[0] : ''; if (messageDate !== currentDate) { currentDate = messageDate; const today = new Date().toISOString().split('T')[0]; const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); const yesterdayStr = yesterday.toISOString().split('T')[0]; let dateLabel = ''; if (messageDate === today) { dateLabel = 'Today'; } else if (messageDate === yesterdayStr) { dateLabel = 'Yesterday'; } else { const date = new Date(messageDate); dateLabel = date.toLocaleDateString([], { weekday: 'long', month: 'short', day: 'numeric' }); } html += ` <div class="message-date"> <span>${dateLabel}</span> </div> `; } // Determine if message is sent by current user const currentUserString = currentUserId.toString(); const msgSender = msg.sender_id.toString(); const isSent = msgSender === currentUserString || (msgSender === 'admin' && isCurrentUserAdmin()); const cls = isSent ? 'sent' : 'received'; const time = msg.created_at ? formatTime(msg.created_at) : ''; const senderName = msg.sender_name || 'Unknown'; html += ` <div class="message ${cls}"> <div class="message-sender" style="font-size: 12px; color: #666; margin-bottom: 2px;"> ${!isSent ? escapeHtml(senderName) : 'You'} </div> <div>${escapeHtml(msg.message_text)}</div> <div class="message-time"> ${time} ${isSent ? (msg.is_read ? '<i class="fas fa-check-double" style="font-size: 10px; color: #34B7F1;"></i>' : '<i class="fas fa-check" style="font-size: 10px;"></i>') : ''} </div> </div> `; }); } container.innerHTML = html; // Scroll to bottom setTimeout(() => { if (container) { container.scrollTop = container.scrollHeight; } }, 100); }) .catch(error => { if (error.name === 'AbortError') { console.log('Fetch aborted - user switched chats'); return; } console.error('Error loading messages:', error); if (container && activeChatId) { container.innerHTML = ` <div class="alert alert-danger m-3">Failed to load messages. Please check your connection.</div> `; } }); } // Send message function sendMessage() { const input = document.getElementById('messageInput'); if (!input) return; const message = input.value.trim(); if (!message) { alert('Please enter a message'); return; } if (!activeChatId) { alert('Please select a conversation first'); return; } // Create temporary message for immediate display const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); const tempMsg = ` <div class="message sent"> <div class="message-sender" style="font-size: 12px; color: #666; margin-bottom: 2px;"> You </div> <div>${escapeHtml(message)}</div> <div class="message-time"> ${time} <i class="fas fa-clock" style="font-size: 10px;"></i> </div> </div> `; // Get messages container const container = document.getElementById('messagesContainer'); if (!container) return; // If "no messages" message exists, replace it if (container.innerHTML.includes('No messages yet')) { container.innerHTML = tempMsg; } else { // Check if we have message-date divs const today = new Date().toISOString().split('T')[0]; const hasTodayDate = container.innerHTML.includes('Today</span>'); if (!hasTodayDate) { // Add today's date container.innerHTML += ` <div class="message-date"> <span>Today</span> </div> `; } container.innerHTML += tempMsg; } // Scroll to bottom setTimeout(() => { if (container) { container.scrollTop = container.scrollHeight; } }, 10); // Clear input input.value = ''; // Prepare form data const formData = new FormData(); formData.append('action', 'send_message'); formData.append('receiver_id', activeChatId); formData.append('message', message); // Cancel any ongoing message sending if (sendMessageController) { sendMessageController.abort(); } sendMessageController = new AbortController(); // Send to server fetch('chat_actions.php', { method: 'POST', body: formData, signal: sendMessageController.signal }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log('Send message response:', data); if (data.success) { // Refresh messages to get proper timestamp and read status setTimeout(() => { if (activeChatId) { loadMessages(); } }, 500); // Refresh conversations list setTimeout(loadConversations, 1000); } else if (data.error) { alert('Error: ' + data.error); } }) .catch(error => { if (error.name === 'AbortError') { console.log('Send message aborted'); return; } console.error('Error sending message:', error); alert('Failed to send message. Please check your connection.'); }); } // Mark messages as read function markAsRead(chatId) { if (!chatId) return; const formData = new FormData(); formData.append('action', 'mark_as_read'); formData.append('chat_id', chatId); fetch('chat_actions.php', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { console.log('Mark as read response:', data); // Update unread badge in chat list if (data.success) { updateActiveChatBadge(chatId, 0); } }) .catch(error => { console.error('Error marking as read:', error); }); } // Toggle favorite function toggleFavorite() { const icon = document.getElementById('favoriteIcon'); if (!icon) return; if (icon.classList.contains('far')) { icon.classList.remove('far'); icon.classList.add('fas', 'text-warning'); alert('Added to favorites'); } else { icon.classList.remove('fas', 'text-warning'); icon.classList.add('far'); alert('Removed from favorites'); } } // Show info modal function showInfoModal(title, content) { const modalId = 'infoModal-' + Date.now(); const modalHtml = ` <div class="modal fade" id="${modalId}" tabindex="-1"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">${title}</h5> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body"> ${content} </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> ${activeChatId !== 'admin' ? `<button type="button" class="btn btn-primary" onclick="startNewChat('${activeChatId}', '${escapeHtml(activeChatName)}'); bootstrap.Modal.getInstance(document.getElementById('${modalId}')).hide();"> <i class="fas fa-comment me-1"></i> Send Message </button>` : '' } </div> </div> </div> </div> `; // Remove any existing modals document.querySelectorAll('[id^="infoModal-"]').forEach(el => el.remove()); // Add new modal to DOM document.body.insertAdjacentHTML('beforeend', modalHtml); // Show modal const modal = new bootstrap.Modal(document.getElementById(modalId)); modal.show(); // Remove modal from DOM after hiding document.getElementById(modalId).addEventListener('hidden.bs.modal', function() { this.remove(); }); } // Show basic contact info (fallback) function showBasicContactInfo() { if (!activeChatId || !activeChatName) return; const infoHtml = ` <h5>Contact Information</h5> <div class="d-flex align-items-center mb-3"> <div class="chat-avatar me-3" style="background: ${getAvatarColor(activeChatId)}; width: 50px; height: 50px;"> ${activeChatName.charAt(0).toUpperCase()} </div> <div> <h6 class="mb-0">${escapeHtml(activeChatName)}</h6> <small class="text-muted">Chat ID: ${activeChatId}</small> </div> </div> <p><strong>Status:</strong> <span class="text-muted">Basic information not available</span></p> <p class="text-muted"><small>Detailed contact information is not available for this user.</small></p> `; showInfoModal('Contact Info', infoHtml); } // View contact info - FIXED VERSION function viewContactInfo() { if (!activeChatId) return; // For admin chat, show admin info if (activeChatId === 'admin') { const infoHtml = ` <h5>Admin Information</h5> <p><strong>Name:</strong> Admin</p> <p><strong>Role:</strong> System Administrator</p> <p><strong>Status:</strong> <span class="text-success">● Online</span></p> <p><strong>Description:</strong> System administrator who can assist with any issues.</p> `; showInfoModal('Admin Info', infoHtml); return; } // For regular users, try to fetch info fetch(`chat_actions.php?action=get_user_info&user_id=${encodeURIComponent(activeChatId)}`) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { if (data.error) { // If endpoint doesn't exist or returns error, show basic info showBasicContactInfo(); return; } // If we have user data let infoHtml = ` <h5>Contact Information</h5> <div class="d-flex align-items-center mb-3"> <div class="chat-avatar me-3" style="background: ${getAvatarColor(activeChatId)}; width: 50px; height: 50px;"> ${activeChatName.charAt(0).toUpperCase()} </div> <div> <h6 class="mb-0">${escapeHtml(activeChatName)}</h6> <small class="text-muted">Chat ID: ${activeChatId}</small> </div> </div> `; if (data.firstname || data.lastname) { infoHtml += `<p><strong>Name:</strong> ${escapeHtml(data.firstname || '')} ${escapeHtml(data.lastname || '')}</p>`; } if (data.email) { infoHtml += `<p><strong>Email:</strong> ${escapeHtml(data.email)}</p>`; } if (data.contact) { infoHtml += `<p><strong>Contact:</strong> ${escapeHtml(data.contact)}</p>`; } if (data.company) { infoHtml += `<p><strong>Company:</strong> ${escapeHtml(data.company)}</p>`; } if (data.is_elite) { infoHtml += '<p><strong><i class="fas fa-crown text-warning"></i> Elite Member</strong></p>'; } // Add join date if available if (data.created_at) { const joinDate = new Date(data.created_at).toLocaleDateString(); infoHtml += `<p><strong>Member Since:</strong> ${joinDate}</p>`; } showInfoModal('Contact Info', infoHtml); }) .catch(error => { console.error('Error loading contact info:', error); // Fallback to basic info showBasicContactInfo(); }); } // Clear chat function clearChat() { if (!activeChatId) { alert('No active chat selected'); return; } const modalElement = document.getElementById('clearChatModal'); if (modalElement) { const modal = new bootstrap.Modal(modalElement); modal.show(); } } function confirmClearChat() { if (!activeChatId) return; const formData = new FormData(); formData.append('action', 'clear_chat'); formData.append('chat_id', activeChatId); fetch('chat_actions.php', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { console.log('Clear chat response:', data); const modalElement = document.getElementById('clearChatModal'); if (modalElement) { const modal = bootstrap.Modal.getInstance(modalElement); if (modal) modal.hide(); } if (data.success) { alert('Chat cleared successfully'); // Reload messages (should show empty) loadMessages(); // Reload conversations loadConversations(); } else { alert('Error: ' + (data.error || 'Failed to clear chat')); } }) .catch(error => { console.error('Error clearing chat:', error); alert('Failed to clear chat. Please try again.'); }); } // Delete chat function deleteChat() { if (!activeChatId) { alert('No active chat selected'); return; } const modalElement = document.getElementById('deleteChatModal'); if (modalElement) { const modal = new bootstrap.Modal(modalElement); modal.show(); } } function confirmDeleteChat() { if (!activeChatId) return; const formData = new FormData(); formData.append('action', 'delete_chat'); formData.append('chat_id', activeChatId); fetch('chat_actions.php', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { console.log('Delete chat response:', data); const modalElement = document.getElementById('deleteChatModal'); if (modalElement) { const modal = bootstrap.Modal.getInstance(modalElement); if (modal) modal.hide(); } if (data.success) { alert('Chat deleted successfully'); // Reset UI resetChatUI(); // Reload conversations loadConversations(); } else { alert('Error: ' + (data.error || 'Failed to delete chat')); } }) .catch(error => { console.error('Error deleting chat:', error); alert('Failed to delete chat. Please try again.'); }); } // Block chat function blockChat() { if (!activeChatId) { alert('No active chat selected'); return; } // Don't allow blocking admin if (activeChatId === 'admin') { alert('Cannot block admin'); return; } const blockUserName = document.getElementById('blockUserName'); if (blockUserName) { blockUserName.textContent = activeChatName; } const modalElement = document.getElementById('blockChatModal'); if (modalElement) { const modal = new bootstrap.Modal(modalElement); modal.show(); } } function confirmBlockChat() { if (!activeChatId) return; const formData = new FormData(); formData.append('action', 'block_chat'); formData.append('chat_id', activeChatId); fetch('chat_actions.php', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { console.log('Block chat response:', data); const modalElement = document.getElementById('blockChatModal'); if (modalElement) { const modal = bootstrap.Modal.getInstance(modalElement); if (modal) modal.hide(); } if (data.success) { alert('User blocked successfully'); // Reset UI resetChatUI(); // Reload conversations loadConversations(); } else { alert('Error: ' + (data.error || 'Failed to block user')); } }) .catch(error => { console.error('Error blocking chat:', error); alert('Failed to block user. Please try again.'); }); } // Report chat function reportChat() { if (!activeChatId) { alert('No active chat selected'); return; } const reason = prompt(`Why do you want to report ${activeChatName}? Please provide details:`, ''); if (reason) { alert(`Report submitted for ${activeChatName}. Thank you for helping us maintain a safe community.`); // You can send the report to server here } } // Reset chat UI function resetChatUI() { activeChatId = null; activeChatName = ''; const chatHeader = document.getElementById('chatHeader'); const emptyChat = document.getElementById('emptyChat'); const messageInputArea = document.getElementById('messageInputArea'); const messagesContainer = document.getElementById('messagesContainer'); if (chatHeader) chatHeader.style.display = 'none'; if (emptyChat) emptyChat.style.display = 'flex'; if (messageInputArea) messageInputArea.style.display = 'none'; if (messagesContainer) { messagesContainer.innerHTML = ` <div class="empty-chat" id="emptyChat"> <div> <i class="fas fa-comments fa-3x mb-3 text-muted"></i> <h4 class="text-muted mb-2">Chat to know more!</h4> <p class="text-muted">Select a conversation to start chatting</p> </div> </div> `; } // Update chat list active state updateActiveChat(null); } // Filter chats function filterChats(filter) { // Update active tab document.querySelectorAll('.filter-tab').forEach(tab => { tab.classList.remove('active'); }); if (event && event.target) { event.target.classList.add('active'); } switch(filter) { case 'all': filteredChats = [...allChats]; break; case 'unread': filteredChats = allChats.filter(chat => chat.unread_count > 0); break; case 'favorites': // For now, show all. You can implement favorite logic later filteredChats = [...allChats]; alert('Favorite filter coming soon!'); break; case 'elite': filteredChats = allChats.filter(chat => chat.is_elite); break; } displayChats(filteredChats); } // Search chats function searchChats() { const searchInput = document.getElementById('searchChat'); if (!searchInput) return; const query = searchInput.value.toLowerCase().trim(); if (!query) { // If search is empty, show filtered chats displayChats(filteredChats); return; } const results = filteredChats.filter(chat => chat.name.toLowerCase().includes(query) || (chat.last_message && chat.last_message.toLowerCase().includes(query)) || (chat.company && chat.company.toLowerCase().includes(query)) ); const chatList = document.getElementById('chatList'); if (!chatList) return; if (results.length === 0) { chatList.innerHTML = ` <div class="text-center py-5 text-muted"> <i class="fas fa-search fa-2x mb-3"></i> <p>No conversations found</p> <small>Try searching with different keywords</small> </div> `; } else { displayChats(results); } } // Start new chat with user function startNewChat(userId, userName) { console.log('Starting new chat with:', { userId, userName }); // Close search modal if open const modalElement = document.querySelector('.modal.show'); if (modalElement) { const modal = bootstrap.Modal.getInstance(modalElement); if (modal) modal.hide(); } // Clear search input const searchInput = document.getElementById('searchChat'); if (searchInput) searchInput.value = ''; // Open the chat openChat(userId, userName); } // Search users (for new chat) function searchUsers() { const searchInput = document.getElementById('searchChat'); if (!searchInput) return; const query = searchInput.value.trim(); if (query.length < 2) return; fetch(`chat_actions.php?action=search_users&query=${encodeURIComponent(query)}`) .then(response => response.json()) .then(data => { if (data.error) { console.error('Search error:', data.error); return; } // Show search results in dropdown or modal if (data.length > 0) { showUserSearchResults(data); } }) .catch(error => { console.error('Error searching users:', error); }); } // Show user search results function showUserSearchResults(users) { let html = '<div class="search-results p-2">'; html += '<h6 class="mb-2">Search Results</h6>'; users.forEach(user => { const avatarText = user.firstname ? user.firstname.charAt(0).toUpperCase() : '?'; const avatarColor = getAvatarColor(user.id); const userName = `${escapeHtml(user.firstname || '')} ${escapeHtml(user.lastname || '')}`.trim(); html += ` <div class="search-result-item p-2 border-bottom" onclick="startNewChat('${user.id}', '${userName}')" style="cursor: pointer;"> <div class="d-flex align-items-center"> <div class="chat-avatar me-3" style="background: ${avatarColor}; width: 40px; height: 40px;"> ${avatarText} </div> <div> <strong>${userName}</strong> ${user.company ? `<br><small class="text-muted">${escapeHtml(user.company)}</small>` : ''} </div> </div> </div> `; }); html += '</div>'; // Create and show modal const modal = new bootstrap.Modal(document.createElement('div')); modal._element.innerHTML = ` <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Search Results</h5> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body"> ${html} </div> </div> </div> `; modal.show(); } // Initialize chat function initializeChat() { console.log('Initializing chat system...'); console.log('Current User:', { id: currentUserId, name: currentUserName, isAdmin: isCurrentUserAdmin() }); // Load conversations initially loadConversations(); // Set up event listeners const messageInput = document.getElementById('messageInput'); if (messageInput) { messageInput.addEventListener('keypress', function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); // Focus on message input when chat is opened messageInput.addEventListener('focus', function() { if (activeChatId) { // Mark as read when user starts typing markAsRead(activeChatId); } }); } // Auto-refresh every 30 seconds setInterval(() => { if (activeChatId) { loadMessages(); } loadConversations(); }, 30000); // Add keyboard shortcuts document.addEventListener('keydown', function(e) { // Ctrl/Cmd + K to focus search if ((e.ctrlKey || e.metaKey) && e.key === 'k') { e.preventDefault(); const searchInput = document.getElementById('searchChat'); if (searchInput) searchInput.focus(); } // Escape to clear search if (e.key === 'Escape') { const searchInput = document.getElementById('searchChat'); if (searchInput === document.activeElement && searchInput.value) { searchInput.value = ''; searchChats(); } } }); } // Update online status function updateOnlineStatus() { if (!activeChatId) return; // Simulate online status (you can implement real status updates) const statusElement = document.getElementById('currentChatStatus'); if (statusElement) { const isOnline = Math.random() > 0.5; // Random for demo statusElement.textContent = isOnline ? 'Online' : 'Last seen today at ' + new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); statusElement.style.color = isOnline ? '#25D366' : '#999'; } } // Load chat statistics function loadChatStats() { fetch('chat_actions.php?action=get_stats') .then(response => response.json()) .then(data => { if (data.success) { console.log('Chat stats:', data); // You can display stats somewhere in UI if needed } }) .catch(error => { console.error('Error loading chat stats:', error); }); } // Start chat system when page loads document.addEventListener('DOMContentLoaded', function() { // Check if user is logged in if (!currentUserId || currentUserId === 0) { alert('Please login to use chat'); window.location.href = '../login.php'; return; } // Initialize chat system initializeChat(); // Update online status every 10 seconds for active chat setInterval(updateOnlineStatus, 10000); // Load chat stats loadChatStats(); }); </script> </body> </html>
SAVE CHANGES
[ CANCEL ]
Name
Type
Actions
.. (Parent Directory)
📄 chat_actions(1).php
FILE
Ren
[EDIT]
DEL
📄 chat_actions.php
FILE
Ren
[EDIT]
DEL
📄 chats.php
FILE
Ren
[EDIT]
DEL
📄 messages(1).php
FILE
Ren
[EDIT]
DEL
📄 messages(2).php
FILE
Ren
[EDIT]
DEL
📄 messages.php
FILE
Ren
[EDIT]
DEL
📄 test.html
FILE
Ren
[EDIT]
DEL