219 lines
15 KiB
PHP
219 lines
15 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/includes/layout.php';
|
|
|
|
ensure_schema();
|
|
|
|
$errors = [];
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'update_status') {
|
|
$shipmentId = (int) ($_POST['shipment_id'] ?? 0);
|
|
$status = $_POST['status'] ?? 'posted';
|
|
|
|
$allowed = ['posted', 'offered', 'confirmed', 'in_transit', 'delivered'];
|
|
if ($shipmentId <= 0 || !in_array($status, $allowed, true)) {
|
|
$errors[] = t('error_invalid');
|
|
} else {
|
|
$stmt = db()->prepare("UPDATE shipments SET status = :status WHERE id = :id");
|
|
$stmt->execute([':status' => $status, ':id' => $shipmentId]);
|
|
set_flash('success', t('success_status'));
|
|
header('Location: ' . url_with_lang('admin_dashboard.php'));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
$shipments = [];
|
|
try {
|
|
$stmt = db()->query("SELECT * FROM shipments ORDER BY created_at DESC LIMIT 30");
|
|
$shipments = $stmt->fetchAll();
|
|
} catch (Throwable $e) {
|
|
$shipments = [];
|
|
}
|
|
|
|
$stats = [
|
|
'total_shipments' => 0,
|
|
'active_shipments' => 0,
|
|
'total_shippers' => 0,
|
|
'total_truck_owners' => 0,
|
|
];
|
|
|
|
try {
|
|
$stats['total_shipments'] = (int)db()->query("SELECT COUNT(*) FROM shipments")->fetchColumn();
|
|
$stats['active_shipments'] = (int)db()->query("SELECT COUNT(*) FROM shipments WHERE status != 'delivered'")->fetchColumn();
|
|
$stats['total_shippers'] = (int)db()->query("SELECT COUNT(*) FROM users WHERE role = 'shipper'")->fetchColumn();
|
|
$stats['total_truck_owners'] = (int)db()->query("SELECT COUNT(*) FROM users WHERE role = 'truck_owner'")->fetchColumn();
|
|
} catch (Throwable $e) {}
|
|
|
|
$flash = get_flash();
|
|
|
|
render_header(t('admin_dashboard'), 'admin');
|
|
?>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-lg-3">
|
|
<?php render_admin_sidebar('dashboard'); ?>
|
|
</div>
|
|
<div class="col-lg-9">
|
|
<div class="page-intro mb-4">
|
|
<h1 class="section-title mb-1"><?= e(t('admin_dashboard')) ?></h1>
|
|
<p class="muted mb-0">Overview of your platform's performance and recent activity.</p>
|
|
</div>
|
|
|
|
<!-- Stats Row -->
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-3">
|
|
<div class="panel p-4 text-center h-100 shadow-sm border-0 rounded-4 position-relative overflow-hidden" style="background: linear-gradient(135deg, #ffffff, #f8f9fa);">
|
|
<div class="position-absolute opacity-10" style="inset-inline-end: 10px; top: 15px;"><i class="bi bi-box-seam" style="font-size: 3.5rem;"></i></div>
|
|
<div class="text-primary mb-2 position-relative"><i class="bi bi-box-seam fs-2"></i></div>
|
|
<h3 class="h2 mb-0 fw-bold position-relative"><?= $stats['total_shipments'] ?></h3>
|
|
<p class="text-muted small text-uppercase mb-0 fw-bold position-relative" style="letter-spacing: 0.5px;">Total Shipments</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="panel p-4 text-center h-100 shadow-sm border-0 rounded-4 position-relative overflow-hidden" style="background: linear-gradient(135deg, #ffffff, #f8f9fa);">
|
|
<div class="position-absolute opacity-10" style="inset-inline-end: 10px; top: 15px;"><i class="bi bi-truck" style="font-size: 3.5rem;"></i></div>
|
|
<div class="text-warning mb-2 position-relative"><i class="bi bi-truck fs-2"></i></div>
|
|
<h3 class="h2 mb-0 fw-bold position-relative"><?= $stats['active_shipments'] ?></h3>
|
|
<p class="text-muted small text-uppercase mb-0 fw-bold position-relative" style="letter-spacing: 0.5px;">Active Shipments</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="panel p-4 text-center h-100 shadow-sm border-0 rounded-4 position-relative overflow-hidden" style="background: linear-gradient(135deg, #ffffff, #f8f9fa);">
|
|
<div class="position-absolute opacity-10" style="inset-inline-end: 10px; top: 15px;"><i class="bi bi-people" style="font-size: 3.5rem;"></i></div>
|
|
<div class="text-success mb-2 position-relative"><i class="bi bi-people fs-2"></i></div>
|
|
<h3 class="h2 mb-0 fw-bold position-relative"><?= $stats['total_shippers'] ?></h3>
|
|
<p class="text-muted small text-uppercase mb-0 fw-bold position-relative" style="letter-spacing: 0.5px;">Total Shippers</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="panel p-4 text-center h-100 shadow-sm border-0 rounded-4 position-relative overflow-hidden" style="background: linear-gradient(135deg, #ffffff, #f8f9fa);">
|
|
<div class="position-absolute opacity-10" style="inset-inline-end: 10px; top: 15px;"><i class="bi bi-person-vcard" style="font-size: 3.5rem;"></i></div>
|
|
<div class="text-info mb-2 position-relative"><i class="bi bi-person-vcard fs-2"></i></div>
|
|
<h3 class="h2 mb-0 fw-bold position-relative"><?= $stats['total_truck_owners'] ?></h3>
|
|
<p class="text-muted small text-uppercase mb-0 fw-bold position-relative" style="letter-spacing: 0.5px;">Truck Owners</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<!-- Main Content: Shipments -->
|
|
<div class="col-lg-8">
|
|
<div class="panel p-4 shadow-sm border-0 h-100 rounded-4 d-flex flex-column">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2 class="h5 mb-0 fw-bold"><i class="bi bi-clock-history text-muted me-2"></i>Recent Shipments</h2>
|
|
<span class="badge bg-light text-dark border"><?= e(count($shipments)) ?> shown</span>
|
|
</div>
|
|
<?php if ($flash): ?>
|
|
<div class="alert alert-success" data-auto-dismiss="true"><?= e($flash['message']) ?></div>
|
|
<?php endif; ?>
|
|
<?php if ($errors): ?>
|
|
<div class="alert alert-warning"><?= e(implode(' ', $errors)) ?></div>
|
|
<?php endif; ?>
|
|
<?php if (!$shipments): ?>
|
|
<div class="text-center p-5 text-muted flex-grow-1 d-flex flex-column justify-content-center">
|
|
<i class="bi bi-inbox fs-1 mb-3 d-block opacity-50"></i>
|
|
<p class="mb-0"><?= e(t('no_shipments')) ?></p>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="table-responsive flex-grow-1">
|
|
<table class="table align-middle mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-uppercase small text-muted border-top-0">Shipment</th>
|
|
<th class="text-uppercase small text-muted border-top-0">Route</th>
|
|
<th class="text-uppercase small text-muted border-top-0"><?= e(t('status')) ?></th>
|
|
<th class="text-uppercase small text-muted border-top-0 text-end">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($shipments as $row): ?>
|
|
<tr>
|
|
<td>
|
|
<div class="fw-bold"><?= e($row['shipper_company']) ?></div>
|
|
<small class="text-muted"><?= e($row['payment_method'] === 'bank_transfer' ? t('payment_bank') : t('payment_thawani')) ?></small>
|
|
</td>
|
|
<td>
|
|
<div class="d-flex align-items-center gap-2">
|
|
<span class="fw-medium"><?= e($row['origin_city']) ?></span>
|
|
<i class="bi bi-arrow-right text-muted small"></i>
|
|
<span class="fw-medium"><?= e($row['destination_city']) ?></span>
|
|
</div>
|
|
</td>
|
|
<td><span class="badge <?= e($row['status']) ?> rounded-pill px-3 py-2"><?= e(status_label($row['status'])) ?></span></td>
|
|
<td class="text-end">
|
|
<form class="d-flex gap-2 justify-content-end" method="post">
|
|
<input type="hidden" name="action" value="update_status">
|
|
<input type="hidden" name="shipment_id" value="<?= e($row['id']) ?>">
|
|
<select class="form-select form-select-sm" name="status" style="width: auto;">
|
|
<option value="posted" <?= $row['status'] === 'posted' ? 'selected' : '' ?>><?= e(t('status_posted')) ?></option>
|
|
<option value="offered" <?= $row['status'] === 'offered' ? 'selected' : '' ?>><?= e(t('status_offered')) ?></option>
|
|
<option value="confirmed" <?= $row['status'] === 'confirmed' ? 'selected' : '' ?>><?= e(t('status_confirmed')) ?></option>
|
|
<option value="in_transit" <?= $row['status'] === 'in_transit' ? 'selected' : '' ?>><?= e(t('status_in_transit')) ?></option>
|
|
<option value="delivered" <?= $row['status'] === 'delivered' ? 'selected' : '' ?>><?= e(t('status_delivered')) ?></option>
|
|
</select>
|
|
<button class="btn btn-sm btn-primary px-3 rounded-pill" type="submit"><i class="bi bi-check2"></i> Save</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar: Quick Links List -->
|
|
<div class="col-lg-4">
|
|
<div class="panel p-4 shadow-sm border-0 h-100 rounded-4" style="background-color: #fafbfc;">
|
|
<h2 class="h5 mb-4 fw-bold"><i class="bi bi-lightning-charge text-warning me-2"></i>Quick Links</h2>
|
|
<div class="list-group list-group-flush bg-transparent">
|
|
<a href="<?= e(url_with_lang('admin_countries.php')) ?>" class="list-group-item list-group-item-action bg-transparent border-bottom d-flex align-items-center py-3 px-0">
|
|
<div class="bg-white rounded p-3 shadow-sm me-3 text-primary d-flex align-items-center justify-content-center" style="width: 48px; height: 48px;"><i class="bi bi-globe2 fs-5"></i></div>
|
|
<div>
|
|
<h6 class="mb-1 fw-bold">Manage Countries</h6>
|
|
<small class="text-muted d-block line-height-sm">Add or remove supported countries</small>
|
|
</div>
|
|
<i class="bi bi-chevron-right ms-auto text-muted small"></i>
|
|
</a>
|
|
<a href="<?= e(url_with_lang('admin_cities.php')) ?>" class="list-group-item list-group-item-action bg-transparent border-bottom d-flex align-items-center py-3 px-0">
|
|
<div class="bg-white rounded p-3 shadow-sm me-3 text-primary d-flex align-items-center justify-content-center" style="width: 48px; height: 48px;"><i class="bi bi-pin-map fs-5"></i></div>
|
|
<div>
|
|
<h6 class="mb-1 fw-bold">Manage Cities</h6>
|
|
<small class="text-muted d-block line-height-sm">Configure cities for routing</small>
|
|
</div>
|
|
<i class="bi bi-chevron-right ms-auto text-muted small"></i>
|
|
</a>
|
|
<a href="<?= e(url_with_lang('register.php')) ?>" class="list-group-item list-group-item-action bg-transparent border-bottom d-flex align-items-center py-3 px-0">
|
|
<div class="bg-white rounded p-3 shadow-sm me-3 text-success d-flex align-items-center justify-content-center" style="width: 48px; height: 48px;"><i class="bi bi-person-plus fs-5"></i></div>
|
|
<div>
|
|
<h6 class="mb-1 fw-bold">Register User</h6>
|
|
<small class="text-muted d-block line-height-sm">Manually onboard a new user</small>
|
|
</div>
|
|
<i class="bi bi-chevron-right ms-auto text-muted small"></i>
|
|
</a>
|
|
<a href="<?= e(url_with_lang('admin_company_profile.php')) ?>" class="list-group-item list-group-item-action bg-transparent border-bottom d-flex align-items-center py-3 px-0">
|
|
<div class="bg-white rounded p-3 shadow-sm me-3 text-secondary d-flex align-items-center justify-content-center" style="width: 48px; height: 48px;"><i class="bi bi-buildings fs-5"></i></div>
|
|
<div>
|
|
<h6 class="mb-1 fw-bold">Company Profile</h6>
|
|
<small class="text-muted d-block line-height-sm">Update platform branding</small>
|
|
</div>
|
|
<i class="bi bi-chevron-right ms-auto text-muted small"></i>
|
|
</a>
|
|
<a href="<?= e(url_with_lang('admin_landing_pages.php')) ?>" class="list-group-item list-group-item-action bg-transparent d-flex align-items-center py-3 px-0">
|
|
<div class="bg-white rounded p-3 shadow-sm me-3 text-info d-flex align-items-center justify-content-center" style="width: 48px; height: 48px;"><i class="bi bi-layout-text-window-reverse fs-5"></i></div>
|
|
<div>
|
|
<h6 class="mb-1 fw-bold">Landing Pages</h6>
|
|
<small class="text-muted d-block line-height-sm">Edit homepage content and sections</small>
|
|
</div>
|
|
<i class="bi bi-chevron-right ms-auto text-muted small"></i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php render_footer(); ?>
|