206 lines
9.3 KiB
PHP
206 lines
9.3 KiB
PHP
<?php
|
|
session_start();
|
|
if (!isset($_SESSION['user_id'])) {
|
|
header('Location: login.php');
|
|
exit;
|
|
}
|
|
require_once 'db/config.php';
|
|
$db = db();
|
|
$stmt = $db->prepare("SELECT coach_mode, single_coach_id FROM settings ORDER BY id DESC LIMIT 1");
|
|
$stmt->execute();
|
|
$settings = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
$coach_mode = $settings['coach_mode'] ?? 'multi';
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Messages</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="assets/css/custom.css">
|
|
<style>
|
|
.conversations-list {
|
|
height: 80vh;
|
|
overflow-y: auto;
|
|
}
|
|
.chat-messages {
|
|
height: 65vh;
|
|
overflow-y: auto;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="index.php">Coaching</a>
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<div class="collapse navbar-collapse" id="navbarNav">
|
|
<ul class="navbar-nav ms-auto">
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="index.php">Home</a>
|
|
</li>
|
|
<?php if ($coach_mode === 'multi'): ?>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="coaches.php">Coaches</a>
|
|
</li>
|
|
<?php endif; ?>
|
|
<?php if (isset($_SESSION['user_id'])): ?>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="dashboard.php">Dashboard</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="messages.php">Messages</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="logout.php">Logout</a>
|
|
</li>
|
|
<?php else: ?>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="login.php">Login</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="register-coach.php">Register as Coach</a>
|
|
</li>
|
|
<?php endif; ?>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container py-5">
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="conversations-list card">
|
|
<div class="card-header">Conversations</div>
|
|
<ul class="list-group list-group-flush" id="conversations-container">
|
|
<!-- Conversations will be loaded here -->
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-8">
|
|
<div class="chat-area card">
|
|
<div class="card-header" id="chat-header">Select a conversation</div>
|
|
<div class="card-body chat-messages" id="messages-container">
|
|
<!-- Messages will be loaded here -->
|
|
</div>
|
|
<div class="card-footer">
|
|
<form id="message-form" class="d-flex">
|
|
<input type="text" class="form-control" id="message-input" placeholder="Type a message..." autocomplete="off">
|
|
<button type="submit" class="btn btn-primary">Send</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const conversationsContainer = document.getElementById('conversations-container');
|
|
const messagesContainer = document.getElementById('messages-container');
|
|
const messageForm = document.getElementById('message-form');
|
|
const messageInput = document.getElementById('message-input');
|
|
const chatHeader = document.getElementById('chat-header');
|
|
|
|
let currentPeer = null;
|
|
let pollingInterval = null;
|
|
|
|
async function fetchConversations() {
|
|
const response = await fetch('api/messages.php?action=get_conversations');
|
|
const conversations = await response.json();
|
|
conversationsContainer.innerHTML = '';
|
|
conversations.forEach(conv => {
|
|
const unread = conv.unread_count > 0 ? `<span class="badge bg-primary float-end">${conv.unread_count}</span>` : '';
|
|
const li = document.createElement('li');
|
|
li.className = 'list-group-item list-group-item-action';
|
|
li.style.cursor = 'pointer';
|
|
li.dataset.userId = conv.user_id;
|
|
li.dataset.userType = conv.user_type;
|
|
li.innerHTML = `<h6>${conv.name} ${unread}</h6><small>${conv.message}</small>`;
|
|
li.addEventListener('click', () => {
|
|
currentPeer = { id: conv.user_id, type: conv.user_type, name: conv.name };
|
|
loadMessages(currentPeer);
|
|
});
|
|
conversationsContainer.appendChild(li);
|
|
});
|
|
}
|
|
|
|
async function loadMessages(peer) {
|
|
if (pollingInterval) clearInterval(pollingInterval);
|
|
|
|
chatHeader.textContent = `Chat with ${peer.name}`;
|
|
const response = await fetch(`api/messages.php?action=get_messages&user_id=${peer.id}&user_type=${peer.type}`);
|
|
const messages = await response.json();
|
|
messagesContainer.innerHTML = '';
|
|
messages.forEach(msg => appendMessage(msg));
|
|
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
|
|
|
|
pollingInterval = setInterval(() => {
|
|
fetch(`api/messages.php?action=get_messages&user_id=${peer.id}&user_type=${peer.type}`)
|
|
.then(response => response.json())
|
|
.then(newMessages => {
|
|
if (newMessages.length > messages.length) {
|
|
messagesContainer.innerHTML = '';
|
|
newMessages.forEach(msg => appendMessage(msg));
|
|
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
}
|
|
});
|
|
}, 5000);
|
|
fetchConversations();
|
|
}
|
|
|
|
function appendMessage(msg) {
|
|
const div = document.createElement('div');
|
|
const isSender = msg.sender_type === '<?php echo $_SESSION["user_type"]; ?>' && msg.sender_id == '<?php echo $_SESSION["user_id"]; ?>';
|
|
div.className = `message mb-2 p-2 rounded ${isSender ? 'sent bg-primary text-white align-self-end' : 'received bg-light'}`;
|
|
div.textContent = msg.message;
|
|
messagesContainer.appendChild(div);
|
|
}
|
|
|
|
messageForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
if (!currentPeer || !messageInput.value.trim()) return;
|
|
|
|
const message = {
|
|
receiver_id: currentPeer.id,
|
|
receiver_type: currentPeer.type,
|
|
message: messageInput.value.trim()
|
|
};
|
|
|
|
const response = await fetch('api/messages.php?action=send_message', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(message)
|
|
});
|
|
|
|
if (response.ok) {
|
|
appendMessage({ ...message, sender_id: '<?php echo $_SESSION["user_id"]; ?>', sender_type: '<?php echo $_SESSION["user_type"]; ?>' });
|
|
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
messageInput.value = '';
|
|
fetchConversations(); // To update last message
|
|
}
|
|
});
|
|
|
|
fetchConversations();
|
|
setInterval(fetchConversations, 10000); // Periodically check for new conversations/messages
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const peerId = urlParams.get('user_id');
|
|
const peerType = urlParams.get('user_type');
|
|
const peerName = urlParams.get('user_name'); // You might need to fetch this if not in URL
|
|
|
|
if (peerId && peerType) {
|
|
currentPeer = { id: peerId, type: peerType, name: peerName || 'User' };
|
|
loadMessages(currentPeer);
|
|
}
|
|
});
|
|
</script>
|
|
<script src="assets/js/main.js"></script>
|
|
</body>
|
|
</html>
|