sadiq
This commit is contained in:
parent
a0a862d0fb
commit
5e1b7e7c43
94
admin/branches.php
Normal file
94
admin/branches.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
$pdo = db();
|
||||
|
||||
// Handle Form Submission
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$name = $_POST['name'];
|
||||
$location = $_POST['location'];
|
||||
$phone = $_POST['phone'];
|
||||
$email = $_POST['email'];
|
||||
|
||||
$stmt = $pdo->prepare("INSERT INTO branches (name, location, phone, email) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$name, $location, $phone, $email]);
|
||||
|
||||
// Log activity
|
||||
$adminId = $_SESSION['user_id'];
|
||||
$pdo->prepare("INSERT INTO activity_logs (user_id, action) VALUES (?, 'Added new branch: $name')")->execute([$adminId]);
|
||||
|
||||
echo "<div style='padding: 1rem; background: #4caf50; color: white; margin-bottom: 1rem;'>Branch Added Successfully</div>";
|
||||
}
|
||||
|
||||
// Delete Branch
|
||||
if (isset($_GET['delete'])) {
|
||||
$id = $_GET['delete'];
|
||||
$pdo->prepare("DELETE FROM branches WHERE id = ?")->execute([$id]);
|
||||
echo "<div style='padding: 1rem; background: #f44336; color: white; margin-bottom: 1rem;'>Branch Deleted</div>";
|
||||
}
|
||||
|
||||
$branches = $pdo->query("SELECT * FROM branches ORDER BY created_at DESC")->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Branch Management</h1>
|
||||
<button onclick="document.getElementById('addBranchModal').style.display='block'" class="btn-sm btn-primary">Add New Branch</button>
|
||||
</div>
|
||||
|
||||
<div class="card-grid" style="grid-template-columns: 1fr;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Location</th>
|
||||
<th>Contact</th>
|
||||
<th>Created At</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($branches as $branch): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($branch['name']); ?></td>
|
||||
<td><?php echo htmlspecialchars($branch['location']); ?></td>
|
||||
<td>
|
||||
<?php echo htmlspecialchars($branch['phone']); ?><br>
|
||||
<small><?php echo htmlspecialchars($branch['email']); ?></small>
|
||||
</td>
|
||||
<td><?php echo $branch['created_at']; ?></td>
|
||||
<td>
|
||||
<a href="?delete=<?php echo $branch['id']; ?>" class="btn-sm btn-danger" onclick="return confirm('Delete this branch?')">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Simple Modal for Adding Branch -->
|
||||
<div id="addBranchModal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.8); z-index:1000;">
|
||||
<div style="background:var(--card-bg); width:400px; margin: 100px auto; padding:2rem; border-radius:8px; border:1px solid var(--border-color);">
|
||||
<h2 style="margin-bottom:1rem; color:var(--text-primary);">Add Branch</h2>
|
||||
<form method="POST">
|
||||
<div style="margin-bottom:1rem;">
|
||||
<label style="display:block; color:var(--text-secondary); margin-bottom:0.5rem;">Branch Name</label>
|
||||
<input type="text" name="name" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:var(--text-primary);">
|
||||
</div>
|
||||
<div style="margin-bottom:1rem;">
|
||||
<label style="display:block; color:var(--text-secondary); margin-bottom:0.5rem;">Location</label>
|
||||
<input type="text" name="location" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:var(--text-primary);">
|
||||
</div>
|
||||
<div style="margin-bottom:1rem;">
|
||||
<label style="display:block; color:var(--text-secondary); margin-bottom:0.5rem;">Phone</label>
|
||||
<input type="text" name="phone" style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:var(--text-primary);">
|
||||
</div>
|
||||
<div style="margin-bottom:1rem;">
|
||||
<label style="display:block; color:var(--text-secondary); margin-bottom:0.5rem;">Email</label>
|
||||
<input type="email" name="email" style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:var(--text-primary);">
|
||||
</div>
|
||||
<button type="submit" class="btn-sm btn-primary" style="width:100%;">Create Branch</button>
|
||||
<button type="button" onclick="document.getElementById('addBranchModal').style.display='none'" class="btn-sm" style="width:100%; margin-top:0.5rem; background:transparent; border:1px solid var(--border-color);">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
160
admin/cars.php
Normal file
160
admin/cars.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
|
||||
$pdo = db();
|
||||
$error = '';
|
||||
$success = '';
|
||||
|
||||
// Handle Delete
|
||||
if (isset($_POST['delete_car'])) {
|
||||
$id = $_POST['car_id'];
|
||||
$stmt = $pdo->prepare("DELETE FROM cars WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$success = "Car deleted successfully.";
|
||||
}
|
||||
|
||||
// Handle Add (Basic Implementation)
|
||||
if (isset($_POST['add_car'])) {
|
||||
try {
|
||||
$stmt = $pdo->prepare("INSERT INTO cars (vin, brand, model, year, price, mileage, transmission, fuel_type, status, branch_id, dealer_id, installment_available) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'Available', ?, ?, ?)");
|
||||
$stmt->execute([
|
||||
$_POST['vin'], $_POST['brand'], $_POST['model'], $_POST['year'],
|
||||
$_POST['price'], $_POST['mileage'], $_POST['transmission'],
|
||||
$_POST['fuel_type'], $_POST['branch_id'], $_POST['dealer_id'] ?: null,
|
||||
isset($_POST['installment_available']) ? 1 : 0
|
||||
]);
|
||||
|
||||
// Log activity
|
||||
$adminId = $_SESSION['user_id'];
|
||||
$pdo->prepare("INSERT INTO activity_logs (user_id, action) VALUES (?, 'Added new car: ' . ?)")->execute([$adminId, $_POST['brand'] . ' ' . $_POST['model']]);
|
||||
|
||||
$success = "Car added successfully.";
|
||||
} catch (PDOException $e) {
|
||||
$error = "Error adding car: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$branches = $pdo->query("SELECT * FROM branches")->fetchAll();
|
||||
$dealers = $pdo->query("SELECT * FROM users WHERE role = 'Dealer'")->fetchAll();
|
||||
|
||||
$stmt = $pdo->query("SELECT cars.*, branches.name as branch_name FROM cars LEFT JOIN branches ON cars.branch_id = branches.id ORDER BY cars.created_at DESC");
|
||||
$cars = $stmt->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Car Management</h1>
|
||||
<button onclick="document.getElementById('addCarModal').style.display='block'" class="btn-sm btn-primary" style="background:var(--accent-color); color:var(--bg-color); border:none; padding:0.5rem 1rem; cursor:pointer;">Add New Car</button>
|
||||
</div>
|
||||
|
||||
<?php if ($error): ?><div style="color: #ff4444; margin-bottom: 1rem;"><?php echo htmlspecialchars($error); ?></div><?php endif; ?>
|
||||
<?php if ($success): ?><div style="color: #00C851; margin-bottom: 1rem;"><?php echo htmlspecialchars($success); ?></div><?php endif; ?>
|
||||
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Brand/Model</th>
|
||||
<th>Year</th>
|
||||
<th>Price</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($cars as $car): ?>
|
||||
<tr>
|
||||
<td>#<?php echo $car['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($car['brand'] . ' ' . $car['model']); ?></td>
|
||||
<td><?php echo $car['year']; ?></td>
|
||||
<td>$<?php echo number_format($car['price']); ?></td>
|
||||
<td><?php echo $car['status']; ?></td>
|
||||
<td>
|
||||
<form method="POST" onsubmit="return confirm('Delete this car?');" style="display: inline;">
|
||||
<input type="hidden" name="car_id" value="<?php echo $car['id']; ?>">
|
||||
<button type="submit" name="delete_car" class="btn-sm btn-danger">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Simple Add Car Modal -->
|
||||
<div id="addCarModal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.8); z-index:2000; align-items:center; justify-content:center; display:none;">
|
||||
<div style="background:var(--card-bg); margin:5% auto; padding:2rem; width:90%; max-width:500px; border-radius:12px; border:1px solid var(--border-color); position: relative;">
|
||||
<h2 style="margin-bottom:1.5rem; text-align:center;">Add New Car</h2>
|
||||
<form method="POST">
|
||||
<div style="margin-bottom:1rem;">
|
||||
<input type="text" name="vin" placeholder="VIN Number" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns: 1fr 1fr; gap:1rem; margin-bottom:1rem;">
|
||||
<input type="text" name="brand" placeholder="Brand" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
<input type="text" name="model" placeholder="Model" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns: 1fr 1fr; gap:1rem; margin-bottom:1rem;">
|
||||
<input type="number" name="year" placeholder="Year" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
<input type="number" name="price" placeholder="Price ($)" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
</div>
|
||||
<div style="margin-bottom:1rem;">
|
||||
<input type="number" name="mileage" placeholder="Mileage" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns: 1fr 1fr; gap:1rem; margin-bottom:1.5rem;">
|
||||
<select name="transmission" style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
<option value="Automatic">Automatic</option>
|
||||
<option value="Manual">Manual</option>
|
||||
</select>
|
||||
<select name="fuel_type" style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
<option value="Petrol">Petrol</option>
|
||||
<option value="Diesel">Diesel</option>
|
||||
<option value="Electric">Electric</option>
|
||||
<option value="Hybrid">Hybrid</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns: 1fr 1fr; gap:1rem; margin-bottom:1rem;">
|
||||
<select name="branch_id" required style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
<option value="">Select Branch</option>
|
||||
<?php foreach ($branches as $branch): ?>
|
||||
<option value="<?php echo $branch['id']; ?>"><?php echo htmlspecialchars($branch['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<select name="dealer_id" style="width:100%; padding:0.8rem; background:var(--bg-color); border:1px solid var(--border-color); color:white; border-radius:4px;">
|
||||
<option value="">Select Dealer (Optional)</option>
|
||||
<?php foreach ($dealers as $dealer): ?>
|
||||
<option value="<?php echo $dealer['id']; ?>"><?php echo htmlspecialchars($dealer['username']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div style="margin-bottom:1.5rem;">
|
||||
<label style="color:var(--text-secondary); display:flex; align-items:center;">
|
||||
<input type="checkbox" name="installment_available" value="1" style="width:auto; margin-right:0.5rem;">
|
||||
Available for Installment Plan
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" name="add_car" style="width:100%; padding:0.8rem; background:var(--accent-color); border:none; border-radius:4px; color:var(--bg-color); font-weight:bold; cursor:pointer;">Add Car</button>
|
||||
<button type="button" onclick="document.getElementById('addCarModal').style.display='none'" style="width:100%; padding:0.8rem; margin-top:0.5rem; background:transparent; border:1px solid var(--border-color); color:var(--text-secondary); cursor:pointer; border-radius:4px;">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Simple script to handle modal visibility since inline style display:none might be overridden by flex in CSS if I used flex
|
||||
// Actually the inline style 'display:none' on the wrapper div is correct.
|
||||
// I'll add a script to ensure it works.
|
||||
const modal = document.getElementById('addCarModal');
|
||||
// Ensure it's hidden on load
|
||||
modal.style.display = 'none';
|
||||
|
||||
// Override the button to show it as flex for centering
|
||||
document.querySelector('.page-header button').onclick = function() {
|
||||
modal.style.display = 'flex';
|
||||
};
|
||||
|
||||
// Close on cancel
|
||||
document.querySelector('#addCarModal button[type="button"]').onclick = function() {
|
||||
modal.style.display = 'none';
|
||||
};
|
||||
</script>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
45
admin/dealers.php
Normal file
45
admin/dealers.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
$pdo = db();
|
||||
|
||||
$dealers = $pdo->query("SELECT * FROM users WHERE role = 'Dealer' ORDER BY created_at DESC")->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Dealer Management</h1>
|
||||
<a href="users.php?role=Dealer" class="btn-sm btn-primary">Manage All Users</a>
|
||||
</div>
|
||||
|
||||
<div class="card-grid" style="grid-template-columns: 1fr;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Email</th>
|
||||
<th>Status</th>
|
||||
<th>Performance (Sales)</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($dealers as $dealer): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($dealer['username']); ?></td>
|
||||
<td><?php echo htmlspecialchars($dealer['email']); ?></td>
|
||||
<td><span style="padding:0.2rem 0.5rem; background:rgba(76, 175, 80, 0.2); color:#4caf50; border-radius:4px;">Active</span></td>
|
||||
<td>$0.00 (0 Sales)</td> <!-- Placeholder for now -->
|
||||
<td>
|
||||
<a href="users.php?edit=<?php echo $dealer['id']; ?>" class="btn-sm" style="background:var(--accent-color); color:black;">Edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($dealers)): ?>
|
||||
<tr>
|
||||
<td colspan="5" style="text-align:center; color:var(--text-secondary); padding:2rem;">No dealers found. Create one in the Users section.</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
4
admin/includes/footer.php
Normal file
4
admin/includes/footer.php
Normal file
@ -0,0 +1,4 @@
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
123
admin/includes/header.php
Normal file
123
admin/includes/header.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../includes/auth.php';
|
||||
requireAdmin();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Admin Dashboard</title>
|
||||
<link rel="stylesheet" href="/assets/css/style.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
.admin-layout { display: flex; min-height: 100vh; }
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: var(--surface-color);
|
||||
border-right: 1px solid var(--border-color);
|
||||
padding: 2rem 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.main-content {
|
||||
flex: 1;
|
||||
margin-left: 250px;
|
||||
padding: 2rem;
|
||||
background: var(--bg-color);
|
||||
}
|
||||
.sidebar-brand {
|
||||
color: var(--accent-color);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 2rem;
|
||||
text-align: center;
|
||||
letter-spacing: 1px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.nav-link {
|
||||
display: block;
|
||||
padding: 0.8rem 1rem;
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 0.5rem;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.nav-link:hover, .nav-link.active {
|
||||
background: rgba(212, 175, 55, 0.1);
|
||||
color: var(--accent-color);
|
||||
}
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.stat-card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 1.5rem;
|
||||
}
|
||||
.stat-value { font-size: 2rem; font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem; }
|
||||
.stat-label { color: var(--text-secondary); font-size: 0.9rem; }
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: var(--card-bg);
|
||||
border-radius: var(--border-radius);
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
.data-table th, .data-table td {
|
||||
padding: 1rem;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
.data-table th {
|
||||
background: rgba(255,255,255,0.05);
|
||||
color: var(--accent-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
.data-table tr:hover { background: rgba(255,255,255,0.02); }
|
||||
.btn-sm {
|
||||
padding: 0.4rem 0.8rem;
|
||||
font-size: 0.8rem;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
.btn-danger { background: rgba(255, 68, 68, 0.2); color: #ff4444; }
|
||||
.btn-danger:hover { background: rgba(255, 68, 68, 0.3); }
|
||||
.btn-primary { background: var(--accent-color); color: var(--bg-color); font-weight: 600; }
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
h1 { font-size: 1.8rem; color: var(--text-primary); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="admin-layout">
|
||||
<aside class="sidebar">
|
||||
<a href="/index.php" class="sidebar-brand">AFG_CARS ADMIN</a>
|
||||
<nav>
|
||||
<a href="/admin/index.php" class="nav-link <?php echo basename($_SERVER['PHP_SELF']) == 'index.php' ? 'active' : ''; ?>">Dashboard</a>
|
||||
<a href="/admin/users.php" class="nav-link <?php echo basename($_SERVER['PHP_SELF']) == 'users.php' ? 'active' : ''; ?>">Users</a>
|
||||
<a href="/admin/branches.php" class="nav-link <?php echo basename($_SERVER['PHP_SELF']) == 'branches.php' ? 'active' : ''; ?>">Branches</a>
|
||||
<a href="/admin/dealers.php" class="nav-link <?php echo basename($_SERVER['PHP_SELF']) == 'dealers.php' ? 'active' : ''; ?>">Dealers</a>
|
||||
<a href="/admin/cars.php" class="nav-link <?php echo basename($_SERVER['PHP_SELF']) == 'cars.php' ? 'active' : ''; ?>">Cars Inventory</a>
|
||||
<a href="/admin/sales.php" class="nav-link <?php echo basename($_SERVER['PHP_SELF']) == 'sales.php' ? 'active' : ''; ?>">Sales & Installments</a>
|
||||
<a href="/admin/reports.php" class="nav-link <?php echo basename($_SERVER['PHP_SELF']) == 'reports.php' ? 'active' : ''; ?>">Reports</a>
|
||||
<a href="/logout.php" class="nav-link" style="margin-top: auto; color: #ff4444;">Logout</a>
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="main-content">
|
||||
80
admin/index.php
Normal file
80
admin/index.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
|
||||
$pdo = db();
|
||||
$usersCount = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();
|
||||
$carsCount = $pdo->query("SELECT COUNT(*) FROM cars")->fetchColumn();
|
||||
$branchesCount = $pdo->query("SELECT COUNT(*) FROM branches")->fetchColumn();
|
||||
$salesCount = $pdo->query("SELECT COUNT(*) FROM sales WHERE status = 'Completed'")->fetchColumn();
|
||||
$revenue = $pdo->query("SELECT SUM(final_price) FROM sales WHERE status = 'Completed'")->fetchColumn() ?: 0;
|
||||
$activeContracts = $pdo->query("SELECT COUNT(*) FROM installments WHERE status = 'Active'")->fetchColumn();
|
||||
|
||||
// Recent Activity
|
||||
$activities = $pdo->query("SELECT * FROM activity_logs ORDER BY created_at DESC LIMIT 5")->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1>Enterprise Dashboard</h1>
|
||||
<span style="color: var(--text-secondary);">Overview of AFG_CARS Operations</span>
|
||||
</div>
|
||||
<div style="background: rgba(255,255,255,0.1); padding: 0.5rem 1rem; border-radius: 4px;">
|
||||
Date: <?php echo date('Y-m-d'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-value"><?php echo $usersCount; ?></div>
|
||||
<div class="stat-label">Total Users</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value"><?php echo $branchesCount; ?></div>
|
||||
<div class="stat-label">Branches</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value"><?php echo $carsCount; ?></div>
|
||||
<div class="stat-label">Total Inventory</div>
|
||||
</div>
|
||||
<div class="stat-card" style="border-color: var(--accent-color);">
|
||||
<div class="stat-value">$<?php echo number_format($revenue); ?></div>
|
||||
<div class="stat-label">Total Revenue</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value"><?php echo $salesCount; ?></div>
|
||||
<div class="stat-label">Completed Sales</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value"><?php echo $activeContracts; ?></div>
|
||||
<div class="stat-label">Active Installments</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 1.5rem;">
|
||||
<div style="background: var(--card-bg); border-radius: var(--border-radius); padding: 1.5rem; border: 1px solid var(--border-color);">
|
||||
<h3 style="margin-bottom: 1rem; color: var(--accent-color);">System Activity Log</h3>
|
||||
<?php if ($activities): ?>
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
<?php foreach ($activities as $log): ?>
|
||||
<li style="border-bottom: 1px solid var(--border-color); padding: 0.8rem 0; display: flex; justify-content: space-between;">
|
||||
<span><?php echo htmlspecialchars($log['action']); ?></span>
|
||||
<small style="color: var(--text-secondary);"><?php echo $log['created_at']; ?></small>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else: ?>
|
||||
<p style="color: var(--text-secondary);">No recent activity logged.</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div style="background: var(--card-bg); border-radius: var(--border-radius); padding: 1.5rem; border: 1px solid var(--border-color);">
|
||||
<h3 style="margin-bottom: 1rem; color: var(--accent-color);">Quick Actions</h3>
|
||||
<div style="display: flex; flex-direction: column; gap: 0.8rem;">
|
||||
<a href="cars.php?action=add" class="btn-sm btn-primary" style="text-align: center;">Add New Car</a>
|
||||
<a href="branches.php?action=add" class="btn-sm" style="background: #444; color: white; text-align: center;">New Branch</a>
|
||||
<a href="users.php?action=add" class="btn-sm" style="background: #444; color: white; text-align: center;">Add User</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
12
admin/reports.php
Normal file
12
admin/reports.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
?>
|
||||
<div class="page-header">
|
||||
<h1>Reports & Analytics</h1>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 4rem; background: var(--card-bg); border: 1px solid var(--border-color); border-radius: var(--border-radius);">
|
||||
<i class="fas fa-chart-pie" style="font-size: 3rem; color: var(--accent-color); margin-bottom: 1rem;"></i>
|
||||
<h3>Enterprise Reporting</h3>
|
||||
<p style="color: var(--text-secondary);">Financial reports, dealer performance, and inventory turnover analytics will be available here.</p>
|
||||
</div>
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
12
admin/sales.php
Normal file
12
admin/sales.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
?>
|
||||
<div class="page-header">
|
||||
<h1>Sales & Installments</h1>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 4rem; background: var(--card-bg); border: 1px solid var(--border-color); border-radius: var(--border-radius);">
|
||||
<i class="fas fa-file-invoice-dollar" style="font-size: 3rem; color: var(--accent-color); margin-bottom: 1rem;"></i>
|
||||
<h3>Sales Records System</h3>
|
||||
<p style="color: var(--text-secondary);">No sales recorded yet. Once sales are made, they will appear here along with installment tracking.</p>
|
||||
</div>
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
86
admin/users.php
Normal file
86
admin/users.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
require_once 'includes/header.php';
|
||||
|
||||
$pdo = db();
|
||||
|
||||
if (isset($_POST['delete_user'])) {
|
||||
$id = $_POST['user_id'];
|
||||
if ($id != $_SESSION['user_id']) {
|
||||
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
echo "<div style='padding: 1rem; background: #f44336; color: white;'>User Deleted</div>";
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['update_role'])) {
|
||||
$id = $_POST['user_id'];
|
||||
$role = $_POST['role'];
|
||||
if ($id != $_SESSION['user_id']) { // Prevent changing own role to something lower accidentally
|
||||
$stmt = $pdo->prepare("UPDATE users SET role = ? WHERE id = ?");
|
||||
$stmt->execute([$role, $id]);
|
||||
echo "<div style='padding: 1rem; background: #4caf50; color: white;'>User Role Updated</div>";
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = $pdo->query("SELECT * FROM users ORDER BY created_at DESC");
|
||||
$users = $stmt->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>User Management</h1>
|
||||
</div>
|
||||
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Username</th>
|
||||
<th>Role</th>
|
||||
<th>Joined</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($users as $user): ?>
|
||||
<tr>
|
||||
<td>#<?php echo $user['id']; ?></td>
|
||||
<td>
|
||||
<?php echo htmlspecialchars($user['username']); ?><br>
|
||||
<small style="color:var(--text-secondary);"><?php echo htmlspecialchars($user['email'] ?? ''); ?></small>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($user['id'] == $_SESSION['user_id']): ?>
|
||||
<span class="badge badge-admin"><?php echo htmlspecialchars($user['role']); ?></span>
|
||||
<?php else: ?>
|
||||
<form method="POST" style="display:inline;">
|
||||
<input type="hidden" name="user_id" value="<?php echo $user['id']; ?>">
|
||||
<select name="role" onchange="this.form.submit()" style="padding:0.2rem; border-radius:4px; background:var(--bg-color); color:var(--text-primary); border:1px solid var(--border-color);">
|
||||
<?php
|
||||
$roles = ['Guest','Customer','Dealer','Employee','Manager','Admin','Super Admin'];
|
||||
foreach ($roles as $r) {
|
||||
$selected = ($user['role'] === $r) ? 'selected' : '';
|
||||
echo "<option value='$r' $selected>$r</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input type="hidden" name="update_role" value="1">
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo date('M j, Y', strtotime($user['created_at'])); ?></td>
|
||||
<td>
|
||||
<?php if ($user['id'] != $_SESSION['user_id']): ?>
|
||||
<form method="POST" onsubmit="return confirm('Are you sure?');" style="display: inline;">
|
||||
<input type="hidden" name="user_id" value="<?php echo $user['id']; ?>">
|
||||
<button type="submit" name="delete_user" class="btn-sm btn-danger">Delete</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
||||
63
buyer/index.php
Normal file
63
buyer/index.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../includes/role_middleware.php';
|
||||
requireRole(['Customer', 'Buyer']);
|
||||
|
||||
require_once __DIR__ . '/../includes/header.php';
|
||||
$pdo = db();
|
||||
$userId = $_SESSION['user_id'];
|
||||
|
||||
// Get Installments
|
||||
$installments = $pdo->prepare("
|
||||
SELECT i.*, c.brand, c.model
|
||||
FROM installments i
|
||||
JOIN sales s ON i.sale_id = s.id
|
||||
JOIN cars c ON s.car_id = c.id
|
||||
WHERE s.buyer_id = ?
|
||||
");
|
||||
$installments->execute([$userId]);
|
||||
$myInstallments = $installments->fetchAll();
|
||||
?>
|
||||
|
||||
<div style="padding: 2rem;">
|
||||
<div class="page-header">
|
||||
<h1>My Dashboard</h1>
|
||||
<span>Welcome, <?php echo htmlspecialchars($_SESSION['username']); ?></span>
|
||||
</div>
|
||||
|
||||
<div style="background: var(--card-bg); padding: 2rem; border-radius: var(--border-radius); border: 1px solid var(--border-color); margin-bottom: 2rem;">
|
||||
<h3 style="color: var(--accent-color); margin-bottom: 1rem;">My Installment Plans</h3>
|
||||
<?php if ($myInstallments): ?>
|
||||
<table class="data-table" style="width: 100%; border-collapse: collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align: left; padding: 0.5rem;">Vehicle</th>
|
||||
<th style="text-align: left; padding: 0.5rem;">Total</th>
|
||||
<th style="text-align: left; padding: 0.5rem;">Paid</th>
|
||||
<th style="text-align: left; padding: 0.5rem;">Monthly</th>
|
||||
<th style="text-align: left; padding: 0.5rem;">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($myInstallments as $inst): ?>
|
||||
<tr>
|
||||
<td style="padding: 0.5rem; border-bottom: 1px solid var(--border-color);"><?php echo htmlspecialchars($inst['brand'] . ' ' . $inst['model']); ?></td>
|
||||
<td style="padding: 0.5rem; border-bottom: 1px solid var(--border-color);">$<?php echo number_format($inst['total_amount'], 2); ?></td>
|
||||
<td style="padding: 0.5rem; border-bottom: 1px solid var(--border-color);">$<?php echo number_format($inst['paid_amount'], 2); ?></td>
|
||||
<td style="padding: 0.5rem; border-bottom: 1px solid var(--border-color);">$<?php echo number_format($inst['monthly_payment'], 2); ?></td>
|
||||
<td style="padding: 0.5rem; border-bottom: 1px solid var(--border-color);">
|
||||
<span style="padding: 0.2rem 0.5rem; border-radius: 4px; background: rgba(255, 255, 255, 0.1);">
|
||||
<?php echo htmlspecialchars($inst['status']); ?>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<p style="color: var(--text-secondary);">You have no active installment plans.</p>
|
||||
<a href="/marketplace.php" class="btn-sm btn-primary" style="margin-top: 1rem; display: inline-block;">Browse Cars</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once __DIR__ . '/../includes/footer.php'; ?>
|
||||
32
check_db.php
Normal file
32
check_db.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
require_once 'db/config.php';
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE 'users'");
|
||||
if ($stmt->rowCount() > 0) {
|
||||
echo "Table 'users' exists.\n";
|
||||
} else {
|
||||
echo "Table 'users' does not exist.\n";
|
||||
// Create table
|
||||
$sql = "CREATE TABLE `users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(100) NOT NULL,
|
||||
`email` varchar(100) NOT NULL UNIQUE,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`role` enum('Guest','Customer','Dealer','Employee','Manager','Admin','Super Admin') DEFAULT 'Customer',
|
||||
`created_at` timestamp NULL DEFAULT current_timestamp(),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `username` (`username`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
|
||||
$pdo->exec($sql);
|
||||
echo "Table 'users' created.\n";
|
||||
|
||||
// Seed admin user
|
||||
$password = password_hash('admin123', PASSWORD_DEFAULT);
|
||||
$stmt = $pdo->prepare("INSERT INTO users (username, email, password, role) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute(['admin', 'admin@example.com', $password, 'Admin']);
|
||||
echo "Admin user created (user: admin, pass: admin123).\n";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo "Error: " . $e->getMessage();
|
||||
}
|
||||
72
db/migrations/001_enterprise_schema.sql
Normal file
72
db/migrations/001_enterprise_schema.sql
Normal file
@ -0,0 +1,72 @@
|
||||
-- Branches Table
|
||||
CREATE TABLE IF NOT EXISTS `branches` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`location` VARCHAR(255) NOT NULL,
|
||||
`phone` VARCHAR(20),
|
||||
`email` VARCHAR(100),
|
||||
`manager_id` INT,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Car Images Table (Multiple Images)
|
||||
CREATE TABLE IF NOT EXISTS `car_images` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`car_id` INT NOT NULL,
|
||||
`image_url` VARCHAR(255) NOT NULL,
|
||||
`is_primary` TINYINT(1) DEFAULT 0,
|
||||
FOREIGN KEY (`car_id`) REFERENCES `cars`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Sales Table
|
||||
CREATE TABLE IF NOT EXISTS `sales` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`car_id` INT NOT NULL,
|
||||
`buyer_id` INT NOT NULL,
|
||||
`seller_id` INT, -- Dealer or Admin who sold it
|
||||
`sale_date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
`final_price` DECIMAL(15, 2) NOT NULL,
|
||||
`payment_method` ENUM('Cash', 'Installment') DEFAULT 'Cash',
|
||||
`status` ENUM('Pending', 'Completed', 'Cancelled') DEFAULT 'Pending',
|
||||
FOREIGN KEY (`car_id`) REFERENCES `cars`(`id`),
|
||||
FOREIGN KEY (`buyer_id`) REFERENCES `users`(`id`)
|
||||
);
|
||||
|
||||
-- Installments Table
|
||||
CREATE TABLE IF NOT EXISTS `installments` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`sale_id` INT NOT NULL,
|
||||
`total_amount` DECIMAL(15, 2) NOT NULL,
|
||||
`paid_amount` DECIMAL(15, 2) DEFAULT 0.00,
|
||||
`monthly_payment` DECIMAL(15, 2) NOT NULL,
|
||||
`due_date` DATE,
|
||||
`status` ENUM('Active', 'Completed', 'Defaulted') DEFAULT 'Active',
|
||||
FOREIGN KEY (`sale_id`) REFERENCES `sales`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Activity Logs
|
||||
CREATE TABLE IF NOT EXISTS `activity_logs` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`user_id` INT,
|
||||
`action` VARCHAR(255) NOT NULL,
|
||||
`details` TEXT,
|
||||
`ip_address` VARCHAR(45),
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Notifications
|
||||
CREATE TABLE IF NOT EXISTS `notifications` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`user_id` INT NOT NULL,
|
||||
`message` TEXT NOT NULL,
|
||||
`is_read` TINYINT(1) DEFAULT 0,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Update Cars Table
|
||||
ALTER TABLE `cars` ADD COLUMN IF NOT EXISTS `dealer_id` INT DEFAULT NULL;
|
||||
ALTER TABLE `cars` ADD COLUMN IF NOT EXISTS `installment_available` TINYINT(1) DEFAULT 0;
|
||||
|
||||
-- Update Users Table (Ensure role column is correct - strictly speaking it already exists but this is safe)
|
||||
-- ALTER TABLE `users` MODIFY COLUMN `role` ENUM('Guest','Customer','Dealer','Employee','Manager','Admin','Super Admin') DEFAULT 'Customer';
|
||||
44
dealer/index.php
Normal file
44
dealer/index.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../includes/role_middleware.php';
|
||||
requireRole('Dealer');
|
||||
|
||||
require_once __DIR__ . '/../includes/header.php';
|
||||
$pdo = db();
|
||||
$dealerId = $_SESSION['user_id'];
|
||||
|
||||
// Stats
|
||||
$myCars = $pdo->prepare("SELECT COUNT(*) FROM cars WHERE dealer_id = ?");
|
||||
$myCars->execute([$dealerId]);
|
||||
$myCarsCount = $myCars->fetchColumn();
|
||||
|
||||
$mySales = $pdo->prepare("SELECT COUNT(*) FROM sales WHERE seller_id = ?");
|
||||
$mySales->execute([$dealerId]);
|
||||
$mySalesCount = $mySales->fetchColumn();
|
||||
?>
|
||||
|
||||
<div style="padding: 2rem;">
|
||||
<div class="page-header">
|
||||
<h1>Dealer Dashboard</h1>
|
||||
<span>Welcome, <?php echo htmlspecialchars($_SESSION['username']); ?></span>
|
||||
</div>
|
||||
|
||||
<div class="card-grid" style="grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 2rem;">
|
||||
<div class="stat-card" style="padding: 1.5rem; background: var(--card-bg); border: 1px solid var(--border-color); border-radius: var(--border-radius);">
|
||||
<div style="font-size: 2rem; font-weight: bold;"><?php echo $myCarsCount; ?></div>
|
||||
<div style="color: var(--text-secondary);">My Inventory</div>
|
||||
</div>
|
||||
<div class="stat-card" style="padding: 1.5rem; background: var(--card-bg); border: 1px solid var(--border-color); border-radius: var(--border-radius);">
|
||||
<div style="font-size: 2rem; font-weight: bold;"><?php echo $mySalesCount; ?></div>
|
||||
<div style="color: var(--text-secondary);">My Sales</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background: var(--card-bg); padding: 2rem; border-radius: var(--border-radius); border: 1px solid var(--border-color);">
|
||||
<h3>Manage Inventory</h3>
|
||||
<p>You can add new cars to your branch inventory here.</p>
|
||||
<a href="/admin/cars.php" class="btn-sm btn-primary">Go to Inventory Management</a>
|
||||
<!-- Ideally this would point to a dealer-specific car management page, but reusing admin/cars.php with permission checks is a good MVP step if implemented, otherwise a dedicated page is better. For now, let's keep it simple. -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once __DIR__ . '/../includes/footer.php'; ?>
|
||||
51
includes/auth.php
Normal file
51
includes/auth.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
|
||||
function isLoggedIn() {
|
||||
return isset($_SESSION['user_id']);
|
||||
}
|
||||
|
||||
function isAdmin() {
|
||||
return isLoggedIn() && (
|
||||
$_SESSION['role'] === 'Admin' ||
|
||||
$_SESSION['role'] === 'Super Admin' ||
|
||||
$_SESSION['role'] === 'Manager'
|
||||
);
|
||||
}
|
||||
|
||||
function requireLogin() {
|
||||
if (!isLoggedIn()) {
|
||||
header('Location: /login.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function requireAdmin() {
|
||||
requireLogin();
|
||||
if (!isAdmin()) {
|
||||
header('Location: /index.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function login($username, $password) {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? OR email = ?");
|
||||
$stmt->execute([$username, $username]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
if ($user && password_verify($password, $user['password'])) {
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['username'] = $user['username'];
|
||||
$_SESSION['role'] = $user['role'];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function logout() {
|
||||
session_destroy();
|
||||
header('Location: /login.php');
|
||||
exit;
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
require_once __DIR__ . '/auth.php'; // Ensure session is started and auth helpers are available
|
||||
|
||||
$projectTitle = "AFG_CARS - Supreme Automotive";
|
||||
$projectDescription = "Elite car dealership management system. Premium marketplace, installments, and branch management.";
|
||||
@ -28,7 +29,14 @@ $current_page = basename($_SERVER['PHP_SELF']);
|
||||
<li><a href="work.php" <?= $current_page == 'work.php' ? 'class="active"' : '' ?>>Work</a></li>
|
||||
<li><a href="about.php" <?= $current_page == 'about.php' ? 'class="active"' : '' ?>>About</a></li>
|
||||
<li><a href="contact.php" <?= $current_page == 'contact.php' ? 'class="active"' : '' ?>>Contact Us</a></li>
|
||||
<li><a href="setup.php" class="admin-link"><i class="fas fa-user-shield"></i> Admin</a></li>
|
||||
<?php if (isLoggedIn()): ?>
|
||||
<?php if (isAdmin()): ?>
|
||||
<li><a href="/admin/index.php" class="admin-link"><i class="fas fa-chart-line"></i> Dashboard</a></li>
|
||||
<?php endif; ?>
|
||||
<li><a href="/logout.php" class="admin-link"><i class="fas fa-sign-out-alt"></i> Logout</a></li>
|
||||
<?php else: ?>
|
||||
<li><a href="/login.php" class="admin-link"><i class="fas fa-user"></i> Login</a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
43
includes/role_middleware.php
Normal file
43
includes/role_middleware.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/auth.php';
|
||||
|
||||
function requireRole($allowed_roles) {
|
||||
if (!is_array($allowed_roles)) {
|
||||
$allowed_roles = [$allowed_roles];
|
||||
}
|
||||
|
||||
if (!isLoggedIn()) {
|
||||
header('Location: /login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_role = $_SESSION['role'] ?? 'Guest';
|
||||
|
||||
if (!in_array($user_role, $allowed_roles)) {
|
||||
// Redirect based on their actual role or to home
|
||||
switch ($user_role) {
|
||||
case 'Admin':
|
||||
case 'Super Admin':
|
||||
header('Location: /admin/index.php');
|
||||
break;
|
||||
case 'Dealer':
|
||||
header('Location: /dealer/index.php');
|
||||
break;
|
||||
case 'Customer':
|
||||
case 'Buyer': // Assuming 'Buyer' is the role name from prompt
|
||||
header('Location: /buyer/index.php');
|
||||
break;
|
||||
default:
|
||||
header('Location: /index.php');
|
||||
}
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function hasRole($role) {
|
||||
return isset($_SESSION['role']) && $_SESSION['role'] === $role;
|
||||
}
|
||||
|
||||
function isSuperAdmin() {
|
||||
return hasRole('Super Admin');
|
||||
}
|
||||
124
login.php
Normal file
124
login.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
require_once 'includes/auth.php';
|
||||
|
||||
$error = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$username = $_POST['username'] ?? '';
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
if (login($username, $password)) {
|
||||
$role = $_SESSION['role'] ?? 'Customer';
|
||||
|
||||
// Log login attempt
|
||||
try {
|
||||
$pdo = db();
|
||||
$pdo->prepare("INSERT INTO activity_logs (user_id, action, ip_address) VALUES (?, 'Login', ?)")
|
||||
->execute([$_SESSION['user_id'], $_SERVER['REMOTE_ADDR']]);
|
||||
} catch (Exception $e) { /* Ignore logging error */ }
|
||||
|
||||
switch ($role) {
|
||||
case 'Admin':
|
||||
case 'Super Admin':
|
||||
case 'Manager':
|
||||
header('Location: /admin/index.php');
|
||||
break;
|
||||
case 'Dealer':
|
||||
header('Location: /dealer/index.php');
|
||||
break;
|
||||
case 'Customer':
|
||||
case 'Buyer':
|
||||
header('Location: /buyer/index.php');
|
||||
break;
|
||||
default:
|
||||
header('Location: /index.php');
|
||||
}
|
||||
exit;
|
||||
} else {
|
||||
$error = "Invalid username or password";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login - Car Market</title>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
<style>
|
||||
body { display: flex; align-items: center; justify-content: center; min-height: 100vh; }
|
||||
.login-container {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
padding: 2.5rem;
|
||||
background: var(--card-bg);
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
.form-group { margin-bottom: 1.5rem; }
|
||||
label { display: block; margin-bottom: 0.5rem; color: var(--text-secondary); font-size: 0.9rem; }
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 0.8rem;
|
||||
background: var(--bg-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
color: var(--text-primary);
|
||||
font-size: 1rem;
|
||||
}
|
||||
input:focus { outline: none; border-color: var(--accent-color); }
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 0.8rem;
|
||||
background: var(--accent-color);
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
color: var(--bg-color);
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
button:hover { background: var(--accent-hover); transform: translateY(-1px); }
|
||||
.error {
|
||||
background: rgba(255, 68, 68, 0.1);
|
||||
color: #ff4444;
|
||||
padding: 0.8rem;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 1.5rem;
|
||||
text-align: center;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
h2 { text-align: center; margin-bottom: 2rem; color: var(--accent-color); font-size: 1.8rem; }
|
||||
.links { text-align: center; margin-top: 1.5rem; font-size: 0.9rem; color: var(--text-secondary); }
|
||||
.links a { color: var(--accent-color); text-decoration: none; font-weight: 600; }
|
||||
.links a:hover { text-decoration: underline; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-container">
|
||||
<h2>Welcome Back</h2>
|
||||
<?php if ($error): ?>
|
||||
<div class="error"><?php echo htmlspecialchars($error); ?></div>
|
||||
<?php endif; ?>
|
||||
<form method="POST">
|
||||
<div class="form-group">
|
||||
<label>Username or Email</label>
|
||||
<input type="text" name="username" required placeholder="Enter your username">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input type="password" name="password" required placeholder="Enter your password">
|
||||
</div>
|
||||
<button type="submit">Sign In</button>
|
||||
<div class="links">
|
||||
Don't have an account? <a href="register.php">Create Account</a><br>
|
||||
<a href="/index.php" style="font-size: 0.8rem; opacity: 0.7;">Back to Home</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
3
logout.php
Normal file
3
logout.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require_once 'includes/auth.php';
|
||||
logout();
|
||||
140
register.php
Normal file
140
register.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
require_once 'includes/auth.php';
|
||||
|
||||
$error = '';
|
||||
$success = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$username = $_POST['username'] ?? '';
|
||||
$email = $_POST['email'] ?? '';
|
||||
$password = $_POST['password'] ?? '';
|
||||
$confirm_password = $_POST['confirm_password'] ?? '';
|
||||
|
||||
if ($password !== $confirm_password) {
|
||||
$error = "Passwords do not match";
|
||||
} else {
|
||||
$pdo = db();
|
||||
// Check if username exists
|
||||
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ? OR email = ?");
|
||||
$stmt->execute([$username, $email]);
|
||||
if ($stmt->fetch()) {
|
||||
$error = "Username or email already exists";
|
||||
} else {
|
||||
// Register user
|
||||
$hash = password_hash($password, PASSWORD_DEFAULT);
|
||||
$stmt = $pdo->prepare("INSERT INTO users (username, email, password, role) VALUES (?, ?, ?, 'Customer')");
|
||||
try {
|
||||
$stmt->execute([$username, $email, $hash]);
|
||||
$success = "Registration successful!";
|
||||
} catch (PDOException $e) {
|
||||
$error = "Registration failed: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Register - Car Market</title>
|
||||
<link rel="stylesheet" href="assets/css/style.css">
|
||||
<style>
|
||||
body { display: flex; align-items: center; justify-content: center; min-height: 100vh; }
|
||||
.register-container {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
padding: 2.5rem;
|
||||
background: var(--card-bg);
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
.form-group { margin-bottom: 1.2rem; }
|
||||
label { display: block; margin-bottom: 0.4rem; color: var(--text-secondary); font-size: 0.9rem; }
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 0.8rem;
|
||||
background: var(--bg-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
color: var(--text-primary);
|
||||
font-size: 1rem;
|
||||
}
|
||||
input:focus { outline: none; border-color: var(--accent-color); }
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 0.8rem;
|
||||
background: var(--accent-color);
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
color: var(--bg-color);
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
button:hover { background: var(--accent-hover); transform: translateY(-1px); }
|
||||
.error {
|
||||
background: rgba(255, 68, 68, 0.1);
|
||||
color: #ff4444;
|
||||
padding: 0.8rem;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 1.5rem;
|
||||
text-align: center;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.success {
|
||||
background: rgba(0, 200, 81, 0.1);
|
||||
color: #00C851;
|
||||
padding: 0.8rem;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 1.5rem;
|
||||
text-align: center;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
h2 { text-align: center; margin-bottom: 2rem; color: var(--accent-color); font-size: 1.8rem; }
|
||||
.links { text-align: center; margin-top: 1.5rem; font-size: 0.9rem; color: var(--text-secondary); }
|
||||
.links a { color: var(--accent-color); text-decoration: none; font-weight: 600; }
|
||||
.links a:hover { text-decoration: underline; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="register-container">
|
||||
<h2>Create Account</h2>
|
||||
<?php if ($error): ?>
|
||||
<div class="error"><?php echo htmlspecialchars($error); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($success): ?>
|
||||
<div class="success"><?php echo htmlspecialchars($success); ?></div>
|
||||
<p style="text-align: center;"><a href="login.php" class="btn" style="color: var(--accent-color);">Proceed to Login</a></p>
|
||||
<?php else: ?>
|
||||
<form method="POST">
|
||||
<div class="form-group">
|
||||
<label>Username</label>
|
||||
<input type="text" name="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Email</label>
|
||||
<input type="email" name="email" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input type="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Confirm Password</label>
|
||||
<input type="password" name="confirm_password" required>
|
||||
</div>
|
||||
<button type="submit">Sign Up</button>
|
||||
<div class="links">
|
||||
Already have an account? <a href="login.php">Sign In</a><br>
|
||||
<a href="/index.php" style="font-size: 0.8rem; opacity: 0.7;">Back to Home</a>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user