normalizeType((string) ($filters['type'] ?? 'all')); $module = $this->normalizeModule((string) ($filters['module'] ?? 'all')); $readState = $this->normalizeReadState((string) ($filters['read_state'] ?? 'all')); $priority = $this->normalizePriority((string) ($filters['priority'] ?? 'all')); $query = trim((string) ($filters['q'] ?? '')); $page = max(1, (int) ($filters['page'] ?? 1)); $perPage = min(max((int) ($filters['per_page'] ?? 20), 12), 40); $lastReadAt = $this->preferences->forUser($user)['activity_last_read_at'] ?? null; $lastReadTimestamp = strtotime((string) $lastReadAt) ?: 0; $items = $this->activity->feed($user)->map(function (array $item) use ($lastReadTimestamp): array { $timestamp = strtotime((string) ($item['created_at'] ?? '')) ?: 0; $item['is_new'] = $timestamp > $lastReadTimestamp; $item['priority'] = $this->priorityFor($item); return $item; }); if ($type !== 'all') { $items = $items->where('type', $type)->values(); } if ($module !== 'all') { $items = $items->where('module', $module)->values(); } if ($readState === 'unread') { $items = $items->filter(fn (array $item): bool => (bool) ($item['is_new'] ?? false))->values(); } elseif ($readState === 'read') { $items = $items->filter(fn (array $item): bool => ! (bool) ($item['is_new'] ?? false))->values(); } if ($priority !== 'all') { $items = $items->where('priority', $priority)->values(); } if ($query !== '') { $needle = mb_strtolower($query); $items = $items->filter(function (array $item) use ($needle): bool { return collect([ $item['title'] ?? '', $item['body'] ?? '', $item['actor']['name'] ?? '', $item['module_label'] ?? '', ])->contains(fn ($value): bool => is_string($value) && str_contains(mb_strtolower($value), $needle)); })->values(); } $total = $items->count(); $lastPage = max(1, (int) ceil($total / $perPage)); $page = min($page, $lastPage); return [ 'items' => $items->forPage($page, $perPage)->values()->all(), 'meta' => [ 'current_page' => $page, 'last_page' => $lastPage, 'per_page' => $perPage, 'total' => $total, ], 'filters' => [ 'type' => $type, 'module' => $module, 'read_state' => $readState, 'priority' => $priority, 'q' => $query, ], 'type_options' => [ ['value' => 'all', 'label' => 'Everything'], ['value' => 'notification', 'label' => 'Notifications'], ['value' => 'comment', 'label' => 'Comments'], ['value' => 'follower', 'label' => 'Followers'], ], 'module_options' => [ ['value' => 'all', 'label' => 'All modules'], ['value' => 'artworks', 'label' => 'Artworks'], ['value' => 'cards', 'label' => 'Cards'], ['value' => 'collections', 'label' => 'Collections'], ['value' => 'stories', 'label' => 'Stories'], ['value' => 'followers', 'label' => 'Followers'], ['value' => 'system', 'label' => 'System'], ], 'read_state_options' => [ ['value' => 'all', 'label' => 'All'], ['value' => 'unread', 'label' => 'Unread'], ['value' => 'read', 'label' => 'Read'], ], 'priority_options' => [ ['value' => 'all', 'label' => 'All priorities'], ['value' => 'high', 'label' => 'High priority'], ['value' => 'medium', 'label' => 'Medium priority'], ['value' => 'low', 'label' => 'Low priority'], ], 'summary' => [ 'unread_count' => $items->filter(fn (array $item): bool => (bool) ($item['is_new'] ?? false))->count(), 'high_priority_count' => $items->where('priority', 'high')->count(), 'comment_count' => $items->where('type', 'comment')->count(), 'follower_count' => $items->where('type', 'follower')->count(), 'last_read_at' => $lastReadAt, ], 'panels' => [ 'attention_now' => $items->filter(fn (array $item): bool => ($item['priority'] ?? 'low') === 'high')->take(5)->values()->all(), 'follow_up_queue' => $items->filter(fn (array $item): bool => (bool) ($item['is_new'] ?? false))->take(5)->values()->all(), ], ]; } private function priorityFor(array $item): string { return match ((string) ($item['type'] ?? '')) { 'comment' => 'high', 'notification' => (bool) ($item['read'] ?? false) ? 'medium' : 'high', 'follower' => 'medium', default => 'low', }; } private function normalizeType(string $value): string { return in_array($value, ['all', 'notification', 'comment', 'follower'], true) ? $value : 'all'; } private function normalizeModule(string $value): string { return in_array($value, ['all', 'artworks', 'cards', 'collections', 'stories', 'followers', 'system'], true) ? $value : 'all'; } private function normalizeReadState(string $value): string { return in_array($value, ['all', 'read', 'unread'], true) ? $value : 'all'; } private function normalizePriority(string $value): string { return in_array($value, ['all', 'high', 'medium', 'low'], true) ? $value : 'all'; } }