183 lines
9.8 KiB
PHP
183 lines
9.8 KiB
PHP
<?php
|
|
session_start();
|
|
require_once __DIR__ . '/db/config.php';
|
|
|
|
use App\Repositories\PurchaseRepository;
|
|
use App\Repositories\CarRepository;
|
|
|
|
if (!isset($_SESSION['user_id']) || ($_SESSION['role'] ?? '') !== 'admin') {
|
|
header('Location: login.php');
|
|
exit;
|
|
}
|
|
|
|
$pdo = db();
|
|
$message = '';
|
|
$purchaseRepo = new PurchaseRepository();
|
|
$carRepo = new CarRepository();
|
|
|
|
if (isset($_POST['action']) && isset($_POST['purchase_id'])) {
|
|
$purchase_id = $_POST['purchase_id'];
|
|
$action = $_POST['action'];
|
|
|
|
try {
|
|
$pdo->beginTransaction();
|
|
|
|
if ($action === 'approve') {
|
|
// Admin verifies -> move to held_in_escrow
|
|
$stmt = $pdo->prepare("UPDATE purchases SET status = 'paid', escrow_status = 'held_in_escrow' WHERE id = ?");
|
|
$stmt->execute([$purchase_id]);
|
|
|
|
// Get car ID and mark as sold
|
|
$stmt = $pdo->prepare("SELECT car_id FROM purchases WHERE id = ?");
|
|
$stmt->execute([$purchase_id]);
|
|
$car_id = $stmt->fetchColumn();
|
|
$carRepo->markAsSold($car_id);
|
|
|
|
$message = "Transaction verified. Funds are now held in Escrow.";
|
|
} elseif ($action === 'release') {
|
|
// Admin releases payment to seller
|
|
$stmt = $pdo->prepare("UPDATE purchases SET status = 'completed', escrow_status = 'released' WHERE id = ?");
|
|
$stmt->execute([$purchase_id]);
|
|
$message = "Payment released to seller. Transaction completed.";
|
|
} elseif ($action === 'reject') {
|
|
$stmt = $pdo->prepare("UPDATE purchases SET status = 'failed', escrow_status = 'cancelled' WHERE id = ?");
|
|
$stmt->execute([$purchase_id]);
|
|
$message = "Transaction rejected and cancelled.";
|
|
}
|
|
|
|
$pdo->commit();
|
|
} catch (Exception $e) {
|
|
$pdo->rollBack();
|
|
$message = "Error: " . $e->getMessage();
|
|
}
|
|
}
|
|
|
|
// Fetch all purchases with car and user info
|
|
$stmt = $pdo->query("
|
|
SELECT p.*, c.brand, c.model, c.year, u.name as buyer_user_name, ci.image_path
|
|
FROM purchases p
|
|
JOIN cars c ON p.car_id = c.id
|
|
JOIN users u ON p.user_id = u.id
|
|
LEFT JOIN car_images ci ON c.id = ci.car_id AND ci.is_main = 1
|
|
ORDER BY p.created_at DESC
|
|
");
|
|
$purchases = $stmt->fetchAll();
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Enterprise Transactions | Admin</title>
|
|
<link rel="stylesheet" href="assets/css/fonts.css">
|
|
<link rel="stylesheet" href="assets/css/style.css?v=<?= time() ?>">
|
|
</head>
|
|
<body>
|
|
<div class="dashboard-container">
|
|
<!-- Sidebar -->
|
|
<aside class="sidebar">
|
|
<a href="index.php" class="sidebar-brand">AFGCARS ENT</a>
|
|
<ul class="sidebar-menu">
|
|
<li><a href="admin_dashboard.php"><span>Dashboard</span></a></li>
|
|
<li><a href="admin_cars.php"><span>Manage Cars</span></a></li>
|
|
<li><a href="admin_purchases.php" class="active"><span>Transactions</span></a></li>
|
|
<li><a href="admin_users.php"><span>Users</span></a></li>
|
|
<li><a href="admin_messages.php"><span>Messages</span></a></li>
|
|
</ul>
|
|
<div class="sidebar-footer">
|
|
<a href="logout.php" class="btn btn-danger btn-sm" style="width: 100%;">Logout</a>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Main Content -->
|
|
<main class="main-content">
|
|
<header class="mb-3">
|
|
<span class="badge badge-primary mb-1">ENTERPRISE MODE</span>
|
|
<h1 class="fw-bold" style="font-size: 2.5rem;">Transaction Engine</h1>
|
|
<p class="text-secondary">Manage Escrow, verify SHA256 tokens, and release payments for secure car marketplace sales.</p>
|
|
</header>
|
|
|
|
<?php if ($message): ?>
|
|
<div class="alert alert-success">
|
|
<span class="text-gold">✓</span> <?= $message ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="glass" style="padding: 2.5rem;">
|
|
<div class="table-container">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Transaction Ref</th>
|
|
<th>Vehicle</th>
|
|
<th>Escrow Status</th>
|
|
<th>Cost Breakdown</th>
|
|
<th>Verification</th>
|
|
<th>Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($purchases as $p): ?>
|
|
<tr>
|
|
<td>
|
|
<div class="fw-bold"><?= htmlspecialchars($p['reference_number'] ?: 'LEGACY-'.$p['id']) ?></div>
|
|
<div class="text-sm text-secondary" style="font-family: monospace; font-size: 0.7rem;"><?= htmlspecialchars($p['transaction_id'] ?: 'N/A') ?></div>
|
|
<div class="text-sm text-secondary"><?= date('M d, H:i', strtotime($p['created_at'])) ?></div>
|
|
</td>
|
|
<td>
|
|
<div style="display: flex; align-items: center; gap: 1.2rem;">
|
|
<img src="<?= htmlspecialchars($p['image_path'] ?: 'assets/images/placeholder-car.jpg') ?>" style="width: 70px; height: 50px; object-fit: cover; border-radius: 8px;">
|
|
<div>
|
|
<div class="fw-bold text-sm"><?= htmlspecialchars($p['brand']) ?></div>
|
|
<div class="text-sm text-secondary"><?= $p['year'] ?></div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div class="badge badge-<?= $p['escrow_status'] === 'released' ? 'success' : ($p['escrow_status'] === 'cancelled' ? 'danger' : 'warning') ?>" style="display: block; text-align: center; margin-bottom: 0.3rem;">
|
|
<?= strtoupper(str_replace('_', ' ', $p['escrow_status'] ?: 'awaiting_verification')) ?>
|
|
</div>
|
|
<span class="text-sm text-secondary">Status: <?= ucfirst($p['status']) ?></span>
|
|
</td>
|
|
<td>
|
|
<div class="text-sm">Base: <span class="text-white">$<?= number_format($p['base_price'], 0) ?></span></div>
|
|
<div class="text-sm">Fee: <span class="text-gold">$<?= number_format($p['marketplace_fee'], 0) ?></span></div>
|
|
<div class="text-gold fw-bold" style="font-size: 1.1rem; border-top: 1px solid rgba(255,255,255,0.1); margin-top: 0.3rem; padding-top: 0.3rem;">Total: $<?= number_format($p['total_amount'] ?: $p['base_price'], 0) ?></div>
|
|
</td>
|
|
<td>
|
|
<div class="text-sm fw-bold"><?= htmlspecialchars($p['buyer_name']) ?></div>
|
|
<div class="text-sm text-secondary">Bank ID: <span class="text-white"><?= htmlspecialchars($p['bank_id'] ?: 'N/A') ?></span></div>
|
|
<div class="text-sm text-secondary" title="<?= htmlspecialchars($p['verification_token']) ?>">Token: <span style="font-family: monospace; font-size: 0.6rem;"><?= substr($p['verification_token'], 0, 12) ?>...</span></div>
|
|
</td>
|
|
<td>
|
|
<?php if ($p['escrow_status'] === 'awaiting_verification' || !$p['escrow_status']): ?>
|
|
<div style="display: flex; gap: 0.8rem; flex-direction: column;">
|
|
<form method="POST">
|
|
<input type="hidden" name="purchase_id" value="<?= $p['id'] ?>">
|
|
<button type="submit" name="action" value="approve" class="btn btn-primary btn-sm" style="width: 100%;">Verify & Hold</button>
|
|
</form>
|
|
<form method="POST">
|
|
<input type="hidden" name="purchase_id" value="<?= $p['id'] ?>">
|
|
<button type="submit" name="action" value="reject" class="text-sm fw-bold" style="background: none; border: none; cursor: pointer; color: var(--danger); width: 100%;">Reject</button>
|
|
</form>
|
|
</div>
|
|
<?php elseif ($p['escrow_status'] === 'held_in_escrow'): ?>
|
|
<form method="POST">
|
|
<input type="hidden" name="purchase_id" value="<?= $p['id'] ?>">
|
|
<button type="submit" name="action" value="release" class="btn btn-success btn-sm" style="width: 100%; background-color: #2ed573;">Release Funds</button>
|
|
</form>
|
|
<?php else: ?>
|
|
<span class="text-secondary text-sm fw-bold">COMPLETED</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</body>
|
|
</html>
|