This commit is contained in:
Flatlogic Bot 2025-11-28 17:43:30 +00:00
parent b30baca81a
commit 2a74e9787f
25 changed files with 2247 additions and 144 deletions

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

@ -0,0 +1,122 @@
body {
background-color: #121212;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cg fill='%231a1a1a' fill-opacity='0.4'%3E%3Crect x='0' y='0' width='100' height='1'/%3E%3Crect x='0' y='0' width='1' height='100'/%3E%3C/g%3E%3C/svg%3E");
color: #FFFFFF;
font-family: 'Roboto', sans-serif;
}
.card-neon {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
transition: background 0.3s ease, box-shadow 0.3s ease;
}
.card-neon:hover {
background: rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
}
/* Typography */
h1, h2, h3, h4, h5 {
font-family: 'Poppins', sans-serif;
font-weight: 700;
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2.25rem;
}
/* Animations */
.card-neon {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.btn-primary:hover,
.btn-secondary:hover,
.list-group-item-action:hover {
transform: translateY(-3px);
transition: transform 0.3s ease;
}
.hero {
background: linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url('https://images.pexels.com/photos/159888/pexels-photo-159888.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1');
background-size: cover;
background-position: center;
color: white;
padding: 100px 0;
text-align: center;
}
.hero h1 {
font-family: 'Poppins', sans-serif;
font-weight: 700;
font-size: 3.5rem;
}
.hero p {
font-size: 1.25rem;
margin-bottom: 30px;
}
.btn-primary {
background: linear-gradient(45deg, #FF4B2B, #FF416C);
border: none;
padding: 15px 30px;
font-size: 1.2rem;
font-weight: 600;
transition: transform 0.3s ease;
}
.btn-primary:hover {
transform: translateY(-3px);
}
.btn-secondary {
background-color: transparent;
border: 2px solid white;
padding: 15px 30px;
font-size: 1.2rem;
font-weight: 600;
color: white;
transition: background-color 0.3s ease, color 0.3s ease;
}
.btn-secondary:hover {
background-color: white;
color: #121212;
}
.features {
padding: 80px 0;
}
.feature-icon {
font-size: 3rem;
color: #FF4B2B;
}
.footer {
background-color: #1E1E1E;
padding: 40px 0;
color: #A0A0A0;
}

77
communities.php Normal file
View File

@ -0,0 +1,77 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$pdo = db();
$stmt = $pdo->query('SELECT * FROM communities ORDER BY name');
$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>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="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 bg-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 active" aria-current="page" 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>
</ul>
</div>
</div>
</nav>
<main class="flex-grow-1">
<section class="container mt-5">
<h1 class="text-center mb-4">Welcome to the Communities Page</h1>
<div class="row">
<?php foreach ($communities as $community): ?>
<div class="col-md-4 mb-4">
<div class="card card-neon h-100">
<div class="card-body d-flex flex-column">
<h5 class="card-title"><?php echo htmlspecialchars($community['name']); ?></h5>
<p class="card-text">Explore and engage with your local community.</p>
<div class="mt-auto">
<a href="discussions.php?community_id=<?php echo $community['id']; ?>" class="btn btn-primary btn-sm">Discussions</a>
<a href="proposals.php?community_id=<?php echo $community['id']; ?>" class="btn btn-secondary btn-sm">Proposals</a>
<a href="events.php?community_id=<?php echo $community['id']; ?>" class="btn btn-info btn-sm">Events</a>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

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;

162
discussion.php Normal file
View File

@ -0,0 +1,162 @@
<?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 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">
<nav class="navbar navbar-expand-lg navbar-dark bg-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="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="card card-neon 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><?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>Replies</h2>
<div class="mb-4">
<?php if (empty($replies)): ?>
<p>No replies yet. Be the first to reply!</p>
<?php else: ?>
<?php foreach ($replies as $reply): ?>
<div class="card card-neon mb-3">
<div class="card-body">
<p class="mb-1"><?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 card-neon">
<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" id="content" name="content" rows="3" required><?php echo htmlspecialchars($content); ?></textarea>
</div>
<button type="submit" class="btn btn-primary btn-gradient">Post Reply</button>
</form>
</div>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

202
discussions.php Normal file
View File

@ -0,0 +1,202 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
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);
$params[] = $limit;
$params[] = $offset;
foreach ($params as $key => $value) {
$stmt->bindValue($key + 1, $value, is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR);
}
$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 bg-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="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">
<h1 class="text-center mb-4">Discussions in <?php echo htmlspecialchars($community['name']); ?></h1>
<div class="card card-neon mb-4">
<div class="card-body">
<h2 class="card-title">Start a New Discussion</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="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="3" required><?php echo htmlspecialchars($content); ?></textarea>
</div>
<button type="submit" class="btn btn-primary btn-gradient">Post Discussion</button>
</form>
</div>
</div>
<h2 class="mb-3">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); ?>">
<button class="btn btn-outline-secondary" type="submit">Search</button>
</div>
</form>
<div class="list-group">
<?php if (empty($discussions)): ?>
<p>No discussions found.</p>
<?php else: ?>
<?php foreach ($discussions as $discussion): ?>
<a href="discussion.php?id=<?php echo $discussion['id']; ?>" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1"><?php echo htmlspecialchars($discussion['title']); ?></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>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
<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>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

135
edit_discussion.php Normal file
View File

@ -0,0 +1,135 @@
<?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
$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="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 bg-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="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">
<h1 class="text-center mb-4">Edit Discussion</h1>
<div class="card card-neon">
<div class="card-body">
<?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">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="5" required><?php echo htmlspecialchars($content); ?></textarea>
</div>
<button type="submit" class="btn btn-primary btn-gradient">Save Changes</button>
<a href="discussion.php?id=<?php echo $discussion_id; ?>" class="btn btn-secondary">Cancel</a>
</form>
</div>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

126
edit_reply.php Normal file
View File

@ -0,0 +1,126 @@
<?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
$stmt = $pdo->prepare('SELECT * 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 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="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 bg-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="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">
<h1 class="text-center mb-4">Edit Reply</h1>
<div class="card card-neon">
<div class="card-body">
<?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">Content</label>
<textarea class="form-control" id="content" name="content" rows="5" required><?php echo htmlspecialchars($content); ?></textarea>
</div>
<button type="submit" class="btn btn-primary btn-gradient">Save Changes</button>
<a href="discussion.php?id=<?php echo $reply['discussion_id']; ?>" class="btn btn-secondary">Cancel</a>
</form>
</div>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

150
event.php Normal file
View File

@ -0,0 +1,150 @@
<?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;
}
$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="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 bg-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="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="card card-neon mb-4">
<div class="card-header">
<h1 class="mb-0"><?php echo htmlspecialchars($event['title']); ?></h1>
<small>in <a href="discussions.php?community_id=<?php echo $event['community_id']; ?>"><?php echo htmlspecialchars($event['community_name']); ?></a> by <?php echo htmlspecialchars($event['user_name']); ?> on <?php echo date('M j, Y, g:i a', strtotime($event['created_at'])); ?></small>
</div>
<div class="card-body">
<p><?php echo nl2br(htmlspecialchars($event['description'])); ?></p>
<p><strong>Starts:</strong> <?php echo date('M j, Y, g:i a', strtotime($event['start_time'])); ?></p>
<p><strong>Ends:</strong> <?php echo date('M j, Y, g:i a', strtotime($event['end_time'])); ?></p>
<p><strong>Location:</strong> <?php echo htmlspecialchars($event['location']); ?></p>
</div>
</div>
<h2>RSVPs</h2>
<div class="d-flex justify-content-around mb-4">
<div class="text-center">
<h3>Attending</h3>
<p class="display-4"><?php echo $attending; ?></p>
</div>
<div class="text-center">
<h3>Not Attending</h3>
<p class="display-4"><?php echo $not_attending; ?></p>
</div>
</div>
<div class="card card-neon">
<div class="card-body text-center">
<h2 class="card-title">RSVP</h2>
<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' : ''; ?>">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' : ''; ?>">Not Attending</button>
</form>
</div>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

173
events.php Normal file
View File

@ -0,0 +1,173 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
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 event form submission
$title = $description = $start_time = $end_time = $location = '';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = trim($_POST['title'] ?? '');
$description = trim($_POST['description'] ?? '');
$start_time = trim($_POST['start_time'] ?? '');
$end_time = trim($_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 (empty($errors)) {
try {
$stmt = $pdo->prepare('INSERT INTO events (community_id, user_id, title, description, start_time, end_time, location) VALUES (?, ?, ?, ?, ?, ?, ?)');
$stmt->execute([$community_id, $user_id, $title, $description, $start_time, $end_time, $location]);
header('Location: events.php?community_id=' . $community_id);
exit;
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
// Fetch events
$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="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 bg-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="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">
<h1 class="text-center mb-4">Events in <?php echo htmlspecialchars($community['name']); ?></h1>
<div class="card card-neon mb-4">
<div class="card-body">
<h2 class="card-title">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">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">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">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">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">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 btn-gradient">Create Event</button>
</form>
</div>
</div>
<h2>Upcoming Events</h2>
<div class="list-group">
<?php if (empty($events)): ?>
<p>No events yet. Be the first to create one!</p>
<?php else: ?>
<?php foreach ($events as $event): ?>
<a href="event.php?id=<?php echo $event['id']; ?>" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1"><?php echo htmlspecialchars($event['title']); ?></h5>
<small><?php echo date('M j, Y, g:i a', strtotime($event['start_time'])); ?></small>
</div>
<p class="mb-1">Location: <?php echo htmlspecialchars($event['location']); ?></p>
<p class="mb-1">Created by: <?php echo htmlspecialchars($event['user_name']); ?></p>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

221
index.php
View File

@ -1,150 +1,83 @@
<?php
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION; <?php session_start(); ?>
$now = date('Y-m-d H:i:s'); <!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 bg-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>
<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 btn-gradient 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 class="text-muted">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-square"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
</div>
<h3>Discuss</h3>
<p class="text-muted">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-trending-up"><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline><polyline points="17 6 23 6 23 12"></polyline></svg>
</div>
<h3>Organize</h3>
<p class="text-muted">Create events and proposals to drive real change in your community.</p>
</div>
</div>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

117
login.php Normal file
View File

@ -0,0 +1,117 @@
<?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 bg-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">
<section class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card card-neon">
<div class="card-body">
<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><?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-3">
<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 btn-gradient">Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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;

170
profile.php Normal file
View File

@ -0,0 +1,170 @@
<?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 details
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user = $stmt->fetch();
// Fetch user's communities
$stmt = $pdo->prepare('SELECT c.* FROM communities c JOIN community_members cm ON c.id = cm.community_id WHERE cm.user_id = ?');
$stmt->execute([$user_id]);
$communities = $stmt->fetchAll();
// Fetch user's discussions
$stmt = $pdo->prepare('SELECT * FROM discussions WHERE user_id = ? ORDER BY created_at DESC');
$stmt->execute([$user_id]);
$discussions = $stmt->fetchAll();
$name = $user['name'];
$city = $user['city'];
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$city = trim($_POST['city'] ?? '');
if (empty($name)) {
$errors[] = 'Name is required';
}
if (empty($city)) {
$errors[] = 'City is required';
}
if (empty($errors)) {
try {
$stmt = $pdo->prepare('UPDATE users SET name = ?, city = ? WHERE id = ?');
$stmt->execute([$name, $city, $user_id]);
header('Location: profile.php');
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>Your Profile - 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 bg-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 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">
<section class="container mt-5">
<h1 class="text-center mb-4">Your Profile</h1>
<div class="row">
<div class="col-md-4">
<div class="card card-neon">
<div class="card-body">
<h2 class="card-title">Your Information</h2>
<p><strong>Name:</strong> <?php echo htmlspecialchars($user['name']); ?></p>
<p><strong>Email:</strong> <?php echo htmlspecialchars($user['email']); ?></p>
<p><strong>City:</strong> <?php echo htmlspecialchars($user['city']); ?></p>
<p><strong>Role:</strong> <?php echo htmlspecialchars($user['role']); ?></p>
</div>
</div>
<div class="card card-neon mt-4">
<div class="card-body">
<h2 class="card-title">Edit Profile</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="profile.php" method="POST">
<div class="mb-3">
<label for="name" class="form-label">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="city" class="form-label">City</label>
<input type="text" class="form-control" id="city" name="city" value="<?php echo htmlspecialchars($city); ?>" required>
</div>
<button type="submit" class="btn btn-primary btn-gradient">Save Changes</button>
</form>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card card-neon">
<div class="card-body">
<h2 class="card-title">Your Communities</h2>
<div class="list-group">
<?php if (empty($communities)): ?>
<p>You are not a member of any communities yet.</p>
<?php else: ?>
<?php foreach ($communities as $community): ?>
<a href="discussions.php?community_id=<?php echo $community['id']; ?>" class="list-group-item list-group-item-action">
<?php echo htmlspecialchars($community['name']); ?>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
<div class="card card-neon mt-4">
<div class="card-body">
<h2 class="card-title">Your Discussions</h2>
<div class="list-group">
<?php if (empty($discussions)): ?>
<p>You have not started any discussions yet.</p>
<?php else: ?>
<?php foreach ($discussions as $discussion): ?>
<a href="discussion.php?id=<?php echo $discussion['id']; ?>" class="list-group-item list-group-item-action">
<?php echo htmlspecialchars($discussion['title']); ?>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

152
proposal.php Normal file
View File

@ -0,0 +1,152 @@
<?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;
}
$proposal_id = $_GET['id'];
$user_id = $_SESSION['user_id'];
$pdo = db();
// Fetch proposal details
$stmt = $pdo->prepare('SELECT p.*, u.name as user_name, c.name as community_name 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) {
header('Location: communities.php');
exit;
}
// Handle voting
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['vote'])) {
$vote = $_POST['vote'];
if (in_array($vote, ['up', 'down'])) {
try {
// Check if user has already voted
$stmt = $pdo->prepare('SELECT id FROM proposal_votes WHERE user_id = ? AND proposal_id = ?');
$stmt->execute([$user_id, $proposal_id]);
if ($stmt->fetch()) {
// Update existing vote
$stmt = $pdo->prepare('UPDATE proposal_votes SET vote = ? WHERE user_id = ? AND proposal_id = ?');
$stmt->execute([$vote, $user_id, $proposal_id]);
} else {
// Insert new vote
$stmt = $pdo->prepare('INSERT INTO proposal_votes (proposal_id, user_id, vote) VALUES (?, ?, ?)');
$stmt->execute([$proposal_id, $user_id, $vote]);
}
header('Location: proposal.php?id=' . $proposal_id);
exit;
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
// Fetch votes
$stmt = $pdo->prepare('SELECT vote, COUNT(*) as count FROM proposal_votes WHERE proposal_id = ? GROUP BY vote');
$stmt->execute([$proposal_id]);
$votes = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$up_votes = $votes['up'] ?? 0;
$down_votes = $votes['down'] ?? 0;
// Check if the current user has voted
$stmt = $pdo->prepare('SELECT vote FROM proposal_votes WHERE user_id = ? AND proposal_id = ?');
$stmt->execute([$user_id, $proposal_id]);
$user_vote = $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($proposal['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">
<nav class="navbar navbar-expand-lg navbar-dark bg-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="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="card card-neon mb-4">
<div class="card-header">
<h1 class="mb-0"><?php echo htmlspecialchars($proposal['title']); ?></h1>
<small>in <a href="discussions.php?community_id=<?php echo $proposal['community_id']; ?>"><?php echo htmlspecialchars($proposal['community_name']); ?></a> by <?php echo htmlspecialchars($proposal['user_name']); ?> on <?php echo date('M j, Y, g:i a', strtotime($proposal['created_at'])); ?></small>
</div>
<div class="card-body">
<p><?php echo nl2br(htmlspecialchars($proposal['description'])); ?></p>
<p><strong>Voting ends:</strong> <?php echo date('M j, Y, g:i a', strtotime($proposal['end_time'])); ?></p>
</div>
</div>
<h2>Voting</h2>
<div class="d-flex justify-content-around mb-4">
<div class="text-center">
<h3>Upvotes</h3>
<p class="display-4"><?php echo $up_votes; ?></p>
</div>
<div class="text-center">
<h3>Downvotes</h3>
<p class="display-4"><?php echo $down_votes; ?></p>
</div>
</div>
<?php if (strtotime($proposal['end_time']) > time()): ?>
<div class="card card-neon">
<div class="card-body text-center">
<h2 class="card-title">Cast Your Vote</h2>
<form action="proposal.php?id=<?php echo $proposal_id; ?>" method="POST" class="d-inline">
<input type="hidden" name="vote" value="up">
<button type="submit" class="btn btn-success btn-lg me-2 <?php echo ($user_vote === 'up') ? 'active' : ''; ?>">Vote Up</button>
</form>
<form action="proposal.php?id=<?php echo $proposal_id; ?>" method="POST" class="d-inline">
<input type="hidden" name="vote" value="down">
<button type="submit" class="btn btn-danger btn-lg <?php echo ($user_vote === 'down') ? 'active' : ''; ?>">Vote Down</button>
</form>
</div>
</div>
<?php else: ?>
<div class="alert alert-info text-center">Voting on this proposal has ended.</div>
<?php endif; ?>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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
proposals.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;
}
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;
}
// Fetch user role
$stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user_role = $stmt->fetchColumn();
// Handle new proposal form submission
$title = $description = $end_time = '';
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $user_role === 'leader') {
$title = trim($_POST['title'] ?? '');
$description = trim($_POST['description'] ?? '');
$end_time = trim($_POST['end_time'] ?? '');
if (empty($title)) {
$errors[] = 'Title is required';
}
if (empty($description)) {
$errors[] = 'Description is required');
}
if (empty($end_time)) {
$errors[] = 'End time is required';
}
if (empty($errors)) {
try {
$stmt = $pdo->prepare('INSERT INTO proposals (community_id, user_id, title, description, end_time) VALUES (?, ?, ?, ?, ?)');
$stmt->execute([$community_id, $user_id, $title, $description, $end_time]);
header('Location: proposals.php?community_id=' . $community_id);
exit;
} catch (PDOException $e) {
$errors[] = 'Database error: ' . $e->getMessage();
}
}
}
// Fetch proposals
$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="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 bg-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="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">
<h1 class="text-center mb-4">Proposals in <?php echo htmlspecialchars($community['name']); ?></h1>
<?php if ($user_role === 'leader'): ?>
<div class="card card-neon mb-4">
<div class="card-body">
<h2 class="card-title">Create a New Proposal</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="proposals.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="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="3" required><?php echo htmlspecialchars($description); ?></textarea>
</div>
<div class="mb-3">
<label for="end_time" class="form-label">End Time</label>
<input type="datetime-local" class="form-control" id="end_time" name="end_time" value="<?php echo htmlspecialchars($end_time); ?>" required>
</div>
<button type="submit" class="btn btn-primary btn-gradient">Create Proposal</button>
</form>
</div>
</div>
<?php endif; ?>
<h2>Active Proposals</h2>
<div class="list-group">
<?php if (empty($proposals)): ?>
<p>No proposals yet. <?php if ($user_role === 'leader'): ?>Be the first to create one!<?php endif; ?></p>
<?php else: ?>
<?php foreach ($proposals as $proposal): ?>
<a href="proposal.php?id=<?php echo $proposal['id']; ?>" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1"><?php echo htmlspecialchars($proposal['title']); ?></h5>
<small>Ends <?php echo date('M j, Y, g:i a', strtotime($proposal['end_time'])); ?></small>
</div>
<p class="mb-1">Created by: <?php echo htmlspecialchars($proposal['user_name']); ?></p>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>

188
signup.php Normal file
View File

@ -0,0 +1,188 @@
<?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 bg-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">
<section class="container mt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card card-neon">
<div class="card-body">
<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><?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 btn-gradient">Sign Up</button>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</main>
<footer class="bg-dark text-white text-center p-3 mt-auto">
<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>
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;
</script>
</body>
</html>