migrant-web/app/Http/Controllers/Admin/SponsorController.php

283 lines
12 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Sponsor;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Illuminate\Support\Facades\Hash;
class SponsorController extends Controller
{
/**
* List all sponsors with filters, search, and sorting.
*/
public function index(Request $request)
{
$query = Sponsor::query();
// Server-side Search
if ($request->filled('search')) {
$search = $request->input('search');
$query->where(function($q) use ($search) {
$q->where('full_name', 'like', "%{$search}%")
->orWhere('organization_name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%")
->orWhere('mobile', 'like', "%{$search}%");
});
}
// Server-side Status filter
if ($request->filled('status') && $request->input('status') !== 'All') {
$query->where('status', strtolower($request->input('status')));
}
// Verification filter
if ($request->filled('verification') && $request->input('verification') !== 'All') {
$isVerified = $request->input('verification') === 'Verified';
$query->where('is_verified', $isVerified);
}
// License filter
if ($request->filled('license') && $request->input('license') !== 'All') {
$license = $request->input('license');
if ($license === 'Expired') {
$query->where('license_expiry', '<', now());
} elseif ($license === 'Valid') {
$query->where('license_expiry', '>=', now());
} elseif ($license === 'Expiring Soon') {
$query->whereBetween('license_expiry', [now(), now()->addDays(30)]);
}
}
// Nationality filter
if ($request->filled('nationality') && $request->input('nationality') !== 'All') {
$query->where('nationality', $request->input('nationality'));
}
// Server-side Sorting
$sortField = $request->input('sort_field', 'created_at');
$sortOrder = $request->input('sort_order', 'desc');
if (in_array($sortField, ['full_name', 'organization_name', 'email', 'city', 'status', 'created_at'])) {
$query->orderBy($sortField, $sortOrder);
} else {
$query->orderBy('created_at', 'desc');
}
// Paginate
$sponsors = $query->paginate(10)->withQueryString();
// Get distinct nationalities
$nationalities = [
'Afghan', 'Albanian', 'Algerian', 'American', 'Andorran', 'Angolan', 'Argentinian', 'Armenian', 'Australian', 'Austrian',
'Azerbaijani', 'Bahamian', 'Bahraini', 'Bangladeshi', 'Barbadian', 'Belarusian', 'Belgian', 'Belizean', 'Beninese', 'Bhutanese',
'Bolivian', 'Bosnian', 'Brazilian', 'British', 'Bruneian', 'Bulgarian', 'Burkinabe', 'Burmese', 'Burundian', 'Cambodian',
'Cameroonian', 'Canadian', 'Cape Verdean', 'Central African', 'Chadian', 'Chilean', 'Chinese', 'Colombian', 'Comoran', 'Congolese',
'Costa Rican', 'Croatian', 'Cuban', 'Cypriot', 'Czech', 'Danish', 'Djiboutian', 'Dominican', 'Dutch', 'East Timorese',
'Ecuadorian', 'Egyptian', 'Emirati', 'Equatorial Guinean', 'Eritrean', 'Estonian', 'Ethiopian', 'Fijian', 'Filipino', 'Finnish',
'French', 'Gabonese', 'Gambian', 'Georgian', 'German', 'Ghanaian', 'Greek', 'Grenadian', 'Guatemalan', 'Guinean',
'Guyanese', 'Haitian', 'Honduran', 'Hungarian', 'Icelandic', 'Indian', 'Indonesian', 'Iranian', 'Iraqi', 'Irish',
'Italian', 'Ivorian', 'Jamaican', 'Japanese', 'Jordanian', 'Kazakh', 'Kenyan', 'Kuwaiti', 'Kyrgyz', 'Laotian',
'Latvian', 'Lebanese', 'Liberian', 'Libyan', 'Liechtensteiner', 'Lithuanian', 'Luxembourger', 'Macedonian', 'Malagasy', 'Malawian',
'Malaysian', 'Maldivian', 'Malian', 'Maltese', 'Mauritanian', 'Mauritian', 'Mexican', 'Micronesian', 'Moldovan', 'Monacan',
'Mongolian', 'Montenegrin', 'Moroccan', 'Mozambican', 'Namibian', 'Nauruan', 'Nepalese', 'New Zealander', 'Nicaraguan', 'Nigerian',
'Nigerien', 'North Korean', 'Norwegian', 'Omani', 'Pakistani', 'Palauans', 'Palestinian', 'Panamanian', 'Papua New Guinean', 'Paraguayan',
'Peruvian', 'Polish', 'Portuguese', 'Qatari', 'Romanian', 'Russian', 'Rwandan', 'Saint Lucian', 'Salvadoran', 'Samoan',
'San Marinese', 'Sao Tomean', 'Saudi Arabian', 'Senegalese', 'Serbian', 'Seychellois', 'Sierra Leonean', 'Singaporean', 'Slovak', 'Slovenian',
'Solomon Islander', 'Somali', 'South African', 'South Korean', 'Spanish', 'Sri Lankan', 'Sudanese', 'Surinamese', 'Swazi', 'Swedish',
'Swiss', 'Syrian', 'Taiwanese', 'Tajik', 'Tanzanian', 'Thai', 'Togolese', 'Tongan', 'Trinidadian', 'Tunisian',
'Turkish', 'Turkmen', 'Tuvaluan', 'Ugandan', 'Ukrainian', 'Uruguayan', 'Uzbek', 'Vanuatuan', 'Venezuelan', 'Vietnamese',
'Western Samoan', 'Yemeni', 'Zambian', 'Zimbabwean'
];
// Global stats counts (removing Active plans / Pending approval, replacing with Total, Verified, Suspended)
$stats = [
'total' => Sponsor::count(),
'verified' => Sponsor::where('is_verified', true)->count(),
'suspended' => Sponsor::where('status', 'suspended')->count(),
];
return Inertia::render('Admin/CharityOrganizations/Index', [
'sponsors' => $sponsors,
'filters' => $request->only(['search', 'status', 'verification', 'license', 'nationality', 'sort_field', 'sort_order']),
'nationalities' => $nationalities,
'stats' => $stats
]);
}
/**
* Export sponsors as CSV with filters, search, and sorting.
*/
public function export(Request $request)
{
$query = Sponsor::query();
// Server-side Search
if ($request->filled('search')) {
$search = $request->input('search');
$query->where(function($q) use ($search) {
$q->where('full_name', 'like', "%{$search}%")
->orWhere('organization_name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%")
->orWhere('mobile', 'like', "%{$search}%");
});
}
// Server-side Status filter
if ($request->filled('status') && $request->input('status') !== 'All') {
$query->where('status', strtolower($request->input('status')));
}
// Verification filter
if ($request->filled('verification') && $request->input('verification') !== 'All') {
$isVerified = $request->input('verification') === 'Verified';
$query->where('is_verified', $isVerified);
}
// License filter
if ($request->filled('license') && $request->input('license') !== 'All') {
$license = $request->input('license');
if ($license === 'Expired') {
$query->where('license_expiry', '<', now());
} elseif ($license === 'Valid') {
$query->where('license_expiry', '>=', now());
} elseif ($license === 'Expiring Soon') {
$query->whereBetween('license_expiry', [now(), now()->addDays(30)]);
}
}
// Nationality filter
if ($request->filled('nationality') && $request->input('nationality') !== 'All') {
$query->where('nationality', $request->input('nationality'));
}
// Server-side Sorting
$sortField = $request->input('sort_field', 'created_at');
$sortOrder = $request->input('sort_order', 'desc');
if (in_array($sortField, ['full_name', 'organization_name', 'email', 'city', 'status', 'created_at'])) {
$query->orderBy($sortField, $sortOrder);
} else {
$query->orderBy('created_at', 'desc');
}
$sponsors = $query->get();
$headers = [
"Content-type" => "text/csv",
"Content-Disposition" => "attachment; filename=charity_organizations_export_" . date('Ymd_His') . ".csv",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
];
$columns = ['ID', 'Organization Name', 'Full Name', 'Email', 'Mobile', 'City', 'Nationality', 'Address', 'Status', 'Verified', 'License Expiry', 'Created At'];
$callback = function() use ($sponsors, $columns) {
$file = fopen('php://output', 'w');
fputcsv($file, $columns);
foreach ($sponsors as $sponsor) {
fputcsv($file, [
$sponsor->id,
$sponsor->organization_name ?? 'N/A',
$sponsor->full_name,
$sponsor->email,
$sponsor->mobile,
$sponsor->city ?? 'Dubai',
$sponsor->nationality ?? 'N/A',
$sponsor->address ?? 'N/A',
$sponsor->status,
$sponsor->is_verified ? 'Yes' : 'No',
$sponsor->license_expiry ? $sponsor->license_expiry->toDateString() : 'N/A',
$sponsor->created_at ? $sponsor->created_at->toDateTimeString() : 'N/A',
]);
}
fclose($file);
};
return response()->stream($callback, 200, $headers);
}
/**
* Approve and verify a sponsor.
*/
public function verify($id)
{
$sponsor = Sponsor::findOrFail($id);
$sponsor->update([
'is_verified' => true,
'otp_verified_at' => $sponsor->otp_verified_at ?? now(),
'status' => 'active'
]);
return back()->with('success', "Sponsor '{$sponsor->full_name}' verified and status activated successfully.");
}
/**
* Suspend a sponsor.
*/
public function suspend(Request $request, $id)
{
$sponsor = Sponsor::findOrFail($id);
$sponsor->update([
'status' => 'suspended'
]);
return back()->with('success', "Sponsor '{$sponsor->full_name}' suspended successfully.");
}
/**
* Activate a suspended/inactive sponsor.
*/
public function activate($id)
{
$sponsor = Sponsor::findOrFail($id);
$sponsor->update([
'status' => 'active'
]);
return back()->with('success', "Sponsor '{$sponsor->full_name}' activated successfully.");
}
/**
* Delete a sponsor registry.
*/
public function delete($id)
{
$sponsor = Sponsor::findOrFail($id);
$name = $sponsor->full_name;
$sponsor->delete();
return back()->with('success', "Sponsor '{$name}' deleted successfully from database.");
}
/**
* Edit / Update a sponsor's registry fields.
*/
public function update(Request $request, $id)
{
$sponsor = Sponsor::findOrFail($id);
$validated = $request->validate([
'full_name' => 'required|string|max:255',
'organization_name' => 'nullable|string|max:255',
'email' => 'required|email|unique:sponsors,email,' . $sponsor->id,
'mobile' => 'required|string',
'city' => 'required|string',
'nationality' => 'nullable|string',
'address' => 'nullable|string',
'subscription_plan' => 'nullable|string',
'subscription_status' => 'nullable|string',
]);
$sponsor->update($validated);
return back()->with('success', "Sponsor details saved successfully.");
}
}