input('page', 1); $perPage = (int)$request->input('per_page', 15); $query = Announcement::with(['employer.employerProfile', 'sponsor'])->where('status', 'approved')->latest(); $total = $query->count(); $offset = ($page - 1) * $perPage; $announcements = $query->skip($offset)->take($perPage)->get() ->map(function ($announcement) { $postedBy = 'System'; $organization = 'Migrant Support'; if ($announcement->sponsor_id) { $postedBy = $announcement->sponsor->full_name; $organization = $announcement->sponsor->organization_name; } elseif ($announcement->employer_id) { $postedBy = $announcement->employer->name; $organization = $announcement->employer->employerProfile->company_name ?? 'Employer'; } // Decode charity details if they exist in json $charityDetails = null; $content = $announcement->body; if (strpos($announcement->body, '{"type":"Charity"') === 0) { $decoded = json_decode($announcement->body, true); if ($decoded) { $charityDetails = $decoded; $content = $decoded['content'] ?? $announcement->body; } } return [ 'id' => $announcement->id, 'title' => $announcement->title, 'body' => $content, 'type' => $announcement->type, 'employer_name' => $postedBy, 'company_name' => $organization, 'created_at' => $announcement->created_at->toISOString(), 'time_ago' => $announcement->created_at->diffForHumans(), 'charity_details' => $charityDetails, ]; }); return response()->json([ 'success' => true, 'data' => [ 'announcements' => $announcements, 'pagination' => [ 'total' => $total, 'per_page' => $perPage, 'current_page' => $page, 'last_page' => max(1, (int)ceil($total / $perPage)), ] ] ], 200); } catch (\Exception $e) { logger()->error('Mobile Worker Get Announcements Failure: ' . $e->getMessage()); return response()->json([ 'success' => false, 'message' => 'An error occurred while fetching announcements.', 'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error' ], 500); } } /** * Get up to 3 unviewed announcements for the worker, and mark them as viewed. */ public function getNewAnnouncements(Request $request) { /** @var \App\Models\Worker $worker */ $worker = $request->attributes->get('worker'); try { $viewedIds = AnnouncementView::where('worker_id', $worker->id)->pluck('announcement_id'); $dbAnnouncements = Announcement::with(['employer.employerProfile', 'sponsor']) ->where('status', 'approved') ->whereNotIn('id', $viewedIds) ->latest('id') ->limit(3) ->get(); // Mark them as viewed foreach ($dbAnnouncements as $announcement) { AnnouncementView::firstOrCreate([ 'worker_id' => $worker->id, 'announcement_id' => $announcement->id, ]); } $announcements = $dbAnnouncements->map(function ($announcement) { $postedBy = 'System'; $organization = 'Migrant Support'; if ($announcement->sponsor_id) { $postedBy = $announcement->sponsor->full_name; $organization = $announcement->sponsor->organization_name; } elseif ($announcement->employer_id) { $postedBy = $announcement->employer->name; $organization = $announcement->employer->employerProfile->company_name ?? 'Employer'; } // Decode charity details if they exist in json $charityDetails = null; $content = $announcement->body; if (strpos($announcement->body, '{"type":"Charity"') === 0) { $decoded = json_decode($announcement->body, true); if ($decoded) { $charityDetails = $decoded; $content = $decoded['content'] ?? $announcement->body; } } return [ 'id' => $announcement->id, 'title' => $announcement->title, 'body' => $content, 'type' => $announcement->type, 'employer_name' => $postedBy, 'company_name' => $organization, 'created_at' => $announcement->created_at->toISOString(), 'time_ago' => $announcement->created_at->diffForHumans(), 'charity_details' => $charityDetails, ]; }); return response()->json([ 'success' => true, 'data' => [ 'announcements' => $announcements, ] ], 200); } catch (\Exception $e) { logger()->error('Mobile Worker Get New Announcements Failure: ' . $e->getMessage()); return response()->json([ 'success' => false, 'message' => 'An error occurred while fetching new announcements.', 'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error' ], 500); } } /** * Explicitly mark an announcement as viewed by the worker. */ public function markAnnouncementViewed(Request $request, $id) { /** @var \App\Models\Worker $worker */ $worker = $request->attributes->get('worker'); try { AnnouncementView::firstOrCreate([ 'worker_id' => $worker->id, 'announcement_id' => $id, ]); return response()->json([ 'success' => true, 'message' => 'Announcement marked as viewed.' ], 200); } catch (\Exception $e) { logger()->error('Mobile Worker Mark Announcement Viewed Failure: ' . $e->getMessage()); return response()->json([ 'success' => false, 'message' => 'An error occurred.', 'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error' ], 500); } } }