288 lines
12 KiB
PHP
288 lines
12 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');
|
|
|
|
try {
|
|
// Recent charity/update announcements for the dashboard preview
|
|
$recentEvents = Announcement::where('status', 'approved')
|
|
->latest()
|
|
->limit(5)
|
|
->get()
|
|
->map(function ($event) {
|
|
return [
|
|
'id' => $event->id,
|
|
'title' => $event->title,
|
|
'body' => $event->body,
|
|
'type' => $event->type,
|
|
'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,
|
|
'joined_at' => $sponsor->created_at->toIso8601String(),
|
|
],
|
|
'recent_charity_events' => $recentEvents,
|
|
'total_events' => Announcement::where('status', 'approved')->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.
|
|
|
|
$query = Announcement::with(['employer.employerProfile', 'sponsor'])->where('status', 'approved')->latest();
|
|
|
|
if ($type) {
|
|
$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' => $event->type,
|
|
'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' => $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,
|
|
'joined_at' => $sponsor->created_at->toIso8601String(),
|
|
]
|
|
]
|
|
], 200);
|
|
}
|
|
}
|