Sindbad~EG File Manager

Current Path : /home/copmadinaarea/thecopmadinaarea.org/portal/includes/
Upload File :
Current File : /home/copmadinaarea/thecopmadinaarea.org/portal/includes/chat_widget.php

<!-- Chat Widget JavaScript -->
<script>
    // Simple public chat widget
    let chatConversationId = null;
    let chatLastMessageId = 0;
    let chatPollingInterval = null;

    async function initChatConversation() {
        if (chatConversationId) return;
        try {
            const res = await fetch('<?php echo BASE_URL; ?>api/chat_start.php');
            const data = await res.json();
            if (data.success) {
                chatConversationId = data.conversation_id;
                startChatPolling();
            }
        } catch (e) {
            console.error('Chat init failed', e);
        }
    }

    async function sendChatMessage() {
        const input = document.getElementById('chatMessageInput');
        const message = (input.value || '').trim();
        if (!message || !chatConversationId) return;

        const formData = new FormData();
        formData.append('conversation_id', chatConversationId);
        formData.append('message', message);

        try {
            const res = await fetch('<?php echo BASE_URL; ?>api/chat_send.php', {
                method: 'POST',
                body: formData
            });
            const data = await res.json();
            if (data.success) {
                input.value = '';
                fetchChatMessages();
            }
        } catch (e) {
            console.error('Chat send failed', e);
        }
    }

    async function fetchChatMessages() {
        if (!chatConversationId) return;
        try {
            const params = new URLSearchParams();
            params.append('conversation_id', chatConversationId);
            params.append('last_message_id', chatLastMessageId);

            const res = await fetch('<?php echo BASE_URL; ?>api/chat_fetch.php?' + params.toString());
            const data = await res.json();
            if (!data.success) return;

            const container = document.getElementById('chatMessagesContainer');
            if (!container) return;

            (data.messages || []).forEach(msg => {
                const bubble = document.createElement('div');
                const isAdmin = msg.sender_type === 'admin';
                const alignment = isAdmin ? 'items-start' : 'items-end';
                const bgClass = isAdmin ? 'bg-white text-gray-800' : 'bg-blue-600 text-white';
                const time = msg.created_at ? new Date(msg.created_at).toLocaleTimeString() : '';

                bubble.className = 'flex ' + alignment;
                bubble.innerHTML = '<div class="max-w-[80%] px-3 py-2 rounded-lg text-xs shadow ' + bgClass + '">' +
                    '<div class="whitespace-pre-line">' + escapeHtml(msg.message_text || '') + '</div>' +
                    (time ? '<div class="mt-1 text-[10px] opacity-70">' + time + '</div>' : '') +
                    '</div>';

                container.appendChild(bubble);
                chatLastMessageId = Math.max(chatLastMessageId, parseInt(msg.id || 0, 10));
            });

            if (data.messages && data.messages.length > 0) {
                container.scrollTop = container.scrollHeight;
            }
        } catch (e) {
            console.error('Chat fetch failed', e);
        }
    }

    function startChatPolling() {
        if (chatPollingInterval) return;
        fetchChatMessages();
        chatPollingInterval = setInterval(fetchChatMessages, 4000);
    }

    function toggleChatWidget() {
        const panel = document.getElementById('chatWidgetPanel');
        if (!panel) return;
        const isHidden = panel.classList.contains('hidden');
        panel.classList.toggle('hidden');
        if (isHidden) {
            initChatConversation();
        }
    }

    function handleChatKeyDown(event) {
        if (event.key === 'Enter' && !event.shiftKey) {
            event.preventDefault();
            sendChatMessage();
        }
    }

    function escapeHtml(text) {
        const map = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#039;'
        };
        return String(text).replace(/[&<>"']/g, function(m) { return map[m]; });
    }
</script>

<!-- Floating Chat Widget -->
<div class="fixed bottom-4 right-4 z-50">
    <!-- Chat Panel -->
    <div id="chatWidgetPanel" class="hidden mb-3 w-80 sm:w-96 bg-white rounded-2xl shadow-2xl border border-gray-200 flex flex-col overflow-hidden">
        <div class="px-4 py-3 flex items-center justify-between" style="background: linear-gradient(135deg, #1E40AF 0%, #9333EA 100%);">
            <div class="flex items-center space-x-2">
                <i class="fas fa-comments text-white"></i>
                <span class="text-sm font-semibold text-white">Chat with Admin</span>
            </div>
            <button onclick="toggleChatWidget()" class="text-white hover:text-gray-200 text-xs">
                <i class="fas fa-times"></i>
            </button>
        </div>
        <div id="chatMessagesContainer" class="flex-1 px-3 py-2 space-y-2 overflow-y-auto bg-gray-50" style="max-height: 260px;"></div>
        <div class="border-t border-gray-200 p-2 bg-white">
            <textarea id="chatMessageInput" rows="2" class="w-full text-xs px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-1 focus:ring-blue-500 resize-none" placeholder="Type your message..." onkeydown="handleChatKeyDown(event)"></textarea>
            <div class="mt-2 flex justify-end">
                <button type="button" onclick="sendChatMessage()" class="px-3 py-1 rounded-full text-xs font-semibold text-white shadow" style="background: linear-gradient(135deg, #1E40AF 0%, #F97316 100%);">
                    Send
                </button>
            </div>
        </div>
    </div>

    <!-- Chat Toggle Button -->
    <button type="button" onclick="toggleChatWidget()" class="w-14 h-14 rounded-full shadow-xl flex items-center justify-center text-white text-2xl focus:outline-none hover:scale-110 transition-transform" style="background: linear-gradient(135deg, #1E40AF 0%, #F97316 100%);">
        <i class="fas fa-comments"></i>
    </button>
</div>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists