migrant-web/app/Http/Controllers/Api/SponsorController.php
2026-06-17 22:20:17 +05:30

330 lines
14 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Announcement;
use App\Models\Sponsor;
use Illuminate\Http\Request;
class SponsorController extends Controller
{
/**
* GET /api/sponsors/dashboard
*
* Returns the sponsor's profile summary and unread charity event count.
*/
public function getDashboard(Request $request)
{
/** @var Sponsor $sponsor */
$sponsor = $request->attributes->get('sponsor');
$sponsorId = $sponsor ? $sponsor->id : null;
try {
// Recent charity/update announcements for the dashboard preview
$recentEvents = Announcement::where(function ($q) use ($sponsorId) {
$q->where('status', 'approved');
if ($sponsorId) {
$q->orWhere('sponsor_id', $sponsorId);
}
})
->latest()
->limit(5)
->get()
->map(function ($event) {
$content = $event->body;
if (strpos($event->body, '{"type":"Charity"') === 0) {
$decoded = json_decode($event->body, true);
if ($decoded) {
$content = $decoded['content'] ?? $event->body;
}
}
return [
'id' => $event->id,
'title' => $event->title,
'body' => $content,
'type' => strtolower($event->type),
'status' => $event->status ?? 'pending',
'created_at' => $event->created_at->toIso8601String(),
'time_ago' => $event->created_at->diffForHumans(),
];
});
return response()->json([
'success' => true,
'data' => [
'sponsor' => [
'id' => $sponsor->id,
'full_name' => $sponsor->full_name,
'organization_name' => $sponsor->organization_name,
'mobile' => $sponsor->mobile,
'email' => $sponsor->email,
'city' => $sponsor->city,
'nationality' => $sponsor->nationality,
'is_verified' => $sponsor->is_verified,
'status' => $sponsor->status,
'license_file' => $sponsor->license_file ? asset($sponsor->license_file) : null,
'emirates_id_file' => $sponsor->emirates_id_file ? asset($sponsor->emirates_id_file) : null,
'license_expiry' => $sponsor->license_expiry ? $sponsor->license_expiry->toDateString() : null,
'validity' => $sponsor->license_expiry ? ($sponsor->license_expiry->isFuture() ? 'Valid' : 'Expired') : 'Pending Review',
'joined_at' => $sponsor->created_at->toIso8601String(),
],
'recent_charity_events' => $recentEvents,
'total_events' => Announcement::where(function ($q) use ($sponsorId) {
$q->where('status', 'approved');
if ($sponsorId) {
$q->orWhere('sponsor_id', $sponsorId);
}
})->count(),
'employer_stats' => [
'total' => \App\Models\User::where('role', 'employer')->count(),
'active' => \App\Models\User::where('role', 'employer')->where('subscription_status', 'active')->count(),
],
'worker_stats' => [
'total' => \App\Models\Worker::count(),
'active' => \App\Models\Worker::where('status', 'active')->count(),
],
]
], 200);
} catch (\Exception $e) {
logger()->error('Sponsor Dashboard API Failure: ' . $e->getMessage());
return response()->json([
'success' => false,
'message' => 'An error occurred while loading your dashboard.',
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
], 500);
}
}
/**
* GET /api/sponsors/charity-events
*
* Returns a paginated list of all charity/announcement events.
*/
public function getCharityEvents(Request $request)
{
try {
$page = (int) $request->input('page', 1);
$perPage = (int) $request->input('per_page', 15);
$type = $request->input('type'); // optional filter: 'charity', 'update', etc.
/** @var Sponsor $sponsor */
$sponsor = $request->attributes->get('sponsor');
$sponsorId = $sponsor ? $sponsor->id : null;
$query = Announcement::with(['employer.employerProfile', 'sponsor'])
->where(function ($q) use ($sponsorId) {
$q->where('status', 'approved');
if ($sponsorId) {
$q->orWhere('sponsor_id', $sponsorId);
}
})
->latest();
if ($type) {
if (strtolower($type) === 'charity') {
$query->whereIn('type', ['charity', 'Charity']);
} else {
$query->where('type', $type);
}
}
$total = $query->count();
$offset = ($page - 1) * $perPage;
$events = $query->skip($offset)->take($perPage)->get()
->map(function ($event) {
$postedBy = 'System';
$organization = 'Migrant Support';
if ($event->sponsor_id) {
$postedBy = $event->sponsor->full_name;
$organization = $event->sponsor->organization_name;
} elseif ($event->employer_id) {
$postedBy = $event->employer->name;
$organization = optional($event->employer)->employerProfile->company_name ?? 'Migrant Support';
}
// Decode charity details if they exist in json
$charityDetails = null;
$content = $event->body;
if (strpos($event->body, '{"type":"Charity"') === 0) {
$decoded = json_decode($event->body, true);
if ($decoded) {
$charityDetails = $decoded;
$content = $decoded['content'] ?? $event->body;
}
}
return [
'id' => $event->id,
'title' => $event->title,
'body' => $content,
'type' => strtolower($event->type),
'status' => $event->status ?? 'pending',
'remarks' => $event->remarks,
'posted_by' => $postedBy,
'organization' => $organization,
'created_at' => $event->created_at->toIso8601String(),
'time_ago' => $event->created_at->diffForHumans(),
'charity_details' => $charityDetails,
];
});
return response()->json([
'success' => true,
'data' => [
'events' => $events,
'pagination' => [
'total' => $total,
'per_page' => $perPage,
'current_page' => $page,
'last_page' => max(1, (int) ceil($total / $perPage)),
],
]
], 200);
} catch (\Exception $e) {
logger()->error('Sponsor Charity Events API Failure: ' . $e->getMessage());
return response()->json([
'success' => false,
'message' => 'An error occurred while fetching charity events.',
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
], 500);
}
}
/**
* POST /api/sponsors/charity-events
*
* Creates/Posts a new charity event for the authenticated sponsor.
*/
public function postCharityEvent(Request $request)
{
/** @var Sponsor $sponsor */
$sponsor = $request->attributes->get('sponsor');
if (!$sponsor) {
return response()->json([
'success' => false,
'message' => 'Unauthorized.'
], 401);
}
$validator = \Illuminate\Support\Facades\Validator::make($request->all(), [
'title' => 'required|string|max:255',
'body' => 'required|string',
'type' => 'nullable|string|in:charity,info,warning,success',
'event_date' => 'required|string',
'start_time' => 'required|string',
'end_time' => 'required|string',
'provided_items' => 'required|string',
'location_details' => 'required|string',
'location_pin' => 'required|string|url',
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'message' => 'Validation error.',
'errors' => $validator->errors()
], 422);
}
try {
$eventTime = $request->start_time . ' - ' . $request->end_time;
$bodyJson = json_encode([
'type' => 'Charity',
'provided_items' => $request->provided_items,
'event_date' => $request->event_date,
'event_time' => $eventTime,
'location_details' => $request->location_details,
'location_pin' => $request->location_pin,
'content' => $request->body,
]);
$event = Announcement::create([
'title' => $request->title,
'body' => $bodyJson,
'type' => $request->type ?? 'charity',
'sponsor_id' => $sponsor->id,
'status' => 'pending',
]);
// Decode charity details for the response representation
$charityDetails = null;
$content = $event->body;
if (strpos($event->body, '{"type":"Charity"') === 0) {
$decoded = json_decode($event->body, true);
if ($decoded) {
$charityDetails = $decoded;
$content = $decoded['content'] ?? $event->body;
}
}
return response()->json([
'success' => true,
'message' => 'Charity event posted successfully.',
'data' => [
'id' => $event->id,
'title' => $event->title,
'body' => $content,
'type' => strtolower($event->type),
'posted_by' => $sponsor->full_name,
'organization' => $sponsor->organization_name,
'created_at' => $event->created_at->toIso8601String(),
'charity_details' => $charityDetails,
]
], 201);
} catch (\Exception $e) {
logger()->error('Sponsor Post Charity Event API Failure: ' . $e->getMessage());
return response()->json([
'success' => false,
'message' => 'An error occurred while posting the charity event.',
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
], 500);
}
}
/**
* GET /api/sponsors/profile
*
* Returns the authenticated sponsor's full profile.
*/
public function getProfile(Request $request)
{
/** @var Sponsor $sponsor */
$sponsor = $request->attributes->get('sponsor');
return response()->json([
'success' => true,
'data' => [
'sponsor' => [
'id' => $sponsor->id,
'full_name' => $sponsor->full_name,
'organization_name' => $sponsor->organization_name,
'mobile' => $sponsor->mobile,
'email' => $sponsor->email,
'nationality' => $sponsor->nationality,
'city' => $sponsor->city,
'address' => $sponsor->address,
'country_code' => $sponsor->country_code,
'is_verified' => $sponsor->is_verified,
'status' => $sponsor->status,
'license_file' => $sponsor->license_file ? asset($sponsor->license_file) : null,
'emirates_id_file' => $sponsor->emirates_id_file ? asset($sponsor->emirates_id_file) : null,
'license_expiry' => $sponsor->license_expiry ? $sponsor->license_expiry->toDateString() : null,
'validity' => $sponsor->license_expiry ? ($sponsor->license_expiry->isFuture() ? 'Valid' : 'Expired') : 'Pending Review',
'joined_at' => $sponsor->created_at->toIso8601String(),
]
]
], 200);
}
}