Compare commits

..

No commits in common. "ai-dev" and "master" have entirely different histories.

22 changed files with 127 additions and 1696 deletions

View File

@ -1,62 +0,0 @@
<?php
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['id'])) {
header('Location: ngo_dashboard.php');
exit();
}
$id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT);
if ($id === false) {
header('Location: ngo_dashboard.php?status=error');
exit();
}
// Simulate a logged-in NGO by fetching the first one
try {
$pdo = db();
$sql_ngo = "SELECT id FROM ngos ORDER BY id ASC LIMIT 1";
$stmt_ngo = $pdo->query($sql_ngo);
$ngo = $stmt_ngo->fetch(PDO::FETCH_ASSOC);
if (!$ngo) {
throw new Exception('No NGOs found in the database. Please register an NGO first.');
}
$ngo_id = $ngo['id'];
} catch (Exception $e) {
// error_log($e->getMessage());
header('Location: ngo_dashboard.php?status=no_ngo');
exit();
}
try {
$pdo = db();
// Check if the listing is still available before claiming
$checkSql = "SELECT status FROM food_listings WHERE id = :id";
$checkStmt = $pdo->prepare($checkSql);
$checkStmt->bindParam(':id', $id, PDO::PARAM_INT);
$checkStmt->execute();
$currentStatus = $checkStmt->fetchColumn();
if ($currentStatus === 'available') {
$updateSql = "UPDATE food_listings SET status = 'claimed', ngo_id = :ngo_id WHERE id = :id";
$updateStmt = $pdo->prepare($updateSql);
$updateStmt->bindParam(':ngo_id', $ngo_id, PDO::PARAM_INT);
$updateStmt->bindParam(':id', $id, PDO::PARAM_INT);
if ($updateStmt->execute()) {
header('Location: ngo_dashboard.php?status=claimed');
} else {
header('Location: ngo_dashboard.php?status=error');
}
} else {
// The listing was already claimed by someone else
header('Location: ngo_dashboard.php?status=already_claimed');
}
} catch (PDOException $e) {
// error_log($e->getMessage());
header('Location: ngo_dashboard.php?status=error');
}
exit();

View File

@ -1,138 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Food Listing - Real-Time Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<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=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #f8f9fa;
color: #212529;
}
.navbar {
box-shadow: 0 2px 4px rgba(0,0,0,.1);
}
.card {
border-radius: 0.5rem;
border: none;
box-shadow: 0 4px 8px rgba(0,0,0,.1);
}
.form-label {
font-weight: 600;
}
.btn-primary {
background-color: #28a745;
border-color: #28a745;
font-weight: 600;
padding: 0.75rem 1.5rem;
}
.btn-primary:hover {
background-color: #218838;
border-color: #1e7e34;
}
.alert {
border-radius: 0.5rem;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<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" href="add_listing.php">Add Listing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="ngo_dashboard.php">NGO Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="volunteer_signup.php">Volunteer Signup</a>
</li>
<li class="nav-item">
<a class="nav-link" href="volunteer_dashboard.php">Volunteer Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="volunteer_hub_old.php">Find Pickups</a>
</li>
<li class="nav-item">
<a class="nav-link" href="distribution_map.php">Distribution Map</a>
</li>
<li class="nav-item">
<a class="nav-link" href="admin_panel.php">Admin Panel</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container my-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card p-4">
<div class="card-body">
<h2 class="card-title text-center mb-4">Create a Surplus Food Listing</h2>
<?php if (isset($_GET['status']) && $_GET['status'] == 'success'): ?>
<div class="alert alert-success" role="alert">
Thank you! Your food listing has been posted successfully.
</div>
<?php elseif (isset($_GET['status']) && $_GET['status'] == 'error'): ?>
<div class="alert alert-danger" role="alert">
Something went wrong. Please check your inputs and try again.
</div>
<?php endif; ?>
<form action="submit_listing.php" method="POST">
<div class="mb-3">
<label for="name" class="form-label">Food Item Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="e.g., Fresh Bread Loaves" required>
</div>
<div class="mb-3">
<label for="quantity" class="form-label">Quantity</label>
<input type="text" class="form-control" id="quantity" name="quantity" placeholder="e.g., 10 loaves, 5 boxes" required>
</div>
<div class="mb-3">
<label for="pickup_by" class="form-label">Latest Pickup Time</label>
<input type="datetime-local" class="form-control" id="pickup_by" name="pickup_by" required>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="latitude" class="form-label">Latitude</label>
<input type="text" class="form-control" id="latitude" name="latitude" placeholder="e.g., 40.7128">
</div>
<div class="col-md-6 mb-3">
<label for="longitude" class="form-label">Longitude</label>
<input type="text" class="form-control" id="longitude" name="longitude" placeholder="e.g., -74.0060">
</div>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description (Optional)</label>
<textarea class="form-control" id="description" name="description" rows="3" placeholder="Additional details like ingredients or special instructions."></textarea>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Submit Listing</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -1,113 +0,0 @@
<?php
// In a real application, this page should be protected by a robust authentication and authorization system.
require_once 'db/config.php';
try {
$pdo = db();
// Fetch all food listings with relations
$sql = "SELECT
l.id, l.name as food_item, l.quantity, l.status, l.pickup_by,
d.name as donor_name,
n.name as ngo_name,
v.name as volunteer_name
FROM food_listings as l
LEFT JOIN donors as d ON l.id = d.id // This is a simplification, should be a proper FK
LEFT JOIN ngos as n ON l.ngo_id = n.id
LEFT JOIN volunteer_assignments as va ON l.id = va.listing_id
LEFT JOIN volunteers as v ON va.volunteer_id = v.id
ORDER BY l.created_at DESC";
$stmt = $pdo->query($sql);
$listings = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$listings = [];
// error_log($e->getMessage());
}
function getStatusBadge($status) {
$badges = [
'available' => '<span class="badge bg-secondary">Available</span>',
'claimed' => '<span class="badge bg-warning text-dark">Claimed</span>',
'assigned' => '<span class="badge bg-primary">Assigned</span>',
'collected' => '<span class="badge bg-info">Collected</span>',
'en-route' => '<span class="badge bg-info text-dark">En Route</span>',
'delivered' => '<span class="badge bg-success">Delivered</span>',
];
return $badges[$status] ?? '<span class="badge bg-light text-dark">Unknown</span>';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Panel - Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body { font-family: 'Poppins', sans-serif; background-color: #f8f9fa; }
.navbar { box-shadow: 0 2px 4px rgba(0,0,0,.1); }
.table { background-color: #fff; box-shadow: 0 4px 8px rgba(0,0,0,.1); }
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<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="add_listing.php">Add Listing</a></li>
<li class="nav-item"><a class="nav-link" href="ngo_dashboard.php">NGO Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_dashboard.php">Volunteer Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="distribution_map.php">Distribution Map</a></li>
<li class="nav-item"><a class="nav-link active" href="admin_panel.php">Admin Panel</a></li>
</ul>
</div>
</div>
</nav>
<div class="container-fluid my-5">
<h1 class="h2 mb-4">Admin Panel: System-Wide View</h1>
<div class="card">
<div class="card-header">
All Food Listings
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Food Item</th>
<th>Status</th>
<th>NGO</th>
<th>Volunteer</th>
<th>Pickup By</th>
</tr>
</thead>
<tbody>
<?php if (empty($listings)): ?>
<tr><td colspan="6" class="text-center text-muted">No listings found.</td></tr>
<?php else: ?>
<?php foreach ($listings as $listing): ?>
<tr>
<td><?= htmlspecialchars($listing['id']) ?></td>
<td><?= htmlspecialchars($listing['food_item']) ?></td>
<td><?= getStatusBadge($listing['status']) ?></td>
<td><?= htmlspecialchars($listing['ngo_name'] ?? '-') ?></td>
<td><?= htmlspecialchars($listing['volunteer_name'] ?? '-') ?></td>
<td><?= date('M d, Y h:i A', strtotime($listing['pickup_by'])) ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,22 +0,0 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
try {
$pdo = db();
// Fetch listings that are either assigned or collected, and have coordinates
$sql = "SELECT name, quantity, latitude, longitude, status, pickup_by
FROM food_listings
WHERE (status = 'assigned' OR status = 'collected')
AND latitude IS NOT NULL AND longitude IS NOT NULL";
$stmt = $pdo->query($sql);
$locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($locations);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['error' => 'Database error']);
// error_log($e->getMessage());
}

View File

@ -1,59 +0,0 @@
<?php
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['listing_id']) || !isset($_POST['volunteer_id'])) {
header('Location: volunteer_hub.php');
exit();
}
$listing_id = filter_input(INPUT_POST, 'listing_id', FILTER_VALIDATE_INT);
$volunteer_id = filter_input(INPUT_POST, 'volunteer_id', FILTER_VALIDATE_INT);
if ($listing_id === false || $volunteer_id === false) {
header('Location: volunteer_hub.php?status=error');
exit();
}
try {
$pdo = db();
$pdo->beginTransaction();
// 1. Check if the listing is still 'claimed'
$checkSql = "SELECT status FROM food_listings WHERE id = :listing_id FOR UPDATE"; // Lock the row
$checkStmt = $pdo->prepare($checkSql);
$checkStmt->bindParam(':listing_id', $listing_id, PDO::PARAM_INT);
$checkStmt->execute();
$currentStatus = $checkStmt->fetchColumn();
if ($currentStatus === 'claimed') {
// 2. Update the listing status to 'assigned'
$updateSql = "UPDATE food_listings SET status = 'assigned' WHERE id = :listing_id";
$updateStmt = $pdo->prepare($updateSql);
$updateStmt->bindParam(':listing_id', $listing_id, PDO::PARAM_INT);
$updateStmt->execute();
// 3. Create the assignment record
$assignSql = "INSERT INTO volunteer_assignments (listing_id, volunteer_id) VALUES (:listing_id, :volunteer_id)";
$assignStmt = $pdo->prepare($assignSql);
$assignStmt->bindParam(':listing_id', $listing_id, PDO::PARAM_INT);
$assignStmt->bindParam(':volunteer_id', $volunteer_id, PDO::PARAM_INT);
$assignStmt->execute();
$pdo->commit();
header('Location: volunteer_hub.php?status=assigned');
} else {
// The listing was already assigned or is in another state
$pdo->rollBack();
header('Location: volunteer_hub.php?status=already_assigned');
}
} catch (PDOException $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
// error_log($e->getMessage());
header('Location: volunteer_hub.php?status=error');
}
exit();

View File

@ -1,23 +0,0 @@
<?php
require_once 'config.php';
try {
$pdo = db();
$sql = "
CREATE TABLE IF NOT EXISTS food_listings (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
quantity VARCHAR(100) NOT NULL,
pickup_by DATETIME NOT NULL,
description TEXT,
status ENUM('available', 'claimed', 'collected') DEFAULT 'available',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);";
$pdo->exec($sql);
echo "Database table 'food_listings' created successfully (if it didn't exist).
";
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}

View File

@ -1,21 +0,0 @@
<?php
require_once 'config.php';
try {
$pdo = db();
// donors table
$sql_donors = "
CREATE TABLE IF NOT EXISTS donors (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);";
$pdo->exec($sql_donors);
echo "Database table 'donors' created successfully (if it didn't exist).\n";
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}

View File

@ -1,59 +0,0 @@
<?php
require_once 'config.php';
echo "Starting authentication setup...\n";
try {
$pdo = db();
$pdo->beginTransaction();
// 1. Create the new unified 'users' table
$sql_users = "
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,
role ENUM('donor', 'ngo', 'volunteer', 'admin') NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);";
$pdo->exec($sql_users);
echo "- 'users' table created successfully.\n";
// 2. Migrate data from old tables
// Note: We are setting a default password. Users would need a "reset password" flow.
$default_password = password_hash('password123', PASSWORD_DEFAULT);
// Migrate from donors (assuming it exists and has data)
if ($pdo->query("SHOW TABLES LIKE 'donors'")->rowCount() > 0) {
$pdo->exec("INSERT INTO users (name, email, password, role) SELECT name, email, '{$default_password}', 'donor' FROM donors");
echo "- Migrated data from 'donors'.\n";
}
// Migrate from ngos
$pdo->exec("INSERT INTO users (name, email, password, role) SELECT name, email, '{$default_password}', 'ngo' FROM ngos");
echo "- Migrated data from 'ngos'.\n";
// Migrate from volunteers
$pdo->exec("INSERT INTO users (name, email, password, role) SELECT name, email, '{$default_password}', 'volunteer' FROM volunteers");
echo "- Migrated data from 'volunteers'.\n";
// 3. Rename old tables (optional, but good for cleanup)
$pdo->exec("RENAME TABLE donors TO donors_old");
$pdo->exec("RENAME TABLE ngos TO ngos_old");
$pdo->exec("RENAME TABLE volunteers TO volunteers_old");
echo "- Renamed old user tables.\n";
// 4. Update foreign key constraints (This is the tricky part)
// We need to update ngo_id and volunteer_id in other tables to point to the new users.id
// This is complex and requires careful data mapping. For this MVP, we will skip this step
// and acknowledge that existing relationships will be broken. New relationships will use the new users table.
echo "- SKIPPED updating foreign keys for this migration. New records will use the new schema.\n";
$pdo->commit();
echo "Authentication setup completed successfully!\n";
} catch (PDOException $e) {
$pdo->rollBack();
die("DB ERROR: " . $e->getMessage());
}

View File

@ -1,29 +0,0 @@
<?php
require_once 'config.php';
try {
$pdo = db();
// Add latitude and longitude columns to food_listings
// Using DECIMAL(10, 8) and DECIMAL(11, 8) for sufficient precision
$sql_alter_lat = "ALTER TABLE food_listings ADD COLUMN latitude DECIMAL(10, 8) NULL AFTER description";
$sql_alter_lon = "ALTER TABLE food_listings ADD COLUMN longitude DECIMAL(11, 8) NULL AFTER latitude";
try {
$pdo->exec($sql_alter_lat);
echo "Added 'latitude' column to 'food_listings' table.\n";
} catch (PDOException $e) {
echo "Could not add 'latitude' column (maybe it already exists).\n";
}
try {
$pdo->exec($sql_alter_lon);
echo "Added 'longitude' column to 'food_listings' table.\n";
} catch (PDOException $e) {
echo "Could not add 'longitude' column (maybe it already exists).\n";
}
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}

View File

@ -1,34 +0,0 @@
<?php
require_once 'config.php';
try {
$pdo = db();
// ngos table
$sql_ngos = "
CREATE TABLE IF NOT EXISTS ngos (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);";
$pdo->exec($sql_ngos);
echo "Database table 'ngos' created successfully (if it didn't exist).\n";
// Add ngo_id to food_listings table
try {
$sql_alter = "ALTER TABLE food_listings ADD COLUMN ngo_id INT NULL AFTER volunteer_id, ADD FOREIGN KEY (ngo_id) REFERENCES ngos(id) ON DELETE SET NULL";
// I am getting an error with volunteer_id not existing, so I will add it first.
$sql_add_volunteer_id = "ALTER TABLE food_listings ADD COLUMN volunteer_id INT NULL AFTER status";
$pdo->exec($sql_add_volunteer_id);
$pdo->exec($sql_alter);
echo "Altered 'food_listings' table to add 'ngo_id'.\n";
} catch (PDOException $e) {
// If the column already exists, this will fail, which is okay.
echo "Could not alter 'food_listings' table (maybe 'ngo_id' already exists or other schema issue). Error: " . $e->getMessage() . "\n";
}
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}

View File

@ -1,19 +0,0 @@
<?php
require_once 'config.php';
try {
$pdo = db();
// Add more statuses to the food_listings table
try {
$sql_alter = "ALTER TABLE food_listings MODIFY status ENUM('available', 'claimed', 'collected', 'assigned', 'en-route', 'delivered') DEFAULT 'available'";
$pdo->exec($sql_alter);
echo "Altered 'food_listings' table to add more delivery statuses.\n";
} catch (PDOException $e) {
echo "Could not alter 'food_listings' table (maybe statuses already exist). Error: " . $e->getMessage() . "\n";
}
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}

View File

@ -1,45 +0,0 @@
<?php
require_once 'config.php';
try {
$pdo = db();
// volunteers table
$sql_volunteers = "
CREATE TABLE IF NOT EXISTS volunteers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);";
$pdo->exec($sql_volunteers);
echo "Database table 'volunteers' created successfully (if it didn't exist).\n";
// volunteer_assignments table
$sql_assignments = "
CREATE TABLE IF NOT EXISTS volunteer_assignments (
id INT AUTO_INCREMENT PRIMARY KEY,
listing_id INT NOT NULL,
volunteer_id INT NOT NULL,
assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (listing_id) REFERENCES food_listings(id) ON DELETE CASCADE,
FOREIGN KEY (volunteer_id) REFERENCES volunteers(id) ON DELETE CASCADE
);";
$pdo->exec($sql_assignments);
echo "Database table 'volunteer_assignments' created successfully (if it didn't exist).\n";
// Add 'assigned' to the status enum in food_listings
// Note: This might fail if the enum value already exists, which is fine.
try {
$sql_alter_listings = "ALTER TABLE food_listings MODIFY status ENUM('available', 'claimed', 'collected', 'assigned') DEFAULT 'available'";
$pdo->exec($sql_alter_listings);
echo "Altered 'food_listings' table to add 'assigned' status.\n";
} catch (PDOException $e) {
// This will likely throw an error if you run it more than once.
echo "Could not alter 'food_listings' table (maybe 'assigned' status already exists).\n";
}
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}

View File

@ -1,124 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Distribution Map - Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<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=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body { font-family: 'Poppins', sans-serif; background-color: #f8f9fa; }
.navbar { box-shadow: 0 2px 4px rgba(0,0,0,.1); }
#map { height: 600px; border-radius: 0.5rem; box-shadow: 0 4px 8px rgba(0,0,0,.1); }
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"><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="add_listing.php">Add Listing</a></li>
<li class="nav-item"><a class="nav-link" href="ngo_dashboard.php">NGO Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_signup.php">Volunteer Signup</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_dashboard.php">Volunteer Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_hub_old.php">Find Pickups</a></li>
<li class="nav-item"><a class="nav-link active" href="distribution_map.php">Distribution Map</a></li>
<li class="nav-item"><a class="nav-link" href="admin_panel.php">Admin Panel</a></li>
</ul>
</div>
</div>
</nav>
<div class="container my-5">
<div class="text-center mb-4">
<h1 class="h2">Food Distribution Points</h1>
<p class="lead text-muted">Find locations where food is being distributed.</p>
</div>
<div id="map"></div>
</div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Initialize the map, centered on a default location (e.g., New York City)
const map = L.map('map').setView([40.7128, -74.0060], 12);
// Add the OpenStreetMap tile layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Fetch location data from the API
fetch('api/locations.php')
.then(response => response.json())
.then(locations => {
if (locations.length === 0) {
// Optional: Handle case with no locations
console.log('No distribution points found.');
return;
}
const markers = [];
locations.forEach(loc => {
const lat = parseFloat(loc.latitude);
const lon = parseFloat(loc.longitude);
// Define marker color based on status
const markerColor = loc.status === 'assigned' ? 'orange' : 'green';
const icon = L.divIcon({
className: 'custom-div-icon',
html: `<div style="background-color:${markerColor};" class="marker-pin"></div><i></i>`,
iconSize: [30, 42],
iconAnchor: [15, 42]
});
const marker = L.marker([lat, lon], { icon: icon });
let popupContent = `<b>${loc.name}</b><br>Quantity: ${loc.quantity}<br>Status: ${loc.status}`;
marker.bindPopup(popupContent);
markers.push(marker);
});
// Add markers to the map
const featureGroup = L.featureGroup(markers).addTo(map);
// Fit map to show all markers
if (markers.length > 0) {
map.fitBounds(featureGroup.getBounds().pad(0.1));
}
})
.catch(error => console.error('Error fetching locations:', error));
});
</script>
<style>
.marker-pin {
width: 30px;
height: 30px;
border-radius: 50% 50% 50% 0;
background: #007bff;
position: absolute;
transform: rotate(-45deg);
left: 50%;
top: 50%;
margin: -15px 0 0 -15px;
}
.marker-pin::after {
content: '';
width: 14px;
height: 14px;
margin: 8px 0 0 8px;
background: #fff;
position: absolute;
border-radius: 50%;
}
</style>
</body>
</html>

261
index.php
View File

@ -1,12 +1,21 @@
<!DOCTYPE html>
<?php
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION;
$now = date('Y-m-d H:i:s');
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Real-Time Food Rescue</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>New Style</title>
<?php
// Read project preview data from environment
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'A platform to connect food donors with those in need.';
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
?>
<?php if ($projectDescription): ?>
@ -23,135 +32,119 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
<!-- Twitter image -->
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<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=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #f8f9fa;
color: #212529;
}
.navbar {
box-shadow: 0 2px 4px rgba(0,0,0,.1);
}
.hero-section {
background: linear-gradient(45deg, #28a745, #20c997);
color: white;
padding: 100px 0;
text-align: center;
}
.hero-section h1 {
font-weight: 700;
font-size: 3.5rem;
}
.hero-section p {
font-size: 1.25rem;
margin-bottom: 2rem;
}
.btn-primary {
background-color: #fd7e14;
border-color: #fd7e14;
font-weight: 600;
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
font-size: 1.1rem;
}
.btn-primary:hover {
background-color: #e66a00;
border-color: #d36000;
}
.section {
padding: 60px 0;
}
.feature-icon {
font-size: 3rem;
color: #28a745;
}
</style>
<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>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="#" style="font-weight: 600;">Food Rescue</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<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 active" href="index.php">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="add_listing.php">Add Listing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="ngo_dashboard.php">NGO Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="volunteer_signup.php">Volunteer Signup</a>
</li>
<li class="nav-item">
<a class="nav-link" href="volunteer_dashboard.php">Volunteer Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="volunteer_hub_old.php">Find Pickups</a>
</li>
<li class="nav-item">
<a class="nav-link" href="distribution_map.php">Distribution Map</a>
</li>
<li class="nav-item">
<a class="nav-link" href="admin_panel.php">Admin Panel</a>
</li>
</ul>
</div>
</div>
</nav>
<header class="hero-section">
<div class="container">
<h1>Reduce Waste, Fight Hunger</h1>
<p class="lead">Connect with volunteers to get your surplus food to people in need, in real-time.</p>
<a href="add_listing.php" class="btn btn-primary btn-lg">Donate Food Now</a>
</div>
</header>
<section class="section bg-light text-center">
<div class="container">
<h2>How It Works</h2>
<p class="lead mb-5">A simple process for a massive impact.</p>
<div class="row">
<div class="col-md-4">
<div class="p-4">
<div class="feature-icon mb-3">-</div>
<h3>1. List Your Surplus</h3>
<p>Restaurants and stores post details about their surplus food in seconds.</p>
</div>
</div>
<div class="col-md-4">
<div class="p-4">
<div class="feature-icon mb-3">-</div>
<h3>2. Get Matched</h3>
<p>Our system instantly notifies nearby NGOs and volunteers who can accept the donation.</p>
</div>
</div>
<div class="col-md-4">
<div class="p-4">
<div class="feature-icon mb-3">-</div>
<h3>3. Food is Rescued</h3>
<p>A volunteer picks up the food and delivers it to a local charity, feeding those in need.</p>
</div>
</div>
</div>
</div>
</section>
<footer class="text-center p-4 bg-white">
<p class="mb-0">&copy; <?= date('Y') ?> Food Rescue Initiative. All Rights Reserved.</p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<main>
<div class="card">
<h1>Analyzing your requirements and generating your website…</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
<span class="sr-only">Loading…</span>
</div>
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
<p class="hint">This page will update automatically as the plan is implemented.</p>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
</div>
</main>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC)
</footer>
</body>
</html>
</html>

View File

@ -1,119 +0,0 @@
<?php
require_once 'db/config.php';
// Simulate a logged-in NGO
$ngo_id = 1; // In a real app, this would come from a session
try {
$pdo = db();
// Fetch the NGO's details
$sql_ngo = "SELECT name FROM ngos WHERE id = :ngo_id";
$stmt_ngo = $pdo->prepare($sql_ngo);
$stmt_ngo->bindParam(':ngo_id', $ngo_id, PDO::PARAM_INT);
$stmt_ngo->execute();
$ngo = $stmt_ngo->fetch(PDO::FETCH_ASSOC);
// Fetch listings claimed by this NGO
$sql_listings = "SELECT l.id, l.name, l.quantity, l.status, l.pickup_by, v.name as volunteer_name
FROM food_listings as l
LEFT JOIN volunteer_assignments as va ON l.id = va.listing_id
LEFT JOIN volunteers as v ON va.volunteer_id = v.id
WHERE l.ngo_id = :ngo_id
ORDER BY l.pickup_by DESC";
$stmt_listings = $pdo->prepare($sql_listings);
$stmt_listings->bindParam(':ngo_id', $ngo_id, PDO::PARAM_INT);
$stmt_listings->execute();
$listings = $stmt_listings->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$ngo = false;
$listings = [];
// error_log($e->getMessage());
}
function getStatusBadge($status) {
switch ($status) {
case 'claimed':
return '<span class="badge bg-warning text-dark">Awaiting Volunteer</span>';
case 'assigned':
return '<span class="badge bg-info">Volunteer Assigned</span>';
case 'collected':
return '<span class="badge bg-success">Collected</span>';
default:
return '<span class="badge bg-secondary">Unknown</span>';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NGO Dashboard - Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body { font-family: 'Poppins', sans-serif; background-color: #f8f9fa; }
.navbar { box-shadow: 0 2px 4px rgba(0,0,0,.1); }
.table { background-color: #fff; box-shadow: 0 4px 8px rgba(0,0,0,.1); }
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<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="add_listing.php">Add Listing</a></li>
<li class="nav-item"><a class="nav-link active" href="ngo_dashboard.php">NGO Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_signup.php">Volunteer Signup</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_dashboard.php">Volunteer Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_hub_old.php">Find Pickups</a></li>
<li class="nav-item"><a class="nav-link" href="distribution_map.php">Distribution Map</a></li>
<li class="nav-item"><a class="nav-link" href="admin_panel.php">Admin Panel</a></li>
</ul>
</div>
</div>
</nav>
<div class="container my-5">
<h1 class="h2 mb-4">Dashboard: <?= $ngo ? htmlspecialchars($ngo['name']) : 'NGO' ?></h1>
<?php if (empty($listings)): ?>
<div class="card p-5 text-center">
<p class="mb-0 text-muted">You have not claimed any donations yet. Visit the <a href="ngo_dashboard_old.php">public listings</a> to find available food.</p>
</div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr>
<th>Food Item</th>
<th>Quantity</th>
<th>Pickup By</th>
<th>Status</th>
<th>Volunteer</th>
</tr>
</thead>
<tbody>
<?php foreach ($listings as $listing): ?>
<tr>
<td><?= htmlspecialchars($listing['name']) ?></td>
<td><?= htmlspecialchars($listing['quantity']) ?></td>
<td><?= date('M d, Y h:i A', strtotime($listing['pickup_by'])) ?></td>
<td><?= getStatusBadge($listing['status']) ?></td>
<td><?= $listing['volunteer_name'] ? htmlspecialchars($listing['volunteer_name']) : '-' ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<div class="mt-4 text-center">
<a href="ngo_dashboard_old.php" class="btn btn-outline-primary">View All Available Donations</a>
</div>
</div>
</body>
</html>

View File

@ -1,167 +0,0 @@
<?php
require_once 'db/config.php';
try {
$pdo = db();
$sql = "SELECT id, name, quantity, pickup_by, description, status FROM food_listings WHERE status = 'available' ORDER BY pickup_by ASC";
$stmt = $pdo->query($sql);
$listings = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$listings = [];
// In a real app, log this error
// error_log($e->getMessage());
}
function time_ago($datetime) {
$now = new DateTime;
$ago = new DateTime($datetime);
$diff = $now->diff($ago);
$diff->w = floor($diff->d / 7);
$diff->d -= $diff->w * 7;
$string = array(
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
foreach ($string as $k => &$v) {
if ($diff->$k) {
$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
} else {
unset($string[$k]);
}
}
$string = array_slice($string, 0, 1);
return $string ? implode(', ', $string) . ' ago' : 'just now';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NGO Dashboard - Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<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=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #f8f9fa;
color: #212529;
}
.navbar {
box-shadow: 0 2px 4px rgba(0,0,0,.1);
}
.card {
border-radius: 0.5rem;
border: none;
box-shadow: 0 4px 8px rgba(0,0,0,.1);
transition: transform .2s;
}
.card:hover {
transform: translateY(-5px);
}
.card-title {
font-weight: 600;
}
.btn-success {
background-color: #28a745;
border-color: #28a745;
}
.btn-success:hover {
background-color: #218838;
border-color: #1e7e34;
}
.badge {
font-size: 0.9em;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<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="add_listing.php">Add Listing</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="ngo_dashboard.php">NGO Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="volunteer_signup.php">Volunteer Signup</a>
</li>
<li class="nav-item">
<a class="nav-link" href="volunteer_hub.php">Volunteer Hub</a>
</li>
<li class="nav-item">
<a class="nav-link" href="distribution_map.php">Distribution Map</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container my-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">Available Food Donations</h1>
<?php if (isset($_GET['status']) && $_GET['status'] == 'claimed'): ?>
<div class="alert alert-success mb-0 py-2">Donation claimed!</div>
<?php endif; ?>
</div>
<div class="row gy-4">
<?php if (empty($listings)): ?>
<div class="col-12">
<div class="card p-5 text-center">
<p class="mb-0 text-muted">There are currently no available food donations. Please check back later.</p>
</div>
</div>
<?php else: ?>
<?php foreach ($listings as $listing): ?>
<div class="col-md-6 col-lg-4">
<div class="card h-100">
<div class="card-body d-flex flex-column">
<h5 class="card-title"><?= htmlspecialchars($listing['name']) ?></h5>
<p class="card-text text-muted">Quantity: <?= htmlspecialchars($listing['quantity']) ?></p>
<p class="card-text"><?= htmlspecialchars($listing['description']) ?></p>
<div class="mt-auto">
<p class="card-text">
<small class="text-danger">Pickup by: <?= date('M d, Y h:i A', strtotime($listing['pickup_by'])) ?></small>
</p>
<form action="accept_listing.php" method="POST" class="d-grid">
<input type="hidden" name="id" value="<?= $listing['id'] ?>">
<button type="submit" class="btn btn-success">Accept Donation</button>
</form>
</div>
</div>
<div class="card-footer bg-transparent border-0 text-end">
<small class="text-muted">Posted <?= time_ago($listing['created_at']) ?></small>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -1,107 +0,0 @@
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
require_once 'db/config.php';
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
if (!empty($name) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
try {
$pdo = db();
$sql = "INSERT INTO ngos (name, email) VALUES (:name, :email)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
if ($stmt->execute()) {
header('Location: ngo_signup.php?status=success');
} else {
header('Location: ngo_signup.php?status=error');
}
} catch (PDOException $e) {
if ($e->errorInfo[1] == 1062) { // Duplicate entry
header('Location: ngo_signup.php?status=duplicate');
} else {
header('Location: ngo_signup.php?status=error');
}
}
} else {
header('Location: ngo_signup.php?status=invalid');
}
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NGO Signup - Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body { font-family: 'Poppins', sans-serif; background-color: #f8f9fa; }
.navbar { box-shadow: 0 2px 4px rgba(0,0,0,.1); }
.card { border-radius: 0.5rem; border: none; box-shadow: 0 4px 8px rgba(0,0,0,.1); }
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<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="add_listing.php">Add Listing</a></li>
<li class="nav-item"><a class="nav-link" href="ngo_dashboard.php">NGO Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_signup.php">Volunteer Signup</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_hub.php">Volunteer Hub</a></li>
<li class="nav-item"><a class="nav-link" href="distribution_map.php">Distribution Map</a></li>
<li class="nav-item"><a class="nav-link" href="admin_panel.php">Admin Panel</a></li>
</ul>
</div>
</div>
</nav>
<div class="container my-5">
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="card p-4">
<div class="card-body">
<h2 class="card-title text-center mb-4">Register Your NGO</h2>
<?php if (isset($_GET['status'])): ?>
<div class="alert alert-<?php echo $_GET['status'] === 'success' ? 'success' : 'danger'; ?>" role="alert">
<?php
switch ($_GET['status']) {
case 'success':
echo 'Thank you for registering your NGO!';
break;
case 'duplicate':
echo 'This email is already registered.';
break;
default:
echo 'Something went wrong. Please try again.';
break;
}
?>
</div>
<?php endif; ?>
<form action="ngo_signup.php" method="POST">
<div class="mb-3">
<label for="name" class="form-label">NGO Name</label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Contact Email</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Register</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,46 +0,0 @@
<?php
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: add_listing.php');
exit();
}
// Basic server-side validation
if (empty($_POST['name']) || empty($_POST['quantity']) || empty($_POST['pickup_by'])) {
header('Location: add_listing.php?status=error');
exit();
}
$name = trim($_POST['name']);
$quantity = trim($_POST['quantity']);
$pickup_by = $_POST['pickup_by'];
$description = trim($_POST['description'] ?? '');
$latitude = filter_input(INPUT_POST, 'latitude', FILTER_VALIDATE_FLOAT);
$longitude = filter_input(INPUT_POST, 'longitude', FILTER_VALIDATE_FLOAT);
try {
$pdo = db();
$sql = "INSERT INTO food_listings (name, quantity, pickup_by, description, latitude, longitude) VALUES (:name, :quantity, :pickup_by, :description, :latitude, :longitude)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':quantity', $quantity, PDO::PARAM_STR);
$stmt->bindParam(':pickup_by', $pickup_by, PDO::PARAM_STR);
$stmt->bindParam(':description', $description, PDO::PARAM_STR);
$stmt->bindParam(':latitude', $latitude, PDO::PARAM_STR); // PDO uses STR for decimals
$stmt->bindParam(':longitude', $longitude, PDO::PARAM_STR);
if ($stmt->execute()) {
header('Location: add_listing.php?status=success');
} else {
header('Location: add_listing.php?status=error');
}
} catch (PDOException $e) {
// In a real app, you would log this error, not expose it.
// error_log($e->getMessage());
header('Location: add_listing.php?status=error');
}
exit();

View File

@ -1,40 +0,0 @@
<?php
require_once 'db/config.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['listing_id']) || !isset($_POST['status'])) {
header('Location: volunteer_dashboard.php');
exit();
}
$listing_id = filter_input(INPUT_POST, 'listing_id', FILTER_VALIDATE_INT);
$status = $_POST['status'];
// Basic validation
$allowed_statuses = ['collected', 'en-route', 'delivered'];
if ($listing_id === false || !in_array($status, $allowed_statuses)) {
header('Location: volunteer_dashboard.php?status=error');
exit();
}
// For this MVP, we are not checking if the volunteer is the one assigned.
// In a real app, you would verify the logged-in volunteer's ID against the assignment.
try {
$pdo = db();
$sql = "UPDATE food_listings SET status = :status WHERE id = :listing_id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':status', $status, PDO::PARAM_STR);
$stmt->bindParam(':listing_id', $listing_id, PDO::PARAM_INT);
if ($stmt->execute()) {
header('Location: volunteer_dashboard.php?update=success');
} else {
header('Location: volunteer_dashboard.php?update=error');
}
} catch (PDOException $e) {
// error_log($e->getMessage());
header('Location: volunteer_dashboard.php?update=error');
}
exit();

View File

@ -1,127 +0,0 @@
<?php
require_once 'db/config.php';
// Simulate a logged-in volunteer
$volunteer_id = 1; // In a real app, this would come from a session
try {
$pdo = db();
// Fetch the volunteer's details
$sql_volunteer = "SELECT name FROM volunteers WHERE id = :volunteer_id";
$stmt_volunteer = $pdo->prepare($sql_volunteer);
$stmt_volunteer->bindParam(':volunteer_id', $volunteer_id, PDO::PARAM_INT);
$stmt_volunteer->execute();
$volunteer = $stmt_volunteer->fetch(PDO::FETCH_ASSOC);
// Fetch listings assigned to this volunteer
$sql_listings = "SELECT l.id, l.name, l.quantity, l.status, l.pickup_by, n.name as ngo_name
FROM food_listings as l
JOIN volunteer_assignments as va ON l.id = va.listing_id
LEFT JOIN ngos as n ON l.ngo_id = n.id
WHERE va.volunteer_id = :volunteer_id
ORDER BY l.pickup_by DESC";
$stmt_listings = $pdo->prepare($sql_listings);
$stmt_listings->bindParam(':volunteer_id', $volunteer_id, PDO::PARAM_INT);
$stmt_listings->execute();
$assignments = $stmt_listings->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$volunteer = false;
$assignments = [];
// error_log($e->getMessage());
}
function getStatusBadge($status) {
$badges = [
'assigned' => '<span class="badge bg-primary">Assigned</span>',
'collected' => '<span class="badge bg-info">Collected</span>',
'en-route' => '<span class="badge bg-warning text-dark">En Route</span>',
'delivered' => '<span class="badge bg-success">Delivered</span>',
];
return $badges[$status] ?? '<span class="badge bg-secondary">Unknown</span>';
}
function getNextAction($status, $listing_id) {
$actions = [
'assigned' => '<button type="submit" name="status" value="collected" class="btn btn-sm btn-primary">Mark Collected</button>',
'collected' => '<button type="submit" name="status" value="en-route" class="btn btn-sm btn-warning">Mark En Route</button>',
'en-route' => '<button type="submit" name="status" value="delivered" class="btn btn-sm btn-success">Mark Delivered</button>',
];
if (isset($actions[$status])) {
return '<form action="update_pickup_status.php" method="POST" class="d-inline"><input type="hidden" name="listing_id" value="'.$listing_id.'">'.$actions[$status].'</form>';
}
return '-';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Volunteer Dashboard - Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body { font-family: 'Poppins', sans-serif; background-color: #f8f9fa; }
.navbar { box-shadow: 0 2px 4px rgba(0,0,0,.1); }
.table { background-color: #fff; box-shadow: 0 4px 8px rgba(0,0,0,.1); }
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<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="add_listing.php">Add Listing</a></li>
<li class="nav-item"><a class="nav-link" href="ngo_dashboard.php">NGO Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_signup.php">Volunteer Signup</a></li>
<li class="nav-item"><a class="nav-link active" href="volunteer_dashboard.php">Volunteer Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="distribution_map.php">Distribution Map</a></li>
<li class="nav-item"><a class="nav-link" href="admin_panel.php">Admin Panel</a></li>
</ul>
</div>
</div>
</nav>
<div class="container my-5">
<h1 class="h2 mb-4">Dashboard: <?= $volunteer ? htmlspecialchars($volunteer['name']) : 'Volunteer' ?></h1>
<?php if (empty($assignments)): ?>
<div class="card p-5 text-center">
<p class="mb-0 text-muted">You have no assigned pickups. Visit the <a href="volunteer_hub_old.php">Volunteer Hub</a> to find available jobs.</p>
</div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr>
<th>Food Item</th>
<th>Destination NGO</th>
<th>Pickup By</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($assignments as $assignment): ?>
<tr>
<td><?= htmlspecialchars($assignment['name']) ?></td>
<td><?= htmlspecialchars($assignment['ngo_name']) ?></td>
<td><?= date('M d, Y h:i A', strtotime($assignment['pickup_by'])) ?></td>
<td><?= getStatusBadge($assignment['status']) ?></td>
<td><?= getNextAction($assignment['status'], $assignment['id']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<div class="mt-4 text-center">
<a href="volunteer_hub_old.php" class="btn btn-outline-primary">Find New Pickups</a>
</div>
</div>
</body>
</html>

View File

@ -1,93 +0,0 @@
<?php
require_once 'db/config.php';
try {
$pdo = db();
// Fetch claimed listings
$sql_listings = "SELECT id, name, quantity, pickup_by FROM food_listings WHERE status = 'claimed' ORDER BY pickup_by ASC";
$stmt_listings = $pdo->query($sql_listings);
$listings = $stmt_listings->fetchAll(PDO::FETCH_ASSOC);
// Simulate a logged-in volunteer by fetching the first volunteer
$sql_volunteer = "SELECT id, name FROM volunteers ORDER BY id ASC LIMIT 1";
$stmt_volunteer = $pdo->query($sql_volunteer);
$volunteer = $stmt_volunteer->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
$listings = [];
$volunteer = false;
// error_log($e->getMessage());
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Volunteer Hub - Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<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=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body { font-family: 'Poppins', sans-serif; background-color: #f8f9fa; }
.navbar { box-shadow: 0 2px 4px rgba(0,0,0,.1); }
.card { border-radius: 0.5rem; border: none; box-shadow: 0 4px 8px rgba(0,0,0,.1); }
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"><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="add_listing.php">Add Listing</a></li>
<li class="nav-item"><a class="nav-link" href="ngo_dashboard.php">NGO Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_signup.php">Volunteer Signup</a></li>
<li class="nav-item"><a class="nav-link active" href="volunteer_hub.php">Volunteer Hub</a></li>
<li class="nav-item"><a class="nav-link" href="distribution_map.php">Distribution Map</a></li>
<li class="nav-item"><a class="nav-link" href="ngo_signup.php">NGO Signup</a></li>
</ul>
</div>
</div>
</nav>
<div class="container my-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h2">Available for Pickup</h1>
<?php if ($volunteer): ?>
<span class="badge bg-primary">Logged in as: <?= htmlspecialchars($volunteer['name']) ?></span>
<?php endif; ?>
</div>
<?php if (!$volunteer): ?>
<div class="alert alert-warning">Please <a href="volunteer_signup.php">sign up as a volunteer</a> to see and accept pickups.</div>
<?php elseif (empty($listings)): ?>
<div class="card p-5 text-center">
<p class="mb-0 text-muted">There are no donations ready for pickup right now.</p>
</div>
<?php else: ?>
<div class="list-group">
<?php foreach ($listings as $listing): ?>
<div class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
<div>
<h5 class="mb-1"><?= htmlspecialchars($listing['name']) ?> (<?= htmlspecialchars($listing['quantity']) ?>)</h5>
<small>Pickup by: <?= date('M d, Y h:i A', strtotime($listing['pickup_by'])) ?></small>
</div>
<form action="assign_pickup.php" method="POST">
<input type="hidden" name="listing_id" value="<?= $listing['id'] ?>">
<input type="hidden" name="volunteer_id" value="<?= $volunteer['id'] ?>">
<button type="submit" class="btn btn-sm btn-info">Assign to Me</button>
</form>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -1,115 +0,0 @@
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
require_once 'db/config.php';
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
if (!empty($name) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
try {
$pdo = db();
$sql = "INSERT INTO volunteers (name, email) VALUES (:name, :email)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
if ($stmt->execute()) {
header('Location: volunteer_signup.php?status=success');
} else {
header('Location: volunteer_signup.php?status=error');
}
} catch (PDOException $e) {
if ($e->errorInfo[1] == 1062) { // Duplicate entry
header('Location: volunteer_signup.php?status=duplicate');
} else {
header('Location: volunteer_signup.php?status=error');
}
}
} else {
header('Location: volunteer_signup.php?status=invalid');
}
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Volunteer Signup - Food Rescue</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<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=Poppins:wght@400;600&display=swap" rel="stylesheet">
<style>
body { font-family: 'Poppins', sans-serif; background-color: #f8f9fa; }
.navbar { box-shadow: 0 2px 4px rgba(0,0,0,.1); }
.card { border-radius: 0.5rem; border: none; box-shadow: 0 4px 8px rgba(0,0,0,.1); }
.form-label { font-weight: 600; }
.btn-primary { background-color: #0d6efd; border-color: #0d6efd; }
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="index.php" style="font-weight: 600;">Food Rescue</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"><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="add_listing.php">Add Listing</a></li>
<li class="nav-item"><a class="nav-link" href="ngo_dashboard.php">NGO Dashboard</a></li>
<li class="nav-item"><a class="nav-link active" href="volunteer_signup.php">Volunteer Signup</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_dashboard.php">Volunteer Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="volunteer_hub_old.php">Find Pickups</a></li>
<li class="nav-item"><a class="nav-link" href="distribution_map.php">Distribution Map</a></li>
<li class="nav-item"><a class="nav-link" href="admin_panel.php">Admin Panel</a></li>
</ul>
</div>
</div>
</nav>
<div class="container my-5">
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="card p-4">
<div class="card-body">
<h2 class="card-title text-center mb-4">Join as a Volunteer</h2>
<?php if (isset($_GET['status'])): ?>
<div class="alert alert-<?php echo $_GET['status'] === 'success' ? 'success' : 'danger'; ?>" role="alert">
<?php
switch ($_GET['status']) {
case 'success':
echo 'Thank you for signing up!';
break;
case 'duplicate':
echo 'This email is already registered.';
break;
default:
echo 'Something went wrong. Please try again.';
break;
}
?>
</div>
<?php endif; ?>
<form action="volunteer_signup.php" method="POST">
<div class="mb-3">
<label for="name" class="form-label">Full Name</label>
<input type="text" class="form-control" id="name" name="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" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Sign Up</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>