Live Tracking page upgrades:
- **Heading rotation** on each truck marker via CSS transform driven by
the heading_degrees broadcast field.
- **Click-to-detail** opens a slide-over showing trip number, status,
route, started-at, current load, an ordered stop list color-coded by
status, and the last 20 timeline events.
- **Route overlay** draws planned-route polyline (stops in order →
dumpsite, dashed), stop markers (pending/arrived/completed/skipped
colors), a diamond marker for the dumpsite, and a translucent
geofence polygon when the dumpsite has one configured.
- **Breadcrumb trail** of the last 60 minutes of GPS pings rendered
as a polyline; new pings tack on incrementally while the panel is
open.
- **Real-time push via Reverb** with polling fallback. Subscribes to
private-admin.live, listens for `.truck.location`, and updates
marker position + the trucks-online list immediately. When Reverb
isn't configured or fails, falls back to 10s polling. Status pill
shows live (push) / polling / offline.
Backend additions:
- GET /admin/live/trucks/{uuid}/trail — recent location pings
- GET /admin/live/trucks/{uuid}/active-trip — full trip + stops +
dumpsite + boundary + recent timeline
- Broadcasting auth route now accepts Sanctum bearer tokens (admin
web posts them via Echo's authorizer callback)
Frontend wiring:
- npm: laravel-echo + pusher-js
- window.Verde.getEcho() lazily inits Echo with bearer-token authorizer
- Layout exposes window.VERDE_BROADCAST with reverb config
196 tests passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 lines
2.7 KiB
PHP
75 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Providers;
|
|
|
|
use App\Services\Payment\ManualPaymentDriver;
|
|
use App\Services\Payment\PayMongoDriver;
|
|
use App\Services\Payment\PaymentDriver;
|
|
use App\Services\Push\FcmPushDriver;
|
|
use App\Services\Push\LogPushDriver;
|
|
use App\Services\Push\PushDriver;
|
|
use App\Services\Sms\FakeSmsService;
|
|
use App\Services\Sms\LogSmsService;
|
|
use App\Services\Sms\SemaphoreSmsService;
|
|
use App\Services\Sms\SmsService;
|
|
use Illuminate\Support\Facades\Broadcast;
|
|
use Illuminate\Support\ServiceProvider;
|
|
|
|
class AppServiceProvider extends ServiceProvider
|
|
{
|
|
public function register(): void
|
|
{
|
|
$this->app->singleton(PaymentDriver::class, function ($app) {
|
|
$driver = config('services.payments.driver', 'manual');
|
|
$key = (string) config('services.paymongo.secret_key');
|
|
|
|
if ($driver === 'paymongo' && $key !== '') {
|
|
return new PayMongoDriver(
|
|
secretKey: $key,
|
|
webhookSecret: (string) config('services.paymongo.webhook_secret'),
|
|
successUrl: (string) config('services.paymongo.success_url'),
|
|
cancelUrl: (string) config('services.paymongo.cancel_url'),
|
|
);
|
|
}
|
|
|
|
return new ManualPaymentDriver();
|
|
});
|
|
|
|
$this->app->singleton(PushDriver::class, function ($app) {
|
|
$driver = config('services.push.driver', 'log');
|
|
$key = (string) config('services.fcm.server_key');
|
|
|
|
if ($driver === 'fcm' && $key !== '') {
|
|
return new FcmPushDriver($key);
|
|
}
|
|
|
|
return new LogPushDriver();
|
|
});
|
|
|
|
$this->app->singleton(SmsService::class, function ($app) {
|
|
$driver = config('services.sms.driver', 'log');
|
|
|
|
return match ($driver) {
|
|
'semaphore' => new SemaphoreSmsService(
|
|
apiKey: (string) config('services.semaphore.api_key'),
|
|
senderName: (string) config('services.semaphore.sender_name', 'VERDE'),
|
|
),
|
|
'fake' => new FakeSmsService(),
|
|
default => new LogSmsService(),
|
|
};
|
|
});
|
|
}
|
|
|
|
public function boot(): void
|
|
{
|
|
// Listeners under App\Listeners are auto-discovered by Laravel 11
|
|
// based on their handle() method's type-hint. Don't register them
|
|
// explicitly here — that causes double-dispatch.
|
|
|
|
// Broadcasting auth needs to accept Sanctum bearer tokens (admin web
|
|
// posts them via Echo's authorizer callback). Without this override
|
|
// it would only accept session cookies via the default `web` guard.
|
|
Broadcast::routes(['middleware' => ['auth:sanctum']]);
|
|
}
|
|
}
|