From 07cfb1670869179b4ce7212fcb25a7aae9763583 Mon Sep 17 00:00:00 2001 From: mohanmd Date: Wed, 10 Jun 2026 17:40:58 +0530 Subject: [PATCH] charity event admin --- .../Admin/AdminExtraController.php | 1 + .../1781092149_passport_passport.pdf | 0 .../1781092408_passport_passport.pdf | 0 .../licenses/1781092147_license_license.pdf | 0 .../licenses/1781092407_license_license.pdf | 0 resources/js/Layouts/AdminLayout.jsx | 2 +- resources/js/Layouts/EmployerLayout.jsx | 2 +- .../js/Pages/Admin/Announcements/Index.jsx | 231 +++++++++++------- resources/js/Pages/Employer/Announcements.jsx | 2 +- routes/web.php | 14 +- tests/Feature/AnnouncementApiTest.php | 2 +- 11 files changed, 155 insertions(+), 99 deletions(-) create mode 100644 public/uploads/documents/1781092149_passport_passport.pdf create mode 100644 public/uploads/documents/1781092408_passport_passport.pdf create mode 100644 public/uploads/licenses/1781092147_license_license.pdf create mode 100644 public/uploads/licenses/1781092407_license_license.pdf diff --git a/app/Http/Controllers/Admin/AdminExtraController.php b/app/Http/Controllers/Admin/AdminExtraController.php index 81590ae..6b555d1 100644 --- a/app/Http/Controllers/Admin/AdminExtraController.php +++ b/app/Http/Controllers/Admin/AdminExtraController.php @@ -485,6 +485,7 @@ public function announcements() 'type' => $ann->type ?? 'Charity', 'posted_by' => $postedBy, 'organization' => $organization, + 'posted_by_email' => $ann->sponsor ? $ann->sponsor->email : ($ann->employer ? $ann->employer->email : null), 'status' => $ann->status ?? 'pending', 'remarks' => $ann->remarks, 'created_at' => $ann->created_at ? $ann->created_at->format('M d, Y h:i A') : 'Just now', diff --git a/public/uploads/documents/1781092149_passport_passport.pdf b/public/uploads/documents/1781092149_passport_passport.pdf new file mode 100644 index 0000000..e69de29 diff --git a/public/uploads/documents/1781092408_passport_passport.pdf b/public/uploads/documents/1781092408_passport_passport.pdf new file mode 100644 index 0000000..e69de29 diff --git a/public/uploads/licenses/1781092147_license_license.pdf b/public/uploads/licenses/1781092147_license_license.pdf new file mode 100644 index 0000000..e69de29 diff --git a/public/uploads/licenses/1781092407_license_license.pdf b/public/uploads/licenses/1781092407_license_license.pdf new file mode 100644 index 0000000..e69de29 diff --git a/resources/js/Layouts/AdminLayout.jsx b/resources/js/Layouts/AdminLayout.jsx index 0326a11..37e9019 100644 --- a/resources/js/Layouts/AdminLayout.jsx +++ b/resources/js/Layouts/AdminLayout.jsx @@ -40,7 +40,7 @@ export default function AdminLayout({ children, title = 'Dashboard' }) { { name: 'Campaigns & Alerts', href: '/admin/notifications', icon: BellRing }, { name: 'Reports & Analytics', href: '/admin/analytics', icon: BarChart3 }, { name: 'System Audit Logs', href: '/admin/audit-logs', icon: History }, - { name: 'Charity Events', href: '/admin/announcements', icon: Heart }, + { name: 'Charity Events', href: '/admin/events', icon: Heart }, { name: 'Skills', href: '/admin/master-data/skills', icon: Settings }, { name: 'Reason Master', href: '/admin/master-data/reasons', icon: List }, ]; diff --git a/resources/js/Layouts/EmployerLayout.jsx b/resources/js/Layouts/EmployerLayout.jsx index e5cd2d0..9935581 100644 --- a/resources/js/Layouts/EmployerLayout.jsx +++ b/resources/js/Layouts/EmployerLayout.jsx @@ -68,7 +68,7 @@ export default function EmployerLayout({ children, title, fullPage = false }) { { name: 'Shortlist', translationKey: 'shortlist', href: '/employer/shortlist', icon: Bookmark }, { name: 'Candidates', translationKey: 'candidates', href: '/employer/candidates', icon: UserCheck }, { name: 'Messages', translationKey: 'messages', href: '/employer/messages', icon: MessageSquare, badge: unread_messages_count }, - { name: 'Charity Events', translationKey: 'charity_events', href: '/employer/announcements', icon: Heart }, + { name: 'Charity Events', translationKey: 'charity_events', href: '/employer/events', icon: Heart }, { name: 'Subscription', translationKey: 'subscription', href: '/employer/subscription', icon: CreditCard }, { name: 'Payment History', translationKey: 'payment_history', href: '/employer/payments', icon: FileText }, { name: 'My Profile', translationKey: 'my_profile', href: '/employer/profile', icon: User }, diff --git a/resources/js/Pages/Admin/Announcements/Index.jsx b/resources/js/Pages/Admin/Announcements/Index.jsx index 6c24e69..875b5ca 100644 --- a/resources/js/Pages/Admin/Announcements/Index.jsx +++ b/resources/js/Pages/Admin/Announcements/Index.jsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Head, router } from '@inertiajs/react'; +import { Head, router, Link } from '@inertiajs/react'; import AdminLayout from '../../../Layouts/AdminLayout'; import { Heart, Plus, Trash2, Send, CheckCircle2, Check, X, @@ -68,7 +68,7 @@ export default function Announcements({ initialAnnouncements }) { return; } - router.post(route('admin.announcements.store'), { + router.post(route('admin.events.store'), { title: newAnnouncement.title, content: newAnnouncement.content, provided_items: newAnnouncement.provided_items, @@ -107,7 +107,7 @@ export default function Announcements({ initialAnnouncements }) { }; const handleApprove = (id) => { - router.post(route('admin.announcements.approve', id), {}, { + router.post(route('admin.events.approve', id), {}, { onSuccess: () => { showToast('Charity Event approved successfully'); setTimeout(() => window.location.reload(), 500); @@ -124,7 +124,7 @@ export default function Announcements({ initialAnnouncements }) { e.preventDefault(); if (!rejectionRemarks.trim()) return; - router.post(route('admin.announcements.reject', rejectingAnnouncementId), { + router.post(route('admin.events.reject', rejectingAnnouncementId), { remarks: rejectionRemarks }, { onSuccess: () => { @@ -138,7 +138,7 @@ export default function Announcements({ initialAnnouncements }) { const handleDelete = (id) => { if (confirm('Are you sure you want to delete this charity event?')) { - router.delete(route('admin.announcements.delete', id), { + router.delete(route('admin.events.delete', id), { onSuccess: () => { showToast('Charity Event deleted'); setTimeout(() => window.location.reload(), 500); @@ -186,7 +186,7 @@ export default function Announcements({ initialAnnouncements }) { )} -
+
{/* Upper Header section */}
@@ -602,7 +602,7 @@ export default function Announcements({ initialAnnouncements }) {

No charity events match your criteria.

) : ( -
+
{filteredAnnouncements.map((ann) => { const details = ann.charityDetails; const isExpanded = !!expandedCards[ann.id]; @@ -616,71 +616,104 @@ export default function Announcements({ initialAnnouncements }) { return (
+ {/* Top colored accent line */} +
+ {/* Top Card Area */} -
-
-
-
-

- - {ann.title} -

- - {ann.status} - - -
-
- - {ann.organization} - - - {ann.posted_by} -
-
- - {/* Action Control Buttons */} -
- {ann.status === 'pending' && ( -
- - +
+
+ {/* Header Title + Actions */} +
+
+ {/* Status Badge */} +
+ + {ann.status} + + {ann.type === 'charity' && ( + + + Charity + + )}
- )} - + + {/* Event Title */} +

+ {ann.title} +

+
+ + {/* Action Control Buttons */} +
+ {ann.status === 'pending' && ( +
+ + +
+ )} + +
+ + {/* Posted Organization & Author */} + {ann.posted_by_email ? ( + + + {ann.organization} + + + {ann.posted_by} + + ) : ( +
+ + {ann.organization} + + + {ann.posted_by} +
+ )}
- {/* Collapsible Content */} + {/* Description Content */}
-

+

{ann.content}

@@ -688,56 +721,78 @@ export default function Announcements({ initialAnnouncements }) { )} + {ann.status === 'rejected' && ann.remarks && ( -
- Remarks: {ann.remarks} +
+ Rejection Remarks: + {ann.remarks}
)}
- {/* Details metadata row (compact icons) */} + {/* Metadata Details container (Soft boxes/pills stacked vertically) */} {details && ( -
-
- - - {details.provided_items} - +
+ {/* Provided Items */} +
+
+ +
+
+
ITEMS PROVIDED
+
+ {details.provided_items} +
+
-
- - - {details.event_date} - + + {/* Date & Time */} +
+
+ +
+
+
EVENT SCHEDULE
+
+ {details.event_date} ({details.event_time}) +
+
-
- - - {details.location_details} - + + {/* Location */} +
+
+ +
+
+
LOCATION
+
+ {details.location_details} +
+
)}
{/* Bottom Card Footer */} -
+
Published: {ann.created_at} {details?.location_pin && ( View on Map - + )}
diff --git a/resources/js/Pages/Employer/Announcements.jsx b/resources/js/Pages/Employer/Announcements.jsx index fb8e880..f9f400d 100644 --- a/resources/js/Pages/Employer/Announcements.jsx +++ b/resources/js/Pages/Employer/Announcements.jsx @@ -100,7 +100,7 @@ export default function Announcements({ initialAnnouncements }) { const handleCreate = (e) => { e.preventDefault(); - post('/employer/announcements/create', { + post('/employer/events/create', { preserveScroll: true, onSuccess: () => { reset(); diff --git a/routes/web.php b/routes/web.php index faa7c1c..236be15 100644 --- a/routes/web.php +++ b/routes/web.php @@ -193,11 +193,11 @@ return redirect()->back(); })->name('admin.reasons.delete'); - Route::get('/announcements', [\App\Http\Controllers\Admin\AdminExtraController::class, 'announcements'])->name('admin.announcements'); - Route::post('/announcements/create', [\App\Http\Controllers\Admin\AdminExtraController::class, 'storeAnnouncement'])->name('admin.announcements.store'); - Route::post('/announcements/{id}/approve', [\App\Http\Controllers\Admin\AdminExtraController::class, 'approveAnnouncement'])->name('admin.announcements.approve'); - Route::post('/announcements/{id}/reject', [\App\Http\Controllers\Admin\AdminExtraController::class, 'rejectAnnouncement'])->name('admin.announcements.reject'); - Route::delete('/announcements/{id}', [\App\Http\Controllers\Admin\AdminExtraController::class, 'deleteAnnouncement'])->name('admin.announcements.delete'); + Route::get('/events', [\App\Http\Controllers\Admin\AdminExtraController::class, 'announcements'])->name('admin.events'); + Route::post('/events/create', [\App\Http\Controllers\Admin\AdminExtraController::class, 'storeAnnouncement'])->name('admin.events.store'); + Route::post('/events/{id}/approve', [\App\Http\Controllers\Admin\AdminExtraController::class, 'approveAnnouncement'])->name('admin.events.approve'); + Route::post('/events/{id}/reject', [\App\Http\Controllers\Admin\AdminExtraController::class, 'rejectAnnouncement'])->name('admin.events.reject'); + Route::delete('/events/{id}', [\App\Http\Controllers\Admin\AdminExtraController::class, 'deleteAnnouncement'])->name('admin.events.delete'); // New Modules Added Route::get('/safety', [\App\Http\Controllers\Admin\AdminExtraController::class, 'safety'])->name('admin.safety'); @@ -329,8 +329,8 @@ Route::get('/candidates', [\App\Http\Controllers\Employer\CandidateController::class, 'index'])->name('employer.candidates'); Route::post('/candidates/{id}/status', [\App\Http\Controllers\Employer\CandidateController::class, 'updateStatus'])->name('employer.candidates.status'); - Route::get('/announcements', [\App\Http\Controllers\Employer\AnnouncementController::class, 'index'])->name('employer.announcements'); - Route::post('/announcements/create', [\App\Http\Controllers\Employer\AnnouncementController::class, 'store'])->name('employer.announcements.store'); + Route::get('/events', [\App\Http\Controllers\Employer\AnnouncementController::class, 'index'])->name('employer.events'); + Route::post('/events/create', [\App\Http\Controllers\Employer\AnnouncementController::class, 'store'])->name('employer.events.store'); Route::get('/profile', [\App\Http\Controllers\Employer\ProfileController::class, 'index'])->name('employer.profile'); Route::post('/profile/update', [\App\Http\Controllers\Employer\ProfileController::class, 'update'])->name('employer.profile.update'); diff --git a/tests/Feature/AnnouncementApiTest.php b/tests/Feature/AnnouncementApiTest.php index 1258c73..947482b 100644 --- a/tests/Feature/AnnouncementApiTest.php +++ b/tests/Feature/AnnouncementApiTest.php @@ -288,7 +288,7 @@ public function test_admin_can_reject_announcement_with_remarks() $response = $this->actingAs($admin) ->withSession(['user' => $admin]) - ->post('/admin/announcements/' . $announcement->id . '/reject', [ + ->post('/admin/events/' . $announcement->id . '/reject', [ 'remarks' => 'Inappropriate content or location details.', ]);