arabic translation
This commit is contained in:
parent
2ee38edf60
commit
0ebb8e142e
@ -43,7 +43,7 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
<div class="col-md-10 p-4">
|
||||
<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>
|
||||
<p class="muted mb-0"><?= e(t('overview_performance')) ?></p>
|
||||
</div>
|
||||
|
||||
<!-- Stats Row -->
|
||||
@ -53,7 +53,7 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
<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>
|
||||
<p class="text-muted small text-uppercase mb-0 fw-bold position-relative" style="letter-spacing: 0.5px;"><?= e(t('total_shipments')) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
@ -61,7 +61,7 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
<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>
|
||||
<p class="text-muted small text-uppercase mb-0 fw-bold position-relative" style="letter-spacing: 0.5px;"><?= e(t('active_shipments')) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
@ -69,7 +69,7 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
<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>
|
||||
<p class="text-muted small text-uppercase mb-0 fw-bold position-relative" style="letter-spacing: 0.5px;"><?= e(t('total_shippers')) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
@ -77,7 +77,7 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
<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>
|
||||
<p class="text-muted small text-uppercase mb-0 fw-bold position-relative" style="letter-spacing: 0.5px;"><?= e(t('total_truck_owners')) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -87,8 +87,8 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
<div class="col-lg-8">
|
||||
<div class="panel shadow-sm border-0 h-100 rounded-4 d-flex flex-column">
|
||||
<div class="panel-heading d-flex justify-content-between align-items-center">
|
||||
<h2 class="h5 mb-0 fw-bold text-white"><i class="bi bi-clock-history text-white-50 me-2"></i>Recent Shipments</h2>
|
||||
<span class="badge bg-white text-dark"><?= e(count($shipments)) ?> shown</span>
|
||||
<h2 class="h5 mb-0 fw-bold text-white"><i class="bi bi-clock-history text-white-50 me-2"></i><?= e(t('recent_shipments')) ?></h2>
|
||||
<span class="badge bg-white text-dark"><?= e(count($shipments)) ?> <?= e(t('shown')) ?></span>
|
||||
</div>
|
||||
<div class="p-4 flex-grow-1 d-flex flex-column">
|
||||
<?php if ($flash): ?>
|
||||
@ -107,10 +107,10 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
<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('shipment')) ?></th>
|
||||
<th class="text-uppercase small text-muted border-top-0"><?= e(t('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>
|
||||
<th class="text-uppercase small text-muted border-top-0 text-end"><?= e(t('action')) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -129,7 +129,7 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
</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">
|
||||
<a href="<?= e(url_with_lang('shipment_detail.php', ['id' => $row['id']])) ?>" class="btn btn-sm p-1 border-0 bg-transparent text-primary" title="View Details">
|
||||
<a href="<?= e(url_with_lang('shipment_detail.php', ['id' => $row['id']])) ?>" class="btn btn-sm p-1 border-0 bg-transparent text-primary" title="<?= e(t('view_details')) ?>">
|
||||
<i class="bi bi-eye"></i>
|
||||
</a>
|
||||
</td>
|
||||
@ -147,47 +147,47 @@ render_header(t('admin_dashboard'), 'admin', true);
|
||||
<div class="col-lg-4">
|
||||
<div class="panel shadow-sm border-0 h-100 rounded-4" style="background-color: #fafbfc;">
|
||||
<div class="panel-heading">
|
||||
<h2 class="h5 mb-0 fw-bold text-white"><i class="bi bi-lightning-charge text-warning me-2"></i>Quick Links</h2>
|
||||
<h2 class="h5 mb-0 fw-bold text-white"><i class="bi bi-lightning-charge text-warning me-2"></i><?= e(t('quick_links')) ?></h2>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<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>
|
||||
<h6 class="mb-1 fw-bold"><?= e(t('manage_countries')) ?></h6>
|
||||
<small class="text-muted d-block line-height-sm"><?= e(t('add_remove_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>
|
||||
<h6 class="mb-1 fw-bold"><?= e(t('manage_cities')) ?></h6>
|
||||
<small class="text-muted d-block line-height-sm"><?= e(t('configure_cities')) ?></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>
|
||||
<h6 class="mb-1 fw-bold"><?= e(t('register_user')) ?></h6>
|
||||
<small class="text-muted d-block line-height-sm"><?= e(t('manually_onboard')) ?></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>
|
||||
<h6 class="mb-1 fw-bold"><?= e(t('company_profile')) ?></h6>
|
||||
<small class="text-muted d-block line-height-sm"><?= e(t('update_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>
|
||||
<h6 class="mb-1 fw-bold"><?= e(t('landing_pages')) ?></h6>
|
||||
<small class="text-muted d-block line-height-sm"><?= e(t('edit_homepage')) ?></small>
|
||||
</div>
|
||||
<i class="bi bi-chevron-right ms-auto text-muted small"></i>
|
||||
</a>
|
||||
|
||||
@ -5,7 +5,7 @@ require_once __DIR__ . '/includes/layout.php';
|
||||
|
||||
// Check permission
|
||||
if (!has_permission('view_reports') && !has_permission('manage_shippers')) {
|
||||
render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippers');
|
||||
render_header(t('shippers_statements'), 'reports_shippers');
|
||||
echo '<div class="container py-5"><div class="alert alert-danger">Access Denied. You do not have permission to view reports.</div></div>';
|
||||
render_footer();
|
||||
exit;
|
||||
@ -72,7 +72,7 @@ if ($shipperId) {
|
||||
}
|
||||
}
|
||||
|
||||
render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippers', true);
|
||||
render_header(t('shippers_statements'), 'reports_shippers', true);
|
||||
?>
|
||||
|
||||
<!-- Select2 CSS -->
|
||||
@ -132,12 +132,12 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
<!-- Screen Only Header -->
|
||||
<div class="page-intro d-flex justify-content-between align-items-center mb-4 no-print">
|
||||
<div>
|
||||
<h1 class="section-title mb-1">Shipper Statements</h1>
|
||||
<p class="muted mb-0">View and print financial statements for shippers.</p>
|
||||
<h1 class="section-title mb-1"><?= e(t('shippers_statements')) ?></h1>
|
||||
<p class="muted mb-0"><?= e(t('view_print_statements')) ?></p>
|
||||
</div>
|
||||
<?php if ($shipper): ?>
|
||||
<button onclick="window.print()" class="btn btn-dark">
|
||||
<i class="bi bi-printer me-2"></i>Print Formal Statement
|
||||
<i class="bi bi-printer me-2"></i><?= e(t('print_formal_statement')) ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@ -146,9 +146,9 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
<div class="panel p-4 mb-4 no-print filter-form">
|
||||
<form method="get" class="row g-3 align-items-end">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small text-muted">Select Shipper</label>
|
||||
<label class="form-label small text-muted"><?= e(t('select_shipper')) ?></label>
|
||||
<select name="shipper_id" id="shipperSelect" class="form-select" onchange="this.form.submit()">
|
||||
<option value="">-- Choose a Shipper --</option>
|
||||
<option value=""><?= e(t('choose_shipper')) ?></option>
|
||||
<?php foreach ($allShippers as $s): ?>
|
||||
<option value="<?= $s['id'] ?>" <?= $shipperId == $s['id'] ? 'selected' : '' ?>>
|
||||
<?= e($s['full_name']) ?> (<?= e($s['company_name'] ?: 'No Company') ?>)
|
||||
@ -157,21 +157,21 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">Start Date</label>
|
||||
<label class="form-label small text-muted"><?= e(t('start_date')) ?></label>
|
||||
<input type="date" name="start_date" class="form-control" value="<?= e($startDate) ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">End Date</label>
|
||||
<label class="form-label small text-muted"><?= e(t('end_date')) ?></label>
|
||||
<input type="date" name="end_date" class="form-control" value="<?= e($endDate) ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-primary w-100">Filter</button>
|
||||
<button type="submit" class="btn btn-primary w-100"><?= e(t('filter')) ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if ($shipperId && !$shipper): ?>
|
||||
<div class="alert alert-warning">Shipper not found.</div>
|
||||
<div class="alert alert-warning"><?= e(t('shipper_not_found')) ?></div>
|
||||
<?php elseif ($shipper): ?>
|
||||
<div class="panel p-5 bg-white">
|
||||
<!-- Print Header (Compact) -->
|
||||
@ -181,7 +181,7 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
<p class="mt-1"><?= date('F j, Y') ?></p>
|
||||
</div>
|
||||
<div class="print-header-right">
|
||||
<h1>Statement of Account</h1>
|
||||
<h1><?= e(t('statement_of_account')) ?></h1>
|
||||
<h2 style="font-size: 12pt; margin: 0; font-weight: normal;">كشف حساب</h2>
|
||||
</div>
|
||||
</div>
|
||||
@ -189,7 +189,7 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
<!-- Info Section (Compact) -->
|
||||
<div class="statement-info row">
|
||||
<div class="col-6">
|
||||
<h5>Billed To / إلى السيد</h5>
|
||||
<h5><?= e(t('billed_to')) ?> / إلى السيد</h5>
|
||||
<h4><?= e($shipper['full_name']) ?></h4>
|
||||
<div class="small text-muted">
|
||||
<?= e($shipper['company_name'] ?: '-') ?><br>
|
||||
@ -199,17 +199,17 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<h5>Summary / ملخص</h5>
|
||||
<h5><?= e(t('summary')) ?> / ملخص</h5>
|
||||
<div class="small">
|
||||
<div><strong>Date:</strong> <?= date('Y-m-d') ?></div>
|
||||
<?php if ($startDate || $endDate): ?>
|
||||
<div><strong>Period:</strong> <?= e($startDate ?: 'Start') ?> to <?= e($endDate ?: 'Now') ?></div>
|
||||
<div><strong><?= e(t('period')) ?>:</strong> <?= e($startDate ?: 'Start') ?> to <?= e($endDate ?: 'Now') ?></div>
|
||||
<?php else: ?>
|
||||
<div><strong>Period:</strong> All Time</div>
|
||||
<div><strong><?= e(t('period')) ?>:</strong> <?= e(t('all_time')) ?></div>
|
||||
<?php endif; ?>
|
||||
<div><strong>Count:</strong> <?= count($shipments) ?></div>
|
||||
<div><strong><?= e(t('total_count')) ?>:</strong> <?= count($shipments) ?></div>
|
||||
<div class="fs-5 fw-bold text-primary mt-1">
|
||||
<?= number_format($totalAmount, 2) ?> OMR
|
||||
<?= format_currency($totalAmount) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -218,18 +218,18 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
<!-- Table -->
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered align-middle">
|
||||
<thead class="table-light">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date <br> <span class="fw-normal text-muted">التاريخ</span></th>
|
||||
<th>Ref # <br> <span class="fw-normal text-muted">رقم الشحنة</span></th>
|
||||
<th>Route <br> <span class="fw-normal text-muted">المسار</span></th>
|
||||
<th>Status <br> <span class="fw-normal text-muted">الحالة</span></th>
|
||||
<th class="text-end">Amount (OMR) <br> <span class="fw-normal text-muted">المبلغ</span></th>
|
||||
<th><?= e(t('route')) ?> <br> <span class="fw-normal text-muted">المسار</span></th>
|
||||
<th><?= e(t('status')) ?> <br> <span class="fw-normal text-muted">الحالة</span></th>
|
||||
<th class="text-end"><?= e(t('amount')) ?> <br> <span class="fw-normal text-muted">المبلغ</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($shipments)): ?>
|
||||
<tr><td colspan="5" class="text-center py-4 text-muted">No completed shipments found for this period.</td></tr>
|
||||
<tr><td colspan="5" class="text-center py-4 text-muted"><?= e(t('no_completed_shipments')) ?></td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($shipments as $row): ?>
|
||||
<tr>
|
||||
@ -240,10 +240,10 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
<div class="small text-muted"><?= e($row['cargo_description']) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<?= e(ucfirst(str_replace('_', ' ', $row['status']))) ?>
|
||||
<?= e(status_label($row['status'])) ?>
|
||||
</td>
|
||||
<td class="text-end fw-bold">
|
||||
<?= number_format((float)$row['total_price'], 2) ?>
|
||||
<?= format_currency((float)$row['total_price']) ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
@ -251,8 +251,8 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="total-row table-active">
|
||||
<td colspan="4" class="text-end text-uppercase">Total Balance / الإجمالي</td>
|
||||
<td class="text-end text-dark"><?= number_format($totalAmount, 2) ?> OMR</td>
|
||||
<td colspan="4" class="text-end text-uppercase"><?= e(t('total_balance')) ?> / الإجمالي</td>
|
||||
<td class="text-end text-dark"><?= format_currency($totalAmount) ?></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
@ -262,12 +262,12 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
<div class="print-footer">
|
||||
<div class="row">
|
||||
<div class="col-6 text-start">
|
||||
Authorized Signature<br>
|
||||
<?= e(t('authorized_signature')) ?><br>
|
||||
_______________________
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
Printed on <?= date('Y-m-d H:i') ?><br>
|
||||
This is a computer-generated document.
|
||||
<?= e(t('printed_on')) ?> <?= date('Y-m-d H:i') ?><br>
|
||||
<?= e(t('generated_doc')) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -283,7 +283,7 @@ render_header(t('shippers_statements') ?: 'Shippers Statements', 'reports_shippe
|
||||
$(document).ready(function() {
|
||||
$('#shipperSelect').select2({
|
||||
width: '100%',
|
||||
placeholder: '-- Choose a Shipper --',
|
||||
placeholder: '<?= e(t('choose_shipper')) ?>',
|
||||
allowClear: true
|
||||
});
|
||||
});
|
||||
|
||||
@ -26,13 +26,15 @@ $selectName = '';
|
||||
$join = '';
|
||||
$orderBy = 'total_amount DESC';
|
||||
|
||||
$pageTitle = t('shipments_by_origin_country');
|
||||
|
||||
switch ($reportType) {
|
||||
case 'countries_origin':
|
||||
$selectName = "COALESCE(co.name_en, 'Unknown') as name";
|
||||
$join = "LEFT JOIN cities c ON s.origin_city = c.name_en
|
||||
LEFT JOIN countries co ON c.country_id = co.id";
|
||||
$groupBy = "co.name_en";
|
||||
$pageTitle = "Shipments by Origin Country";
|
||||
$pageTitle = t('shipments_by_origin_country');
|
||||
break;
|
||||
|
||||
case 'countries_dest':
|
||||
@ -40,25 +42,25 @@ switch ($reportType) {
|
||||
$join = "LEFT JOIN cities c ON s.destination_city = c.name_en
|
||||
LEFT JOIN countries co ON c.country_id = co.id";
|
||||
$groupBy = "co.name_en";
|
||||
$pageTitle = "Shipments by Destination Country";
|
||||
$pageTitle = t('shipments_by_dest_country');
|
||||
break;
|
||||
|
||||
case 'cities_origin':
|
||||
$selectName = "s.origin_city as name";
|
||||
$groupBy = "s.origin_city";
|
||||
$pageTitle = "Shipments by Origin City";
|
||||
$pageTitle = t('shipments_by_origin_city');
|
||||
break;
|
||||
|
||||
case 'cities_dest':
|
||||
$selectName = "s.destination_city as name";
|
||||
$groupBy = "s.destination_city";
|
||||
$pageTitle = "Shipments by Destination City";
|
||||
$pageTitle = t('shipments_by_dest_city');
|
||||
break;
|
||||
|
||||
case 'shippers':
|
||||
$selectName = "s.shipper_name as name"; // simplified, could join users table
|
||||
$groupBy = "s.shipper_name";
|
||||
$pageTitle = "Shipments by Shipper";
|
||||
$pageTitle = t('shipments_by_shipper');
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -67,7 +69,7 @@ switch ($reportType) {
|
||||
$join = "LEFT JOIN cities c ON s.origin_city = c.name_en
|
||||
LEFT JOIN countries co ON c.country_id = co.id";
|
||||
$groupBy = "co.name_en";
|
||||
$pageTitle = "Shipments by Origin Country";
|
||||
$pageTitle = t('shipments_by_origin_country');
|
||||
break;
|
||||
}
|
||||
|
||||
@ -104,54 +106,96 @@ foreach ($results as $row) {
|
||||
$grandTotalProfit += $row['total_profit'];
|
||||
}
|
||||
|
||||
render_header('Reports Summary', 'reports_summary', true);
|
||||
render_header(t('summary_report'), 'reports_summary', true);
|
||||
?>
|
||||
|
||||
<div class="row g-0">
|
||||
<div class="col-md-2 bg-white border-end min-vh-100">
|
||||
<div class="col-md-2 bg-white border-end min-vh-100 d-print-none">
|
||||
<?php render_admin_sidebar('reports_summary'); ?>
|
||||
</div>
|
||||
<div class="col-md-10 p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
|
||||
<!-- Print Header -->
|
||||
<div class="d-none d-print-block mb-4">
|
||||
<div class="row align-items-center mb-4">
|
||||
<div class="col-6">
|
||||
<?php
|
||||
$logoPath = get_setting('logo_path');
|
||||
if ($logoPath): ?>
|
||||
<img src="<?= e($logoPath) ?>" alt="Company Logo" style="max-height: 80px; width: auto;">
|
||||
<?php else: ?>
|
||||
<h2 class="fw-bold mb-0 text-dark"><?= e(get_setting('company_name', 'CargoLink')) ?></h2>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<h3 class="mb-1 text-dark fw-bold"><?= e(t('summary_report')) ?></h3>
|
||||
<p class="mb-0 text-muted small">
|
||||
<?= e(get_setting('company_address')) ?><br>
|
||||
<?= e(get_setting('company_email')) ?> | <?= e(get_setting('company_phone')) ?>
|
||||
</p>
|
||||
<p class="mb-0 text-muted small mt-2">
|
||||
<?= e(t('generated')) ?>: <?= date('d M Y, H:i') ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="border p-3 rounded bg-light">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<strong class="text-muted d-block small text-uppercase"><?= e(t('report_type')) ?></strong>
|
||||
<span class="fs-5 fw-bold text-dark"><?= e($pageTitle) ?></span>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<strong class="text-muted d-block small text-uppercase"><?= e(t('period')) ?></strong>
|
||||
<span class="fs-5 fw-bold text-dark"><?= e($startDate) ?> — <?= e($endDate) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 d-print-none">
|
||||
<div>
|
||||
<h1 class="section-title mb-1">Summary Reports</h1>
|
||||
<p class="muted mb-0">Analyze shipment performance, revenue, and profits.</p>
|
||||
<h1 class="section-title mb-1"><?= e(t('summary_report')) ?></h1>
|
||||
<p class="muted mb-0"><?= e(t('analyze_performance')) ?></p>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-outline-secondary btn-sm" onclick="window.print()">
|
||||
<i class="bi bi-printer me-2"></i>Print
|
||||
<i class="bi bi-printer me-2"></i><?= e(t('print')) ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel p-4 mb-4">
|
||||
<div class="panel p-4 mb-4 d-print-none">
|
||||
<form method="get" class="row g-3 align-items-end">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">Report Type</label>
|
||||
<label class="form-label small text-muted"><?= e(t('report_type')) ?></label>
|
||||
<select name="type" class="form-select" onchange="this.form.submit()">
|
||||
<option value="countries_origin" <?= $reportType === 'countries_origin' ? 'selected' : '' ?>>By Origin Country</option>
|
||||
<option value="countries_dest" <?= $reportType === 'countries_dest' ? 'selected' : '' ?>>By Destination Country</option>
|
||||
<option value="cities_origin" <?= $reportType === 'cities_origin' ? 'selected' : '' ?>>By Origin City</option>
|
||||
<option value="cities_dest" <?= $reportType === 'cities_dest' ? 'selected' : '' ?>>By Destination City</option>
|
||||
<option value="shippers" <?= $reportType === 'shippers' ? 'selected' : '' ?>>By Shipper</option>
|
||||
<option value="countries_origin" <?= $reportType === 'countries_origin' ? 'selected' : '' ?>><?= e(t('shipments_by_origin_country')) ?></option>
|
||||
<option value="countries_dest" <?= $reportType === 'countries_dest' ? 'selected' : '' ?>><?= e(t('shipments_by_dest_country')) ?></option>
|
||||
<option value="cities_origin" <?= $reportType === 'cities_origin' ? 'selected' : '' ?>><?= e(t('shipments_by_origin_city')) ?></option>
|
||||
<option value="cities_dest" <?= $reportType === 'cities_dest' ? 'selected' : '' ?>><?= e(t('shipments_by_dest_city')) ?></option>
|
||||
<option value="shippers" <?= $reportType === 'shippers' ? 'selected' : '' ?>><?= e(t('shipments_by_shipper')) ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">Start Date</label>
|
||||
<label class="form-label small text-muted"><?= e(t('start_date')) ?></label>
|
||||
<input type="date" name="start_date" class="form-control" value="<?= e($startDate) ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">End Date</label>
|
||||
<label class="form-label small text-muted"><?= e(t('end_date')) ?></label>
|
||||
<input type="date" name="end_date" class="form-control" value="<?= e($endDate) ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-primary w-100">Apply Filter</button>
|
||||
<button type="submit" class="btn btn-primary w-100"><?= e(t('apply_filter')) ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="panel p-0">
|
||||
<div class="p-3 border-bottom bg-light d-flex justify-content-between align-items-center">
|
||||
<div class="panel p-0 print-no-shadow">
|
||||
<div class="p-3 border-bottom bg-light d-flex justify-content-between align-items-center d-print-none">
|
||||
<h5 class="mb-0 fw-bold"><?= e($pageTitle) ?></h5>
|
||||
<span class="badge bg-secondary"><?= e($startDate) ?> to <?= e($endDate) ?></span>
|
||||
</div>
|
||||
@ -159,17 +203,17 @@ render_header('Reports Summary', 'reports_summary', true);
|
||||
<?php if (empty($results)): ?>
|
||||
<div class="p-5 text-center text-muted">
|
||||
<i class="bi bi-bar-chart fs-1 mb-3 d-block"></i>
|
||||
<p class="mb-0">No paid shipments found for this period.</p>
|
||||
<p class="mb-0"><?= e(t('no_paid_shipments')) ?></p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0 align-middle">
|
||||
<thead class="table-light">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="ps-4">Name</th>
|
||||
<th class="text-center">Shipments</th>
|
||||
<th class="text-end">Total Amount</th>
|
||||
<th class="text-end pe-4">Profit</th>
|
||||
<th class="ps-4"><?= e(t('name')) ?></th>
|
||||
<th class="text-center"><?= e(t('stats_shipments')) ?></th>
|
||||
<th class="text-end"><?= e(t('total_amount')) ?></th>
|
||||
<th class="text-end pe-4"><?= e(t('profit')) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -177,32 +221,36 @@ render_header('Reports Summary', 'reports_summary', true);
|
||||
<tr>
|
||||
<td class="ps-4 fw-medium"><?= e($row['name']) ?></td>
|
||||
<td class="text-center"><?= number_format((int)$row['shipment_count']) ?></td>
|
||||
<td class="text-end text-dark">$<?= number_format((float)$row['total_amount'], 2) ?></td>
|
||||
<td class="text-end pe-4 text-success fw-bold">$<?= number_format((float)$row['total_profit'], 2) ?></td>
|
||||
<td class="text-end text-dark"><?= format_currency((float)$row['total_amount']) ?></td>
|
||||
<td class="text-end pe-4 text-success fw-bold"><?= format_currency((float)$row['total_profit']) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot class="table-light fw-bold border-top">
|
||||
<tr>
|
||||
<td class="ps-4">TOTAL</td>
|
||||
<td class="ps-4"><?= e(t('total_label')) ?></td>
|
||||
<td class="text-center"><?= number_format($totalShipments) ?></td>
|
||||
<td class="text-end">$<?= number_format($grandTotalAmount, 2) ?></td>
|
||||
<td class="text-end pe-4 text-success">$<?= number_format($grandTotalProfit, 2) ?></td>
|
||||
<td class="text-end"><?= format_currency($grandTotalAmount) ?></td>
|
||||
<td class="text-end pe-4 text-success"><?= format_currency($grandTotalProfit) ?></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Print Footer -->
|
||||
<div class="d-none d-print-block print-footer border-top pt-2">
|
||||
<div class="row text-muted small">
|
||||
<div class="col-6">
|
||||
<?= e(t('printed_by')) ?>: <?= e($_SESSION['user_name'] ?? 'Admin') ?>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<?= e(t('generated')) ?>: <?= date('d M Y H:i') ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@media print {
|
||||
.admin-sidebar, .btn, form { display: none !important; }
|
||||
.col-md-10 { width: 100% !important; padding: 0 !important; }
|
||||
.panel { border: none !important; box-shadow: none !important; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<?php render_footer(); ?>
|
||||
@ -5,7 +5,7 @@ require_once __DIR__ . '/includes/layout.php';
|
||||
|
||||
// Check permission
|
||||
if (!has_permission('view_reports') && !has_permission('manage_truck_owners')) {
|
||||
render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports_truck_owners');
|
||||
render_header(t('truck_owners_statements'), 'reports_truck_owners');
|
||||
echo '<div class="container py-5"><div class="alert alert-danger">Access Denied. You do not have permission to view reports.</div></div>';
|
||||
render_footer();
|
||||
exit;
|
||||
@ -72,7 +72,7 @@ if ($ownerId) {
|
||||
}
|
||||
}
|
||||
|
||||
render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports_truck_owners', true);
|
||||
render_header(t('truck_owners_statements'), 'reports_truck_owners', true);
|
||||
?>
|
||||
|
||||
<!-- Select2 CSS -->
|
||||
@ -132,12 +132,12 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
<!-- Screen Only Header -->
|
||||
<div class="page-intro d-flex justify-content-between align-items-center mb-4 no-print">
|
||||
<div>
|
||||
<h1 class="section-title mb-1">Truck Owner Statements</h1>
|
||||
<p class="muted mb-0">View and print financial statements for truck owners.</p>
|
||||
<h1 class="section-title mb-1"><?= e(t('truck_owners_statements')) ?></h1>
|
||||
<p class="muted mb-0"><?= e(t('view_print_owner_statements')) ?></p>
|
||||
</div>
|
||||
<?php if ($owner): ?>
|
||||
<button onclick="window.print()" class="btn btn-dark">
|
||||
<i class="bi bi-printer me-2"></i>Print Formal Statement
|
||||
<i class="bi bi-printer me-2"></i><?= e(t('print_formal_statement')) ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@ -146,9 +146,9 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
<div class="panel p-4 mb-4 no-print filter-form">
|
||||
<form method="get" class="row g-3 align-items-end">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small text-muted">Select Truck Owner</label>
|
||||
<label class="form-label small text-muted"><?= e(t('select_truck_owner')) ?></label>
|
||||
<select name="owner_id" id="ownerSelect" class="form-select" onchange="this.form.submit()">
|
||||
<option value="">-- Choose a Truck Owner --</option>
|
||||
<option value=""><?= e(t('choose_truck_owner')) ?></option>
|
||||
<?php foreach ($allOwners as $o): ?>
|
||||
<option value="<?= $o['id'] ?>" <?= $ownerId == $o['id'] ? 'selected' : '' ?>>
|
||||
<?= e($o['full_name']) ?> (Plate: <?= e($o['plate_no'] ?: '-') ?>)
|
||||
@ -157,21 +157,21 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">Start Date</label>
|
||||
<label class="form-label small text-muted"><?= e(t('start_date')) ?></label>
|
||||
<input type="date" name="start_date" class="form-control" value="<?= e($startDate) ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">End Date</label>
|
||||
<label class="form-label small text-muted"><?= e(t('end_date')) ?></label>
|
||||
<input type="date" name="end_date" class="form-control" value="<?= e($endDate) ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-primary w-100">Filter</button>
|
||||
<button type="submit" class="btn btn-primary w-100"><?= e(t('filter')) ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if ($ownerId && !$owner): ?>
|
||||
<div class="alert alert-warning">Truck Owner not found.</div>
|
||||
<div class="alert alert-warning"><?= e(t('owner_not_found')) ?></div>
|
||||
<?php elseif ($owner): ?>
|
||||
<div class="panel p-5 bg-white">
|
||||
<!-- Print Header (Compact) -->
|
||||
@ -181,7 +181,7 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
<p class="mt-1"><?= date('F j, Y') ?></p>
|
||||
</div>
|
||||
<div class="print-header-right">
|
||||
<h1>Payment Statement</h1>
|
||||
<h1><?= e(t('payment_statement')) ?></h1>
|
||||
<h2 style="font-size: 12pt; margin: 0; font-weight: normal;">كشف مدفوعات</h2>
|
||||
</div>
|
||||
</div>
|
||||
@ -189,9 +189,9 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
<!-- Info Section (Compact) -->
|
||||
<div class="statement-info row">
|
||||
<div class="col-6">
|
||||
<h5>Pay To / إلى السيد</h5>
|
||||
<h5><?= e(t('pay_to')) ?> / إلى السيد</h5>
|
||||
<h4><?= e($owner['full_name']) ?></h4>
|
||||
<div class="text-muted small">Truck Plate: <?= e($owner['plate_no'] ?: '-') ?></div>
|
||||
<div class="text-muted small"><?= e(t('truck_plate')) ?>: <?= e($owner['plate_no'] ?: '-') ?></div>
|
||||
<div class="small text-muted">
|
||||
<?= e($owner['truck_type'] ?: '') ?><br>
|
||||
<?= e($owner['city'] ?: '') ?>, <?= e($owner['country'] ?: '') ?><br>
|
||||
@ -199,17 +199,17 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<h5>Summary / ملخص</h5>
|
||||
<h5><?= e(t('summary')) ?> / ملخص</h5>
|
||||
<div class="small">
|
||||
<div><strong>Date:</strong> <?= date('Y-m-d') ?></div>
|
||||
<?php if ($startDate || $endDate): ?>
|
||||
<div><strong>Period:</strong> <?= e($startDate ?: 'Start') ?> to <?= e($endDate ?: 'Now') ?></div>
|
||||
<div><strong><?= e(t('period')) ?>:</strong> <?= e($startDate ?: 'Start') ?> to <?= e($endDate ?: 'Now') ?></div>
|
||||
<?php else: ?>
|
||||
<div><strong>Period:</strong> All Time</div>
|
||||
<div><strong><?= e(t('period')) ?>:</strong> <?= e(t('all_time')) ?></div>
|
||||
<?php endif; ?>
|
||||
<div><strong>Total Trips:</strong> <?= count($shipments) ?></div>
|
||||
<div><strong><?= e(t('total_trips')) ?>:</strong> <?= count($shipments) ?></div>
|
||||
<div class="fs-5 fw-bold text-primary mt-1">
|
||||
<?= number_format($totalEarnings, 2) ?> OMR
|
||||
<?= format_currency($totalEarnings) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -218,18 +218,18 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
<!-- Table -->
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered align-middle">
|
||||
<thead class="table-light">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date <br> <span class="fw-normal text-muted">التاريخ</span></th>
|
||||
<th>Ref # <br> <span class="fw-normal text-muted">رقم الشحنة</span></th>
|
||||
<th>Route <br> <span class="fw-normal text-muted">المسار</span></th>
|
||||
<th>Status <br> <span class="fw-normal text-muted">الحالة</span></th>
|
||||
<th class="text-end">Earnings (OMR) <br> <span class="fw-normal text-muted">المبلغ</span></th>
|
||||
<th><?= e(t('route')) ?> <br> <span class="fw-normal text-muted">المسار</span></th>
|
||||
<th><?= e(t('status')) ?> <br> <span class="fw-normal text-muted">الحالة</span></th>
|
||||
<th class="text-end"><?= e(t('earnings')) ?> <br> <span class="fw-normal text-muted">المبلغ</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($shipments)): ?>
|
||||
<tr><td colspan="5" class="text-center py-4 text-muted">No completed shipments found for this period.</td></tr>
|
||||
<tr><td colspan="5" class="text-center py-4 text-muted"><?= e(t('no_completed_shipments')) ?></td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($shipments as $row): ?>
|
||||
<tr>
|
||||
@ -240,10 +240,10 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
<div class="small text-muted"><?= e($row['cargo_description']) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<?= e(ucfirst(str_replace('_', ' ', $row['status']))) ?>
|
||||
<?= e(status_label($row['status'])) ?>
|
||||
</td>
|
||||
<td class="text-end fw-bold">
|
||||
<?= number_format((float)$row['offer_price'], 2) ?>
|
||||
<?= format_currency((float)$row['offer_price']) ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
@ -251,8 +251,8 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="total-row table-active">
|
||||
<td colspan="4" class="text-end text-uppercase">Total Earnings / الإجمالي</td>
|
||||
<td class="text-end text-dark"><?= number_format($totalEarnings, 2) ?> OMR</td>
|
||||
<td colspan="4" class="text-end text-uppercase"><?= e(t('total_earnings')) ?> / الإجمالي</td>
|
||||
<td class="text-end text-dark"><?= format_currency($totalEarnings) ?></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
@ -262,12 +262,12 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
<div class="print-footer">
|
||||
<div class="row">
|
||||
<div class="col-6 text-start">
|
||||
Authorized Signature<br>
|
||||
<?= e(t('authorized_signature')) ?><br>
|
||||
_______________________
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
Printed on <?= date('Y-m-d H:i') ?><br>
|
||||
This is a computer-generated document.
|
||||
<?= e(t('printed_on')) ?> <?= date('Y-m-d H:i') ?><br>
|
||||
<?= e(t('generated_doc')) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -283,7 +283,7 @@ render_header(t('truck_owners_statements') ?: 'Truck Owner Statements', 'reports
|
||||
$(document).ready(function() {
|
||||
$('#ownerSelect').select2({
|
||||
width: '100%',
|
||||
placeholder: '-- Choose a Truck Owner --',
|
||||
placeholder: '<?= e(t('choose_truck_owner')) ?>',
|
||||
allowClear: true
|
||||
});
|
||||
});
|
||||
|
||||
@ -8,7 +8,7 @@ $isAjax = isset($_GET['ajax']) && $_GET['ajax'] === '1';
|
||||
|
||||
if (!$id) {
|
||||
if ($isAjax) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID']);
|
||||
echo json_encode(['success' => false, 'message' => t('invalid_id')]);
|
||||
exit;
|
||||
}
|
||||
header('Location: admin_shipments.php'); exit;
|
||||
@ -23,7 +23,7 @@ $shipment = $stmt->fetch();
|
||||
|
||||
if (!$shipment) {
|
||||
if ($isAjax) {
|
||||
echo json_encode(['success' => false, 'message' => 'Shipment not found']);
|
||||
echo json_encode(['success' => false, 'message' => t('shipment_not_found')]);
|
||||
exit;
|
||||
}
|
||||
header('Location: admin_shipments.php'); exit;
|
||||
@ -76,9 +76,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$payment_method = trim($_POST['payment_method'] ?? 'thawani');
|
||||
$status = trim($_POST['status'] ?? 'posted');
|
||||
|
||||
if ($shipper_name === '') $errors[] = "Shipper name is required.";
|
||||
if ($origin_city === '') $errors[] = "Origin city is required.";
|
||||
if ($destination_city === '') $errors[] = "Destination city is required.";
|
||||
if ($shipper_name === '') $errors[] = t('error_required');
|
||||
if ($origin_city === '') $errors[] = t('error_required');
|
||||
if ($destination_city === '') $errors[] = t('error_required');
|
||||
|
||||
if (empty($errors)) {
|
||||
$updateSql = "
|
||||
@ -93,7 +93,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$cargo_description, $weight_tons, $pickup_date, $delivery_date,
|
||||
$payment_method, $status, $id
|
||||
]);
|
||||
$flash = "Shipment updated successfully.";
|
||||
$flash = t('shipment_updated_success');
|
||||
|
||||
if ($isAjax) {
|
||||
header('Content-Type: application/json');
|
||||
@ -133,7 +133,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
// -- OUTPUT START --
|
||||
if (!$isAjax):
|
||||
render_header('Edit Shipment', 'admin', true);
|
||||
render_header(t('edit_shipment_tooltip'), 'admin', true);
|
||||
?>
|
||||
|
||||
<div class="row g-0">
|
||||
@ -142,14 +142,14 @@ if (!$isAjax):
|
||||
</div>
|
||||
<div class="col-md-10 p-4">
|
||||
<div class="d-flex align-items-center gap-3 mb-4">
|
||||
<a href="admin_shipments.php" class="btn btn-light border text-secondary" title="Back">
|
||||
<a href="admin_shipments.php" class="btn btn-light border text-secondary" title="<?= t('back') ?>">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<div>
|
||||
<h1 class="section-title mb-1">Edit Shipment #<?= e((string)$shipment['id']) ?></h1>
|
||||
<p class="muted mb-0">Update shipment details and status.</p>
|
||||
<h1 class="section-title mb-1"><?= t('edit_shipment_title') ?><?= e((string)$shipment['id']) ?></h1>
|
||||
<p class="muted mb-0"><?= t('update_shipment_details') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -168,14 +168,14 @@ if (!$isAjax):
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-heading">Shipment Details</div>
|
||||
<div class="panel-heading"><?= t('shipment_details') ?></div>
|
||||
<div class="p-4">
|
||||
<?php endif; // End non-ajax wrapper ?>
|
||||
|
||||
<form method="post" action="admin_shipment_edit.php?id=<?= $id ?><?= $isAjax ? '&ajax=1' : '' ?>" class="ajax-form">
|
||||
<?php if ($isAjax): ?>
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Edit Shipment #<?= e((string)$shipment['id']) ?></h5>
|
||||
<h5 class="modal-title"><?= t('edit_shipment_title') ?><?= e((string)$shipment['id']) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@ -184,19 +184,19 @@ if (!$isAjax):
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Shipper Name</label>
|
||||
<label class="form-label"><?= t('shipper_name') ?></label>
|
||||
<input type="text" name="shipper_name" class="form-control" value="<?= e($shipment['shipper_name']) ?>" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Shipper Company</label>
|
||||
<label class="form-label"><?= t('shipper_company') ?></label>
|
||||
<input type="text" name="shipper_company" class="form-control" value="<?= e((string)$shipment['shipper_company']) ?>">
|
||||
</div>
|
||||
|
||||
<!-- Origin Selection -->
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Origin Country</label>
|
||||
<label class="form-label"><?= t('origin_country') ?></label>
|
||||
<select class="form-select" id="origin_country">
|
||||
<option value="">Select Country</option>
|
||||
<option value=""><?= t('select_country_placeholder') ?></option>
|
||||
<?php foreach ($countries as $c): ?>
|
||||
<option value="<?= e($c['id']) ?>" <?= $c['id'] == $origin_country_id ? 'selected' : '' ?>>
|
||||
<?= e($c['name_en']) ?>
|
||||
@ -205,9 +205,9 @@ if (!$isAjax):
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Origin City</label>
|
||||
<label class="form-label"><?= t('origin') ?></label>
|
||||
<select class="form-select" name="origin_city" id="origin_city" required>
|
||||
<option value="">Select City</option>
|
||||
<option value=""><?= t('select_city_placeholder') ?></option>
|
||||
<!-- If shipment has a city but we couldn't match a country, preserve the value as a fallback option -->
|
||||
<?php if (!$origin_country_id && $shipment['origin_city']): ?>
|
||||
<option value="<?= e($shipment['origin_city']) ?>" selected><?= e($shipment['origin_city']) ?></option>
|
||||
@ -223,9 +223,9 @@ if (!$isAjax):
|
||||
|
||||
<!-- Destination Selection -->
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Destination Country</label>
|
||||
<label class="form-label"><?= t('destination_country') ?></label>
|
||||
<select class="form-select" id="destination_country">
|
||||
<option value="">Select Country</option>
|
||||
<option value=""><?= t('select_country_placeholder') ?></option>
|
||||
<?php foreach ($countries as $c): ?>
|
||||
<option value="<?= e($c['id']) ?>" <?= $c['id'] == $destination_country_id ? 'selected' : '' ?>>
|
||||
<?= e($c['name_en']) ?>
|
||||
@ -234,9 +234,9 @@ if (!$isAjax):
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Destination City</label>
|
||||
<label class="form-label"><?= t('destination') ?></label>
|
||||
<select class="form-select" name="destination_city" id="destination_city" required>
|
||||
<option value="">Select City</option>
|
||||
<option value=""><?= t('select_city_placeholder') ?></option>
|
||||
<!-- Fallback for unmapped city -->
|
||||
<?php if (!$destination_country_id && $shipment['destination_city']): ?>
|
||||
<option value="<?= e($shipment['destination_city']) ?>" selected><?= e($shipment['destination_city']) ?></option>
|
||||
@ -251,38 +251,38 @@ if (!$isAjax):
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<label class="form-label">Cargo Description</label>
|
||||
<label class="form-label"><?= t('cargo') ?></label>
|
||||
<input type="text" name="cargo_description" class="form-control" value="<?= e((string)$shipment['cargo_description']) ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Weight (Tons)</label>
|
||||
<label class="form-label"><?= t('weight') ?></label>
|
||||
<input type="number" step="0.1" name="weight_tons" class="form-control" value="<?= e((string)$shipment['weight_tons']) ?>">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Pickup Date</label>
|
||||
<label class="form-label"><?= t('pickup_date') ?></label>
|
||||
<input type="date" name="pickup_date" class="form-control" value="<?= e((string)$shipment['pickup_date']) ?>">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Delivery Date</label>
|
||||
<label class="form-label"><?= t('delivery_date') ?></label>
|
||||
<input type="date" name="delivery_date" class="form-control" value="<?= e((string)$shipment['delivery_date']) ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Payment Method</label>
|
||||
<label class="form-label"><?= t('payment_method') ?></label>
|
||||
<select name="payment_method" class="form-select">
|
||||
<option value="thawani" <?= $shipment['payment_method'] === 'thawani' ? 'selected' : '' ?>>Thawani</option>
|
||||
<option value="bank_transfer" <?= $shipment['payment_method'] === 'bank_transfer' ? 'selected' : '' ?>>Bank Transfer</option>
|
||||
<option value="thawani" <?= $shipment['payment_method'] === 'thawani' ? 'selected' : '' ?>><?= t('payment_thawani') ?></option>
|
||||
<option value="bank_transfer" <?= $shipment['payment_method'] === 'bank_transfer' ? 'selected' : '' ?>><?= t('payment_bank') ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Status</label>
|
||||
<label class="form-label"><?= t('status') ?></label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="posted" <?= $shipment['status'] === 'posted' ? 'selected' : '' ?>>Posted</option>
|
||||
<option value="offered" <?= $shipment['status'] === 'offered' ? 'selected' : '' ?>>Offered</option>
|
||||
<option value="confirmed" <?= $shipment['status'] === 'confirmed' ? 'selected' : '' ?>>Confirmed</option>
|
||||
<option value="in_transit" <?= $shipment['status'] === 'in_transit' ? 'selected' : '' ?>>In Transit</option>
|
||||
<option value="delivered" <?= $shipment['status'] === 'delivered' ? 'selected' : '' ?>>Delivered</option>
|
||||
<option value="posted" <?= $shipment['status'] === 'posted' ? 'selected' : '' ?>><?= t('status_posted') ?></option>
|
||||
<option value="offered" <?= $shipment['status'] === 'offered' ? 'selected' : '' ?>><?= t('status_offered') ?></option>
|
||||
<option value="confirmed" <?= $shipment['status'] === 'confirmed' ? 'selected' : '' ?>><?= t('status_confirmed') ?></option>
|
||||
<option value="in_transit" <?= $shipment['status'] === 'in_transit' ? 'selected' : '' ?>><?= t('status_in_transit') ?></option>
|
||||
<option value="delivered" <?= $shipment['status'] === 'delivered' ? 'selected' : '' ?>><?= t('status_delivered') ?></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -290,12 +290,12 @@ if (!$isAjax):
|
||||
<?php if ($isAjax): ?>
|
||||
</div> <!-- modal-body end -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?= t('cancel') ?></button>
|
||||
<button type="submit" class="btn btn-primary"><?= t('save_changes') ?></button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="mt-4 pt-3 border-top d-flex justify-content-end">
|
||||
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||||
<button type="submit" class="btn btn-primary"><?= t('save_changes') ?></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
@ -317,14 +317,14 @@ if (!$isAjax):
|
||||
|
||||
countrySelect.addEventListener('change', function() {
|
||||
const countryId = this.value;
|
||||
citySelect.innerHTML = '<option value="">Loading...</option>';
|
||||
citySelect.innerHTML = '<option value=""><?= t('loading_cities') ?></option>';
|
||||
citySelect.disabled = true;
|
||||
|
||||
if (countryId) {
|
||||
fetch('api/get_cities.php?country_id=' + countryId)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
citySelect.innerHTML = '<option value="">Select City</option>';
|
||||
citySelect.innerHTML = '<option value=""><?= t('select_city_placeholder') ?></option>';
|
||||
data.forEach(city => {
|
||||
const option = document.createElement('option');
|
||||
option.value = city.name_en; // Using name as value for DB compatibility
|
||||
@ -335,10 +335,10 @@ if (!$isAjax):
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching cities:', error);
|
||||
citySelect.innerHTML = '<option value="">Error loading cities</option>';
|
||||
citySelect.innerHTML = '<option value=""><?= t('error_loading_cities') ?></option>';
|
||||
});
|
||||
} else {
|
||||
citySelect.innerHTML = '<option value="">Select City</option>';
|
||||
citySelect.innerHTML = '<option value=""><?= t('select_city_placeholder') ?></option>';
|
||||
citySelect.disabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
@ -13,7 +13,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'], $_POST['shi
|
||||
|
||||
if ($action === 'delete') {
|
||||
db()->prepare("DELETE FROM shipments WHERE id = ?")->execute([$shipmentId]);
|
||||
$flash = 'Shipment deleted successfully.';
|
||||
$flash = t('flash_shipment_deleted');
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ $stmt = db()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$shipments = $stmt->fetchAll();
|
||||
|
||||
render_header('Manage Shipments', 'admin', true);
|
||||
render_header(t('manage_shipments'), 'admin', true);
|
||||
?>
|
||||
|
||||
<div class="row g-0">
|
||||
@ -76,8 +76,8 @@ render_header('Manage Shipments', 'admin', true);
|
||||
<div class="col-md-10 p-4">
|
||||
<div class="page-intro d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-4">
|
||||
<div>
|
||||
<h1 class="section-title mb-1">Shipments</h1>
|
||||
<p class="muted mb-0">Manage all shipments across the platform.</p>
|
||||
<h1 class="section-title mb-1"><?= t('shipments_header') ?></h1>
|
||||
<p class="muted mb-0"><?= t('shipments_subtitle') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -88,51 +88,51 @@ render_header('Manage Shipments', 'admin', true);
|
||||
<div class="panel p-4 mb-4">
|
||||
<form method="get" class="row g-3">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label small text-muted">Search</label>
|
||||
<input type="text" name="q" class="form-control" placeholder="Search shipments..." value="<?= e($q) ?>">
|
||||
<label class="form-label small text-muted"><?= t('search_label') ?></label>
|
||||
<input type="text" name="q" class="form-control" placeholder="<?= t('search_shipments_placeholder') ?>" value="<?= e($q) ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">Status</label>
|
||||
<label class="form-label small text-muted"><?= t('status') ?></label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="">All Statuses</option>
|
||||
<option value="posted" <?= $status === 'posted' ? 'selected' : '' ?>>Posted</option>
|
||||
<option value="offered" <?= $status === 'offered' ? 'selected' : '' ?>>Offered</option>
|
||||
<option value="confirmed" <?= $status === 'confirmed' ? 'selected' : '' ?>>Confirmed</option>
|
||||
<option value="in_transit" <?= $status === 'in_transit' ? 'selected' : '' ?>>In Transit</option>
|
||||
<option value="delivered" <?= $status === 'delivered' ? 'selected' : '' ?>>Delivered</option>
|
||||
<option value=""><?= t('all_statuses') ?></option>
|
||||
<option value="posted" <?= $status === 'posted' ? 'selected' : '' ?>><?= t('status_posted') ?></option>
|
||||
<option value="offered" <?= $status === 'offered' ? 'selected' : '' ?>><?= t('status_offered') ?></option>
|
||||
<option value="confirmed" <?= $status === 'confirmed' ? 'selected' : '' ?>><?= t('status_confirmed') ?></option>
|
||||
<option value="in_transit" <?= $status === 'in_transit' ? 'selected' : '' ?>><?= t('status_in_transit') ?></option>
|
||||
<option value="delivered" <?= $status === 'delivered' ? 'selected' : '' ?>><?= t('status_delivered') ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">Sort By</label>
|
||||
<label class="form-label small text-muted"><?= t('sort_by') ?></label>
|
||||
<select name="sort" class="form-select">
|
||||
<option value="newest" <?= $sort === 'newest' ? 'selected' : '' ?>>Newest First</option>
|
||||
<option value="oldest" <?= $sort === 'oldest' ? 'selected' : '' ?>>Oldest First</option>
|
||||
<option value="pickup_asc" <?= $sort === 'pickup_asc' ? 'selected' : '' ?>>Pickup Date (Soonest)</option>
|
||||
<option value="pickup_desc" <?= $sort === 'pickup_desc' ? 'selected' : '' ?>>Pickup Date (Latest)</option>
|
||||
<option value="newest" <?= $sort === 'newest' ? 'selected' : '' ?>><?= t('sort_newest') ?></option>
|
||||
<option value="oldest" <?= $sort === 'oldest' ? 'selected' : '' ?>><?= t('sort_oldest') ?></option>
|
||||
<option value="pickup_asc" <?= $sort === 'pickup_asc' ? 'selected' : '' ?>><?= t('sort_pickup_soonest') ?></option>
|
||||
<option value="pickup_desc" <?= $sort === 'pickup_desc' ? 'selected' : '' ?>><?= t('sort_pickup_latest') ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-1 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary w-100">Filter</button>
|
||||
<button type="submit" class="btn btn-primary w-100"><?= t('filter') ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="panel p-0">
|
||||
<?php if (!$shipments && ($q || $status)): ?>
|
||||
<div class="p-4"><p class="muted mb-0">No shipments found matching your criteria.</p></div>
|
||||
<div class="p-4"><p class="muted mb-0"><?= t('no_shipments_found_criteria') ?></p></div>
|
||||
<?php elseif (!$shipments): ?>
|
||||
<div class="p-4"><p class="muted mb-0">No shipments found on the platform yet.</p></div>
|
||||
<div class="p-4"><p class="muted mb-0"><?= t('no_shipments_platform') ?></p></div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table mb-0 align-middle table-hover">
|
||||
<thead class="table-light">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="ps-4">ID</th>
|
||||
<th>Shipper</th>
|
||||
<th>Route</th>
|
||||
<th>Dates</th>
|
||||
<th>Status</th>
|
||||
<th class="text-end pe-4">Action</th>
|
||||
<th class="ps-4"><?= t('id_col') ?></th>
|
||||
<th><?= t('shipper') ?></th>
|
||||
<th><?= t('route_label') ?></th>
|
||||
<th><?= t('dates_col') ?></th>
|
||||
<th><?= t('status') ?></th>
|
||||
<th class="text-end pe-4"><?= t('action') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -144,12 +144,12 @@ render_header('Manage Shipments', 'admin', true);
|
||||
<div class="text-muted small"><?= e((string)$shipment['shipper_company']) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<div><span class="text-muted small">From:</span> <?= e($shipment['origin_city']) ?></div>
|
||||
<div><span class="text-muted small">To:</span> <?= e($shipment['destination_city']) ?></div>
|
||||
<div><span class="text-muted small"><?= t('from_label') ?></span> <?= e($shipment['origin_city']) ?></div>
|
||||
<div><span class="text-muted small"><?= t('to_label') ?></span> <?= e($shipment['destination_city']) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="small"><span class="text-muted">Pick:</span> <?= e($shipment['pickup_date']) ?></div>
|
||||
<div class="small"><span class="text-muted">Drop:</span> <?= e($shipment['delivery_date']) ?></div>
|
||||
<div class="small"><span class="text-muted"><?= t('pick_label') ?></span> <?= e($shipment['pickup_date']) ?></div>
|
||||
<div class="small"><span class="text-muted"><?= t('drop_label') ?></span> <?= e($shipment['delivery_date']) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
@ -160,23 +160,23 @@ render_header('Manage Shipments', 'admin', true);
|
||||
elseif ($shipment['status'] === 'in_transit') $statusClass = 'bg-warning-subtle text-warning';
|
||||
elseif ($shipment['status'] === 'delivered') $statusClass = 'bg-dark-subtle text-dark';
|
||||
?>
|
||||
<span class="badge <?= $statusClass ?>"><?= e(ucfirst(str_replace('_', ' ', $shipment['status']))) ?></span>
|
||||
<span class="badge <?= $statusClass ?>"><?= e(status_label($shipment['status'])) ?></span>
|
||||
</td>
|
||||
<td class="text-end pe-4">
|
||||
<div class="d-inline-flex gap-1 align-items-center">
|
||||
<a href="shipment_detail.php?id=<?= e((string)$shipment['id']) ?>" class="btn btn-sm p-1 border-0 bg-transparent text-primary" title="View Shipment">
|
||||
<a href="shipment_detail.php?id=<?= e((string)$shipment['id']) ?>" class="btn btn-sm p-1 border-0 bg-transparent text-primary" title="<?= t('view_shipment') ?>">
|
||||
<i class="bi bi-eye"></i>
|
||||
</a>
|
||||
<a href="admin_shipment_edit.php?id=<?= e((string)$shipment['id']) ?>"
|
||||
class="btn btn-sm p-1 border-0 bg-transparent text-primary ajax-modal-trigger"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#editModal"
|
||||
title="Edit Shipment">
|
||||
title="<?= t('edit_shipment_tooltip') ?>">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
<form method="post" class="d-inline m-0 p-0">
|
||||
<input type="hidden" name="shipment_id" value="<?= e((string)$shipment['id']) ?>">
|
||||
<button type="submit" name="action" value="delete" class="btn btn-sm p-1 border-0 bg-transparent text-danger" onclick="return confirm('Delete this shipment?');" title="Delete">
|
||||
<button type="submit" name="action" value="delete" class="btn btn-sm p-1 border-0 bg-transparent text-danger" onclick="return confirm('<?= t('confirm_delete_shipment') ?>');" title="<?= t('delete') ?>">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
@ -190,10 +190,10 @@ render_header('Manage Shipments', 'admin', true);
|
||||
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<div class="px-4 py-3 border-top d-flex justify-content-between align-items-center">
|
||||
<span class="text-muted small">Showing <?= count($shipments) ?> of <?= $total ?> shipments</span>
|
||||
<span class="text-muted small"><?= t('showing') ?> <?= count($shipments) ?> <?= t('of') ?> <?= $total ?> <?= t('shipments_header') ?></span>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>">
|
||||
<a class="page-link" href="?q=<?= urlencode($q) ?>&status=<?= urlencode($status) ?>&sort=<?= urlencode($sort) ?>&page=<?= $page - 1 ?>">Previous</a>
|
||||
<a class="page-link" href="?q=<?= urlencode($q) ?>&status=<?= urlencode($status) ?>&sort=<?= urlencode($sort) ?>&page=<?= $page - 1 ?>"><?= t('previous') ?></a>
|
||||
</li>
|
||||
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
|
||||
<li class="page-item <?= $i === $page ? 'active' : '' ?>">
|
||||
@ -201,7 +201,7 @@ render_header('Manage Shipments', 'admin', true);
|
||||
</li>
|
||||
<?php endfor; ?>
|
||||
<li class="page-item <?= $page >= $totalPages ? 'disabled' : '' ?>">
|
||||
<a class="page-link" href="?q=<?= urlencode($q) ?>&status=<?= urlencode($status) ?>&sort=<?= urlencode($sort) ?>&page=<?= $page + 1 ?>">Next</a>
|
||||
<a class="page-link" href="?q=<?= urlencode($q) ?>&status=<?= urlencode($status) ?>&sort=<?= urlencode($sort) ?>&page=<?= $page + 1 ?>"><?= t('next') ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -216,12 +216,12 @@ render_header('Manage Shipments', 'admin', true);
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="editModalLabel">Edit</h5>
|
||||
<h5 class="modal-title" id="editModalLabel"><?= t('edit_shipment_tooltip') ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center p-5">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
<span class="visually-hidden"><?= t('loading') ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -242,7 +242,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
modalContent.innerHTML = `
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Loading...</h5>
|
||||
<h5 class="modal-title"><?= t('loading') ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center p-5">
|
||||
@ -275,7 +275,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const submitBtn = form.querySelector('button[type="submit"]');
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Saving...';
|
||||
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...';
|
||||
}
|
||||
|
||||
const formData = new FormData(form);
|
||||
@ -287,14 +287,14 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
} else {
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Save Changes';
|
||||
submitBtn.textContent = '<?= t('save_changes') ?>';
|
||||
}
|
||||
const errDiv = form.querySelector('#form-errors');
|
||||
if(errDiv) {
|
||||
errDiv.classList.remove('d-none');
|
||||
errDiv.innerHTML = data.message;
|
||||
} else {
|
||||
alert(data.message || 'An error occurred');
|
||||
alert(data.message || '<?= t('error_occurred') ?>');
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -302,15 +302,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
console.error(err);
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Save Changes';
|
||||
submitBtn.textContent = '<?= t('save_changes') ?>';
|
||||
}
|
||||
alert('An error occurred while saving.');
|
||||
alert('<?= t('error_occurred') ?>');
|
||||
});
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
modalContent.innerHTML = `<div class="modal-body text-danger">Failed to load form.</div>`;
|
||||
modalContent.innerHTML = `<div class="modal-body text-danger"><?= t('failed_load_form') ?></div>`;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -83,7 +83,7 @@ $stmt = db()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$shippers = $stmt->fetchAll();
|
||||
|
||||
render_header('Manage Shippers', 'admin', true);
|
||||
render_header(t('manage_shippers'), 'admin', true);
|
||||
?>
|
||||
|
||||
<div class="row g-0">
|
||||
@ -93,8 +93,8 @@ render_header('Manage Shippers', 'admin', true);
|
||||
<div class="col-md-10 p-4">
|
||||
<div class="page-intro d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-4">
|
||||
<div>
|
||||
<h1 class="section-title mb-1">Shippers</h1>
|
||||
<p class="muted mb-0">Manage registered shippers.</p>
|
||||
<h1 class="section-title mb-1"><?= e(t('shippers')) ?></h1>
|
||||
<p class="muted mb-0"><?= e(t('manage_registered_shippers')) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -105,40 +105,40 @@ render_header('Manage Shippers', 'admin', true);
|
||||
<div class="panel p-4 mb-4">
|
||||
<form method="get" class="row g-3">
|
||||
<div class="col-md-8">
|
||||
<label class="form-label small text-muted">Search</label>
|
||||
<input type="text" name="q" class="form-control" placeholder="Search name, email, company..." value="<?= e($q) ?>">
|
||||
<label class="form-label small text-muted"><?= e(t('search_placeholder_shipper')) ?></label>
|
||||
<input type="text" name="q" class="form-control" placeholder="<?= e(t('search_placeholder_shipper')) ?>" value="<?= e($q) ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">Status</label>
|
||||
<label class="form-label small text-muted"><?= e(t('status')) ?></label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="">All Statuses</option>
|
||||
<option value="active" <?= $status === 'active' ? 'selected' : '' ?>>Active</option>
|
||||
<option value="pending" <?= $status === 'pending' ? 'selected' : '' ?>>Pending</option>
|
||||
<option value="rejected" <?= $status === 'rejected' ? 'selected' : '' ?>>Rejected</option>
|
||||
<option value=""><?= e(t('all_statuses')) ?></option>
|
||||
<option value="active" <?= $status === 'active' ? 'selected' : '' ?>><?= e(t('active')) ?></option>
|
||||
<option value="pending" <?= $status === 'pending' ? 'selected' : '' ?>><?= e(t('pending')) ?></option>
|
||||
<option value="rejected" <?= $status === 'rejected' ? 'selected' : '' ?>><?= e(t('rejected')) ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-1 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary w-100">Filter</button>
|
||||
<button type="submit" class="btn btn-primary w-100"><?= e(t('filter')) ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="panel p-0">
|
||||
<?php if (!$shippers && ($q || $status)): ?>
|
||||
<div class="p-4"><p class="muted mb-0">No shippers found matching your criteria.</p></div>
|
||||
<div class="p-4"><p class="muted mb-0"><?= e(t('no_shippers_criteria')) ?></p></div>
|
||||
<?php elseif (!$shippers): ?>
|
||||
<div class="p-4"><p class="muted mb-0">No shippers registered yet.</p></div>
|
||||
<div class="p-4"><p class="muted mb-0"><?= e(t('no_shippers_registered')) ?></p></div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table mb-0 align-middle table-hover">
|
||||
<thead class="table-light">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="ps-4">ID</th>
|
||||
<th>Name / Company</th>
|
||||
<th>Contact</th>
|
||||
<th>Location</th>
|
||||
<th>Status</th>
|
||||
<th class="text-end pe-4">Action</th>
|
||||
<th><?= e(t('name_company')) ?></th>
|
||||
<th><?= e(t('contact')) ?></th>
|
||||
<th><?= e(t('location')) ?></th>
|
||||
<th><?= e(t('status')) ?></th>
|
||||
<th class="text-end pe-4"><?= e(t('action')) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -158,9 +158,9 @@ render_header('Manage Shippers', 'admin', true);
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($shipper['status'] === 'active'): ?>
|
||||
<span class="badge bg-success-subtle text-success">Active</span>
|
||||
<span class="badge bg-success-subtle text-success"><?= e(t('active')) ?></span>
|
||||
<?php elseif ($shipper['status'] === 'pending'): ?>
|
||||
<span class="badge bg-warning-subtle text-warning">Pending</span>
|
||||
<span class="badge bg-warning-subtle text-warning"><?= e(t('pending')) ?></span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-danger-subtle text-danger"><?= e(ucfirst($shipper['status'] ?? 'unknown')) ?></span>
|
||||
<?php endif; ?>
|
||||
@ -171,22 +171,22 @@ render_header('Manage Shippers', 'admin', true);
|
||||
class="btn btn-sm p-1 border-0 bg-transparent text-primary ajax-modal-trigger"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#editModal"
|
||||
title="Edit Shipper">
|
||||
title="<?= e(t('edit_shipper')) ?>">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
<form method="post" class="d-inline m-0 p-0">
|
||||
<input type="hidden" name="user_id" value="<?= e((string)$shipper['id']) ?>">
|
||||
<?php if ($shipper['status'] !== 'active'): ?>
|
||||
<button type="submit" name="action" value="approve" class="btn btn-sm p-1 border-0 bg-transparent text-success" title="Approve">
|
||||
<button type="submit" name="action" value="approve" class="btn btn-sm p-1 border-0 bg-transparent text-success" title="<?= e(t('approve')) ?>">
|
||||
<i class="bi bi-check-lg"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($shipper['status'] !== 'rejected'): ?>
|
||||
<button type="submit" name="action" value="reject" class="btn btn-sm p-1 border-0 bg-transparent text-warning" title="Reject">
|
||||
<button type="submit" name="action" value="reject" class="btn btn-sm p-1 border-0 bg-transparent text-warning" title="<?= e(t('reject')) ?>">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<button type="submit" name="action" value="delete" class="btn btn-sm p-1 border-0 bg-transparent text-danger" onclick="return confirm('Delete this shipper forever?');" title="Delete">
|
||||
<button type="submit" name="action" value="delete" class="btn btn-sm p-1 border-0 bg-transparent text-danger" onclick="return confirm('<?= e(t('delete_confirm_shipper')) ?>');" title="<?= e(t('delete')) ?>">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
@ -200,7 +200,7 @@ render_header('Manage Shippers', 'admin', true);
|
||||
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<div class="px-4 py-3 border-top d-flex justify-content-between align-items-center">
|
||||
<span class="text-muted small">Showing <?= count($shippers) ?> of <?= $total ?> shippers</span>
|
||||
<span class="text-muted small"><?= e(t('shown')) ?> <?= count($shippers) ?> of <?= $total ?> <?= e(t('shippers')) ?></span>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>">
|
||||
<a class="page-link" href="?q=<?= urlencode($q) ?>&status=<?= urlencode($status) ?>&page=<?= $page - 1 ?>">Previous</a>
|
||||
@ -226,12 +226,12 @@ render_header('Manage Shippers', 'admin', true);
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="editModalLabel">Edit</h5>
|
||||
<h5 class="modal-title" id="editModalLabel"><?= e(t('edit_shipper')) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center p-5">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
<span class="visually-hidden"><?= e(t('loading')) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -252,7 +252,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
modalContent.innerHTML = `
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Loading...</h5>
|
||||
<h5 class="modal-title"><?= e(t('loading')) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center p-5">
|
||||
@ -285,7 +285,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const submitBtn = form.querySelector('button[type="submit"]');
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Saving...';
|
||||
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> <?= e(t('loading')) ?>';
|
||||
}
|
||||
|
||||
const formData = new FormData(form);
|
||||
@ -297,7 +297,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
} else {
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Save Changes';
|
||||
submitBtn.textContent = '<?= e(t('save_changes')) ?>';
|
||||
}
|
||||
const errDiv = form.querySelector('#form-errors');
|
||||
if(errDiv) {
|
||||
@ -312,7 +312,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
console.error(err);
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Save Changes';
|
||||
submitBtn.textContent = '<?= e(t('save_changes')) ?>';
|
||||
}
|
||||
alert('An error occurred while saving.');
|
||||
});
|
||||
|
||||
@ -83,7 +83,7 @@ $stmt = db()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$owners = $stmt->fetchAll();
|
||||
|
||||
render_header('Manage Truck Owners', 'admin', true);
|
||||
render_header(t('manage_truck_owners'), 'admin', true);
|
||||
?>
|
||||
|
||||
<div class="row g-0">
|
||||
@ -93,8 +93,8 @@ render_header('Manage Truck Owners', 'admin', true);
|
||||
<div class="col-md-10 p-4">
|
||||
<div class="page-intro d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-4">
|
||||
<div>
|
||||
<h1 class="section-title mb-1">Truck Owners</h1>
|
||||
<p class="muted mb-0">Review registrations and approve truck owners.</p>
|
||||
<h1 class="section-title mb-1"><?= e(t('truck_owners')) ?></h1>
|
||||
<p class="muted mb-0"><?= e(t('review_registrations')) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -105,40 +105,40 @@ render_header('Manage Truck Owners', 'admin', true);
|
||||
<div class="panel p-4 mb-4">
|
||||
<form method="get" class="row g-3">
|
||||
<div class="col-md-8">
|
||||
<label class="form-label small text-muted">Search</label>
|
||||
<input type="text" name="q" class="form-control" placeholder="Search name, email, plate..." value="<?= e($q) ?>">
|
||||
<label class="form-label small text-muted"><?= e(t('search_placeholder_owner')) ?></label>
|
||||
<input type="text" name="q" class="form-control" placeholder="<?= e(t('search_placeholder_owner')) ?>" value="<?= e($q) ?>">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small text-muted">Status</label>
|
||||
<label class="form-label small text-muted"><?= e(t('status')) ?></label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="">All Statuses</option>
|
||||
<option value="active" <?= $status === 'active' ? 'selected' : '' ?>>Active</option>
|
||||
<option value="pending" <?= $status === 'pending' ? 'selected' : '' ?>>Pending</option>
|
||||
<option value="rejected" <?= $status === 'rejected' ? 'selected' : '' ?>>Rejected</option>
|
||||
<option value=""><?= e(t('all_statuses')) ?></option>
|
||||
<option value="active" <?= $status === 'active' ? 'selected' : '' ?>><?= e(t('active')) ?></option>
|
||||
<option value="pending" <?= $status === 'pending' ? 'selected' : '' ?>><?= e(t('pending')) ?></option>
|
||||
<option value="rejected" <?= $status === 'rejected' ? 'selected' : '' ?>><?= e(t('rejected')) ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-1 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary w-100">Filter</button>
|
||||
<button type="submit" class="btn btn-primary w-100"><?= e(t('filter')) ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="panel p-0">
|
||||
<?php if (!$owners && ($q || $status)): ?>
|
||||
<div class="p-4"><p class="muted mb-0">No truck owners found matching your criteria.</p></div>
|
||||
<div class="p-4"><p class="muted mb-0"><?= e(t('no_owners_criteria')) ?></p></div>
|
||||
<?php elseif (!$owners): ?>
|
||||
<div class="p-4"><p class="muted mb-0">No truck owners registered yet.</p></div>
|
||||
<div class="p-4"><p class="muted mb-0"><?= e(t('no_owners_registered')) ?></p></div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table mb-0 align-middle table-hover">
|
||||
<thead class="table-light">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="ps-4">ID</th>
|
||||
<th>Name / Email</th>
|
||||
<th>Truck Info</th>
|
||||
<th>Documents</th>
|
||||
<th>Status</th>
|
||||
<th class="text-end pe-4">Action</th>
|
||||
<th><?= e(t('name_email')) ?></th>
|
||||
<th><?= e(t('truck_info')) ?></th>
|
||||
<th><?= e(t('documents')) ?></th>
|
||||
<th><?= e(t('status')) ?></th>
|
||||
<th class="text-end pe-4"><?= e(t('action')) ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -151,9 +151,9 @@ render_header('Manage Truck Owners', 'admin', true);
|
||||
<div class="text-muted small"><?= e((string)$owner['phone']) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<div><strong>Type:</strong> <?= e((string)$owner['truck_type']) ?></div>
|
||||
<div><strong>Cap:</strong> <?= e((string)$owner['load_capacity']) ?>t</div>
|
||||
<div><strong>Plate:</strong> <?= e((string)$owner['plate_no']) ?></div>
|
||||
<div><strong><?= e(t('truck_type')) ?>:</strong> <?= e((string)$owner['truck_type']) ?></div>
|
||||
<div><strong><?= e(t('cap')) ?>:</strong> <?= e((string)$owner['load_capacity']) ?>t</div>
|
||||
<div><strong><?= e(t('truck_plate')) ?>:</strong> <?= e((string)$owner['plate_no']) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary d-flex align-items-center gap-1" data-bs-toggle="modal" data-bs-target="#docsModal<?= $owner['id'] ?>">
|
||||
@ -161,14 +161,14 @@ render_header('Manage Truck Owners', 'admin', true);
|
||||
<path d="M5.5 7a.5.5 0 0 0 0 1h5a.5.5 0 0 0 0-1zM5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5m0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5"/>
|
||||
<path d="M9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5zm0 1v2A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1z"/>
|
||||
</svg>
|
||||
View Docs
|
||||
<?= e(t('view_docs')) ?>
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($owner['status'] === 'active'): ?>
|
||||
<span class="badge bg-success-subtle text-success">Active</span>
|
||||
<span class="badge bg-success-subtle text-success"><?= e(t('active')) ?></span>
|
||||
<?php elseif ($owner['status'] === 'pending'): ?>
|
||||
<span class="badge bg-warning-subtle text-warning">Pending</span>
|
||||
<span class="badge bg-warning-subtle text-warning"><?= e(t('pending')) ?></span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-danger-subtle text-danger"><?= e(ucfirst($owner['status'] ?? 'unknown')) ?></span>
|
||||
<?php endif; ?>
|
||||
@ -179,22 +179,22 @@ render_header('Manage Truck Owners', 'admin', true);
|
||||
class="btn btn-sm p-1 border-0 bg-transparent text-primary ajax-modal-trigger"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#editModal"
|
||||
title="Edit Owner">
|
||||
title="<?= e(t('edit_owner')) ?>">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
<form method="post" class="d-inline m-0 p-0">
|
||||
<input type="hidden" name="user_id" value="<?= e((string)$owner['id']) ?>">
|
||||
<?php if ($owner['status'] !== 'active'): ?>
|
||||
<button type="submit" name="action" value="approve" class="btn btn-sm p-1 border-0 bg-transparent text-success" title="Approve">
|
||||
<button type="submit" name="action" value="approve" class="btn btn-sm p-1 border-0 bg-transparent text-success" title="<?= e(t('approve')) ?>">
|
||||
<i class="bi bi-check-lg"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($owner['status'] !== 'rejected'): ?>
|
||||
<button type="submit" name="action" value="reject" class="btn btn-sm p-1 border-0 bg-transparent text-warning" title="Reject">
|
||||
<button type="submit" name="action" value="reject" class="btn btn-sm p-1 border-0 bg-transparent text-warning" title="<?= e(t('reject')) ?>">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<button type="submit" name="action" value="delete" class="btn btn-sm p-1 border-0 bg-transparent text-danger" onclick="return confirm('Delete this truck owner forever?');" title="Delete">
|
||||
<button type="submit" name="action" value="delete" class="btn btn-sm p-1 border-0 bg-transparent text-danger" onclick="return confirm('<?= e(t('delete_confirm_owner')) ?>');" title="<?= e(t('delete')) ?>">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
@ -208,7 +208,7 @@ render_header('Manage Truck Owners', 'admin', true);
|
||||
|
||||
<?php if ($totalPages > 1): ?>
|
||||
<div class="px-4 py-3 border-top d-flex justify-content-between align-items-center">
|
||||
<span class="text-muted small">Showing <?= count($owners) ?> of <?= $total ?> truck owners</span>
|
||||
<span class="text-muted small"><?= e(t('shown')) ?> <?= count($owners) ?> of <?= $total ?> <?= e(t('truck_owners')) ?></span>
|
||||
<ul class="pagination pagination-sm mb-0">
|
||||
<li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>">
|
||||
<a class="page-link" href="?q=<?= urlencode($q) ?>&status=<?= urlencode($status) ?>&page=<?= $page - 1 ?>">Previous</a>
|
||||
@ -234,12 +234,12 @@ render_header('Manage Truck Owners', 'admin', true);
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="editModalLabel">Edit</h5>
|
||||
<h5 class="modal-title" id="editModalLabel"><?= e(t('edit_owner')) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center p-5">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
<span class="visually-hidden"><?= e(t('loading')) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -256,11 +256,11 @@ $pic = $owner['truck_pic_path'];
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Documents for <?= e($owner['full_name']) ?></h5>
|
||||
<h5 class="modal-title"><?= e(t('docs_for')) ?> <?= e($owner['full_name']) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h6>ID Card</h6>
|
||||
<h6><?= e(t('id_card_front')) ?> / <?= e(t('id_card_back')) ?></h6>
|
||||
<div class="d-flex gap-2 mb-3 overflow-auto">
|
||||
<?php foreach ($idCards as $path): ?>
|
||||
<a href="<?= e('/' . $path) ?>" target="_blank">
|
||||
@ -269,7 +269,7 @@ $pic = $owner['truck_pic_path'];
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<h6>Truck Registration</h6>
|
||||
<h6><?= e(t('truck_reg')) ?></h6>
|
||||
<div class="d-flex gap-2 mb-3 overflow-auto">
|
||||
<?php foreach ($regs as $path): ?>
|
||||
<a href="<?= e('/' . $path) ?>" target="_blank">
|
||||
@ -278,7 +278,7 @@ $pic = $owner['truck_pic_path'];
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<h6>Truck Picture</h6>
|
||||
<h6><?= e(t('truck_picture')) ?></h6>
|
||||
<?php if ($pic): ?>
|
||||
<div>
|
||||
<a href="<?= e('/' . $pic) ?>" target="_blank">
|
||||
@ -286,7 +286,7 @@ $pic = $owner['truck_pic_path'];
|
||||
</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">No picture uploaded.</span>
|
||||
<span class="text-muted"><?= e(t('no_picture')) ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@ -312,7 +312,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Reset to loading state
|
||||
modalContent.innerHTML = `
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Loading...</h5>
|
||||
<h5 class="modal-title"><?= e(t('loading')) ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center p-5">
|
||||
@ -357,7 +357,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const submitBtn = form.querySelector('button[type="submit"]');
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Saving...';
|
||||
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> <?= e(t('loading')) ?>';
|
||||
}
|
||||
|
||||
const formData = new FormData(form);
|
||||
@ -370,7 +370,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
} else {
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Save Changes';
|
||||
submitBtn.textContent = '<?= e(t('save_changes')) ?>';
|
||||
}
|
||||
const errDiv = form.querySelector('#form-errors');
|
||||
if(errDiv) {
|
||||
@ -385,7 +385,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
console.error(err);
|
||||
if(submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Save Changes';
|
||||
submitBtn.textContent = '<?= e(t('save_changes')) ?>';
|
||||
}
|
||||
alert('An error occurred while saving.');
|
||||
});
|
||||
|
||||
@ -311,6 +311,11 @@ body.app-body {
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
|
||||
/* Fix text-muted in table headers */
|
||||
.table thead th .text-muted {
|
||||
color: var(--sidebar-muted) !important;
|
||||
}
|
||||
|
||||
.table tbody td {
|
||||
vertical-align: middle;
|
||||
padding: 16px 8px;
|
||||
@ -537,3 +542,124 @@ body.app-body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
/* Global Print Styles */
|
||||
@media print {
|
||||
/* Hide browser-added headers/footers (title, date, URL) */
|
||||
@page {
|
||||
margin-top: 1cm;
|
||||
margin-bottom: 1cm;
|
||||
size: auto;
|
||||
}
|
||||
|
||||
/* Kill standard href expansion */
|
||||
a[href]:after {
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
body, [data-theme="dark"] body.app-body {
|
||||
background: #ffffff !important;
|
||||
color: #000000 !important;
|
||||
/* Padding to emulate margin if @page fails */
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* Hide Sidebar, Nav, and Standard Footer */
|
||||
.admin-sidebar,
|
||||
.navbar,
|
||||
.btn,
|
||||
form,
|
||||
.no-print,
|
||||
footer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Expand main content */
|
||||
.col-md-10, .col-lg-10, .col-xl-10 {
|
||||
width: 100% !important;
|
||||
flex: 0 0 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* Reset Panels/Cards for print */
|
||||
.panel, .card {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
background: #ffffff !important;
|
||||
}
|
||||
|
||||
/* Table Adjustments */
|
||||
.table {
|
||||
width: 100% !important;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
background-color: #f8f9fa !important;
|
||||
color: #000000 !important;
|
||||
border-bottom: 2px solid #000000 !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
/* Ensure muted text in headers is visible (dark gray/black) */
|
||||
.table thead th .text-muted {
|
||||
color: #333333 !important;
|
||||
}
|
||||
|
||||
.table tbody td {
|
||||
border-bottom: 1px solid #dee2e6 !important;
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
/* Typography Overrides */
|
||||
h1, h2, h3, h4, h5, h6, p, span, div, td, th {
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #555555 !important;
|
||||
}
|
||||
|
||||
.text-white {
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
/* Badges to outlines */
|
||||
.badge {
|
||||
border: 1px solid #000 !important;
|
||||
background: transparent !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
/* Ensure visibility utilities work in print */
|
||||
.d-print-block {
|
||||
display: block !important;
|
||||
}
|
||||
.d-print-none {
|
||||
display: none !important;
|
||||
}
|
||||
.print-no-shadow {
|
||||
box-shadow: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* Sticky Footer */
|
||||
.print-footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
background: white;
|
||||
padding: 10px 0;
|
||||
border-top: 1px solid #000 !important;
|
||||
z-index: 999;
|
||||
}
|
||||
}
|
||||
329
includes/app.php
329
includes/app.php
@ -122,91 +122,82 @@ $translations = [
|
||||
'pages' => 'Pages',
|
||||
'faqs' => 'FAQs',
|
||||
'landing_pages' => 'Landing Pages',
|
||||
'login_title' => 'Welcome Back',
|
||||
'login_subtitle' => 'Sign in to your account to continue',
|
||||
'email_address' => 'Email address',
|
||||
'email_placeholder' => 'name@example.com',
|
||||
'password' => 'Password',
|
||||
'forgot_password' => 'Forgot password?',
|
||||
'password_placeholder' => 'Enter your password',
|
||||
'change_password' => 'Change Password',
|
||||
'new_password' => 'New Password',
|
||||
'confirm_password' => 'Confirm Password',
|
||||
'passwords_do_not_match' => 'Passwords do not match.',
|
||||
'password_too_short' => 'Password must be at least 6 characters.',
|
||||
'password_updated' => 'Password updated successfully.',
|
||||
'sign_in' => 'Sign In',
|
||||
'dont_have_account' => 'Don\'t have an account?',
|
||||
'register_now' => 'Register now',
|
||||
'reset_password_title' => 'Reset Password',
|
||||
'reset_password_subtitle' => 'Enter your email and we\'ll send you a link to reset your password',
|
||||
'send_reset_link' => 'Send Reset Link',
|
||||
'back_to_login' => 'Back to login',
|
||||
'invalid_image' => 'Invalid image format. Please upload JPG, PNG, GIF, or WEBP.',
|
||||
'upload_failed' => 'Failed to save uploaded file.',
|
||||
'profile_updated' => 'Profile updated successfully.',
|
||||
'my_profile' => 'My Profile',
|
||||
'profile_picture' => 'Profile Picture',
|
||||
'change_picture' => 'Change Picture',
|
||||
'picture_hint' => 'JPG, PNG, or GIF up to 5MB',
|
||||
'full_name' => 'Full Name',
|
||||
'email_hint' => 'Email address cannot be changed.',
|
||||
'account_role' => 'Account Role',
|
||||
'save_changes' => 'Save Changes',
|
||||
'reg_title' => 'Create your logistics account',
|
||||
'reg_subtitle' => 'Shippers and truck owners can self-register with full profile details.',
|
||||
'reg_success_pending' => 'Registration completed successfully. Your account is pending admin approval.',
|
||||
'reg_success' => 'Registration completed successfully.',
|
||||
'role' => 'Role',
|
||||
'shipper' => 'Shipper',
|
||||
'truck_owner' => 'Truck Owner',
|
||||
'email' => 'Email',
|
||||
'phone' => 'Phone',
|
||||
'country' => 'Country',
|
||||
'select_country' => 'Select country',
|
||||
'city' => 'City',
|
||||
'select_city' => 'Select city',
|
||||
'address' => 'Address',
|
||||
'shipper_details' => 'Shipper details',
|
||||
'company_name' => 'Company name',
|
||||
'truck_details' => 'Truck owner details',
|
||||
'truck_type' => 'Truck type',
|
||||
'load_capacity' => 'Load capacity (tons)',
|
||||
'plate_no' => 'Plate number',
|
||||
'bank_account' => 'Bank Account / IBAN',
|
||||
'bank_name' => 'Bank Name',
|
||||
'bank_branch' => 'Bank Branch',
|
||||
'id_card_front' => 'ID card (Front Face)',
|
||||
'id_card_back' => 'ID card (Back Face)',
|
||||
'truck_reg_front' => 'Truck Registration (Front Face)',
|
||||
'truck_reg_back' => 'Truck Registration (Back Face)',
|
||||
'truck_picture' => 'Clear Truck Photo (showing plate number)',
|
||||
'create_account' => 'Create account',
|
||||
'back_to_admin' => 'Back to admin',
|
||||
'welcome_back' => 'Welcome to your dashboard. Manage your cargo shipments here.',
|
||||
'total_shipments_posted' => 'Total Shipments',
|
||||
'active_shipments' => 'Active Shipments',
|
||||
'delivered_shipments' => 'Delivered Shipments',
|
||||
'route_label' => 'Route',
|
||||
'total_label' => 'total',
|
||||
'welcome_back_owner' => 'Find loads and submit your best rate.',
|
||||
'total_offers' => 'Total Offers',
|
||||
'won_shipments' => 'Won Shipments',
|
||||
'nav_platform_users' => 'Platform Users',
|
||||
'notification_templates' => 'Notification Templates',
|
||||
'manage_permissions' => 'Manage Permissions',
|
||||
'create_user' => 'Create User',
|
||||
'edit_user' => 'Edit User',
|
||||
'delete_user' => 'Delete User',
|
||||
'confirm_delete' => 'Are you sure you want to delete this user?',
|
||||
'permissions' => 'Permissions',
|
||||
'no_users' => 'No platform users found.',
|
||||
'user_created' => 'User created successfully.',
|
||||
'user_updated' => 'User updated successfully.',
|
||||
'user_deleted' => 'User deleted successfully.',
|
||||
'error_email_exists' => 'Email already exists.',
|
||||
'shipper_shipments' => 'Shipper Shipments',
|
||||
'truck_owners_statements' => 'Truck Owner Statements'
|
||||
'edit_homepage' => 'Edit homepage content and sections',
|
||||
'view_details' => 'View Details',
|
||||
'manage_shippers' => 'Manage Shippers',
|
||||
'manage_registered_shippers' => 'Manage registered shippers.',
|
||||
'search_placeholder_shipper' => 'Search name, email, company...',
|
||||
'all_statuses' => 'All Statuses',
|
||||
'pending' => 'Pending',
|
||||
'rejected' => 'Rejected',
|
||||
'active' => 'Active',
|
||||
'no_shippers_criteria' => 'No shippers found matching your criteria.',
|
||||
'no_shippers_registered' => 'No shippers registered yet.',
|
||||
'name_company' => 'Name / Company',
|
||||
'location' => 'Location',
|
||||
'edit_shipper' => 'Edit Shipper',
|
||||
'approve' => 'Approve',
|
||||
'reject' => 'Reject',
|
||||
'delete' => 'Delete',
|
||||
'delete_confirm_shipper' => 'Delete this shipper forever?',
|
||||
'loading' => 'Loading...',
|
||||
'manage_truck_owners' => 'Manage Truck Owners',
|
||||
'review_registrations' => 'Review registrations and approve truck owners.',
|
||||
'search_placeholder_owner' => 'Search name, email, plate...',
|
||||
'no_owners_criteria' => 'No truck owners found matching your criteria.',
|
||||
'no_owners_registered' => 'No truck owners registered yet.',
|
||||
'name_email' => 'Name / Email',
|
||||
'truck_info' => 'Truck Info',
|
||||
'documents' => 'Documents',
|
||||
'view_docs' => 'View Docs',
|
||||
'edit_owner' => 'Edit Owner',
|
||||
'delete_confirm_owner' => 'Delete this truck owner forever?',
|
||||
'docs_for' => 'Documents for',
|
||||
'truck_reg' => 'Truck Registration',
|
||||
'no_picture' => 'No picture uploaded.',
|
||||
'cap' => 'Cap',
|
||||
'manage_shipments' => 'Manage Shipments',
|
||||
'shipments_header' => 'Shipments',
|
||||
'shipments_subtitle' => 'Manage all shipments across the platform.',
|
||||
'flash_shipment_deleted' => 'Shipment deleted successfully.',
|
||||
'search_shipments_placeholder' => 'Search shipments...',
|
||||
'search_label' => 'Search',
|
||||
'sort_by' => 'Sort By',
|
||||
'sort_newest' => 'Newest First',
|
||||
'sort_oldest' => 'Oldest First',
|
||||
'sort_pickup_soonest' => 'Pickup Date (Soonest)',
|
||||
'sort_pickup_latest' => 'Pickup Date (Latest)',
|
||||
'no_shipments_found_criteria' => 'No shipments found matching your criteria.',
|
||||
'no_shipments_platform' => 'No shipments found on the platform yet.',
|
||||
'id_col' => 'ID',
|
||||
'dates_col' => 'Dates',
|
||||
'from_label' => 'From:',
|
||||
'to_label' => 'To:',
|
||||
'pick_label' => 'Pick:',
|
||||
'drop_label' => 'Drop:',
|
||||
'view_shipment' => 'View Shipment',
|
||||
'edit_shipment_tooltip' => 'Edit Shipment',
|
||||
'confirm_delete_shipment' => 'Delete this shipment?',
|
||||
'showing' => 'Showing',
|
||||
'of' => 'of',
|
||||
'previous' => 'Previous',
|
||||
'next' => 'Next',
|
||||
'error_occurred' => 'An error occurred',
|
||||
'failed_load_form' => 'Failed to load form.',
|
||||
'edit_shipment_title' => 'Edit Shipment #',
|
||||
'update_shipment_details' => 'Update shipment details and status.',
|
||||
'shipment_not_found' => 'Shipment not found',
|
||||
'shipment_updated_success' => 'Shipment updated successfully.',
|
||||
'invalid_id' => 'Invalid ID',
|
||||
'back' => 'Back',
|
||||
'shipment_details' => 'Shipment Details',
|
||||
'origin_country' => 'Origin Country',
|
||||
'destination_country' => 'Destination Country',
|
||||
'select_country_placeholder' => 'Select Country',
|
||||
'select_city_placeholder' => 'Select City',
|
||||
'loading_cities' => 'Loading...',
|
||||
'error_loading_cities' => 'Error loading cities',
|
||||
'cancel' => 'Cancel'
|
||||
),
|
||||
"ar" => array (
|
||||
'app_name' => 'CargoLink',
|
||||
@ -317,91 +308,82 @@ $translations = [
|
||||
'pages' => 'الصفحات',
|
||||
'faqs' => 'الأسئلة الشائعة',
|
||||
'landing_pages' => 'إعدادات الصفحة الرئيسية',
|
||||
'login_title' => 'مرحبًا بعودتك',
|
||||
'login_subtitle' => 'قم بتسجيل الدخول إلى حسابك للمتابعة',
|
||||
'email_address' => 'البريد الإلكتروني',
|
||||
'email_placeholder' => 'name@example.com',
|
||||
'password' => 'كلمة المرور',
|
||||
'forgot_password' => 'هل نسيت كلمة المرور؟',
|
||||
'password_placeholder' => 'أدخل كلمة المرور',
|
||||
'change_password' => 'تغيير كلمة المرور',
|
||||
'new_password' => 'كلمة المرور الجديدة',
|
||||
'confirm_password' => 'تأكيد كلمة المرور',
|
||||
'passwords_do_not_match' => 'كلمات المرور غير متطابقة.',
|
||||
'password_too_short' => 'يجب أن تتكون كلمة المرور من 6 أحرف على الأقل.',
|
||||
'password_updated' => 'تم تحديث كلمة المرور بنجاح.',
|
||||
'sign_in' => 'تسجيل الدخول',
|
||||
'dont_have_account' => 'ليس لديك حساب؟',
|
||||
'register_now' => 'سجل الآن',
|
||||
'reset_password_title' => 'إعادة تعيين كلمة المرور',
|
||||
'reset_password_subtitle' => 'أدخل بريدك الإلكتروني وسنرسل لك رابطًا لإعادة تعيين كلمة المرور',
|
||||
'send_reset_link' => 'إرسال رابط إعادة التعيين',
|
||||
'back_to_login' => 'العودة لتسجيل الدخول',
|
||||
'invalid_image' => 'صيغة صورة غير صالحة. يرجى تحميل JPG أو PNG أو GIF أو WEBP.',
|
||||
'upload_failed' => 'فشل في حفظ الملف المحمل.',
|
||||
'profile_updated' => 'تم تحديث الملف الشخصي بنجاح.',
|
||||
'my_profile' => 'ملفي الشخصي',
|
||||
'profile_picture' => 'صورة الملف الشخصي',
|
||||
'change_picture' => 'تغيير الصورة',
|
||||
'picture_hint' => 'JPG، PNG، أو GIF حتى 5 ميغابايت',
|
||||
'full_name' => 'الاسم الكامل',
|
||||
'email_hint' => 'لا يمكن تغيير عنوان البريد الإلكتروني.',
|
||||
'account_role' => 'دور الحساب',
|
||||
'save_changes' => 'حفظ التغييرات',
|
||||
'reg_title' => 'أنشئ حسابك اللوجستي',
|
||||
'reg_subtitle' => 'يمكن للشاحنين وأصحاب الشاحنات التسجيل الذاتي ببيانات الملف الشخصي الكاملة.',
|
||||
'reg_success_pending' => 'اكتمل التسجيل بنجاح. حسابك في انتظار موافقة الإدارة.',
|
||||
'reg_success' => 'اكتمل التسجيل بنجاح.',
|
||||
'role' => 'الدور',
|
||||
'shipper' => 'شاحن',
|
||||
'truck_owner' => 'مالك شاحنة',
|
||||
'email' => 'البريد الإلكتروني',
|
||||
'phone' => 'الهاتف',
|
||||
'country' => 'البلد',
|
||||
'select_country' => 'اختر البلد',
|
||||
'city' => 'المدينة',
|
||||
'select_city' => 'اختر المدينة',
|
||||
'address' => 'العنوان',
|
||||
'shipper_details' => 'تفاصيل الشاحن',
|
||||
'company_name' => 'اسم الشركة',
|
||||
'truck_details' => 'تفاصيل مالك الشاحنة',
|
||||
'truck_type' => 'نوع الشاحنة',
|
||||
'load_capacity' => 'سعة الحمولة (طن)',
|
||||
'plate_no' => 'رقم اللوحة',
|
||||
'bank_account' => 'الحساب البنكي / الآيبان',
|
||||
'bank_name' => 'اسم البنك',
|
||||
'bank_branch' => 'فرع البنك',
|
||||
'id_card_front' => 'البطاقة الشخصية (الوجه الأمامي)',
|
||||
'id_card_back' => 'البطاقة الشخصية (الوجه الخلفي)',
|
||||
'truck_reg_front' => 'تسجيل الشاحنة (الوجه الأمامي)',
|
||||
'truck_reg_back' => 'تسجيل الشاحنة (الوجه الخلفي)',
|
||||
'truck_picture' => 'صورة واضحة للشاحنة (تظهر رقم اللوحة)',
|
||||
'create_account' => 'إنشاء حساب',
|
||||
'back_to_admin' => 'العودة للإدارة',
|
||||
'welcome_back' => 'مرحبًا بك في لوحة القيادة الخاصة بك. قم بإدارة شحناتك هنا.',
|
||||
'total_shipments_posted' => 'إجمالي الشحنات',
|
||||
'active_shipments' => 'الشحنات النشطة',
|
||||
'delivered_shipments' => 'الشحنات المسلمة',
|
||||
'route_label' => 'المسار',
|
||||
'total_label' => 'المجموع',
|
||||
'welcome_back_owner' => 'ابحث عن الأحمال وقدم أفضل سعر لديك.',
|
||||
'total_offers' => 'إجمالي العروض',
|
||||
'won_shipments' => 'الشحنات الفائزة',
|
||||
'nav_platform_users' => 'مستخدمو المنصة',
|
||||
'notification_templates' => 'قوالب الإشعارات',
|
||||
'manage_permissions' => 'إدارة الصلاحيات',
|
||||
'create_user' => 'إنشاء مستخدم',
|
||||
'edit_user' => 'تعديل المستخدم',
|
||||
'delete_user' => 'حذف المستخدم',
|
||||
'confirm_delete' => 'هل أنت متأكد أنك تريد حذف هذا المستخدم؟',
|
||||
'permissions' => 'الصلاحيات',
|
||||
'no_users' => 'لم يتم العثور على مستخدمين.',
|
||||
'user_created' => 'تم إنشاء المستخدم بنجاح.',
|
||||
'user_updated' => 'تم تحديث المستخدم بنجاح.',
|
||||
'user_deleted' => 'تم حذف المستخدم بنجاح.',
|
||||
'error_email_exists' => 'البريد الإلكتروني موجود بالفعل.',
|
||||
'shipper_shipments' => 'شحنات الشاحنين',
|
||||
'truck_owners_statements' => 'كشوفات أصحاب الشاحنات'
|
||||
'edit_homepage' => 'تعديل محتوى الصفحة الرئيسية والأقسام',
|
||||
'view_details' => 'عرض التفاصيل',
|
||||
'manage_shippers' => 'إدارة الشاحنين',
|
||||
'manage_registered_shippers' => 'إدارة الشاحنين المسجلين.',
|
||||
'search_placeholder_shipper' => 'ابحث بالاسم، البريد، الشركة...',
|
||||
'all_statuses' => 'كل الحالات',
|
||||
'pending' => 'قيد الانتظار',
|
||||
'rejected' => 'مرفوض',
|
||||
'active' => 'نشط',
|
||||
'no_shippers_criteria' => 'لم يتم العثور على شاحنين مطابقين لمعاييرك.',
|
||||
'no_shippers_registered' => 'لا يوجد شاحنين مسجلين بعد.',
|
||||
'name_company' => 'الاسم / الشركة',
|
||||
'location' => 'الموقع',
|
||||
'edit_shipper' => 'تعديل الشاحن',
|
||||
'approve' => 'موافقة',
|
||||
'reject' => 'رفض',
|
||||
'delete' => 'حذف',
|
||||
'delete_confirm_shipper' => 'هل أنت متأكد من حذف هذا الشاحن نهائياً؟',
|
||||
'loading' => 'جاري التحميل...',
|
||||
'manage_truck_owners' => 'إدارة أصحاب الشاحنات',
|
||||
'review_registrations' => 'مراجعة التسجيلات والموافقة على أصحاب الشاحنات.',
|
||||
'search_placeholder_owner' => 'ابحث بالاسم، البريد، اللوحة...',
|
||||
'no_owners_criteria' => 'لم يتم العثور على أصحاب شاحنات مطابقين لمعاييرك.',
|
||||
'no_owners_registered' => 'لا يوجد أصحاب شاحنات مسجلين بعد.',
|
||||
'name_email' => 'الاسم / البريد',
|
||||
'truck_info' => 'معلومات الشاحنة',
|
||||
'documents' => 'المستندات',
|
||||
'view_docs' => 'عرض المستندات',
|
||||
'edit_owner' => 'تعديل المالك',
|
||||
'delete_confirm_owner' => 'هل أنت متأكد من حذف مالك الشاحنة هذا نهائياً؟',
|
||||
'docs_for' => 'مستندات',
|
||||
'truck_reg' => 'تسجيل الشاحنة',
|
||||
'no_picture' => 'لا توجد صورة محملة.',
|
||||
'cap' => 'السعة',
|
||||
'manage_shipments' => 'إدارة الشحنات',
|
||||
'shipments_header' => 'الشحنات',
|
||||
'shipments_subtitle' => 'إدارة جميع الشحنات عبر المنصة.',
|
||||
'flash_shipment_deleted' => 'تم حذف الشحنة بنجاح.',
|
||||
'search_shipments_placeholder' => 'البحث في الشحنات...',
|
||||
'search_label' => 'بحث',
|
||||
'sort_by' => 'ترتيب حسب',
|
||||
'sort_newest' => 'الأحدث أولاً',
|
||||
'sort_oldest' => 'الأقدم أولاً',
|
||||
'sort_pickup_soonest' => 'تاريخ الاستلام (الأقرب)',
|
||||
'sort_pickup_latest' => 'تاريخ الاستلام (الأبعد)',
|
||||
'no_shipments_found_criteria' => 'لم يتم العثور على شحنات مطابقة لمعايير البحث.',
|
||||
'no_shipments_platform' => 'لا توجد شحنات على المنصة بعد.',
|
||||
'id_col' => 'المعرف',
|
||||
'dates_col' => 'التواريخ',
|
||||
'from_label' => 'من:',
|
||||
'to_label' => 'إلى:',
|
||||
'pick_label' => 'استلام:',
|
||||
'drop_label' => 'تسليم:',
|
||||
'view_shipment' => 'عرض الشحنة',
|
||||
'edit_shipment_tooltip' => 'تعديل الشحنة',
|
||||
'confirm_delete_shipment' => 'حذف هذه الشحنة؟',
|
||||
'showing' => 'عرض',
|
||||
'of' => 'من',
|
||||
'previous' => 'السابق',
|
||||
'next' => 'التالي',
|
||||
'error_occurred' => 'حدث خطأ',
|
||||
'failed_load_form' => 'فشل تحميل النموذج.',
|
||||
'edit_shipment_title' => 'تعديل الشحنة #',
|
||||
'update_shipment_details' => 'تحديث تفاصيل الشحنة والحالة.',
|
||||
'shipment_not_found' => 'الشحنة غير موجودة',
|
||||
'shipment_updated_success' => 'تم تحديث الشحنة بنجاح.',
|
||||
'invalid_id' => 'معرف غير صحيح',
|
||||
'back' => 'رجوع',
|
||||
'shipment_details' => 'تفاصيل الشحنة',
|
||||
'origin_country' => 'بلد الانطلاق',
|
||||
'destination_country' => 'بلد الوصول',
|
||||
'select_country_placeholder' => 'اختر البلد',
|
||||
'select_city_placeholder' => 'اختر المدينة',
|
||||
'loading_cities' => 'جاري التحميل...',
|
||||
'error_loading_cities' => 'خطأ في تحميل المدن',
|
||||
'cancel' => 'إلغاء'
|
||||
)
|
||||
];
|
||||
|
||||
@ -610,4 +592,9 @@ function has_permission(string $permissionSlug, ?int $userId = null): bool
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function format_currency(float $amount): string
|
||||
{
|
||||
return number_format($amount, 3) . ' OMR';
|
||||
}
|
||||
|
||||
@ -259,23 +259,23 @@ function render_admin_sidebar(string $active = 'dashboard'): void
|
||||
<i class="bi bi-speedometer2 me-2"></i><?= e(t('dashboard')) ?>
|
||||
</a>
|
||||
<a class="admin-nav-link <?= $active === 'shipments' ? 'active' : '' ?>" href="<?= e(url_with_lang('admin_shipments.php')) ?>">
|
||||
<i class="bi bi-box2-fill me-2"></i><?= e(t('shipments') ?: 'Shipments') ?>
|
||||
<i class="bi bi-box2-fill me-2"></i><?= e(t('shipments')) ?>
|
||||
</a>
|
||||
|
||||
<a class="nav-link fw-bold text-muted text-uppercase mt-2 d-flex justify-content-between align-items-center p-2 rounded" style="cursor: pointer; font-size: 0.85rem;" data-bs-toggle="collapse" data-bs-target="#collapseReports" aria-expanded="<?= $reportsActive ? 'true' : 'false' ?>">
|
||||
<span><i class="bi bi-file-earmark-bar-graph-fill me-2"></i><?= e(t('reports') ?: 'Reports') ?></span>
|
||||
<span><i class="bi bi-file-earmark-bar-graph-fill me-2"></i><?= e(t('reports')) ?></span>
|
||||
<i class="bi bi-chevron-down small"></i>
|
||||
</a>
|
||||
<div class="collapse <?= $reportsActive ? 'show' : '' ?>" id="collapseReports">
|
||||
<div class="nav flex-column gap-1 ms-3 border-start ps-2 border-2">
|
||||
<a class="admin-nav-link <?= $active === 'reports_summary' ? 'active' : '' ?>" href="<?= e(url_with_lang('admin_reports_summary.php')) ?>">
|
||||
<i class="bi bi-pie-chart-fill me-2"></i>Analytics
|
||||
<i class="bi bi-pie-chart-fill me-2"></i><?= e(t('analytics')) ?>
|
||||
</a>
|
||||
<a class="admin-nav-link <?= $active === 'reports_shippers' ? 'active' : '' ?>" href="<?= e(url_with_lang('admin_reports_shippers.php')) ?>">
|
||||
<i class="bi bi-people me-2"></i><?= e(t('shipper_shipments') ?: 'Shipper Shipments') ?>
|
||||
<i class="bi bi-people me-2"></i><?= e(t('shipper_shipments')) ?>
|
||||
</a>
|
||||
<a class="admin-nav-link <?= $active === 'reports_truck_owners' ? 'active' : '' ?>" href="<?= e(url_with_lang('admin_reports_truck_owners.php')) ?>">
|
||||
<i class="bi bi-truck me-2"></i><?= e(t('truck_owners_statements') ?: 'Truck Owner Statements') ?>
|
||||
<i class="bi bi-truck me-2"></i><?= e(t('truck_owners_statements')) ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -293,7 +293,7 @@ function render_admin_sidebar(string $active = 'dashboard'): void
|
||||
<i class="bi bi-plug me-2"></i><?= e(t('integrations')) ?>
|
||||
</a>
|
||||
<a class="admin-nav-link <?= $active === 'notification_templates' ? 'active' : '' ?>" href="<?= e(url_with_lang('admin_notification_templates.php')) ?>">
|
||||
<i class="bi bi-bell-fill me-2"></i><?= e(t('notification_templates') ?: 'Notifications') ?>
|
||||
<i class="bi bi-bell-fill me-2"></i><?= e(t('notification_templates')) ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -204,7 +204,7 @@ render_header(t('shipment_detail'));
|
||||
<i class="bi bi-check-circle-fill fs-4 me-2"></i>
|
||||
<div>
|
||||
<strong>Payment Complete</strong><br>
|
||||
Total Paid: $<?= e($shipment['total_price']) ?> (Includes $<?= e($shipment['platform_fee']) ?> platform fee)
|
||||
Total Paid: <?= format_currency((float)$shipment['total_price']) ?> (Includes <?= format_currency((float)$shipment['platform_fee']) ?> platform fee)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -248,16 +248,16 @@ render_header(t('shipment_detail'));
|
||||
<h5 class="card-title fw-bold mb-3">Payment Breakdown</h5>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-muted">Truck Offer</span>
|
||||
<span class="fw-medium">$<?= number_format($offerPrice, 2) ?></span>
|
||||
<span class="fw-medium"><?= format_currency($offerPrice) ?></span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-3">
|
||||
<span class="text-muted">Platform Fee (<?= e($platformFeePercentage * 100) ?>%)</span>
|
||||
<span class="fw-medium">$<?= number_format($fee, 2) ?></span>
|
||||
<span class="fw-medium"><?= format_currency($fee) ?></span>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="fw-bold fs-5">Total</span>
|
||||
<span class="fw-bold fs-4 text-primary">$<?= number_format($total, 2) ?></span>
|
||||
<span class="fw-bold fs-4 text-primary"><?= format_currency($total) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user