Contacts
This commit is contained in:
parent
a37fc59b93
commit
ca7f5831fa
32
api/send_message.php
Normal file
32
api/send_message.php
Normal 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']);
|
||||
}
|
||||
@ -1,51 +1,3 @@
|
||||
|
||||
body {
|
||||
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;
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
132
dashboard.php
132
dashboard.php
@ -1,58 +1,112 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
// If user is not logged in, redirect to login page
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
require_once 'db/config.php';
|
||||
include 'header.php';
|
||||
?>
|
||||
|
||||
<main class="container flex-grow-1 my-5">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Conversations
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item"><a href="#">User 1</a></li>
|
||||
<li class="list-group-item"><a href="#">User 2</a></li>
|
||||
<li class="list-group-item"><a href="#">User 3</a></li>
|
||||
</ul>
|
||||
$pdo = db();
|
||||
$current_user_id = $_SESSION['user_id'];
|
||||
|
||||
// Check if we are viewing a specific chat
|
||||
$chat_with_id = isset($_GET['chat_with_id']) ? (int)$_GET['chat_with_id'] : null;
|
||||
|
||||
if ($chat_with_id) {
|
||||
// Chat view
|
||||
$stmt = $pdo->prepare('SELECT display_name FROM users WHERE id = ?');
|
||||
$stmt->execute([$chat_with_id]);
|
||||
$chat_with_user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// Fetch messages
|
||||
$stmt = $pdo->prepare('SELECT * FROM messages WHERE (sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?) ORDER BY created_at ASC');
|
||||
$stmt->execute([$current_user_id, $chat_with_id, $chat_with_id, $current_user_id]);
|
||||
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
?>
|
||||
<div class="d-flex flex-column" style="height: calc(100vh - 56px);">
|
||||
<header class="p-3 bg-light border-bottom">
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<a href="dashboard.php" class="btn btn-secondary">< Back</a>
|
||||
<h1 class="h5 mb-0">Chat with <?php echo htmlspecialchars($chat_with_user['display_name']); ?></h1>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Chat with User 1
|
||||
</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>
|
||||
<div class="card-body" style="height: 400px; overflow-y: auto;">
|
||||
<!-- Chat messages will go here -->
|
||||
<div class="d-flex justify-content-end mb-3">
|
||||
<div class="bg-primary text-white p-2 rounded">
|
||||
Hello!
|
||||
<?php endforeach; ?>
|
||||
</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>
|
||||
</main>
|
||||
|
||||
<footer class="p-3 bg-light border-top">
|
||||
<div class="container-fluid">
|
||||
<form id="message-form">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Type a message...">
|
||||
<button class="btn btn-primary" type="button">Send</button>
|
||||
<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>
|
||||
</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';
|
||||
?>
|
||||
|
||||
21
db/migrations/001_create_messages_table.php
Normal file
21
db/migrations/001_create_messages_table.php
Normal 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());
|
||||
}
|
||||
|
||||
@ -22,7 +22,14 @@ try {
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);";
|
||||
$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) {
|
||||
die("DB SETUP ERROR: " . $e->getMessage());
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
|
||||
<footer class="footer mt-auto py-3 bg-dark text-white">
|
||||
<div class="container text-center">
|
||||
<small>harmony3 © 2025</small>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> -->
|
||||
</body>
|
||||
|
||||
30
header.php
30
header.php
@ -23,14 +23,14 @@
|
||||
<body class="d-flex flex-column min-vh-100">
|
||||
|
||||
<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">
|
||||
<i class="bi bi-chat-quote-fill"></i>
|
||||
harmony3
|
||||
</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">
|
||||
<?php if (isset($_SESSION['user_id'])): ?>
|
||||
@ -52,3 +52,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
|
||||
@ -15,7 +15,7 @@ include 'header.php';
|
||||
|
||||
// If user is already logged in, redirect to dashboard
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
echo '<script>window.top.location.href = "dashboard.php";</script>';
|
||||
header("Location: dashboard.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
@ -47,8 +47,8 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
if ($user && password_verify($password, $user['password_hash'])) {
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['display_name'] = $user['display_name'];
|
||||
// Use JS redirect for consistency
|
||||
echo '<script>window.top.location.href = "dashboard.php";</script>';
|
||||
// Standard PHP redirect
|
||||
header("Location: dashboard.php");
|
||||
exit;
|
||||
} else {
|
||||
$errors[] = 'Invalid email or password.';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user