Compare commits

...

4 Commits

Author SHA1 Message Date
Flatlogic Bot
faaf46de25 V5 2025-11-28 18:46:25 +00:00
Flatlogic Bot
27c6849991 v4 2025-11-28 18:04:41 +00:00
Flatlogic Bot
f3fecfd7d2 v2 2025-11-28 17:49:50 +00:00
Flatlogic Bot
2a74e9787f v1 2025-11-28 17:43:30 +00:00
30 changed files with 3200 additions and 143 deletions

483
assets/css/custom.css Normal file
View File

@ -0,0 +1,483 @@
body {
background-color: #0d1117;
color: #c9d1d9;
font-family: 'Roboto', sans-serif;
background-image: none;
}
.navbar {
background-color: rgba(13, 17, 23, 0.8);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.nav-link {
color: #c9d1d9;
transition: color 0.3s ease;
}
.nav-link:hover, .nav-link.active {
color: #58a6ff;
}
.hero {
background: radial-gradient(ellipse at bottom, #1f6feb 0%, #0d1117 80%);
padding: 120px 0;
text-align: center;
border-bottom: 1px solid #30363d;
}
.hero h1 {
font-family: 'Poppins', sans-serif;
font-weight: 700;
font-size: 3.8rem;
color: #ffffff;
text-shadow: 0 2px 4px rgba(0,0,0,0.5);
}
.hero p {
font-size: 1.2rem;
color: #c9d1d9;
max-width: 600px;
margin: 0 auto 30px;
}
.btn-primary {
background-color: #238636;
border-color: #238636;
padding: 12px 28px;
font-size: 1.1rem;
font-weight: 600;
transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
}
.btn-primary:hover {
background-color: #2ea043;
border-color: #2ea043;
}
.btn-secondary {
background-color: transparent;
border: 1px solid #30363d;
color: #58a6ff;
padding: 12px 28px;
font-size: 1.1rem;
font-weight: 600;
transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out, color 0.2s ease-in-out;
}
.btn-secondary:hover {
background-color: #58a6ff;
border-color: #58a6ff;
color: #ffffff;
}
.features {
padding: 100px 0;
background-color: #0d1117;
}
.feature-icon {
font-size: 2.5rem;
color: #58a6ff;
margin-bottom: 1.5rem;
display: inline-block;
padding: 1rem;
background-color: rgba(31, 111, 235, 0.1);
border-radius: 50%;
}
.features h3 {
font-family: 'Poppins', sans-serif;
font-weight: 600;
color: #f0f6fc;
}
.features p {
color: #8b949e;
}
.footer {
background-color: #161b22;
padding: 40px 0;
color: #8b949e;
border-top: 1px solid #3036d;
}
h1, h2, h3, h4, h5 {
font-family: 'Poppins', sans-serif;
font-weight: 600;
color: #f0f6fc;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem;
}
.form-container {
background-color: rgba(22, 27, 34, 0.8);
padding: 2.5rem;
border-radius: 1rem;
border: 1px solid #30363d;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.form-container .form-label {
color: #c9d1d9;
font-weight: 600;
}
.form-container .form-control {
background-color: #0d1117;
color: #c9d1d9;
border: 1px solid #30363d;
border-radius: 0.5rem;
padding: 0.75rem 1rem;
}
.form-container .form-control:focus {
background-color: #161b22;
color: #c9d1d9;
border-color: #58a6ff;
box-shadow: 0 0 0 0.25rem rgba(88, 166, 255, 0.25);
}
.form-container .btn-primary {
width: 100%;
}
.discussion-card {
background-color: #161b22;
border: 1px solid #30363d;
border-radius: 0.5rem;
padding: 1.5rem;
margin-bottom: 1rem;
transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
}
.discussion-card:hover {
background-color: #1f242c;
border-color: #58a6ff;
}
.discussion-card a {
color: #f0f6fc;
text-decoration: none;
}
.discussion-card a:hover {
text-decoration: underline;
}
.discussion-card .card-text {
color: #c9d1d9 !important;
}
.pagination .page-item .page-link {
background-color: #161b22;
border-color: #30363d;
color: #58a6ff;
}
.pagination .page-item.active .page-link {
background-color: #58a6ff;
border-color: #58a6ff;
color: #ffffff;
}
.pagination .page-item.disabled .page-link {
background-color: #161b22;
border-color: #30363d;
color: #484f58;
}
.discussion-post {
background-color: #161b22;
border: 1px solid #30363d;
border-radius: 0.5rem;
margin-bottom: 2rem;
}
.discussion-post .card-header {
background-color: rgba(31, 111, 235, 0.1);
border-bottom: 1px solid #30363d;
}
.discussion-post .card-body {
padding: 2rem;
}
.reply-card {
background-color: #0d1117;
border: 1px solid #30363d;
border-radius: 0.5rem;
padding: 1.5rem;
margin-bottom: 1rem;
}
.reply-card .reply-header {
font-size: 0.9rem;
color: #8b949e;
margin-bottom: 0.5rem;
}
.profile-container {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 2rem;
margin-top: 2rem;
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.event-card {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
margin-bottom: 1.5rem;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.event-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
}
.event-card a {
text-decoration: none;
color: inherit;
}
.event-card-header {
background-color: rgba(0, 0, 0, 0.2);
padding: 1rem 1.5rem;
}
.event-card-header h5 {
margin-bottom: 0;
color: #fff;
}
.event-card-body {
padding: 1.5rem;
}
.event-card-footer {
background-color: rgba(0, 0, 0, 0.1);
padding: 1rem 1.5rem;
font-size: 0.9rem;
color: #ccc;
}
.proposal-card {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
margin-bottom: 1.5rem;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.proposal-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
}
.proposal-card a {
text-decoration: none;
color: inherit;
}
.proposal-card-body {
padding: 1.5rem;
}
.proposal-card-footer {
background-color: rgba(0, 0, 0, 0.1);
padding: 1rem 1.5rem;
font-size: 0.9rem;
color: #ccc;
display: flex;
justify-content: space-between;
align-items: center;
}
.event-details-container {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 2.5rem;
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.event-details-header {
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
padding-bottom: 1.5rem;
margin-bottom: 1.5rem;
}
.rsvp-section {
background: rgba(255, 255, 255, 0.05);
border-radius: 15px;
padding: 2rem;
margin-top: 2rem;
text-align: center;
}
.rsvp-count {
font-size: 3rem;
font-weight: bold;
color: #fff;
}
.rsvp-label {
font-size: 1.2rem;
color: #ccc;
}
.proposal-details-container {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 2.5rem;
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.proposal-details-header {
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
padding-bottom: 1.5rem;
margin-bottom: 1.5rem;
}
.proposal-status {
font-size: 1.2rem;
font-weight: bold;
padding: 0.5rem 1rem;
border-radius: 8px;
color: #fff;
}
.proposal-status-pending {
background-color: #ffc107;
}
.proposal-status-approved {
background-color: #28a745;
}
.proposal-status-rejected {
background-color: #dc3545;
}
.message-item {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
margin-bottom: 1rem;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.message-item:hover {
transform: translateY(-5px);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
}
.message-item a {
text-decoration: none;
color: inherit;
padding: 1.5rem;
display: block;
}
.message-item-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
}
.chat-container {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.chat-messages {
height: 60vh;
overflow-y: auto;
padding: 1.5rem;
}
.message-bubble {
border-radius: 20px;
padding: 0.8rem 1rem;
max-width: 75%;
margin-bottom: 1rem;
}
.message-sent {
background-color: #0d6efd;
color: white;
align-self: flex-end;
margin-left: auto;
}
.message-received {
background-color: rgba(255, 255, 255, 0.2);
color: white;
align-self: flex-start;
}
.chat-input-group {
background-color: rgba(0, 0, 0, 0.2);
padding: 1rem;
}
.chat-input-group .form-control {
background-color: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
color: white;
}
.chat-input-group .form-control::placeholder {
color: rgba(255, 255, 255, 0.5);
}
.profile-avatar {
width: 150px;
height: 150px;
border-radius: 50%;
border: 3px solid #58a6ff;
margin-bottom: 1.5rem;
}
.profile-details p {
font-size: 1.1rem;
margin-bottom: 0.5rem;
}
.profile-details p strong {
color: #8b949e;
width: 100px;
display: inline-block;
}

18
assets/js/city-finder.js Normal file
View File

@ -0,0 +1,18 @@
function getCity() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
// Using a free reverse geocoding API
fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}`)
.then(response => response.json())
.then(data => {
if (data.address && data.address.city) {
document.getElementById('city').value = data.address.city;
}
})
.catch(err => console.error("Error fetching city:", err));
});
}
}
window.onload = getCity;

98
communities.php Normal file
View File

@ -0,0 +1,98 @@
<?php
session_start();
require_once 'db/config.php';
// Fetch user role if logged in
$user_role = null;
if (isset($_SESSION['user_id'])) {
$pdo = db();
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
}
try {
$pdo = db();
$stmt = $pdo->query('SELECT * FROM communities ORDER BY name');
$communities = $stmt->fetchAll();
} catch (PDOException $e) {
$error_message = "Error fetching communities: " . $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Communities - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&family=Roboto:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">Community Hub</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 (isset($_SESSION['user_id'])): ?>
<li class="nav-item"><a class="nav-link active" aria-current="page" href="communities.php">Communities</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage Communities</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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="signup.php">Sign Up</a></li>
<?php endif; ?>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<div class="container py-5">
<h1 class="text-center mb-5">Explore Communities</h1>
<?php if (!empty($error_message)): ?>
<div class="alert alert-danger"><?php echo $error_message; ?></div>
<?php elseif (empty($communities)): ?>
<div class="text-center">
<p>No communities found. Be the first to create one!</p>
<a href="signup.php" class="btn btn-primary">Get Started</a>
</div>
<?php else: ?>
<div class="row gy-4">
<?php foreach ($communities as $community): ?>
<div class="col-md-6 col-lg-4">
<div class="card h-100" style="background-color: #161b22; border-color: #30363d;">
<div class="card-body d-flex flex-column">
<h5 class="card-title" style="color: #f0f6fc;"><?php echo htmlspecialchars($community['name']); ?></h5>
<p class="card-text flex-grow-1" style="color: #8b949e;">A place for residents of <?php echo htmlspecialchars($community['name']); ?> to connect and organize.</p>
<a href="discussions.php?community_id=<?php echo $community['id']; ?>" class="btn btn-secondary mt-auto">View Discussions</a>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</main>
<footer class="footer text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

124
conversation.php Normal file
View File

@ -0,0 +1,124 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$with_id = $_GET['with'] ?? null;
if (!$with_id) {
header('Location: messages.php');
exit;
}
$pdo = db();
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
// Fetch the other user's info
$stmt = $pdo->prepare("SELECT username FROM users WHERE id = ?");
$stmt->execute([$with_id]);
$with_user = $stmt->fetch();
// Fetch conversation
$stmt = $pdo->prepare("SELECT m.*, u.username as sender_username FROM messages m JOIN users u ON m.sender_id = u.id WHERE (m.sender_id = ? AND m.receiver_id = ?) OR (m.sender_id = ? AND m.receiver_id = ?) ORDER BY m.created_at ASC");
$stmt->execute([$user_id, $with_id, $with_id, $user_id]);
$messages = $stmt->fetchAll();
// Handle new message
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['message'])) {
$message = $_POST['message'];
$stmt = $pdo->prepare("INSERT INTO messages (sender_id, receiver_id, message) VALUES (?, ?, ?)");
$stmt->execute([$user_id, $with_id, $message]);
header("Location: conversation.php?with=$with_id");
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Conversation with <?php echo htmlspecialchars($with_user['username']); ?> - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="events.php">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php">Proposals</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</a></li>
<li class="nav-item"><a class="nav-link active" aria-current="page" href="messages.php">Messages</a></li>
<li class="nav-item"><a class="nav-link" href="logout.php">Logout</a></li>
</ul>
</div>
</div>
</nav>
<main class="container mt-5 flex-grow-1 d-flex flex-column">
<div class="text-center mb-4">
<h1 class="display-5 text-white">Conversation with <?php echo htmlspecialchars($with_user['username']); ?></h1>
</div>
<div class="chat-container flex-grow-1 d-flex flex-column">
<div class="chat-messages flex-grow-1">
<?php foreach ($messages as $msg): ?>
<div class="d-flex <?php echo $msg['sender_id'] == $user_id ? 'justify-content-end' : 'justify-content-start'; ?> mb-3">
<div class="message-bubble <?php echo $msg['sender_id'] == $user_id ? 'message-sent' : 'message-received'; ?>">
<p class="mb-0"><?php echo htmlspecialchars($msg['message']); ?></p>
<small class="d-block text-end mt-1 opacity-75"><?php echo date('g:i a', strtotime($msg['created_at'])); ?></small>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="chat-input-group">
<form method="POST">
<div class="input-group">
<input type="text" name="message" class="form-control" placeholder="Type your message..." autocomplete="off">
<button type="submit" class="btn btn-primary"><i class="fas fa-paper-plane"></i></button>
</div>
</form>
</div>
</div>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Scroll to the bottom of the chat on page load
const chatMessages = document.querySelector('.chat-messages');
chatMessages.scrollTop = chatMessages.scrollHeight;
</script>
</body>
</html>

144
create_proposal.php Normal file
View File

@ -0,0 +1,144 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$community_id = $_GET['community_id'] ?? null;
if (!$community_id) {
echo "Community ID is required.";
exit;
}
$pdo = db();
$stmt = $pdo->prepare('SELECT * FROM communities WHERE id = ?');
$stmt->execute([$community_id]);
$community = $stmt->fetch();
if (!$community) {
echo "Community not found.";
exit;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!empty($_POST['title']) && !empty($_POST['description'])) {
$title = $_POST['title'];
$description = $_POST['description'];
$end_time = !empty($_POST['end_time']) ? date('Y-m-d H:i:s', strtotime($_POST['end_time'])) : date('Y-m-d H:i:s', strtotime('+7 days'));
try {
$stmt = $pdo->prepare("INSERT INTO proposals (user_id, community_id, title, description, end_time) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$user_id, $community_id, $title, $description, $end_time]);
// Send email notification
require_once __DIR__ . '/mail/MailService.php';
$user_stmt = $pdo->prepare('SELECT email, name FROM users WHERE id = ?');
$user_stmt->execute([$user_id]);
$user = $user_stmt->fetch();
if ($user) {
$to = $user['email'];
$subject = "Proposal Created: " . $title;
$html_content = "<h1>Your new proposal has been created!</h1><p><b>Title:</b> {$title}</p><p><b>Community:</b> {$community['name']}</p>";
$text_content = "Your new proposal '{$title}' has been created in the community '{$community['name']}'.";
MailService::sendMail($to, $subject, $html_content, $text_content);
}
header("Location: proposals.php?community_id=$community_id");
exit;
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
exit;
}
} else {
echo "Title and description are required.";
exit;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Proposal - <?php echo htmlspecialchars($community['name']); ?> - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="discussions.php?community_id=<?php echo $community_id; ?>">Discussions</a></li>
<li class="nav-item"><a class="nav-link" href="events.php?community_id=<?php echo $community_id; ?>">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php?community_id=<?php echo $community_id; ?>">Proposals</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="container mt-5 flex-grow-1">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="form-container">
<h2 class="text-white text-center mb-4">Create a New Proposal in <?php echo htmlspecialchars($community['name']); ?></h2>
<form method="POST" action="create_proposal.php?community_id=<?php echo $community_id; ?>">
<div class="mb-3">
<label for="title" class="form-label text-white-50">Title</label>
<input type="text" class="form-control" id="title" name="title" required>
</div>
<div class="mb-3">
<label for="description" class="form-label text-white-50">Description</label>
<textarea class="form-control" id="description" name="description" rows="8" required></textarea>
</div>
<div class="mb-3">
<label for="end_time" class="form-label text-white-50">End Time</label>
<input type="datetime-local" class="form-control" id="end_time" name="end_time">
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg">Submit Proposal</button>
</div>
</form>
</div>
</div>
</div>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

22
db/migrate.php Normal file
View File

@ -0,0 +1,22 @@
<?php
require_once __DIR__ . '/config.php';
function run_migrations() {
$pdo = db();
$migrations_dir = __DIR__ . '/migrations';
$files = glob($migrations_dir . '/*.sql');
sort($files);
foreach ($files as $file) {
$sql = file_get_contents($file);
try {
$pdo->exec($sql);
echo "Migration successful: " . basename($file) . "\n";
} catch (PDOException $e) {
echo "Migration failed for " . basename($file) . ": " . $e->getMessage() . "\n";
}
}
}
run_migrations();

View File

@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS `users` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`email` VARCHAR(255) NOT NULL UNIQUE,
`password` VARCHAR(255) NOT NULL,
`city` VARCHAR(255) NOT NULL,
`role` ENUM('member', 'leader') NOT NULL DEFAULT 'member',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

View File

@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS `communities` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL UNIQUE,
`leader_id` INT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`leader_id`) REFERENCES `users`(`id`)
);

View File

@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS `community_members` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT NOT NULL,
`community_id` INT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`),
FOREIGN KEY (`community_id`) REFERENCES `communities`(`id`)
);

View File

@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS `discussions` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`community_id` INT NOT NULL,
`user_id` INT NOT NULL,
`title` VARCHAR(255) NOT NULL,
`content` TEXT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`community_id`) REFERENCES `communities`(`id`),
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
);
CREATE TABLE IF NOT EXISTS `discussion_replies` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`discussion_id` INT NOT NULL,
`user_id` INT NOT NULL,
`content` TEXT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`discussion_id`) REFERENCES `discussions`(`id`),
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
);

View File

@ -0,0 +1,24 @@
CREATE TABLE IF NOT EXISTS `proposals` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`community_id` INT NOT NULL,
`user_id` INT NOT NULL,
`title` VARCHAR(255) NOT NULL,
`description` TEXT NOT NULL,
`end_time` TIMESTAMP NOT NULL,
`status` ENUM('active', 'resolved') NOT NULL DEFAULT 'active',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`community_id`) REFERENCES `communities`(`id`),
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
);
CREATE TABLE IF NOT EXISTS `proposal_votes` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`proposal_id` INT NOT NULL,
`user_id` INT NOT NULL,
`vote` ENUM('up', 'down') NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `user_proposal_vote` (`user_id`, `proposal_id`),
FOREIGN KEY (`proposal_id`) REFERENCES `proposals`(`id`),
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
);

View File

@ -0,0 +1,25 @@
CREATE TABLE IF NOT EXISTS `events` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`community_id` INT NOT NULL,
`user_id` INT NOT NULL,
`title` VARCHAR(255) NOT NULL,
`description` TEXT NOT NULL,
`start_time` TIMESTAMP NOT NULL,
`end_time` TIMESTAMP NOT NULL,
`location` VARCHAR(255) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`community_id`) REFERENCES `communities`(`id`),
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
);
CREATE TABLE IF NOT EXISTS `event_rsvps` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`event_id` INT NOT NULL,
`user_id` INT NOT NULL,
`rsvp` ENUM('attending', 'not_attending') NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `user_event_rsvp` (`user_id`, `event_id`),
FOREIGN KEY (`event_id`) REFERENCES `events`(`id`),
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
);

View File

@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS `messages` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`sender_id` INT NOT NULL,
`recipient_id` INT NOT NULL,
`content` TEXT NOT NULL,
`is_read` BOOLEAN NOT NULL DEFAULT FALSE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`sender_id`) REFERENCES `users`(`id`),
FOREIGN KEY (`recipient_id`) REFERENCES `users`(`id`)
);

51
delete_discussion.php Normal file
View File

@ -0,0 +1,51 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
if (!isset($_GET['id'])) {
header('Location: communities.php');
exit;
}
$discussion_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch discussion to get community_id and user_id
$stmt = $pdo->prepare('SELECT community_id, user_id FROM discussions WHERE id = ?');
$stmt->execute([$discussion_id]);
$discussion = $stmt->fetch();
if (!$discussion) {
header('Location: communities.php');
exit;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
// Check if user is authorized to delete
if ($discussion['user_id'] != $user_id && $user_role != 'leader') {
header('Location: discussion.php?id=' . $discussion_id);
exit;
}
// Delete replies first
$stmt = $pdo->prepare('DELETE FROM discussion_replies WHERE discussion_id = ?');
$stmt->execute([$discussion_id]);
// Delete discussion
$stmt = $pdo->prepare('DELETE FROM discussions WHERE id = ?');
$stmt->execute([$discussion_id]);
header('Location: discussions.php?community_id=' . $discussion['community_id']);
exit;

47
delete_reply.php Normal file
View File

@ -0,0 +1,47 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
if (!isset($_GET['id'])) {
header('Location: communities.php');
exit;
}
$reply_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch reply to get discussion_id and user_id
$stmt = $pdo->prepare('SELECT discussion_id, user_id FROM discussion_replies WHERE id = ?');
$stmt->execute([$reply_id]);
$reply = $stmt->fetch();
if (!$reply) {
header('Location: communities.php');
exit;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
// Check if user is authorized to delete
if ($reply['user_id'] != $user_id && $user_role != 'leader') {
header('Location: discussion.php?id=' . $reply['discussion_id']);
exit;
}
// Delete reply
$stmt = $pdo->prepare('DELETE FROM discussion_replies WHERE id = ?');
$stmt->execute([$reply_id]);
header('Location: discussion.php?id=' . $reply['discussion_id']);
exit;

185
discussion.php Normal file
View File

@ -0,0 +1,185 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
// Fetch user role if logged in
$user_role = null;
if (isset($_SESSION['user_id'])) {
$pdo = db();
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
}
if (!isset($_GET['id'])) {
header('Location: communities.php');
exit;
}
$discussion_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch discussion details
$stmt = $pdo->prepare('SELECT d.*, u.name as user_name, c.name as community_name, c.id as community_id FROM discussions d JOIN users u ON d.user_id = u.id JOIN communities c ON d.community_id = c.id WHERE d.id = ?');
$stmt->execute([$discussion_id]);
$discussion = $stmt->fetch();
if (!$discussion) {
header('Location: communities.php');
exit;
}
// Fetch user role in the community
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
// Handle new reply form submission
$content = '';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content'])) {
$content = trim($_POST['content']);
if (empty($content)) {
$errors[] = 'Reply content cannot be empty';
}
if (empty($errors)) {
try {
$stmt = $pdo->prepare('INSERT INTO discussion_replies (discussion_id, user_id, content) VALUES (?, ?, ?)');
$stmt->execute([$discussion_id, $user_id, $content]);
header('Location: discussion.php?id=' . $discussion_id);
exit;
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
// Fetch replies
$stmt = $pdo->prepare('SELECT dr.*, u.name as user_name FROM discussion_replies dr JOIN users u ON dr.user_id = u.id WHERE dr.discussion_id = ? ORDER BY dr.created_at ASC');
$stmt->execute([$discussion_id]);
$replies = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($discussion['title']); ?> - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">Community Hub</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="events.php">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php">Proposals</a></li>
<?php if (isset($_SESSION['user_id'])): ?>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage Communities</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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="signup.php">Sign Up</a></li>
<?php endif; ?>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<section class="container mt-5">
<div class="card bg-dark text-white mb-4">
<div class="card-header">
<h1 class="mb-0"><?php echo htmlspecialchars($discussion['title']); ?></h1>
<small>in <a href="discussions.php?community_id=<?php echo $discussion['community_id']; ?>"><?php echo htmlspecialchars($discussion['community_name']); ?></a> by <?php echo htmlspecialchars($discussion['user_name']); ?> on <?php echo date('M j, Y, g:i a', strtotime($discussion['created_at'])); ?></small>
</div>
<div class="card-body">
<p class="card-text"><?php echo nl2br(htmlspecialchars($discussion['content'])); ?></p>
<?php if ($discussion['user_id'] == $user_id || $user_role == 'leader'): ?>
<div class="mt-3">
<a href="edit_discussion.php?id=<?php echo $discussion['id']; ?>" class="btn btn-secondary btn-sm">Edit</a>
<a href="delete_discussion.php?id=<?php echo $discussion['id']; ?>" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to delete this discussion?');">Delete</a>
</div>
<?php endif; ?>
</div>
</div>
<h2 class="text-white">Replies</h2>
<div class="mb-4">
<?php if (empty($replies)):
<div class="text-center p-4 bg-dark text-white" style="border-radius: 0.5rem;">
<p class="mb-0">No replies yet. Be the first to reply!</p>
</div>
<?php else: ?>
<?php foreach ($replies as $reply):
<div class="card bg-dark text-white mb-3">
<div class="card-body">
<p class="card-text"><?php echo nl2br(htmlspecialchars($reply['content'])); ?></p>
<small>by <?php echo htmlspecialchars($reply['user_name']); ?> on <?php echo date('M j, Y, g:i a', strtotime($reply['created_at'])); ?></small>
<?php if ($reply['user_id'] == $user_id || $user_role == 'leader'): ?>
<div class="mt-2">
<a href="edit_reply.php?id=<?php echo $reply['id']; ?>" class="btn btn-secondary btn-sm">Edit</a>
<a href="delete_reply.php?id=<?php echo $reply['id']; ?>" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to delete this reply?');">Delete</a>
</div>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="card bg-dark text-white">
<div class="card-body">
<h2 class="card-title">Post a Reply</h2>
<?php if (!empty($errors):
<div class="alert alert-danger">
<?php foreach ($errors as $error):
<p><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="discussion.php?id=<?php echo $discussion_id; ?>" method="POST">
<div class="mb-3">
<label for="content" class="form-label">Your Reply</label>
<textarea class="form-control bg-dark text-white" id="content" name="content" rows="3" required><?php echo htmlspecialchars($content); ?></textarea>
</div>
<button type="submit" class="btn btn-primary">Post Reply</button>
</form>
</div>
</div>
</section>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

227
discussions.php Normal file
View File

@ -0,0 +1,227 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
// Fetch user role if logged in
$user_role = null;
if (isset($_SESSION['user_id'])) {
$pdo = db();
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
}
if (!isset($_GET['community_id'])) {
header('Location: communities.php');
exit;
}
$community_id = $_GET['community_id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch community details
$stmt = $pdo->prepare('SELECT * FROM communities WHERE id = ?');
$stmt->execute([$community_id]);
$community = $stmt->fetch();
if (!$community) {
header('Location: communities.php');
exit;
}
// Handle new discussion form submission
$title = $content = '';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = trim($_POST['title'] ?? '');
$content = trim($_POST['content'] ?? '');
if (empty($title)) {
$errors[] = 'Title is required';
}
if (empty($content)) {
$errors[] = 'Content is required';
}
if (empty($errors)) {
try {
$stmt = $pdo->prepare('INSERT INTO discussions (community_id, user_id, title, content) VALUES (?, ?, ?, ?)');
$stmt->execute([$community_id, $user_id, $title, $content]);
header('Location: discussions.php?community_id=' . $community_id);
exit;
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
// Search
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
// Pagination
$limit = 10;
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $limit;
// Build where clause for search
$where_clause = 'WHERE d.community_id = ?';
$params = [$community_id];
if (!empty($search)) {
$where_clause .= ' AND (d.title LIKE ? OR d.content LIKE ?)';
$params[] = '%' . $search . '%';
$params[] = '%' . $search . '%';
}
// Fetch total number of discussions
$stmt = $pdo->prepare('SELECT COUNT(*) FROM discussions d ' . $where_clause);
$stmt->execute($params);
$total_discussions = $stmt->fetchColumn();
$total_pages = ceil($total_discussions / $limit);
// Fetch discussions for the current page
$sql = 'SELECT d.*, u.name as user_name FROM discussions d JOIN users u ON d.user_id = u.id ' . $where_clause . ' ORDER BY d.created_at DESC LIMIT ? OFFSET ?';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1, $community_id, PDO::PARAM_INT);
if (!empty($search)) {
$search_param = '%' . $search . '%';
$stmt->bindParam(2, $search_param, PDO::PARAM_STR);
$stmt->bindParam(3, $search_param, PDO::PARAM_STR);
$stmt->bindParam(4, $limit, PDO::PARAM_INT);
$stmt->bindParam(5, $offset, PDO::PARAM_INT);
} else {
$stmt->bindParam(2, $limit, PDO::PARAM_INT);
$stmt->bindParam(3, $offset, PDO::PARAM_INT);
}
$stmt->execute();
$discussions = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($community['name']); ?> Discussions - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">Community Hub</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="discussions.php?community_id=<?php echo $community_id; ?>">Discussions</a></li>
<li class="nav-item"><a class="nav-link" href="events.php?community_id=<?php echo $community_id; ?>">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php?community_id=<?php echo $community_id; ?>">Proposals</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage Communities</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<div class="container py-5">
<h1 class="text-center mb-5">Discussions in <?php echo htmlspecialchars($community['name']); ?></h1>
<div class="form-container mb-5">
<h2 class="mb-4">Start a New Discussion</h2>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p class="mb-0"><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="discussions.php?community_id=<?php echo $community_id; ?>" method="POST">
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" class="form-control" id="title" name="title" value="<?php echo htmlspecialchars($title); ?>" required>
</div>
<div class="mb-3">
<label for="content" class="form-label">Content</label>
<textarea class="form-control" id="content" name="content" rows="4" required><?php echo htmlspecialchars($content); ?></textarea>
</div>
<button type="submit" class="btn btn-primary">Post Discussion</button>
</form>
</div>
<h2 class="mb-4">Existing Discussions</h2>
<form action="discussions.php" method="GET" class="mb-4">
<input type="hidden" name="community_id" value="<?php echo $community_id; ?>">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search discussions..." name="search" value="<?php echo htmlspecialchars($search); ?>" style="background-color: #0d1117; color: #c9d1d9; border-color: #30363d;">
<button class="btn btn-outline-secondary" type="submit" style="border-color: #30363d; color: #58a6ff;">Search</button>
</div>
</form>
<div>
<?php if (empty($discussions)): ?>
<div class="text-center p-4" style="background-color: #161b22; border-radius: 0.5rem;">
<p class="mb-0">No discussions found. Be the first to start one!</p>
</div>
<?php else: ?>
<?php foreach ($discussions as $discussion): ?>
<div class="discussion-card">
<div class="d-flex justify-content-between align-items-center mb-2">
<h5 class="mb-0">
<a href="discussion.php?id=<?php echo $discussion['id']; ?>"><?php echo htmlspecialchars($discussion['title']); ?></a>
</h5>
<small><?php echo date('M j, Y, g:i a', strtotime($discussion['created_at'])); ?></small>
</div>
<p class="mb-1">Started by: <?php echo htmlspecialchars($discussion['user_name']); ?></p>
<p class="card-text"><?php echo htmlspecialchars($discussion['content']); ?></p>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php if ($total_pages > 1): ?>
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center mt-4">
<li class="page-item <?php echo ($page <= 1) ? 'disabled' : ''; ?>">
<a class="page-link" href="?community_id=<?php echo $community_id; ?>&page=<?php echo $page - 1; ?>&search=<?php echo urlencode($search); ?>">Previous</a>
</li>
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<li class="page-item <?php echo ($page == $i) ? 'active' : ''; ?>">
<a class="page-link" href="?community_id=<?php echo $community_id; ?>&page=<?php echo $i; ?>&search=<?php echo urlencode($search); ?>"><?php echo $i; ?></a>
</li>
<?php endfor; ?>
<li class="page-item <?php echo ($page >= $total_pages) ? 'disabled' : ''; ?>">
<a class="page-link" href="?community_id=<?php echo $community_id; ?>&page=<?php echo $page + 1; ?>&search=<?php echo urlencode($search); ?>">Next</a>
</li>
</ul>
</nav>
<?php endif; ?>
</div>
</main>
<footer class="footer text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

161
edit_discussion.php Normal file
View File

@ -0,0 +1,161 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
// Fetch user role if logged in
$user_role = null;
if (isset($_SESSION['user_id'])) {
$pdo = db();
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
}
if (!isset($_GET['id'])) {
header('Location: communities.php');
exit;
}
$discussion_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch discussion
$stmt = $pdo->prepare('SELECT * FROM discussions WHERE id = ?');
$stmt->execute([$discussion_id]);
$discussion = $stmt->fetch();
if (!$discussion) {
header('Location: communities.php');
exit;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
// Check if user is authorized to edit
if ($discussion['user_id'] != $user_id && $user_role != 'leader') {
header('Location: discussion.php?id=' . $discussion_id);
exit;
}
$title = $discussion['title'];
$content = $discussion['content'];
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = trim($_POST['title'] ?? '');
$content = trim($_POST['content'] ?? '');
if (empty($title)) {
$errors[] = 'Title is required';
}
if (empty($content)) {
$errors[] = 'Content is required';
}
if (empty($errors)) {
try {
$stmt = $pdo->prepare('UPDATE discussions SET title = ?, content = ? WHERE id = ?');
$stmt->execute([$title, $content, $discussion_id]);
header('Location: discussion.php?id=' . $discussion_id);
exit;
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit Discussion - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="events.php?community_id=<?php echo $discussion['community_id']; ?>">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php?community_id=<?php echo $discussion['community_id']; ?>">Proposals</a></li>
<li class="nav-item"><a class="nav-link" href="discussions.php?community_id=<?php echo $discussion['community_id']; ">Discussions</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<section class="container mt-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="form-container">
<h1 class="text-white text-center mb-4">Edit Discussion</h1>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="edit_discussion.php?id=<?php echo $discussion_id; ?>" method="POST">
<div class="mb-3">
<label for="title" class="form-label text-white-50">Title</label>
<input type="text" class="form-control" id="title" name="title" value="<?php echo htmlspecialchars($title); ?>" required>
</div>
<div class="mb-3">
<label for="content" class="form-label text-white-50">Content</label>
<textarea class="form-control" id="content" name="content" rows="8" required><?php echo htmlspecialchars($content); ?></textarea>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a href="discussion.php?id=<?php echo $discussion_id; ?>" class="btn btn-secondary me-md-2">Cancel</a>
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
</section>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

156
edit_reply.php Normal file
View File

@ -0,0 +1,156 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
// Fetch user role if logged in
$user_role = null;
if (isset($_SESSION['user_id'])) {
$pdo = db();
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
}
if (!isset($_GET['id'])) {
header('Location: communities.php');
exit;
}
$reply_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch reply
$stmt = $pdo->prepare('SELECT * FROM discussion_replies WHERE id = ?');
$stmt->execute([$reply_id]);
$reply = $stmt->fetch();
// Fetch discussion to get community_id
$stmt = $pdo->prepare('SELECT community_id FROM discussions WHERE id = ?');
$stmt->execute([$reply['discussion_id']]);
$discussion = $stmt->fetch();
if (!$reply) {
header('Location: communities.php');
exit;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
// Check if user is authorized to edit
if ($reply['user_id'] != $user_id && $user_role != 'leader') {
header('Location: discussion.php?id=' . $reply['discussion_id']);
exit;
}
$content = $reply['content'];
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$content = trim($_POST['content'] ?? '');
if (empty($content)) {
$errors[] = 'Content is required';
}
if (empty($errors)) {
try {
$stmt = $pdo->prepare('UPDATE discussion_replies SET content = ? WHERE id = ?');
$stmt->execute([$content, $reply_id]);
header('Location: discussion.php?id=' . $reply['discussion_id']);
exit;
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit Reply - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="events.php?community_id=<?php echo $discussion['community_id']; ?>">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php?community_id=<?php echo $discussion['community_id']; ?>">Proposals</a></li>
<li class="nav-item"><a class="nav-link" href="discussions.php?community_id=<?php echo $discussion['community_id']; ">Discussions</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<section class="container mt-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="form-container">
<h1 class="text-white text-center mb-4">Edit Reply</h1>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="edit_reply.php?id=<?php echo $reply_id; ?>" method="POST">
<div class="mb-3">
<label for="content" class="form-label text-white-50">Content</label>
<textarea class="form-control" id="content" name="content" rows="8" required><?php echo htmlspecialchars($content); ?></textarea>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a href="discussion.php?id=<?php echo $reply['discussion_id']; ?>" class="btn btn-secondary me-md-2">Cancel</a>
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
</section>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

180
event.php Normal file
View File

@ -0,0 +1,180 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
// Fetch user role if logged in
$user_role = null;
if (isset($_SESSION['user_id'])) {
$pdo = db();
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
}
if (!isset($_GET['id'])) {
header('Location: communities.php');
exit;
}
$event_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch event details
$stmt = $pdo->prepare('SELECT e.*, u.name as user_name, c.name as community_name FROM events e JOIN users u ON e.user_id = u.id JOIN communities c ON e.community_id = c.id WHERE e.id = ?');
$stmt->execute([$event_id]);
$event = $stmt->fetch();
if (!$event) {
header('Location: communities.php');
exit;
}
// Handle RSVP
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['rsvp'])) {
$rsvp = $_POST['rsvp'];
if (in_array($rsvp, ['attending', 'not_attending'])) {
try {
// Check if user has already RSVPed
$stmt = $pdo->prepare('SELECT id FROM event_rsvps WHERE user_id = ? AND event_id = ?');
$stmt->execute([$user_id, $event_id]);
if ($stmt->fetch()) {
// Update existing RSVP
$stmt = $pdo->prepare('UPDATE event_rsvps SET rsvp = ? WHERE user_id = ? AND event_id = ?');
$stmt->execute([$rsvp, $user_id, $event_id]);
} else {
// Insert new RSVP
$stmt = $pdo->prepare('INSERT INTO event_rsvps (event_id, user_id, rsvp) VALUES (?, ?, ?)');
$stmt->execute([$event_id, $user_id, $rsvp]);
}
header('Location: event.php?id=' . $event_id);
exit;
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
// Fetch RSVPs
$stmt = $pdo->prepare('SELECT rsvp, COUNT(*) as count FROM event_rsvps WHERE event_id = ? GROUP BY rsvp');
$stmt->execute([$event_id]);
$rsvps = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$attending = $rsvps['attending'] ?? 0;
$not_attending = $rsvps['not_attending'] ?? 0;
// Check if the current user has RSVPed
$stmt = $pdo->prepare('SELECT rsvp FROM event_rsvps WHERE user_id = ? AND event_id = ?');
$stmt->execute([$user_id, $event_id]);
$user_rsvp = $stmt->fetchColumn();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($event['title']); ?> - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="events.php?community_id=<?php echo $event['community_id']; ?>">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php?community_id=<?php echo $event['community_id']; ?>">Proposals</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<section class="container mt-5">
<div class="event-details-container">
<div class="event-details-header">
<h1 class="display-4 text-white"><?php echo htmlspecialchars($event['title']); ?></h1>
<p class="lead text-white-50">
in <a href="discussions.php?community_id=<?php echo $event['community_id']; ?>" class="text-white-50"><?php echo htmlspecialchars($event['community_name']); ?></a> by <?php echo htmlspecialchars($event['user_name']); ?>
</p>
</div>
<div class="event-details-body text-white">
<p class="fs-5"><?php echo nl2br(htmlspecialchars($event['description'])); ?></p>
<hr class="border-light">
<div class="row mt-4 fs-5">
<div class="col-md-4">
<p><i class="fas fa-map-marker-alt me-2 text-primary"></i><strong>Location:</strong> <?php echo htmlspecialchars($event['location']); ?></p>
</div>
<div class="col-md-4">
<p><i class="far fa-clock me-2 text-primary"></i><strong>Starts:</strong> <?php echo date('M j, Y, g:i a', strtotime($event['start_time'])); ?></p>
</div>
<div class="col-md-4">
<p><i class="far fa-clock me-2 text-primary"></i><strong>Ends:</strong> <?php echo date('M j, Y, g:i a', strtotime($event['end_time'])); ?></p>
</div>
</div>
</div>
</div>
<div class="rsvp-section">
<h2 class="text-white mb-4">RSVPs</h2>
<div class="row justify-content-center">
<div class="col-md-4 text-center">
<p class="rsvp-label">Attending</p>
<p class="rsvp-count text-success"><?php echo $attending; ?></p>
</div>
<div class="col-md-4 text-center">
<p class="rsvp-label">Not Attending</p>
<p class="rsvp-count text-danger"><?php echo $not_attending; ?></p>
</div>
</div>
<div class="mt-4">
<h3 class="text-white mb-3">Will you be there?</h3>
<form action="event.php?id=<?php echo $event_id; ?>" method="POST" class="d-inline">
<input type="hidden" name="rsvp" value="attending">
<button type="submit" class="btn btn-success btn-lg me-2 <?php echo ($user_rsvp === 'attending') ? 'active' : ''; ?>"><i class="fas fa-check me-2"></i>Attending</button>
</form>
<form action="event.php?id=<?php echo $event_id; ?>" method="POST" class="d-inline">
<input type="hidden" name="rsvp" value="not_attending">
<button type="submit" class="btn btn-danger btn-lg <?php echo ($user_rsvp === 'not_attending') ? 'active' : ''; ?>"><i class="fas fa-times me-2"></i>Not Attending</button>
</form>
</div>
</div>
</section>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

204
events.php Normal file
View File

@ -0,0 +1,204 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$community_id = $_GET['community_id'] ?? null;
if (!$community_id) {
echo "Community ID is required.";
exit;
}
$pdo = db();
$stmt = $pdo->prepare('SELECT * FROM communities WHERE id = ?');
$stmt->execute([$community_id]);
$community = $stmt->fetch();
if (!$community) {
echo "Community not found.";
exit;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
// Handle event creation
$errors = [];
$title = $description = $start_time = $end_time = $location = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = trim($_POST['title'] ?? '');
$description = trim($_POST['description'] ?? '');
$start_time = $_POST['start_time'] ?? '';
$end_time = $_POST['end_time'] ?? '';
$location = trim($_POST['location'] ?? '');
if (empty($title)) {
$errors[] = 'Title is required.';
}
if (empty($description)) {
$errors[] = 'Description is required.';
}
if (empty($start_time)) {
$errors[] = 'Start time is required.';
}
if (empty($end_time)) {
$errors[] = 'End time is required.';
}
if (empty($location)) {
$errors[] = 'Location is required.';
}
if (strtotime($start_time) >= strtotime($end_time)) {
$errors[] = 'End time must be after start time.';
}
if (empty($errors)) {
$stmt = $pdo->prepare('INSERT INTO events (community_id, user_id, title, description, start_time, end_time, location) VALUES (?, ?, ?, ?, ?, ?, ?)');
if ($stmt->execute([$community_id, $user_id, $title, $description, $start_time, $end_time, $location])) {
header("Location: events.php?community_id=$community_id");
exit;
} else {
$errors[] = 'Failed to create event. Please try again.';
}
}
}
// Fetch events for the community
$stmt = $pdo->prepare('SELECT e.*, u.name as user_name FROM events e JOIN users u ON e.user_id = u.id WHERE e.community_id = ? ORDER BY e.start_time DESC');
$stmt->execute([$community_id]);
$events = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($community['name']); ?> Events - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="discussions.php?community_id=<?php echo $community_id; ?>">Discussions</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php?community_id=<?php echo $community_id; ?>">Proposals</a></li>
<li class="nav-item"><a class="nav-link" href="events.php?community_id=<?php echo $community_id; ?>">Events</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<section class="container mt-5">
<div class="text-center mb-5">
<h1 class="display-4 text-white">Events in <?php echo htmlspecialchars($community['name']); ?></h1>
<p class="lead text-white-50">Stay up-to-date with the latest happenings.</p>
</div>
<div class="form-container mb-5">
<h2 class="card-title text-white">Create a New Event</h2>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="events.php?community_id=<?php echo $community_id; ?>" method="POST">
<div class="mb-3">
<label for="title" class="form-label text-white-50">Title</label>
<input type="text" class="form-control" id="title" name="title" value="<?php echo htmlspecialchars($title); ?>" required>
</div>
<div class="mb-3">
<label for="description" class="form-label text-white-50">Description</label>
<textarea class="form-control" id="description" name="description" rows="3" required><?php echo htmlspecialchars($description); ?></textarea>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="start_time" class="form-label text-white-50">Start Time</label>
<input type="datetime-local" class="form-control" id="start_time" name="start_time" value="<?php echo htmlspecialchars($start_time); ?>" required>
</div>
<div class="col-md-6 mb-3">
<label for="end_time" class="form-label text-white-50">End Time</label>
<input type="datetime-local" class="form-control" id="end_time" name="end_time" value="<?php echo htmlspecialchars($end_time); ?>" required>
</div>
</div>
<div class="mb-3">
<label for="location" class="form-label text-white-50">Location</label>
<input type="text" class="form-control" id="location" name="location" value="<?php echo htmlspecialchars($location); ?>" required>
</div>
<button type="submit" class="btn btn-primary w-100">Create Event</button>
</form>
</div>
<h2 class="text-white mb-4">Upcoming Events</h2>
<div class="row">
<?php if (empty($events)): ?>
<div class="col">
<div class="form-container text-center">
<p class="lead text-white-50">No events yet. Be the first to create one!</p>
</div>
</div>
<?php else: ?>
<?php foreach ($events as $event): ?>
<div class="col-lg-6">
<div class="event-card">
<a href="event.php?id=<?php echo $event['id']; ?>">
<div class="event-card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0"><?php echo htmlspecialchars($event['title']); ?></h5>
<span class="badge bg-primary"><?php echo date('M j', strtotime($event['start_time'])); ?></span>
</div>
<div class="event-card-body">
<p class="mb-2"><i class="fas fa-map-marker-alt me-2 text-white-50"></i><?php echo htmlspecialchars($event['location']); ?></p>
<p class="mb-0"><i class="far fa-clock me-2 text-white-50"></i><?php echo date('g:i a', strtotime($event['start_time'])); ?> - <?php echo date('g:i a', strtotime($event['end_time'])); ?></p>
</div>
<div class="event-card-footer">
<small>Created by: <?php echo htmlspecialchars($event['user_name']); ?></small>
</div>
</a>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</section>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

235
index.php
View File

@ -1,150 +1,99 @@
<?php
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION; <?php
$now = date('Y-m-d H:i:s'); session_start();
require_once 'db/config.php'; // Add this line
// Fetch user role if logged in
$user_role = null;
if (isset($_SESSION['user_id'])) {
$pdo = db();
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
}
?> ?>
<!doctype html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Style</title> <title>Community Hub</title>
<?php <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
// Read project preview data from environment <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&family=Roboto:wght@400;700&display=swap" rel="stylesheet">
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? ''; <link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
?>
<?php if ($projectDescription): ?>
<!-- Meta description -->
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
<!-- Open Graph meta tags -->
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<!-- Twitter meta tags -->
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<!-- Open Graph image -->
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<!-- Twitter image -->
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% { background-position: 0% 0%; }
100% { background-position: 100% 100%; }
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}
.loader {
margin: 1.25rem auto 1.25rem;
width: 48px;
height: 48px;
border: 3px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hint {
opacity: 0.9;
}
.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; border: 0;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin: 0 0 1rem;
letter-spacing: -1px;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
}
code {
background: rgba(0,0,0,0.2);
padding: 2px 6px;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
footer {
position: absolute;
bottom: 1rem;
font-size: 0.8rem;
opacity: 0.7;
}
</style>
</head> </head>
<body> <body class="d-flex flex-column min-vh-100">
<main>
<div class="card"> <nav class="navbar navbar-expand-lg navbar-dark">
<h1>Analyzing your requirements and generating your website…</h1> <div class="container-fluid">
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes"> <a class="navbar-brand" href="index.php">Community Hub</a>
<span class="sr-only">Loading…</span> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
</div> <span class="navbar-toggler-icon"></span>
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p> </button>
<p class="hint">This page will update automatically as the plan is implemented.</p> <div class="collapse navbar-collapse" id="navbarNav">
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p> <ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="index.php">Home</a></li>
<?php if (isset($_SESSION['user_id'])): ?>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage Communities</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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="signup.php">Sign Up</a></li>
<?php endif; ?>
</ul>
</div>
</div> </div>
</main> </nav>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC) <main class="flex-grow-1">
</footer> <header class="hero text-white text-center">
<div class="container">
<h1 class="display-4">Build Your Community. Shape Your City.</h1>
<p class="lead">The platform where neighbors connect, leaders emerge, and real change starts with one discussion.</p>
<a href="signup.php" class="btn btn-primary me-2">Join Your City</a>
<a href="communities.php" class="btn btn-secondary">Explore Communities</a>
</div>
</header>
<section class="features text-center py-5">
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="feature-icon mb-3">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
</div>
<h3>Connect</h3>
<p>Join communities in your city and connect with your neighbors.</p>
</div>
<div class="col-md-4">
<div class="feature-icon mb-3">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-message-circle"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path></svg>
</div>
<h3>Discuss</h3>
<p>Start and participate in discussions about topics that matter to you.</p>
</div>
<div class="col-md-4">
<div class="feature-icon mb-3">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-calendar"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>
</div>
<h3>Organize</h3>
<p>Create events and proposals to drive real change in your community.</p>
</div>
</div>
</div>
</section>
</main>
<footer class="footer text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body> </body>
</html> </html>

113
login.php Normal file
View File

@ -0,0 +1,113 @@
<?php
session_start();
require_once 'db/config.php';
$email = $password = '';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Valid email is required';
}
if (empty($password)) {
$errors[] = 'Password is required';
}
if (empty($errors)) {
try {
$pdo = db();
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
header('Location: communities.php');
exit;
} else {
$errors[] = 'Invalid email or password';
}
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">Community Hub</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 (isset($_SESSION['user_id'])): ?>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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 active" aria-current="page" href="login.php">Login</a></li>
<li class="nav-item"><a class="nav-link" href="signup.php">Sign Up</a></li>
<?php endif; ?>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1 d-flex align-items-center justify-content-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 col-lg-5">
<div class="form-container">
<h1 class="text-center mb-4">Login to Your Account</h1>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p class="mb-0"><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="login.php" method="POST">
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($email); ?>" required>
</div>
<div class="mb-4">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
<footer class="footer text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

7
logout.php Normal file
View File

@ -0,0 +1,7 @@
<?php
session_start();
session_unset();
session_destroy();
header('Location: index.php');
exit;

192
manage_communities.php Normal file
View File

@ -0,0 +1,192 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
if ($user_role !== 'leader') {
header('Location: communities.php');
exit;
}
$errors = [];
$name = '';
$description = '';
$edit_id = null;
// Handle community creation and updates
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name']);
$description = trim($_POST['description']);
$edit_id = $_POST['edit_id'] ?? null;
if (empty($name)) {
$errors[] = 'Community name is required.';
}
if (empty($description)) {
$errors[] = 'Description is required.';
}
if (empty($errors)) {
if ($edit_id) {
// Update existing community
$stmt = $pdo->prepare('UPDATE communities SET name = ?, description = ? WHERE id = ? AND leader_id = ?');
$stmt->execute([$name, $description, $edit_id, $user_id]);
} else {
// Create new community
$stmt = $pdo->prepare('INSERT INTO communities (name, description, leader_id) VALUES (?, ?, ?)');
$stmt->execute([$name, $description, $user_id]);
}
header('Location: manage_communities.php');
exit;
}
}
// Handle community deletion
if (isset($_GET['delete'])) {
$delete_id = $_GET['delete'];
$stmt = $pdo->prepare('DELETE FROM communities WHERE id = ? AND leader_id = ?');
$stmt->execute([$delete_id, $user_id]);
header('Location: manage_communities.php');
exit;
}
// Handle editing a community
if (isset($_GET['edit'])) {
$edit_id = $_GET['edit'];
$stmt = $pdo->prepare('SELECT * FROM communities WHERE id = ? AND leader_id = ?');
$stmt->execute([$edit_id, $user_id]);
$community_to_edit = $stmt->fetch();
if ($community_to_edit) {
$name = $community_to_edit['name'];
$description = $community_to_edit['description'];
}
}
// Fetch communities led by the user
$stmt = $pdo->prepare('SELECT * FROM communities WHERE leader_id = ? ORDER BY name');
$stmt->execute([$user_id]);
$communities = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Communities - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link active" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<section class="container mt-5">
<div class="text-center mb-5">
<h1 class="display-4 text-white">Manage Communities</h1>
<p class="lead text-white-50">Create, edit, and manage your communities.</p>
</div>
<div class="form-container mb-5">
<h2 class="text-white mb-4"><?php echo $edit_id ? 'Edit Community' : 'Create a New Community'; ?></h2>
<?php if (!empty($errors)):
<div class="alert alert-danger">
<?php foreach ($errors as $error):
<p><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="manage_communities.php" method="POST">
<input type="hidden" name="edit_id" value="<?php echo $edit_id; ?>">
<div class="mb-3">
<label for="name" class="form-label text-white-50">Community Name</label>
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($name); ?>" required>
</div>
<div class="mb-3">
<label for="description" class="form-label text-white-50">Description</label>
<textarea class="form-control" id="description" name="description" rows="3" required><?php echo htmlspecialchars($description); ?></textarea>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<?php if ($edit_id):
<a href="manage_communities.php" class="btn btn-secondary me-md-2">Cancel Edit</a>
<?php endif; ?>
<button type="submit" class="btn btn-primary"><?php echo $edit_id ? 'Save Changes' : 'Create Community'; ?></button>
</div>
</form>
</div>
<h2 class="text-white mb-4">Your Communities</h2>
<div class="row">
<?php if (empty($communities)):
<div class="col">
<div class="form-container text-center">
<p class="lead text-white-50">You have not created any communities yet.</p>
</div>
</div>
<?php else: ?>
<?php foreach ($communities as $community):
<div class="col-md-6 mb-4">
<div class="card bg-white-10 text-white h-100">
<div class="card-body d-flex flex-column">
<h5 class="card-title"><?php echo htmlspecialchars($community['name']); ?></h5>
<p class="card-text flex-grow-1"><?php echo htmlspecialchars($community['description']); ?></p>
<div class="mt-auto">
<a href="manage_communities.php?edit=<?php echo $community['id']; ?>" class="btn btn-sm btn-outline-light me-2"><i class="fas fa-edit me-1"></i>Edit</a>
<a href="manage_communities.php?delete=<?php echo $community['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('Are you sure you want to delete this community?');"><i class="fas fa-trash me-1"></i>Delete</a>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</section>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

111
messages.php Normal file
View File

@ -0,0 +1,111 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch conversations
$stmt = $pdo->prepare("SELECT u.id as user_id, u.username, m.message, m.created_at
FROM messages m
JOIN users u ON u.id = m.sender_id OR u.id = m.receiver_id
WHERE (m.sender_id = :user_id OR m.receiver_id = :user_id)
AND u.id != :user_id
AND m.id IN (
SELECT MAX(id) FROM messages
WHERE sender_id = :user_id OR receiver_id = :user_id
GROUP BY LEAST(sender_id, receiver_id), GREATEST(sender_id, receiver_id)
)
ORDER BY m.created_at DESC");
$stmt->execute(['user_id' => $user_id]);
$conversations = $stmt->fetchAll();
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Messages - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="events.php">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php">Proposals</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</a></li>
<li class="nav-item"><a class="nav-link active" aria-current="page" href="messages.php">Messages</a></li>
<li class="nav-item"><a class="nav-link" href="logout.php">Logout</a></li>
</ul>
</div>
</div>
</nav>
<main class="container mt-5 flex-grow-1">
<div class="text-center mb-5">
<h1 class="display-4 text-white">Messages</h1>
<p class="lead text-white-50">Your recent conversations.</p>
</div>
<div class="row justify-content-center">
<div class="col-lg-10">
<?php if (empty($conversations)): ?>
<div class="form-container text-center">
<p class="lead text-white-50">You have no conversations yet.</p>
</div>
<?php else: ?>
<?php foreach ($conversations as $convo): ?>
<div class="message-item">
<a href="conversation.php?with=<?php echo $convo['user_id']; ?>">
<div class="message-item-header">
<h5 class="text-white mb-0"><?php echo htmlspecialchars($convo['username']); ?></h5>
<small class="text-white-50"><?php echo date('M j, Y, g:i a', strtotime($convo['created_at'])); ?></small>
</div>
<p class="text-white-50 mb-0"><?php echo htmlspecialchars(substr($convo['message'], 0, 100)); ?>...</p>
</a>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

79
profile.php Normal file
View File

@ -0,0 +1,79 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Profile - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">Community Hub</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="events.php">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php">Proposals</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage Communities</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link active" aria-current="page" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<div class="container">
<div class="profile-container text-center">
<img src="https://i.pravatar.cc/150?u=<?php echo $user_id; ?>" alt="User Avatar" class="profile-avatar">
<h1 class="mb-4"><?php echo htmlspecialchars($user['name']); ?></h1>
<div class="profile-details text-start mx-auto" style="max-width: 400px;">
<p><strong>Email:</strong> <?php echo htmlspecialchars($user['email']); ?></p>
<p><strong>City:</strong> <?php echo htmlspecialchars($user['city']); ?></p>
<p><strong>Role:</strong> <span class="badge bg-primary"><?php echo htmlspecialchars(ucfirst($user['role'])); ?></span></p>
</div>
</div>
</div>
</main>
<footer class="footer text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

109
proposal.php Normal file
View File

@ -0,0 +1,109 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$proposal_id = $_GET['id'] ?? null;
if (!$proposal_id) {
// Redirect or show an error if no proposal ID is provided
header('Location: proposals.php');
exit;
}
$pdo = db();
// Fetch proposal data
$stmt = $pdo->prepare("SELECT p.*, u.name, c.id as community_id FROM proposals p JOIN users u ON p.user_id = u.id JOIN communities c ON p.community_id = c.id WHERE p.id = ?");
$stmt->execute([$proposal_id]);
$proposal = $stmt->fetch();
if (!$proposal) {
// Redirect or show an error if proposal not found
header('Location: proposals.php');
exit;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$_SESSION['user_id']]);
$user_role = $stmt->fetchColumn();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Proposal Details - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="discussions.php?community_id=<?php echo $proposal['community_id']; ?>">Discussions</a></li>
<li class="nav-item"><a class="nav-link" href="events.php?community_id=<?php echo $proposal['community_id']; ?>">Events</a></li>
<li class="nav-item"><a class="nav-link" href="proposals.php?community_id=<?php echo $proposal['community_id']; ?>">Proposals</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="container mt-5 flex-grow-1">
<div class="proposal-details-container">
<div class="proposal-details-header">
<h1 class="display-4 text-white"><?php echo htmlspecialchars($proposal['title']); ?></h1>
<p class="lead text-white-50">Submitted by <?php echo htmlspecialchars($proposal['name']); ?></p>
</div>
<div class="proposal-details-body text-white">
<p class="fs-5"><?php echo nl2br(htmlspecialchars($proposal['description'])); ?></p>
<hr class="border-light">
<div class="d-flex justify-content-between align-items-center mt-4">
<p class="fs-5 mb-0"><strong>Status:</strong></p>
<?php
$status_class = 'proposal-status-pending';
if ($proposal['status'] === 'approved') {
$status_class = 'proposal-status-approved';
} elseif ($proposal['status'] === 'rejected') {
$status_class = 'proposal-status-rejected';
}
?>
<span class="proposal-status <?php echo $status_class; ?>"><?php echo htmlspecialchars(ucfirst($proposal['status'])); ?></span>
</div>
</div>
</div>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

122
proposals.php Normal file
View File

@ -0,0 +1,122 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$community_id = $_GET['community_id'] ?? null;
if (!$community_id) {
echo "Community ID is required.";
exit;
}
$pdo = db();
$stmt = $pdo->prepare('SELECT * FROM communities WHERE id = ?');
$stmt->execute([$community_id]);
$community = $stmt->fetch();
if (!$community) {
echo "Community not found.";
exit;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
// Fetch proposals for the community
$stmt = $pdo->prepare('SELECT p.*, u.name as user_name FROM proposals p JOIN users u ON p.user_id = u.id WHERE p.community_id = ? ORDER BY p.created_at DESC');
$stmt->execute([$community_id]);
$proposals = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($community['name']); ?> Proposals - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<div class="background-animation"></div>
<nav class="navbar navbar-expand-lg navbar-dark bg-transparent">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<i class="fas fa-cubes me-2"></i>Community Hub
</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>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="discussions.php?community_id=<?php echo $community_id; ?>">Discussions</a></li>
<li class="nav-item"><a class="nav-link" href="events.php?community_id=<?php echo $community_id; ?>">Events</a></li>
<li class="nav-item"><a class="nav-link active" aria-current="page" href="proposals.php?community_id=<?php echo $community_id; ?>">Proposals</a></li>
<?php if ($user_role === 'leader'): ?>
<li class="nav-item"><a class="nav-link" href="manage_communities.php">Manage</a></li>
<?php endif; ?>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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>
</ul>
</div>
</div>
</nav>
<main class="container mt-5 flex-grow-1">
<div class="d-flex justify-content-between align-items-center mb-5">
<div>
<h1 class="display-4 text-white">Proposals in <?php echo htmlspecialchars($community['name']); ?></h1>
<p class="lead text-white-50">Shape the future of your community.</p>
</div>
<a href="create_proposal.php?community_id=<?php echo $community_id; ?>" class="btn btn-primary btn-lg"><i class="fas fa-plus me-2"></i>New Proposal</a>
</div>
<div class="row">
<?php if (empty($proposals)): ?>
<div class="col">
<div class="form-container text-center">
<p class="lead text-white-50">No proposals yet. Be the first to create one!</p>
</div>
</div>
<?php else: ?>
<?php foreach ($proposals as $proposal): ?>
<div class="col-lg-6">
<div class="proposal-card">
<a href="proposal.php?id=<?php echo $proposal['id']; ?>">
<div class="proposal-card-body">
<h5 class="card-title text-white"><?php echo htmlspecialchars($proposal['title']); ?></h5>
<p class="card-text text-white-50"><?php echo htmlspecialchars(substr($proposal['description'], 0, 150)); ?>...</p>
</div>
<div class="proposal-card-footer">
<small>By <?php echo htmlspecialchars($proposal['user_name']); ?></small>
<small><?php echo date('M j, Y', strtotime($proposal['created_at'])); ?></small>
</div>
</a>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</main>
<footer class="footer">
<div class="container text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

167
signup.php Normal file
View File

@ -0,0 +1,167 @@
<?php
session_start();
require_once 'db/config.php';
$name = $email = $password = $city = '';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
$city = trim($_POST['city'] ?? '');
if (empty($name)) {
$errors[] = 'Name is required';
}
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Valid email is required';
}
if (empty($password)) {
$errors[] = 'Password is required';
}
if (empty($city)) {
$errors[] = 'City is required';
}
if (empty($errors)) {
try {
$pdo = db();
// Check if user already exists
$stmt = $pdo->prepare('SELECT id FROM users WHERE email = ?');
$stmt->execute([$email]);
if ($stmt->fetch()) {
$errors[] = 'User with this email already exists';
} else {
$pdo->beginTransaction();
// Check if community for the city exists
$stmt = $pdo->prepare('SELECT id FROM communities WHERE name = ?');
$stmt->execute([$city]);
$community = $stmt->fetch();
$role = 'member';
if (!$community) {
$role = 'leader';
}
// Insert the new user
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('INSERT INTO users (name, email, password, city, role) VALUES (?, ?, ?, ?, ?)');
$stmt->execute([$name, $email, $hashed_password, $city, $role]);
$user_id = $pdo->lastInsertId();
if ($role === 'leader') {
$stmt = $pdo->prepare('INSERT INTO communities (name, leader_id) VALUES (?, ?)');
$stmt->execute([$city, $user_id]);
$community_id = $pdo->lastInsertId();
} else {
$community_id = $community['id'];
}
// Add user to community
$stmt = $pdo->prepare('INSERT INTO community_members (user_id, community_id) VALUES (?, ?)');
$stmt->execute([$user_id, $community_id]);
$pdo->commit();
$_SESSION['user_id'] = $user_id;
header('Location: communities.php');
exit;
}
} catch (PDOException $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign Up - Community Hub</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">Community Hub</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 (isset($_SESSION['user_id'])): ?>
<li class="nav-item"><a class="nav-link" href="communities.php">Communities</a></li>
<li class="nav-item"><a class="nav-link" href="profile.php">Profile</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 active" aria-current="page" href="signup.php">Sign Up</a></li>
<?php endif; ?>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1 d-flex align-items-center justify-content-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 col-lg-5">
<div class="form-container">
<h1 class="text-center mb-4">Create Your Account</h1>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger">
<?php foreach ($errors as $error): ?>
<p class="mb-0"><?php echo $error; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form action="signup.php" method="POST" id="signup-form">
<div class="mb-3">
<label for="name" class="form-label">Full Name</label>
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($name); ?>" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($email); ?>" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="mb-3">
<label for="city" class="form-label">City</label>
<input type="text" class="form-control" id="city" name="city" value="<?php echo htmlspecialchars($city); ?>" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Sign Up</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
<footer class="footer text-center">
<p>&copy; <?php echo date("Y"); ?> Community Hub. All Rights Reserved.</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/city-finder.js?v=<?php echo time(); ?>"></script>
</body>
</html>