select('email')->from('users')->where('role', 'employer'); }); // 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::whereNotIn('email', function($q) { $q->select('email')->from('users')->where('role', 'employer'); })->count(), 'verified' => Sponsor::whereNotIn('email', function($q) { $q->select('email')->from('users')->where('role', 'employer'); })->where('is_verified', true)->count(), 'suspended' => Sponsor::whereNotIn('email', function($q) { $q->select('email')->from('users')->where('role', 'employer'); })->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::whereNotIn('email', function($q) { $q->select('email')->from('users')->where('role', 'employer'); }); // 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."); } }