283 lines
12 KiB
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.");
|
|
}
|
|
}
|