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'); } }