The ride table holds two generations of status values: the legacy CamelCase
set ('Finished', 'CancelFromPassenger') and the lowercase set written by
backend/ride/rides/* today ('completed', 'cancelled_by_passenger'). Admin
queries only matched the legacy set, so on live data:
- get_rides_by_status.php returned nothing meaningful for every filter, and
the "in progress" default masked it.
- dashbord.php reported total_driver_earnings as NULL, completed_rides as a
fraction of the real count, and cancelled_rides as 0.
- driver_avg_duration averaged in negative durations, yielding "-00h 22m".
All three now match on LOWER(status) across both families.
Staff/pending.php ran with no authentication at all, exposing pending
admins' names and phone numbers to any caller; it now goes through
connect.php with a role check. It also returned HTTP 400 for everything when
the `users` table was absent — each source is queried independently and
reports its own availability.
Console:
- Render rides from either schema generation (price/date/time and
start_location coordinates, or the older address/created_at columns).
- Null aggregates render as "—" rather than a measured 0.00.
- Add tariff/promo, WhatsApp send and encryption modules, all super-admin
gated; pricing remains read-only.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
63 lines
2.3 KiB
PHP
63 lines
2.3 KiB
PHP
<?php
|
|
/**
|
|
* Admin/Staff/pending.php
|
|
* جلب الحسابات المعلقة للإداريين والخدمة
|
|
*/
|
|
// connect.php يفرض JWT — بدونه كانت هذه النقطة تكشف أسماء وأرقام
|
|
// المشرفين المعلقين لأي زائر بلا أي مصادقة.
|
|
require_once __DIR__ . '/../../connect.php';
|
|
|
|
if ($role !== 'admin' && $role !== 'super_admin') {
|
|
http_response_code(403);
|
|
echo json_encode(['error' => 'Unauthorized: Admin access required']);
|
|
exit;
|
|
}
|
|
|
|
$allPending = [];
|
|
$sources = [];
|
|
|
|
// كل مصدر يُجلب على حدة: غياب جدول users في بعض عمليات النشر كان يُفشل
|
|
// الطلب بالكامل ويخفي طلبات المشرفين المعلقة أيضاً.
|
|
try {
|
|
$stmt1 = $con->query("SELECT id, name, phone, role, created_at, 'admin' as type FROM adminUser WHERE status = 'pending'");
|
|
$admins = $stmt1->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
foreach ($admins as &$admin) {
|
|
$admin['name'] = $encryptionHelper->decryptData($admin['name']) ?: $admin['name'];
|
|
$admin['phone'] = $encryptionHelper->decryptData($admin['phone']) ?: $admin['phone'];
|
|
}
|
|
unset($admin);
|
|
|
|
$allPending = array_merge($allPending, $admins);
|
|
$sources['admins'] = 'ok';
|
|
} catch (Throwable $e) {
|
|
error_log("[Staff Pending] adminUser query failed: " . $e->getMessage());
|
|
$sources['admins'] = 'unavailable';
|
|
}
|
|
|
|
try {
|
|
$stmt2 = $con->query("SELECT id, first_name, last_name, phone, user_type as role, created_at, 'service' as type FROM users WHERE status = 'pending' AND user_type = 'service'");
|
|
$services = $stmt2->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
foreach ($services as &$service) {
|
|
$service['name'] = trim(
|
|
($encryptionHelper->decryptData($service['first_name']) ?: $service['first_name']) . ' ' .
|
|
($encryptionHelper->decryptData($service['last_name']) ?: $service['last_name'])
|
|
);
|
|
$service['phone'] = $encryptionHelper->decryptData($service['phone']) ?: $service['phone'];
|
|
}
|
|
unset($service);
|
|
|
|
$allPending = array_merge($allPending, $services);
|
|
$sources['service_staff'] = 'ok';
|
|
} catch (Throwable $e) {
|
|
error_log("[Staff Pending] users query failed: " . $e->getMessage());
|
|
$sources['service_staff'] = 'unavailable';
|
|
}
|
|
|
|
printSuccess([
|
|
"data" => $allPending,
|
|
"sources" => $sources,
|
|
]);
|
|
exit();
|