Autosave: 20260216-081907

This commit is contained in:
Flatlogic Bot 2026-02-16 08:19:07 +00:00
parent f65de53240
commit 6f72517df1
17 changed files with 1312 additions and 6 deletions

100
admin/bookings.php Normal file
View File

@ -0,0 +1,100 @@
<?php
require_once '../db/config.php';
require_once 'includes/auth.php';
requireAdmin();
$page_title = 'Bookings Management';
$success = '';
// Handle Status Update
if (isset($_GET['status']) && isset($_GET['id'])) {
$id = $_GET['id'];
$status = $_GET['status'];
$stmt = db()->prepare("UPDATE bookings SET status = ? WHERE id = ?");
$stmt->execute([$status, $id]);
$success = 'Booking status updated to ' . $status;
}
$bookings = db()->query("
SELECT b.*, u.name as user_name, u.email as user_email, c.brand, c.model, c.price
FROM bookings b
JOIN users u ON b.user_id = u.id
JOIN cars c ON b.car_id = c.id
ORDER BY b.booking_date DESC
")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bookings - AFG Admin</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<?php include 'includes/sidebar.php'; ?>
<main class="main-content">
<?php include 'includes/header.php'; ?>
<?php if ($success): ?>
<div style="background: rgba(22, 163, 74, 0.1); color: var(--success); padding: 1rem; border-radius: 8px; margin-bottom: 1.5rem; border: 1px solid var(--success);">
<?php echo $success; ?>
</div>
<?php endif; ?>
<div class="data-table-container">
<table>
<thead>
<tr>
<th>Customer</th>
<th>Car Requested</th>
<th>Price</th>
<th>Date</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($bookings as $b): ?>
<tr>
<td>
<strong><?php echo htmlspecialchars($b['user_name']); ?></strong><br>
<small><?php echo htmlspecialchars($b['user_email']); ?></small>
</td>
<td><?php echo htmlspecialchars($b['brand'] . ' ' . $b['model']); ?></td>
<td>$<?php echo number_format($b['price']); ?></td>
<td><?php echo date('M d, Y', strtotime($b['booking_date'])); ?></td>
<td>
<span style="padding: 4px 8px; border-radius: 20px; font-size: 0.75rem;
background: <?php
echo $b['status'] == 'approved' ? 'rgba(22,163,74,0.1)' :
($b['status'] == 'rejected' ? 'rgba(220,38,38,0.1)' : 'rgba(37,99,235,0.1)');
?>;
color: <?php
echo $b['status'] == 'approved' ? 'var(--success)' :
($b['status'] == 'rejected' ? 'var(--danger)' : 'var(--accent)');
?>;">
<?php echo ucfirst($b['status']); ?>
</span>
</td>
<td>
<div style="display: flex; gap: 5px;">
<a href="?id=<?php echo $b['id']; ?>&status=approved" class="btn btn-success" style="padding: 5px;" title="Approve">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>
</a>
<a href="?id=<?php echo $b['id']; ?>&status=rejected" class="btn btn-danger" style="padding: 5px;" title="Reject">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
</a>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($bookings)): ?>
<tr><td colspan="6" style="text-align: center; color: #9ca3af;">No bookings found.</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
</main>
</body>
</html>

186
admin/cars.php Normal file
View File

@ -0,0 +1,186 @@
<?php
require_once '../db/config.php';
require_once 'includes/auth.php';
requireAdmin();
$page_title = 'Cars Management';
$success = '';
$error = '';
// Handle Delete
if (isset($_GET['delete'])) {
$id = $_GET['delete'];
$stmt = db()->prepare("DELETE FROM cars WHERE id = ?");
if ($stmt->execute([$id])) {
$success = 'Car deleted successfully.';
}
}
// Handle Add / Edit
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
$brand = $_POST['brand'] ?? '';
$model = $_POST['model'] ?? '';
$year = $_POST['year'] ?? '';
$price = $_POST['price'] ?? '';
$city = $_POST['city'] ?? 'Kabul';
$fuel = $_POST['fuel_type'] ?? 'Gasoline';
$transmission = $_POST['transmission'] ?? 'Automatic';
$description = $_POST['description'] ?? '';
$id = $_POST['id'] ?? null;
// Handle Image Upload
$main_image = $_POST['current_image'] ?? '';
if (!empty($_FILES['image']['name'])) {
$target_dir = "uploads/";
$file_ext = strtolower(pathinfo($_FILES["image"]["name"], PATHINFO_EXTENSION));
$file_name = time() . "_" . uniqid() . "." . $file_ext;
$target_file = $target_dir . $file_name;
if (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file)) {
$main_image = 'admin/' . $target_file;
}
}
if ($action === 'add') {
$stmt = db()->prepare("INSERT INTO cars (brand, model, year, price, city, fuel_type, transmission, description, main_image) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
if ($stmt->execute([$brand, $model, $year, $price, $city, $fuel, $transmission, $description, $main_image])) {
$success = 'Car added successfully.';
}
} elseif ($action === 'edit') {
$stmt = db()->prepare("UPDATE cars SET brand=?, model=?, year=?, price=?, city=?, fuel_type=?, transmission=?, description=?, main_image=? WHERE id=?");
if ($stmt->execute([$brand, $model, $year, $price, $city, $fuel, $transmission, $description, $main_image, $id])) {
$success = 'Car updated successfully.';
}
}
}
$cars = db()->query("SELECT * FROM cars ORDER BY created_at DESC")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cars Management - AFG Admin</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<?php include 'includes/sidebar.php'; ?>
<main class="main-content">
<?php include 'includes/header.php'; ?>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
<h3>Inventory Overview</h3>
<a href="#addCarModal" class="btn btn-primary">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
Add New Car
</a>
</div>
<?php if ($success): ?>
<div style="background: rgba(22, 163, 74, 0.1); color: var(--success); padding: 1rem; border-radius: 8px; margin-bottom: 1.5rem; border: 1px solid var(--success);">
<?php echo $success; ?>
</div>
<?php endif; ?>
<div class="data-table-container">
<table>
<thead>
<tr>
<th>Image</th>
<th>Brand & Model</th>
<th>Year</th>
<th>Price</th>
<th>City</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($cars as $car): ?>
<tr>
<td>
<img src="../<?php echo !empty($car['main_image']) ? $car['main_image'] : 'assets/images/cars/default.jpg'; ?>"
style="width: 60px; height: 40px; object-fit: cover; border-radius: 4px;">
</td>
<td>
<strong><?php echo htmlspecialchars($car['brand']); ?></strong><br>
<small style="color: #6b7280;"><?php echo htmlspecialchars($car['model']); ?></small>
</td>
<td><?php echo $car['year']; ?></td>
<td>$<?php echo number_format($car['price']); ?></td>
<td><?php echo $car['city']; ?></td>
<td>
<span style="padding: 4px 8px; border-radius: 20px; font-size: 0.75rem; background: <?php echo $car['status'] == 'available' ? 'rgba(22,163,74,0.1)' : 'rgba(220,38,38,0.1)'; ?>; color: <?php echo $car['status'] == 'available' ? 'var(--success)' : 'var(--danger)'; ?>;">
<?php echo ucfirst($car['status']); ?>
</span>
</td>
<td>
<div style="display: flex; gap: 8px;">
<a href="?delete=<?php echo $car['id']; ?>" class="btn btn-danger" style="padding: 5px;" onclick="return confirm('Are you sure?')">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
</a>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<!-- Add Car Modal -->
<div id="addCarModal" class="modal">
<div class="modal-content">
<div style="display: flex; justify-content: space-between; margin-bottom: 1.5rem;">
<h3>Add New Listing</h3>
<a href="#" style="text-decoration: none; color: #6b7280; font-size: 1.5rem;">&times;</a>
</div>
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="add">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem;">
<div>
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Brand</label>
<input type="text" name="brand" required style="width: 100%; padding: 8px; border-radius: 4px; border: 1px solid #ddd;">
</div>
<div>
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Model</label>
<input type="text" name="model" required style="width: 100%; padding: 8px; border-radius: 4px; border: 1px solid #ddd;">
</div>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem;">
<div>
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Year</label>
<input type="number" name="year" required style="width: 100%; padding: 8px; border-radius: 4px; border: 1px solid #ddd;">
</div>
<div>
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Price ($)</label>
<input type="number" name="price" required style="width: 100%; padding: 8px; border-radius: 4px; border: 1px solid #ddd;">
</div>
</div>
<div style="margin-bottom: 1rem;">
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">City</label>
<select name="city" style="width: 100%; padding: 8px; border-radius: 4px; border: 1px solid #ddd;">
<option value="Kabul">Kabul</option>
<option value="Herat">Herat</option>
<option value="Mazar-i-Sharif">Mazar-i-Sharif</option>
<option value="Kandahar">Kandahar</option>
<option value="Jalalabad">Jalalabad</option>
</select>
</div>
<div style="margin-bottom: 1rem;">
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Main Image</label>
<input type="file" name="image" accept="image/*" style="width: 100%;">
</div>
<div style="margin-bottom: 1.5rem;">
<label style="display: block; font-size: 0.8rem; margin-bottom: 5px;">Description</label>
<textarea name="description" rows="3" style="width: 100%; padding: 8px; border-radius: 4px; border: 1px solid #ddd;"></textarea>
</div>
<button type="submit" class="btn btn-primary" style="width: 100%;">Save Car Listing</button>
</form>
</div>
</div>
</main>
</body>
</html>

228
admin/css/style.css Normal file
View File

@ -0,0 +1,228 @@
:root {
--primary: #1e3a8a;
--accent: #2563eb;
--bg: #f3f4f6;
--card: #ffffff;
--text: #1f2937;
--sidebar: #111827;
--sidebar-text: #9ca3af;
--danger: #dc2626;
--success: #16a34a;
--radius: 12px;
}
[data-theme="dark"] {
--bg: #111827;
--card: #1f2937;
--text: #f3f4f6;
--sidebar: #0f172a;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Inter', sans-serif;
}
body {
background: var(--bg);
color: var(--text);
display: flex;
transition: background 0.3s;
}
/* Sidebar */
.sidebar {
width: 260px;
height: 100vh;
background: var(--sidebar);
color: white;
position: fixed;
left: 0;
top: 0;
padding: 2rem 1rem;
display: flex;
flex-direction: column;
z-index: 1000;
}
.sidebar-logo {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 2rem;
color: white;
text-decoration: none;
display: flex;
align-items: center;
gap: 10px;
}
.nav-links {
list-style: none;
flex: 1;
}
.nav-links li {
margin-bottom: 0.5rem;
}
.nav-links a {
color: var(--sidebar-text);
text-decoration: none;
padding: 0.8rem 1rem;
display: flex;
align-items: center;
gap: 12px;
border-radius: var(--radius);
transition: 0.3s;
}
.nav-links a:hover, .nav-links a.active {
background: var(--accent);
color: white;
}
/* Main Content */
.main-content {
margin-left: 260px;
width: calc(100% - 260px);
padding: 2rem;
}
.top-bar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
/* Dashboard Cards */
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.stat-card {
background: var(--card);
padding: 1.5rem;
border-radius: var(--radius);
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
display: flex;
align-items: center;
gap: 1rem;
transition: transform 0.3s;
}
.stat-card:hover {
transform: translateY(-5px);
}
.stat-icon {
width: 48px;
height: 48px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(37, 99, 235, 0.1);
color: var(--accent);
}
.stat-info h3 {
font-size: 0.875rem;
color: #6b7280;
margin-bottom: 0.25rem;
}
.stat-info p {
font-size: 1.5rem;
font-weight: bold;
}
/* Data Table */
.data-table-container {
background: var(--card);
border-radius: var(--radius);
padding: 1.5rem;
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
}
th {
text-align: left;
padding: 1rem;
border-bottom: 2px solid var(--bg);
color: #6b7280;
}
td {
padding: 1rem;
border-bottom: 1px solid var(--bg);
}
/* Buttons */
.btn {
padding: 0.5rem 1rem;
border-radius: 8px;
border: none;
cursor: pointer;
font-weight: 500;
transition: 0.3s;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
}
.btn-primary { background: var(--accent); color: white; }
.btn-danger { background: var(--danger); color: white; }
.btn-success { background: var(--success); color: white; }
/* Modal (CSS Only) */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 2000;
justify-content: center;
align-items: center;
}
.modal:target {
display: flex;
}
.modal-content {
background: var(--card);
padding: 2rem;
border-radius: var(--radius);
width: 500px;
max-width: 90%;
}
/* Mobile Responsive */
@media (max-width: 768px) {
.sidebar {
width: 70px;
padding: 2rem 0.5rem;
}
.sidebar-logo span, .nav-links a span {
display: none;
}
.main-content {
margin-left: 70px;
width: calc(100% - 70px);
}
}

121
admin/dashboard.php Normal file
View File

@ -0,0 +1,121 @@
<?php
require_once '../db/config.php';
require_once 'includes/auth.php';
requireAdmin();
$page_title = 'Dashboard Overview';
// Fetch stats
$total_cars = db()->query("SELECT COUNT(*) FROM cars")->fetchColumn();
$total_users = db()->query("SELECT COUNT(*) FROM users")->fetchColumn();
$total_bookings = db()->query("SELECT COUNT(*) FROM bookings")->fetchColumn();
$total_messages = db()->query("SELECT COUNT(*) FROM contact_messages")->fetchColumn();
$recent_bookings = db()->query("
SELECT b.*, u.name as user_name, c.brand, c.model
FROM bookings b
JOIN users u ON b.user_id = u.id
JOIN cars c ON b.car_id = c.id
ORDER BY b.booking_date DESC LIMIT 5
")->fetchAll();
$recent_messages = db()->query("SELECT * FROM contact_messages ORDER BY created_at DESC LIMIT 5")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - AFG Car Sales</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<?php include 'includes/sidebar.php'; ?>
<main class="main-content">
<?php include 'includes/header.php'; ?>
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon">🚗</div>
<div class="stat-info">
<h3>Total Cars</h3>
<p><?php echo $total_cars; ?></p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">👥</div>
<div class="stat-info">
<h3>Total Users</h3>
<p><?php echo $total_users; ?></p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">📅</div>
<div class="stat-info">
<h3>Bookings</h3>
<p><?php echo $total_bookings; ?></p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">📩</div>
<div class="stat-info">
<h3>Messages</h3>
<p><?php echo $total_messages; ?></p>
</div>
</div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 2rem;">
<!-- Recent Bookings -->
<div class="data-table-container">
<h3 style="margin-bottom: 1.5rem;">Recent Bookings</h3>
<table>
<thead>
<tr>
<th>User</th>
<th>Car</th>
<th>Status</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<?php foreach ($recent_bookings as $booking): ?>
<tr>
<td><?php echo htmlspecialchars($booking['user_name']); ?></td>
<td><?php echo htmlspecialchars($booking['brand'] . ' ' . $booking['model']); ?></td>
<td>
<span class="btn btn-success" style="padding: 2px 8px; font-size: 0.75rem;">
<?php echo ucfirst($booking['status']); ?>
</span>
</td>
<td><?php echo date('M d, Y', strtotime($booking['booking_date'])); ?></td>
</tr>
<?php endforeach; ?>
<?php if (empty($recent_bookings)): ?>
<tr><td colspan="4" style="text-align: center; color: #9ca3af;">No recent bookings</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
<!-- Recent Messages -->
<div class="data-table-container">
<h3 style="margin-bottom: 1.5rem;">Recent Messages</h3>
<div style="display: flex; flex-direction: column; gap: 1rem;">
<?php foreach ($recent_messages as $msg): ?>
<div style="padding: 1rem; background: var(--bg); border-radius: 8px;">
<p style="font-weight: 600; font-size: 0.9rem;"><?php echo htmlspecialchars($msg['name']); ?></p>
<p style="font-size: 0.8rem; color: #6b7280; margin-bottom: 0.5rem;"><?php echo htmlspecialchars($msg['subject']); ?></p>
<p style="font-size: 0.85rem; line-height: 1.4;"><?php echo mb_strimwidth(htmlspecialchars($msg['message']), 0, 100, "..."); ?></p>
</div>
<?php endforeach; ?>
<?php if (empty($recent_messages)): ?>
<p style="text-align: center; color: #9ca3af;">No recent messages</p>
<?php endif; ?>
</div>
</div>
</div>
</main>
</body>
</html>

20
admin/includes/auth.php Normal file
View File

@ -0,0 +1,20 @@
<?php
session_start();
function isAdmin() {
return isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin';
}
function requireAdmin() {
if (!isAdmin()) {
header('Location: index.php');
exit();
}
}
function getAdminData() {
if (!isset($_SESSION['user_id'])) return null;
$stmt = db()->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
return $stmt->fetch();
}

14
admin/includes/header.php Normal file
View File

@ -0,0 +1,14 @@
<div class="top-bar">
<div class="page-title">
<h2 style="font-size: 1.5rem;"><?php echo $page_title ?? 'Dashboard'; ?></h2>
</div>
<div class="user-profile" style="display: flex; align-items: center; gap: 15px;">
<div style="text-align: right;">
<p style="font-weight: 600; font-size: 0.9rem;"><?php echo $_SESSION['user_name']; ?></p>
<p style="font-size: 0.8rem; color: #6b7280;">Administrator</p>
</div>
<div style="width: 40px; height: 40px; border-radius: 50%; background: var(--accent); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;">
<?php echo strtoupper(substr($_SESSION['user_name'], 0, 1)); ?>
</div>
</div>
</div>

View File

@ -0,0 +1,50 @@
<div class="sidebar">
<a href="dashboard.php" class="sidebar-logo">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>
<span>AFG ADMIN</span>
</a>
<ul class="nav-links">
<li>
<a href="dashboard.php" class="<?php echo basename($_SERVER['PHP_SELF']) == 'dashboard.php' ? 'active' : ''; ?>">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg>
<span>Dashboard</span>
</a>
</li>
<li>
<a href="cars.php" class="<?php echo basename($_SERVER['PHP_SELF']) == 'cars.php' ? 'active' : ''; ?>">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 13.1V16c0 .6.4 1 1 1h2"></path><circle cx="7" cy="17" r="2"></circle><path d="M9 17h6"></path><circle cx="17" cy="17" r="2"></circle></svg>
<span>Cars Management</span>
</a>
</li>
<li>
<a href="bookings.php" class="<?php echo basename($_SERVER['PHP_SELF']) == 'bookings.php' ? 'active' : ''; ?>">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>
<span>Bookings</span>
</a>
</li>
<li>
<a href="users.php" class="<?php echo basename($_SERVER['PHP_SELF']) == 'users.php' ? 'active' : ''; ?>">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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>
<span>Users</span>
</a>
</li>
<li>
<a href="messages.php" class="<?php echo basename($_SERVER['PHP_SELF']) == 'messages.php' ? 'active' : ''; ?>">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
<span>Messages</span>
</a>
</li>
<li>
<a href="settings.php" class="<?php echo basename($_SERVER['PHP_SELF']) == 'settings.php' ? 'active' : ''; ?>">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
<span>Settings</span>
</a>
</li>
</ul>
<div style="margin-top: auto; padding-top: 2rem;">
<a href="logout.php" style="color: #ef4444; text-decoration: none; display: flex; align-items: center; gap: 12px; padding: 0.8rem 1rem;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
<span>Logout</span>
</a>
</div>
</div>

102
admin/index.php Normal file
View File

@ -0,0 +1,102 @@
<?php
require_once '../db/config.php';
session_start();
if (isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin') {
header('Location: dashboard.php');
exit();
}
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$stmt = db()->prepare("SELECT * FROM users WHERE email = ? AND role = 'admin'");
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_name'] = $user['name'];
$_SESSION['user_role'] = $user['role'];
header('Location: dashboard.php');
exit();
} else {
$error = 'Invalid admin credentials.';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Login - Car Sales Afghanistan</title>
<link rel="stylesheet" href="css/style.css">
<style>
body {
justify-content: center;
align-items: center;
height: 100vh;
background: #0f172a;
}
.login-card {
background: #1f2937;
padding: 2.5rem;
border-radius: 16px;
width: 100%;
max-width: 400px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
color: white;
border: 1px solid rgba(255,255,255,0.1);
}
.login-card h2 { margin-bottom: 1.5rem; text-align: center; font-size: 1.8rem; }
.form-group { margin-bottom: 1.2rem; }
.form-group label { display: block; margin-bottom: 0.5rem; color: #9ca3af; }
.form-control {
width: 100%;
padding: 0.8rem;
border-radius: 8px;
border: 1px solid #374151;
background: #111827;
color: white;
outline: none;
}
.form-control:focus { border-color: var(--accent); }
.btn-login {
width: 100%;
padding: 0.8rem;
background: var(--accent);
color: white;
border: none;
border-radius: 8px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: 0.3s;
}
.btn-login:hover { background: #1d4ed8; transform: translateY(-2px); }
.error { color: #ef4444; margin-bottom: 1rem; text-align: center; font-size: 0.9rem; }
</style>
</head>
<body>
<div class="login-card">
<h2>Admin Portal</h2>
<?php if ($error): ?>
<div class="error"><?php echo $error; ?></div>
<?php endif; ?>
<form method="POST">
<div class="form-group">
<label>Email Address</label>
<input type="email" name="email" class="form-control" required placeholder="admin@gmail.com">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" required placeholder="••••••••">
</div>
<button type="submit" class="btn-login">Secure Login</button>
</form>
</div>
</body>
</html>

5
admin/logout.php Normal file
View File

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

76
admin/messages.php Normal file
View File

@ -0,0 +1,76 @@
<?php
require_once '../db/config.php';
require_once 'includes/auth.php';
requireAdmin();
$page_title = 'Customer Messages';
$success = '';
// Handle Delete
if (isset($_GET['delete'])) {
$id = $_GET['delete'];
$stmt = db()->prepare("DELETE FROM contact_messages WHERE id = ?");
$stmt->execute([$id]);
$success = 'Message deleted.';
}
// Handle Read Status
if (isset($_GET['read'])) {
$id = $_GET['read'];
$stmt = db()->prepare("UPDATE contact_messages SET is_read = 1 WHERE id = ?");
$stmt->execute([$id]);
}
$messages = db()->query("SELECT * FROM contact_messages ORDER BY created_at DESC")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Messages - AFG Admin</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<?php include 'includes/sidebar.php'; ?>
<main class="main-content">
<?php include 'includes/header.php'; ?>
<?php if ($success): ?>
<div style="background: rgba(22, 163, 74, 0.1); color: var(--success); padding: 1rem; border-radius: 8px; margin-bottom: 1.5rem; border: 1px solid var(--success);">
<?php echo $success; ?>
</div>
<?php endif; ?>
<div class="stats-grid" style="grid-template-columns: 1fr;">
<?php foreach ($messages as $m): ?>
<div class="stat-card" style="display: block; border-left: 4px solid <?php echo $m['is_read'] ? '#e5e7eb' : 'var(--accent)'; ?>;">
<div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem;">
<div>
<h4 style="margin-bottom: 5px;"><?php echo htmlspecialchars($m['subject']); ?></h4>
<p style="font-size: 0.85rem; color: #6b7280;">From: <strong><?php echo htmlspecialchars($m['name']); ?></strong> (<?php echo htmlspecialchars($m['email']); ?>)</p>
</div>
<div style="text-align: right;">
<span style="font-size: 0.75rem; color: #9ca3af;"><?php echo date('M d, Y H:i', strtotime($m['created_at'])); ?></span>
<div style="margin-top: 10px; display: flex; gap: 10px; justify-content: flex-end;">
<?php if (!$m['is_read']): ?>
<a href="?read=<?php echo $m['id']; ?>" class="btn btn-primary" style="padding: 4px 10px; font-size: 0.7rem;">Mark as Read</a>
<?php endif; ?>
<a href="?delete=<?php echo $m['id']; ?>" class="btn btn-danger" style="padding: 4px 10px; font-size: 0.7rem;" onclick="return confirm('Delete message?')">Delete</a>
</div>
</div>
</div>
<div style="background: var(--bg); padding: 1rem; border-radius: 8px; font-size: 0.9rem; line-height: 1.6;">
<?php echo nl2br(htmlspecialchars($m['message'])); ?>
</div>
</div>
<?php endforeach; ?>
<?php if (empty($messages)): ?>
<div class="data-table-container" style="text-align: center; color: #9ca3af; padding: 3rem;">
No customer messages found.
</div>
<?php endif; ?>
</div>
</main>
</body>
</html>

126
admin/settings.php Normal file
View File

@ -0,0 +1,126 @@
<?php
require_once '../db/config.php';
require_once 'includes/auth.php';
requireAdmin();
$page_title = 'Site Settings';
$success = '';
$error = '';
// Fetch current settings
$settings = db()->query("SELECT * FROM settings WHERE id = 1")->fetch();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['update_site'])) {
$site_name = $_POST['site_name'];
$primary_color = $_POST['primary_color'];
$dark_mode = isset($_POST['dark_mode']) ? 1 : 0;
$stmt = db()->prepare("UPDATE settings SET site_name = ?, primary_color = ?, dark_mode = ? WHERE id = 1");
if ($stmt->execute([$site_name, $primary_color, $dark_mode])) {
$success = 'Site settings updated successfully.';
$settings = db()->query("SELECT * FROM settings WHERE id = 1")->fetch();
}
}
if (isset($_POST['update_password'])) {
$old_pass = $_POST['old_password'];
$new_pass = $_POST['new_password'];
$confirm_pass = $_POST['confirm_password'];
$user = getAdminData();
if (password_verify($old_pass, $user['password'])) {
if ($new_pass === $confirm_pass) {
if (strlen($new_pass) >= 8) {
$hashed = password_hash($new_pass, PASSWORD_DEFAULT);
$stmt = db()->prepare("UPDATE users SET password = ? WHERE id = ?");
$stmt->execute([$hashed, $user['id']]);
$success = 'Admin password updated successfully.';
} else {
$error = 'New password must be at least 8 characters.';
}
} else {
$error = 'Passwords do not match.';
}
} else {
$error = 'Incorrect old password.';
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Settings - AFG Admin</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<?php include 'includes/sidebar.php'; ?>
<main class="main-content">
<?php include 'includes/header.php'; ?>
<?php if ($success): ?>
<div style="background: rgba(22, 163, 74, 0.1); color: var(--success); padding: 1rem; border-radius: 8px; margin-bottom: 1.5rem; border: 1px solid var(--success);">
<?php echo $success; ?>
</div>
<?php endif; ?>
<?php if ($error): ?>
<div style="background: rgba(220, 38, 38, 0.1); color: var(--danger); padding: 1rem; border-radius: 8px; margin-bottom: 1.5rem; border: 1px solid var(--danger);">
<?php echo $error; ?>
</div>
<?php endif; ?>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;">
<!-- General Settings -->
<div class="data-table-container">
<h3 style="margin-bottom: 1.5rem;">General Configuration</h3>
<form method="POST">
<input type="hidden" name="update_site" value="1">
<div style="margin-bottom: 1.2rem;">
<label style="display: block; font-size: 0.9rem; margin-bottom: 8px;">Website Name</label>
<input type="text" name="site_name" value="<?php echo htmlspecialchars($settings['site_name']); ?>"
style="width: 100%; padding: 10px; border-radius: 8px; border: 1px solid #ddd;">
</div>
<div style="margin-bottom: 1.2rem;">
<label style="display: block; font-size: 0.9rem; margin-bottom: 8px;">Primary Theme Color</label>
<input type="color" name="primary_color" value="<?php echo $settings['primary_color']; ?>"
style="width: 100%; height: 40px; padding: 2px; border-radius: 8px; border: 1px solid #ddd; cursor: pointer;">
</div>
<div style="margin-bottom: 1.5rem; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="dark_mode" id="dark_mode" <?php echo $settings['dark_mode'] ? 'checked' : ''; ?> style="width: 20px; height: 20px;">
<label for="dark_mode" style="font-size: 0.9rem; cursor: pointer;">Enable System-wide Dark Mode</label>
</div>
<button type="submit" class="btn btn-primary" style="width: 100%;">Save Global Settings</button>
</form>
</div>
<!-- Security Settings -->
<div class="data-table-container">
<h3 style="margin-bottom: 1.5rem;">Admin Security</h3>
<form method="POST">
<input type="hidden" name="update_password" value="1">
<div style="margin-bottom: 1.2rem;">
<label style="display: block; font-size: 0.9rem; margin-bottom: 8px;">Current Password</label>
<input type="password" name="old_password" required placeholder="••••••••"
style="width: 100%; padding: 10px; border-radius: 8px; border: 1px solid #ddd;">
</div>
<div style="margin-bottom: 1.2rem;">
<label style="display: block; font-size: 0.9rem; margin-bottom: 8px;">New Password</label>
<input type="password" name="new_password" required placeholder="Min 8 characters"
style="width: 100%; padding: 10px; border-radius: 8px; border: 1px solid #ddd;">
</div>
<div style="margin-bottom: 1.5rem;">
<label style="display: block; font-size: 0.9rem; margin-bottom: 8px;">Confirm New Password</label>
<input type="password" name="confirm_password" required placeholder="Repeat new password"
style="width: 100%; padding: 10px; border-radius: 8px; border: 1px solid #ddd;">
</div>
<button type="submit" class="btn btn-danger" style="width: 100%;">Update Secure Password</button>
</form>
</div>
</div>
</main>
</body>
</html>

94
admin/users.php Normal file
View File

@ -0,0 +1,94 @@
<?php
require_once '../db/config.php';
require_once 'includes/auth.php';
requireAdmin();
$page_title = 'Users Management';
$success = '';
// Handle Delete
if (isset($_GET['delete'])) {
$id = $_GET['delete'];
if ($id != $_SESSION['user_id']) { // Prevent self-deletion
$stmt = db()->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$id]);
$success = 'User deleted successfully.';
}
}
// Handle Role Change
if (isset($_GET['toggle_role'])) {
$id = $_GET['toggle_role'];
$current_role = $_GET['current'];
$new_role = ($current_role === 'admin') ? 'user' : 'admin';
$stmt = db()->prepare("UPDATE users SET role = ? WHERE id = ?");
$stmt->execute([$new_role, $id]);
$success = 'User role updated.';
}
$users = db()->query("SELECT * FROM users ORDER BY created_at DESC")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Users - AFG Admin</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<?php include 'includes/sidebar.php'; ?>
<main class="main-content">
<?php include 'includes/header.php'; ?>
<?php if ($success): ?>
<div style="background: rgba(22, 163, 74, 0.1); color: var(--success); padding: 1rem; border-radius: 8px; margin-bottom: 1.5rem; border: 1px solid var(--success);">
<?php echo $success; ?>
</div>
<?php endif; ?>
<div class="data-table-container">
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Role</th>
<th>Joined Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td>#<?php echo $user['id']; ?></td>
<td><strong><?php echo htmlspecialchars($user['name']); ?></strong></td>
<td><?php echo htmlspecialchars($user['email']); ?></td>
<td>
<span style="padding: 4px 8px; border-radius: 20px; font-size: 0.75rem; background: <?php echo $user['role'] == 'admin' ? 'rgba(37,99,235,0.1)' : 'rgba(107,114,128,0.1)'; ?>; color: <?php echo $user['role'] == 'admin' ? 'var(--accent)' : '#6b7280'; ?>;">
<?php echo ucfirst($user['role']); ?>
</span>
</td>
<td><?php echo date('M d, Y', strtotime($user['created_at'])); ?></td>
<td>
<div style="display: flex; gap: 8px;">
<a href="?toggle_role=<?php echo $user['id']; ?>&current=<?php echo $user['role']; ?>" class="btn btn-primary" style="padding: 5px;" title="Toggle Role">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><polyline points="16 11 18 13 22 9"></polyline></svg>
</a>
<?php if ($user['id'] != $_SESSION['user_id']): ?>
<a href="?delete=<?php echo $user['id']; ?>" class="btn btn-danger" style="padding: 5px;" onclick="return confirm('Delete this user?')">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
</a>
<?php endif; ?>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</main>
</body>
</html>

View File

@ -16,18 +16,35 @@ CREATE TABLE IF NOT EXISTS users (
CREATE TABLE IF NOT EXISTS cars ( CREATE TABLE IF NOT EXISTS cars (
id INT AUTO_INCREMENT PRIMARY KEY, id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
brand VARCHAR(50) NOT NULL, brand VARCHAR(50) NOT NULL,
model VARCHAR(50) NOT NULL, model VARCHAR(50) NOT NULL,
year INT NOT NULL, year INT NOT NULL,
price DECIMAL(10, 2) NOT NULL, price DECIMAL(10, 2) NOT NULL,
fuel_type VARCHAR(20) DEFAULT 'Gasoline',
transmission VARCHAR(20) DEFAULT 'Automatic',
city ENUM('Kabul', 'Herat', 'Mazar-i-Sharif', 'Kandahar', 'Jalalabad') NOT NULL, city ENUM('Kabul', 'Herat', 'Mazar-i-Sharif', 'Kandahar', 'Jalalabad') NOT NULL,
description TEXT, description TEXT,
main_image VARCHAR(255), main_image VARCHAR(255),
status ENUM('available', 'sold') DEFAULT 'available', status ENUM('available', 'sold') DEFAULT 'available',
is_hot_deal BOOLEAN DEFAULT FALSE, is_hot_deal BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE );
CREATE TABLE IF NOT EXISTS car_images (
id INT AUTO_INCREMENT PRIMARY KEY,
car_id INT,
image_path VARCHAR(255) NOT NULL,
FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS bookings (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
car_id INT,
status ENUM('pending', 'approved', 'rejected') DEFAULT 'pending',
booking_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE
); );
CREATE TABLE IF NOT EXISTS contact_messages ( CREATE TABLE IF NOT EXISTS contact_messages (
@ -36,9 +53,20 @@ CREATE TABLE IF NOT EXISTS contact_messages (
email VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL,
subject VARCHAR(200), subject VARCHAR(200),
message TEXT NOT NULL, message TEXT NOT NULL,
is_read BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
CREATE TABLE IF NOT EXISTS settings (
id INT PRIMARY KEY AUTO_INCREMENT,
site_name VARCHAR(100) DEFAULT 'Car Sales Afghanistan',
site_logo VARCHAR(255) DEFAULT 'assets/images/logo.png',
primary_color VARCHAR(10) DEFAULT '#1e3a8a',
dark_mode BOOLEAN DEFAULT TRUE
);
INSERT IGNORE INTO settings (id, site_name) VALUES (1, 'Car Sales Afghanistan');
-- Default Admin Account (Password: 12345678) -- Default Admin Account (Password: 12345678)
INSERT IGNORE INTO users (id, name, email, password, role) VALUES INSERT IGNORE INTO users (id, name, email, password, role) VALUES
(1, 'Mohammad Sadiq', 'admin@gmail.com', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'admin'); (1, 'Mohammad Sadiq', 'admin@gmail.com', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'admin');

View File

@ -22,8 +22,14 @@
<li><a href="contact.php">Contact</a></li> <li><a href="contact.php">Contact</a></li>
</ul> </ul>
<div class="auth-buttons"> <div class="auth-buttons">
<a href="login.php" class="btn btn-outline" style="margin-right: 10px;">Login</a> <?php if (isset($_SESSION['user_id'])): ?>
<a href="register.php" class="btn btn-primary">Register</a> <span style="margin-right: 15px; color: var(--text-muted);">Hi, <strong><?php echo htmlspecialchars($_SESSION['user_name']); ?></strong></span>
<a href="<?php echo ($_SESSION['user_role'] === 'admin') ? 'admin/dashboard.php' : 'user_dashboard.php'; ?>" class="btn btn-outline" style="margin-right: 10px;">Dashboard</a>
<a href="logout.php" class="btn btn-primary" style="background: #ef4444; border-color: #ef4444;">Logout</a>
<?php else: ?>
<a href="login.php" class="btn btn-outline" style="margin-right: 10px;">Login</a>
<a href="register.php" class="btn btn-primary">Register</a>
<?php endif; ?>
</div> </div>
</nav> </nav>
</div> </div>

View File

@ -21,7 +21,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_SESSION['user_name'] = $user['name']; $_SESSION['user_name'] = $user['name'];
$_SESSION['user_role'] = $user['role']; $_SESSION['user_role'] = $user['role'];
header('Location: index.php'); if ($user['role'] === 'admin') {
header('Location: admin/dashboard.php');
} else {
header('Location: user_dashboard.php');
}
exit; exit;
} else { } else {
$error = 'Invalid email or password.'; $error = 'Invalid email or password.';

6
logout.php Normal file
View File

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

140
user_dashboard.php Normal file
View File

@ -0,0 +1,140 @@
<?php
session_start();
require_once 'db/config.php';
// Check if logged in
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$user_name = $_SESSION['user_name'];
// Fetch user bookings
try {
$stmt = db()->prepare("
SELECT b.*, c.brand, c.model, c.year, c.price, c.main_image
FROM bookings b
JOIN cars c ON b.car_id = c.id
WHERE b.user_id = ?
ORDER BY b.booking_date DESC
");
$stmt->execute([$user_id]);
$bookings = $stmt->fetchAll();
} catch (PDOException $e) {
$bookings = [];
}
include 'includes/header.php';
?>
<main class="container mt-5">
<div class="row" style="display: flex; gap: 20px; flex-wrap: wrap;">
<!-- User Sidebar Info -->
<div style="flex: 1; min-width: 300px;">
<div class="glass-card">
<div style="text-align: center; margin-bottom: 20px;">
<div style="width: 80px; height: 80px; background: var(--accent-gold); border-radius: 50%; margin: 0 auto 15px; display: flex; align-items: center; justify-content: center; font-size: 2rem; color: #1a1a1a; font-weight: bold;">
<?php echo strtoupper(substr($user_name, 0, 1)); ?>
</div>
<h3><?php echo htmlspecialchars($user_name); ?></h3>
<p style="color: var(--text-muted);">Premium Member</p>
</div>
<hr style="border: none; border-top: 1px solid var(--glass-border); margin: 20px 0;">
<ul style="list-style: none; padding: 0;">
<li style="margin-bottom: 15px;">
<a href="#" style="color: var(--accent-gold); text-decoration: none; display: flex; align-items: center; gap: 10px;">
<span>📊</span> My Overview
</a>
</li>
<li style="margin-bottom: 15px;">
<a href="cars.php" style="color: white; text-decoration: none; display: flex; align-items: center; gap: 10px;">
<span>🚗</span> Browse Cars
</a>
</li>
<li style="margin-bottom: 15px;">
<a href="logout.php" style="color: #ff4444; text-decoration: none; display: flex; align-items: center; gap: 10px;">
<span>🚪</span> Logout
</a>
</li>
</ul>
</div>
</div>
<!-- Main Content -->
<div style="flex: 3; min-width: 300px;">
<div class="glass-card mb-4">
<h2>Welcome to your Dashboard</h2>
<p style="color: var(--text-muted);">Manage your bookings and view your saved cars.</p>
</div>
<div class="glass-card">
<h3 style="margin-bottom: 20px;">My Booking Requests</h3>
<?php if (empty($bookings)): ?>
<div style="text-align: center; padding: 40px; border: 1px dashed var(--glass-border); border-radius: 12px;">
<p style="color: var(--text-muted); margin-bottom: 20px;">You haven't made any booking requests yet.</p>
<a href="cars.php" class="btn btn-primary">Browse Available Cars</a>
</div>
<?php else: ?>
<div style="overflow-x: auto;">
<table style="width: 100%; border-collapse: collapse; text-align: left;">
<thead>
<tr style="border-bottom: 2px solid var(--glass-border);">
<th style="padding: 15px 10px;">Car</th>
<th style="padding: 15px 10px;">Price</th>
<th style="padding: 15px 10px;">Date</th>
<th style="padding: 15px 10px;">Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($bookings as $booking): ?>
<tr style="border-bottom: 1px solid var(--glass-border);">
<td style="padding: 15px 10px;">
<div style="display: flex; align-items: center; gap: 15px;">
<img src="<?php echo htmlspecialchars($booking['main_image']); ?>" alt="Car" style="width: 60px; height: 40px; object-fit: cover; border-radius: 4px;">
<div>
<strong><?php echo htmlspecialchars($booking['brand'] . ' ' . $booking['model']); ?></strong>
<div style="font-size: 0.8rem; color: var(--text-muted);"><?php echo $booking['year']; ?></div>
</div>
</div>
</td>
<td style="padding: 15px 10px;">$<?php echo number_format($booking['price']); ?></td>
<td style="padding: 15px 10px;"><?php echo date('M d, Y', strtotime($booking['booking_date'])); ?></td>
<td style="padding: 15px 10px;">
<?php
$statusClass = '';
if ($booking['status'] === 'approved') $statusClass = 'color: #10b981;';
elseif ($booking['status'] === 'rejected') $statusClass = 'color: #ef4444;';
else $statusClass = 'color: #f59e0b;';
?>
<span style="<?php echo $statusClass; ?> font-weight: bold; text-transform: capitalize;">
<?php echo $booking['status']; ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</main>
<style>
.glass-card {
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 25px;
margin-bottom: 20px;
}
.mt-5 { margin-top: 3rem; }
.mb-4 { margin-bottom: 1.5rem; }
</style>
<?php include 'includes/footer.php'; ?>