37650-vm/admin/cars.php
Flatlogic Bot 9643b213d0 sad
2026-01-21 08:43:40 +00:00

222 lines
12 KiB
PHP

<?php
session_start();
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header("Location: ../login.php");
exit();
}
require_once '../db/config.php';
$pdo = db();
// Handle Add/Edit/Delete
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$carId = filter_input(INPUT_POST, 'car_id', FILTER_VALIDATE_INT);
if (isset($_POST['delete_car'])) {
$stmt = $pdo->prepare("DELETE FROM cars WHERE id = ?");
$stmt->execute([$carId]);
header("Location: cars.php");
exit();
}
// Sanitize and validate inputs
$make = trim(filter_input(INPUT_POST, 'make', FILTER_SANITIZE_SPECIAL_CHARS));
$model = trim(filter_input(INPUT_POST, 'model', FILTER_SANITIZE_SPECIAL_CHARS));
$year = filter_input(INPUT_POST, 'year', FILTER_VALIDATE_INT);
$price = filter_input(INPUT_POST, 'price', FILTER_VALIDATE_FLOAT);
$status = in_array($_POST['status'], ['approved', 'pending', 'sold', 'reserved']) ? $_POST['status'] : 'pending';
$description = trim(filter_input(INPUT_POST, 'description', FILTER_SANITIZE_SPECIAL_CHARS));
$color = trim(filter_input(INPUT_POST, 'color', FILTER_SANITIZE_SPECIAL_CHARS));
$mileage = filter_input(INPUT_POST, 'mileage', FILTER_VALIDATE_INT);
$imageUrl = $_POST['existing_image']; // Keep existing image by default
if (isset($_FILES['image']) && $_FILES['image']['error'] == 0) {
$targetDir = "../assets/images/cars/";
if (!is_dir($targetDir)) mkdir($targetDir, 0775, true);
$fileName = uniqid() . '-' . basename($_FILES["image"]["name"]);
$targetFilePath = $targetDir . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"], $targetFilePath)) {
$imageUrl = 'assets/images/cars/' . $fileName;
}
}
if ($carId) { // Update
$sql = "UPDATE cars SET make=?, model=?, year=?, price=?, status=?, description=?, image_url=?, color=?, mileage=? WHERE id=?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$make, $model, $year, $price, $status, $description, $imageUrl, $color, $mileage, $carId]);
} else { // Insert
$sql = "INSERT INTO cars (make, model, year, price, status, description, image_url, color, mileage) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$make, $model, $year, $price, $status, $description, $imageUrl, $color, $mileage]);
}
header("Location: cars.php");
exit();
}
// Fetching cars with filters
$search = $_GET['search'] ?? '';
$filter_status = $_GET['status'] ?? 'all';
$sql = "SELECT * FROM cars";
$params = [];
$where = [];
if (!empty($search)) {
$where[] = "(make LIKE ? OR model LIKE ?)";
$params[] = "%$search%";
$params[] = "%$search%";
}
if ($filter_status !== 'all') {
$where[] = "status = ?";
$params[] = $filter_status;
}
if (!empty($where)) {
$sql .= " WHERE " . implode(' AND ', $where);
}
$sql .= " ORDER BY created_at DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$cars = $stmt->fetchAll(PDO::FETCH_ASSOC);
$projectName = 'Manage Cars';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($projectName) ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
<link rel="stylesheet" href="../assets/css/custom.css?v=<?= time() ?>">
</head>
<body>
<div class="admin-wrapper">
<?php include 'partials/sidebar.php'; ?>
<main class="admin-main-content">
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Manage Cars</h1>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#carModal"><i class="bi bi-plus-circle me-2"></i>Add New Car</button>
</div>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr><th>Image</th><th>Make & Model</th><th>Price</th><th>Status</th><th>Year</th><th>Actions</th></tr>
</thead>
<tbody>
<?php foreach ($cars as $car): ?>
<tr>
<td><img src="../<?= htmlspecialchars($car['image_url']) ?>" height="50" width="80" style="object-fit: cover;" class="rounded" alt="<?= htmlspecialchars($car['make']) ?>"></td>
<td><b><?= htmlspecialchars($car['make'] . ' ' . $car['model']) ?></b></td>
<td>$<?= number_format($car['price']) ?></td>
<td><span class="badge bg-<?= str_replace(['approved', 'pending','reserved', 'sold'], ['success', 'warning','info', 'danger'], $car['status']) ?>"><?= htmlspecialchars(ucfirst($car['status'])) ?></span></td>
<td><?= htmlspecialchars($car['year']) ?></td>
<td>
<button type="button" class="btn btn-sm btn-outline-primary edit-btn" data-bs-toggle="modal" data-bs-target="#carModal" data-car='<?= htmlspecialchars(json_encode($car), ENT_QUOTES, 'UTF-8') ?>'><i class="bi bi-pencil-square"></i></button>
<form method="POST" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this car?');">
<input type="hidden" name="car_id" value="<?= $car['id'] ?>">
<button type="submit" name="delete_car" class="btn btn-sm btn-outline-danger"><i class="bi bi-trash"></i></button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- Car Modal -->
<div class="modal fade" id="carModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="car_id" id="car_id">
<input type="hidden" name="existing_image" id="existing_image">
<div class="modal-header">
<h5 class="modal-title" id="modalTitle">Add Car</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-md-6"><label class="form-label">Make</label><input type="text" name="make" id="make" class="form-control" required></div>
<div class="col-md-6"><label class="form-label">Model</label><input type="text" name="model" id="model" class="form-control" required></div>
<div class="col-md-6"><label class="form-label">Year</label><input type="number" name="year" id="year" class="form-control" required></div>
<div class="col-md-6"><label class="form-label">Price</label><input type="number" name="price" id="price" class="form-control" step="100" required></div>
<div class="col-md-6"><label class="form-label">Mileage (km)</label><input type="number" name="mileage" id="mileage" class="form-control"></div>
<div class="col-md-6"><label class="form-label">Color</label><input type="text" name="color" id="color" class="form-control"></div>
<div class="col-md-6">
<label class="form-label">Status</label>
<select name="status" id="status" class="form-select">
<option value="pending">Pending</option>
<option value="approved">Approved</option>
<option value="reserved">Reserved</option>
<option value="sold">Sold</option>
</select>
</div>
<div class="col-12"><label class="form-label">Description</label><textarea name="description" id="description" class="form-control" rows="3"></textarea></div>
<div class="col-12">
<label class="form-label">Image</label>
<input type="file" name="image" class="form-control">
<img id="image_preview" src="" class="img-fluid rounded mt-2" style="max-height: 150px; display: none;">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save Car</button>
</div>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const carModal = document.getElementById('carModal');
carModal.addEventListener('show.bs.modal', function (event) {
const button = event.relatedTarget;
const modalTitle = carModal.querySelector('.modal-title');
const form = carModal.querySelector('form');
const imagePreview = document.getElementById('image_preview');
form.reset();
imagePreview.style.display = 'none';
imagePreview.src = '';
const carData = button.dataset.car ? JSON.parse(button.dataset.car) : null;
if (carData) {
modalTitle.textContent = 'Edit Car: ' + carData.make + ' ' + carData.model;
form.querySelector('#car_id').value = carData.id;
form.querySelector('#make').value = carData.make;
form.querySelector('#model').value = carData.model;
form.querySelector('#year').value = carData.year;
form.querySelector('#price').value = carData.price;
form.querySelector('#status').value = carData.status;
form.querySelector('#description').value = carData.description;
form.querySelector('#mileage').value = carData.mileage;
form.querySelector('#color').value = carData.color;
form.querySelector('#existing_image').value = carData.image_url;
if (carData.image_url) {
imagePreview.src = '../' + carData.image_url;
imagePreview.style.display = 'block';
}
} else {
modalTitle.textContent = 'Add New Car';
form.querySelector('#car_id').value = '';
}
});
});
</script>
</body>
</html>