gps_system/app/Livewire/Dashboard.php
sackey 6b878bb0a0
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
Initial commit
2025-09-12 16:19:56 +00:00

192 lines
6.6 KiB
PHP

<?php
namespace App\Livewire;
use Livewire\Component;
use App\Services\TraccarService;
use App\Models\Device;
use App\Models\Event;
use App\Models\Position;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
class Dashboard extends Component
{
public $stats = [];
public $recentEvents = [];
public $devicesStatus = [];
public $mapDevices = [];
protected $traccarService;
public function boot(TraccarService $traccarService)
{
$this->traccarService = $traccarService;
}
public function mount()
{
$this->loadDashboardData();
}
public function loadDashboardData()
{
$user = Auth::user();
// Get user's devices
$devices = Device::where('user_id', $user->id)->get();
// Calculate statistics
$this->stats = [
'total_devices' => $devices->count(),
'online_devices' => $devices->where('status', 'online')->count(),
'offline_devices' => $devices->where('status', 'offline')->count(),
'recent_alerts' => Event::whereIn('device_id', $devices->pluck('id'))
->where('acknowledged', false)
->where('created_at', '>=', now()->subDays(7))
->count(),
];
// Get devices status for widgets
$this->devicesStatus = $devices->map(function ($device) {
return [
'id' => $device->id,
'name' => $device->name,
'status' => $device->status,
'last_update' => $device->last_update,
'is_online' => $device->isOnline(),
'position' => $device->getLatestPosition(),
];
})->toArray();
// Get recent events
$this->recentEvents = Event::with(['device', 'geofence'])
->whereIn('device_id', $devices->pluck('id'))
->orderBy('event_time', 'desc')
->limit(10)
->get()
->map(function ($event) {
return [
'id' => $event->id,
'type' => $event->getReadableType(),
'device_name' => $event->device->name,
'event_time' => $event->event_time,
'acknowledged' => $event->acknowledged,
'severity' => $event->getSeverity(),
'color' => $event->getEventColor(),
];
})->toArray();
// Get devices for map display
$this->mapDevices = $devices->filter(function ($device) {
return $device->currentPosition && $device->currentPosition->valid;
})->map(function ($device) {
$position = $device->currentPosition;
return [
'id' => $device->id,
'name' => $device->name,
'latitude' => $position->latitude,
'longitude' => $position->longitude,
'status' => $device->status,
'speed' => $position->getFormattedSpeed(),
'address' => $position->address ?? 'Unknown location',
'last_update' => $position->device_time,
];
})->values()->toArray();
}
public function acknowledgeEvent($eventId)
{
$event = Event::find($eventId);
if ($event && $event->device->user_id === Auth::id()) {
$event->update([
'acknowledged' => true,
'acknowledged_by' => Auth::id(),
'acknowledged_at' => now(),
]);
$this->loadDashboardData();
$this->dispatch('event-acknowledged');
}
}
public function refreshData()
{
try {
// Sync with Traccar API
$this->syncTraccarData();
$this->loadDashboardData();
$this->dispatch('data-refreshed');
} catch (\Exception $e) {
$this->dispatch('refresh-error', ['message' => 'Failed to refresh data: ' . $e->getMessage()]);
}
}
private function syncTraccarData()
{
$user = Auth::user();
if (!$user->traccar_user_id) {
return; // User not synced with Traccar
}
// Get latest positions from Traccar
$positions = $this->traccarService->getPositions();
foreach ($positions as $positionData) {
$device = Device::where('traccar_device_id', $positionData['deviceId'])->first();
if ($device && $device->user_id === $user->id) {
// Update or create position
$position = Position::updateOrCreate(
['traccar_position_id' => $positionData['id']],
[
'device_id' => $device->id,
'protocol' => $positionData['protocol'] ?? null,
'device_time' => $positionData['deviceTime'],
'fix_time' => $positionData['fixTime'],
'server_time' => $positionData['serverTime'],
'outdated' => $positionData['outdated'] ?? false,
'valid' => $positionData['valid'] ?? true,
'latitude' => $positionData['latitude'],
'longitude' => $positionData['longitude'],
'altitude' => $positionData['altitude'] ?? null,
'speed' => $positionData['speed'] ?? 0,
'course' => $positionData['course'] ?? 0,
'address' => $positionData['address'] ?? null,
'accuracy' => $positionData['accuracy'] ?? null,
'attributes' => $positionData['attributes'] ?? null,
]
);
// Update device status and position
$device->update([
'status' => $this->determineDeviceStatus($positionData),
'last_update' => $positionData['deviceTime'],
'position_id' => $position->id,
]);
}
}
}
private function determineDeviceStatus($positionData): string
{
$deviceTime = new \DateTime($positionData['deviceTime']);
$now = new \DateTime();
$diffMinutes = $now->diff($deviceTime)->i + ($now->diff($deviceTime)->h * 60);
if ($diffMinutes <= 5) {
return 'online';
} elseif ($diffMinutes <= 30) {
return 'offline';
} else {
return 'unknown';
}
}
public function render()
{
return view('livewire.dashboard');
}
}