This commit is contained in:
Flatlogic Bot 2025-11-07 06:42:26 +00:00
parent a37fc59b93
commit ca7f5831fa
8 changed files with 195 additions and 111 deletions

32
api/send_message.php Normal file
View File

@ -0,0 +1,32 @@
<?php
session_start();
header('Content-Type: application/json');
if (!isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'error' => 'Not logged in']);
exit();
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['success' => false, 'error' => 'Invalid request method']);
exit();
}
require_once '../db/config.php';
$sender_id = $_SESSION['user_id'];
$receiver_id = isset($_POST['receiver_id']) ? (int)$_POST['receiver_id'] : 0;
$message = isset($_POST['message']) ? trim($_POST['message']) : '';
if ($receiver_id && !empty($message)) {
try {
$pdo = db();
$stmt = $pdo->prepare('INSERT INTO messages (sender_id, receiver_id, message) VALUES (?, ?, ?)');
$stmt->execute([$sender_id, $receiver_id, $message]);
echo json_encode(['success' => true]);
} catch (PDOException $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
}

View File

@ -1,51 +1,3 @@
html, body {
body { height: 100%;
font-family: 'Inter', sans-serif;
background-color: #121212;
color: #E0E0E0;
}
.navbar-dark .navbar-nav .nav-link {
color: rgba(255, 255, 255, .75);
}
.navbar-dark .navbar-nav .nav-link.active,
.navbar-dark .navbar-nav .nav-link:hover {
color: #fff;
}
.card {
background-color: #1E1E1E;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.form-control {
background-color: #2a2a2a;
color: #fff;
border: 1px solid #444;
}
.form-control:focus {
background-color: #2a2a2a;
color: #fff;
border-color: #0D6EFD;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, .25);
}
.form-control::placeholder {
color: #888;
}
.btn-primary {
background-color: #0D6EFD;
border-color: #0D6EFD;
}
.text-muted {
color: #A0A0A0 !important;
}
.feature-icon {
font-size: 2.5rem;
color: #0D6EFD;
} }

View File

@ -1,58 +1,112 @@
<?php <?php
session_start(); session_start();
// If user is not logged in, redirect to login page
if (!isset($_SESSION['user_id'])) { if (!isset($_SESSION['user_id'])) {
header("Location: login.php"); header('Location: login.php');
exit; exit();
} }
require_once 'db/config.php';
include 'header.php'; include 'header.php';
?>
<main class="container flex-grow-1 my-5"> $pdo = db();
<div class="row"> $current_user_id = $_SESSION['user_id'];
<div class="col-md-4">
<div class="card"> // Check if we are viewing a specific chat
<div class="card-header"> $chat_with_id = isset($_GET['chat_with_id']) ? (int)$_GET['chat_with_id'] : null;
Conversations
</div> if ($chat_with_id) {
<ul class="list-group list-group-flush"> // Chat view
<li class="list-group-item"><a href="#">User 1</a></li> $stmt = $pdo->prepare('SELECT display_name FROM users WHERE id = ?');
<li class="list-group-item"><a href="#">User 2</a></li> $stmt->execute([$chat_with_id]);
<li class="list-group-item"><a href="#">User 3</a></li> $chat_with_user = $stmt->fetch(PDO::FETCH_ASSOC);
</ul>
</div> // Fetch messages
</div> $stmt = $pdo->prepare('SELECT * FROM messages WHERE (sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?) ORDER BY created_at ASC');
<div class="col-md-8"> $stmt->execute([$current_user_id, $chat_with_id, $chat_with_id, $current_user_id]);
<div class="card"> $messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
<div class="card-header">
Chat with User 1 ?>
</div> <div class="d-flex flex-column" style="height: calc(100vh - 56px);">
<div class="card-body" style="height: 400px; overflow-y: auto;"> <header class="p-3 bg-light border-bottom">
<!-- Chat messages will go here --> <div class="container-fluid">
<div class="d-flex justify-content-end mb-3"> <div class="d-flex justify-content-between align-items-center">
<div class="bg-primary text-white p-2 rounded"> <a href="dashboard.php" class="btn btn-secondary">< Back</a>
Hello! <h1 class="h5 mb-0">Chat with <?php echo htmlspecialchars($chat_with_user['display_name']); ?></h1>
</div> <div></div>
</div>
<div class="d-flex justify-content-start mb-3">
<div class="bg-light p-2 rounded">
Hi there!
</div>
</div>
</div>
<div class="card-footer">
<form>
<div class="input-group">
<input type="text" class="form-control" placeholder="Type a message...">
<button class="btn btn-primary" type="button">Send</button>
</div>
</form>
</div> </div>
</div> </div>
</header>
<main class="flex-grow-1" style="overflow-y: auto;">
<div class="container-fluid p-3">
<div class="d-flex flex-column gap-3">
<?php foreach ($messages as $message): ?>
<div class="p-2 rounded <?php echo $message['sender_id'] == $current_user_id ? 'bg-light text-dark align-self-end text-end' : 'bg-primary text-white align-self-start'; ?> col-8">
<?php echo htmlspecialchars($message['message']); ?>
</div>
<?php endforeach; ?>
</div>
</div>
</main>
<footer class="p-3 bg-light border-top">
<div class="container-fluid">
<form id="message-form">
<div class="input-group">
<input type="hidden" name="receiver_id" value="<?php echo $chat_with_id; ?>">
<input type="text" name="message" class="form-control" placeholder="Type a message..." required>
<button class="btn btn-primary" type="submit">Send</button>
</div>
</form>
</div>
</footer>
</div>
<?php
} else {
// Contact list view
$stmt = $pdo->prepare('SELECT id, display_name FROM users WHERE id != ?');
$stmt->execute([$current_user_id]);
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<div class="container mt-4">
<h1 class="h3 mb-3">Contacts</h1>
<div class="list-group">
<?php foreach ($users as $user): ?>
<a href="dashboard.php?chat_with_id=<?php echo $user['id']; ?>" class="list-group-item list-group-item-action">
<?php echo htmlspecialchars($user['display_name']); ?>
</a>
<?php endforeach; ?>
</div> </div>
</div> </div>
</main> <?php
}
?>
<script>
if (document.getElementById('message-form')) {
document.getElementById('message-form').addEventListener('submit', function(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
<?php include 'footer.php'; ?> fetch('api/send_message.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
location.reload();
} else {
alert('Error sending message: ' + data.error);
}
})
.catch(error => {
console.error('Error:', error);
alert('An unexpected error occurred.');
});
});
}
</script>
<?php
include 'footer.php';
?>

View File

@ -0,0 +1,21 @@
<?php
require_once __DIR__ . '/../config.php';
try {
$pdo = db();
$sql = "
CREATE TABLE IF NOT EXISTS messages (
id INT AUTO_INCREMENT PRIMARY KEY,
sender_id INT NOT NULL,
receiver_id INT NOT NULL,
message TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sender_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (receiver_id) REFERENCES users(id) ON DELETE CASCADE
);";
$pdo->exec($sql);
echo "Table 'messages' created successfully (if it didn't exist).\n";
} catch (PDOException $e) {
die("DB MIGRATION ERROR: " . $e->getMessage());
}

View File

@ -22,7 +22,14 @@ try {
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);"; );";
$pdo->exec($sql); $pdo->exec($sql);
echo "Table 'users' created successfully (if it didn't exist).\n"; echo "Table 'users' created successfully (if it didn\'t exist).\n";
// 4. Run migrations
$migration_files = glob(__DIR__ . '/migrations/*.php');
foreach ($migration_files as $file) {
require_once $file;
echo "Ran migration: $file\n";
}
} catch (PDOException $e) { } catch (PDOException $e) {
die("DB SETUP ERROR: " . $e->getMessage()); die("DB SETUP ERROR: " . $e->getMessage());

View File

@ -1,9 +1,5 @@
<footer class="footer mt-auto py-3 bg-dark text-white">
<div class="container text-center">
<small>harmony3 &copy; 2025</small>
</div>
</footer>
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> --> <!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> -->
</body> </body>

View File

@ -23,14 +23,14 @@
<body class="d-flex flex-column min-vh-100"> <body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container"> <div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample" aria-controls="offcanvasExample">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="index.php"> <a class="navbar-brand" href="index.php">
<i class="bi bi-chat-quote-fill"></i> <i class="bi bi-chat-quote-fill"></i>
harmony3 harmony3
</a> </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"> <div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto"> <ul class="navbar-nav ms-auto">
<?php if (isset($_SESSION['user_id'])): ?> <?php if (isset($_SESSION['user_id'])): ?>
@ -52,3 +52,25 @@
</div> </div>
</div> </div>
</nav> </nav>
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Chats</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<div>
Select a user to start a conversation.
</div>
<div class="dropdown mt-3">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown">
Select User
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="#">User 1</a></li>
<li><a class="dropdown-item" href="#">User 2</a></li>
<li><a class="dropdown-item" href="#">User 3</a></li>
</ul>
</div>
</div>
</div>

View File

@ -15,7 +15,7 @@ include 'header.php';
// If user is already logged in, redirect to dashboard // If user is already logged in, redirect to dashboard
if (isset($_SESSION['user_id'])) { if (isset($_SESSION['user_id'])) {
echo '<script>window.top.location.href = "dashboard.php";</script>'; header("Location: dashboard.php");
exit; exit;
} }
@ -47,8 +47,8 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
if ($user && password_verify($password, $user['password_hash'])) { if ($user && password_verify($password, $user['password_hash'])) {
$_SESSION['user_id'] = $user['id']; $_SESSION['user_id'] = $user['id'];
$_SESSION['display_name'] = $user['display_name']; $_SESSION['display_name'] = $user['display_name'];
// Use JS redirect for consistency // Standard PHP redirect
echo '<script>window.top.location.href = "dashboard.php";</script>'; header("Location: dashboard.php");
exit; exit;
} else { } else {
$errors[] = 'Invalid email or password.'; $errors[] = 'Invalid email or password.';