charity event admin
This commit is contained in:
parent
30bef4e28e
commit
07cfb16708
@ -485,6 +485,7 @@ public function announcements()
|
|||||||
'type' => $ann->type ?? 'Charity',
|
'type' => $ann->type ?? 'Charity',
|
||||||
'posted_by' => $postedBy,
|
'posted_by' => $postedBy,
|
||||||
'organization' => $organization,
|
'organization' => $organization,
|
||||||
|
'posted_by_email' => $ann->sponsor ? $ann->sponsor->email : ($ann->employer ? $ann->employer->email : null),
|
||||||
'status' => $ann->status ?? 'pending',
|
'status' => $ann->status ?? 'pending',
|
||||||
'remarks' => $ann->remarks,
|
'remarks' => $ann->remarks,
|
||||||
'created_at' => $ann->created_at ? $ann->created_at->format('M d, Y h:i A') : 'Just now',
|
'created_at' => $ann->created_at ? $ann->created_at->format('M d, Y h:i A') : 'Just now',
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export default function AdminLayout({ children, title = 'Dashboard' }) {
|
|||||||
{ name: 'Campaigns & Alerts', href: '/admin/notifications', icon: BellRing },
|
{ name: 'Campaigns & Alerts', href: '/admin/notifications', icon: BellRing },
|
||||||
{ name: 'Reports & Analytics', href: '/admin/analytics', icon: BarChart3 },
|
{ name: 'Reports & Analytics', href: '/admin/analytics', icon: BarChart3 },
|
||||||
{ name: 'System Audit Logs', href: '/admin/audit-logs', icon: History },
|
{ 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: 'Skills', href: '/admin/master-data/skills', icon: Settings },
|
||||||
{ name: 'Reason Master', href: '/admin/master-data/reasons', icon: List },
|
{ name: 'Reason Master', href: '/admin/master-data/reasons', icon: List },
|
||||||
];
|
];
|
||||||
|
|||||||
@ -68,7 +68,7 @@ export default function EmployerLayout({ children, title, fullPage = false }) {
|
|||||||
{ name: 'Shortlist', translationKey: 'shortlist', href: '/employer/shortlist', icon: Bookmark },
|
{ name: 'Shortlist', translationKey: 'shortlist', href: '/employer/shortlist', icon: Bookmark },
|
||||||
{ name: 'Candidates', translationKey: 'candidates', href: '/employer/candidates', icon: UserCheck },
|
{ name: 'Candidates', translationKey: 'candidates', href: '/employer/candidates', icon: UserCheck },
|
||||||
{ name: 'Messages', translationKey: 'messages', href: '/employer/messages', icon: MessageSquare, badge: unread_messages_count },
|
{ 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: 'Subscription', translationKey: 'subscription', href: '/employer/subscription', icon: CreditCard },
|
||||||
{ name: 'Payment History', translationKey: 'payment_history', href: '/employer/payments', icon: FileText },
|
{ name: 'Payment History', translationKey: 'payment_history', href: '/employer/payments', icon: FileText },
|
||||||
{ name: 'My Profile', translationKey: 'my_profile', href: '/employer/profile', icon: User },
|
{ name: 'My Profile', translationKey: 'my_profile', href: '/employer/profile', icon: User },
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Head, router } from '@inertiajs/react';
|
import { Head, router, Link } from '@inertiajs/react';
|
||||||
import AdminLayout from '../../../Layouts/AdminLayout';
|
import AdminLayout from '../../../Layouts/AdminLayout';
|
||||||
import {
|
import {
|
||||||
Heart, Plus, Trash2, Send, CheckCircle2, Check, X,
|
Heart, Plus, Trash2, Send, CheckCircle2, Check, X,
|
||||||
@ -68,7 +68,7 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
router.post(route('admin.announcements.store'), {
|
router.post(route('admin.events.store'), {
|
||||||
title: newAnnouncement.title,
|
title: newAnnouncement.title,
|
||||||
content: newAnnouncement.content,
|
content: newAnnouncement.content,
|
||||||
provided_items: newAnnouncement.provided_items,
|
provided_items: newAnnouncement.provided_items,
|
||||||
@ -107,7 +107,7 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleApprove = (id) => {
|
const handleApprove = (id) => {
|
||||||
router.post(route('admin.announcements.approve', id), {}, {
|
router.post(route('admin.events.approve', id), {}, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
showToast('Charity Event approved successfully');
|
showToast('Charity Event approved successfully');
|
||||||
setTimeout(() => window.location.reload(), 500);
|
setTimeout(() => window.location.reload(), 500);
|
||||||
@ -124,7 +124,7 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!rejectionRemarks.trim()) return;
|
if (!rejectionRemarks.trim()) return;
|
||||||
|
|
||||||
router.post(route('admin.announcements.reject', rejectingAnnouncementId), {
|
router.post(route('admin.events.reject', rejectingAnnouncementId), {
|
||||||
remarks: rejectionRemarks
|
remarks: rejectionRemarks
|
||||||
}, {
|
}, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
@ -138,7 +138,7 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
|
|
||||||
const handleDelete = (id) => {
|
const handleDelete = (id) => {
|
||||||
if (confirm('Are you sure you want to delete this charity event?')) {
|
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: () => {
|
onSuccess: () => {
|
||||||
showToast('Charity Event deleted');
|
showToast('Charity Event deleted');
|
||||||
setTimeout(() => window.location.reload(), 500);
|
setTimeout(() => window.location.reload(), 500);
|
||||||
@ -186,7 +186,7 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="space-y-6 select-none max-w-6xl mx-auto pb-12">
|
<div className="space-y-6 select-none max-w-7xl mx-auto pb-12">
|
||||||
|
|
||||||
{/* Upper Header section */}
|
{/* Upper Header section */}
|
||||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||||
@ -602,7 +602,7 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
<p className="font-bold text-sm">No charity events match your criteria.</p>
|
<p className="font-bold text-sm">No charity events match your criteria.</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
||||||
{filteredAnnouncements.map((ann) => {
|
{filteredAnnouncements.map((ann) => {
|
||||||
const details = ann.charityDetails;
|
const details = ann.charityDetails;
|
||||||
const isExpanded = !!expandedCards[ann.id];
|
const isExpanded = !!expandedCards[ann.id];
|
||||||
@ -616,46 +616,55 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={ann.id}
|
key={ann.id}
|
||||||
className={`bg-white rounded-xl border border-slate-200 border-l-4 ${statusColorClass} shadow-sm hover:shadow-md transition-all flex flex-col justify-between`}
|
className="group bg-white rounded-2xl border border-slate-200/80 hover:border-slate-300 shadow-sm hover:shadow-md transition-all duration-300 flex flex-col justify-between overflow-hidden relative"
|
||||||
>
|
>
|
||||||
|
{/* Top colored accent line */}
|
||||||
|
<div className={`h-1.5 w-full ${
|
||||||
|
ann.status === 'approved' ? 'bg-gradient-to-r from-emerald-400 to-teal-500' :
|
||||||
|
ann.status === 'rejected' ? 'bg-gradient-to-r from-rose-400 to-red-500' :
|
||||||
|
'bg-gradient-to-r from-amber-400 to-orange-500'
|
||||||
|
}`} />
|
||||||
|
|
||||||
{/* Top Card Area */}
|
{/* Top Card Area */}
|
||||||
<div className="p-4 space-y-3">
|
<div className="p-5 flex-1 flex flex-col justify-between space-y-4">
|
||||||
<div className="flex items-start justify-between gap-2">
|
<div className="space-y-3">
|
||||||
<div className="space-y-1 flex-1 min-w-0">
|
{/* Header Title + Actions */}
|
||||||
<div className="flex items-center space-x-2 flex-wrap gap-y-1">
|
<div className="flex items-start justify-between gap-3">
|
||||||
<h3 className="font-bold text-sm text-slate-800 tracking-tight flex items-center gap-1 min-w-0">
|
<div className="space-y-1.5 flex-1 min-w-0">
|
||||||
<Sparkles className="w-3.5 h-3.5 text-rose-500 fill-rose-50 shrink-0" />
|
{/* Status Badge */}
|
||||||
<span className="truncate block" title={ann.title}>{ann.title}</span>
|
<div className="flex items-center space-x-2">
|
||||||
</h3>
|
<span className={`px-2 py-0.5 rounded-full text-[9px] font-black uppercase tracking-wider shrink-0 border border-solid ${
|
||||||
<span className={`px-2 py-0.5 rounded text-[8px] font-extrabold uppercase tracking-wider shrink-0 ${
|
ann.status === 'approved' ? 'bg-emerald-50 text-emerald-700 border-emerald-100' :
|
||||||
ann.status === 'approved' ? 'bg-emerald-50 text-emerald-700 border border-solid border-emerald-100' :
|
ann.status === 'rejected' ? 'bg-rose-50 text-rose-700 border-rose-100' :
|
||||||
ann.status === 'rejected' ? 'bg-rose-50 text-rose-700 border border-solid border-rose-100' :
|
'bg-amber-50 text-amber-700 border-amber-100'
|
||||||
'bg-amber-50 text-amber-700 border border-solid border-amber-100'
|
|
||||||
}`}>
|
}`}>
|
||||||
{ann.status}
|
{ann.status}
|
||||||
</span>
|
</span>
|
||||||
|
{ann.type === 'charity' && (
|
||||||
|
<span className="bg-teal-50 text-teal-700 border border-solid border-teal-100 px-2 py-0.5 rounded-full text-[9px] font-black uppercase tracking-wider flex items-center gap-0.5">
|
||||||
|
<Heart className="w-2 h-2 fill-teal-600 text-teal-600" />
|
||||||
|
<span>Charity</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
{/* Event Title */}
|
||||||
<div className="flex items-center text-[10px] text-slate-400 font-bold whitespace-nowrap overflow-hidden text-ellipsis">
|
<h3 className="font-extrabold text-sm text-slate-800 leading-snug tracking-tight group-hover:text-[#0F6E56] transition-colors duration-200" title={ann.title}>
|
||||||
<Building className="w-3 h-3 mr-1 text-slate-400 shrink-0" />
|
{ann.title}
|
||||||
<span className="truncate max-w-[120px]" title={ann.organization}>{ann.organization}</span>
|
</h3>
|
||||||
<span className="mx-1">•</span>
|
|
||||||
<User className="w-3 h-3 mr-1 text-slate-400 shrink-0" />
|
|
||||||
<span className="truncate max-w-[100px]" title={ann.posted_by}>{ann.posted_by}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Action Control Buttons */}
|
{/* Action Control Buttons */}
|
||||||
<div className="flex items-center space-x-1 shrink-0">
|
<div className="flex items-center space-x-1 shrink-0">
|
||||||
{ann.status === 'pending' && (
|
{ann.status === 'pending' && (
|
||||||
<div className="flex items-center space-x-1 bg-slate-50 p-0.5 rounded-lg border border-slate-200">
|
<div className="flex items-center space-x-0.5 bg-slate-50 p-0.5 rounded-lg border border-slate-200">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleApprove(ann.id)}
|
onClick={() => handleApprove(ann.id)}
|
||||||
className="p-1 text-emerald-600 hover:bg-emerald-50 rounded transition-colors cursor-pointer border-none bg-transparent"
|
className="p-1 text-emerald-600 hover:bg-emerald-50 rounded transition-colors cursor-pointer border-none bg-transparent"
|
||||||
title="Approve"
|
title="Approve"
|
||||||
>
|
>
|
||||||
<Check className="w-4 h-4" />
|
<Check className="w-3.5 h-3.5" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -663,24 +672,48 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
className="p-1 text-rose-600 hover:bg-rose-50 rounded transition-colors cursor-pointer border-none bg-transparent"
|
className="p-1 text-rose-600 hover:bg-rose-50 rounded transition-colors cursor-pointer border-none bg-transparent"
|
||||||
title="Reject"
|
title="Reject"
|
||||||
>
|
>
|
||||||
<X className="w-4 h-4" />
|
<X className="w-3.5 h-3.5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleDelete(ann.id)}
|
onClick={() => handleDelete(ann.id)}
|
||||||
className="p-1 text-slate-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors cursor-pointer border-none bg-transparent"
|
className="p-1.5 text-slate-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors cursor-pointer border-none bg-transparent"
|
||||||
title="Delete"
|
title="Delete"
|
||||||
>
|
>
|
||||||
<Trash2 className="w-4 h-4" />
|
<Trash2 className="w-3.5 h-3.5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Collapsible Content */}
|
{/* Posted Organization & Author */}
|
||||||
|
{ann.posted_by_email ? (
|
||||||
|
<Link
|
||||||
|
href={`/admin/employers?search=${encodeURIComponent(ann.posted_by_email)}`}
|
||||||
|
className="flex items-center text-[10px] text-slate-500 font-bold bg-slate-50/60 hover:bg-slate-100/80 hover:border-slate-300 py-1 px-2.5 rounded-lg border border-slate-100 transition-all w-fit cursor-pointer no-underline"
|
||||||
|
title="Click to view Employer Profile"
|
||||||
|
>
|
||||||
|
<Building className="w-3 h-3 mr-1 text-slate-400 shrink-0" />
|
||||||
|
<span className="truncate max-w-[120px] text-slate-700" title={ann.organization}>{ann.organization}</span>
|
||||||
|
<span className="mx-1.5 text-slate-300">•</span>
|
||||||
|
<User className="w-3 h-3 mr-1 text-slate-400 shrink-0" />
|
||||||
|
<span className="truncate max-w-[100px] text-slate-600" title={ann.posted_by}>{ann.posted_by}</span>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center text-[10px] text-slate-500 font-bold bg-slate-50/60 py-1 px-2.5 rounded-lg border border-slate-100 w-fit">
|
||||||
|
<Building className="w-3 h-3 mr-1 text-slate-400 shrink-0" />
|
||||||
|
<span className="truncate max-w-[120px] text-slate-700" title={ann.organization}>{ann.organization}</span>
|
||||||
|
<span className="mx-1.5 text-slate-300">•</span>
|
||||||
|
<User className="w-3 h-3 mr-1 text-slate-400 shrink-0" />
|
||||||
|
<span className="truncate max-w-[100px] text-slate-600" title={ann.posted_by}>{ann.posted_by}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Description Content */}
|
||||||
<div className="space-y-2 text-xs">
|
<div className="space-y-2 text-xs">
|
||||||
<p className={`text-slate-600 leading-relaxed ${isExpanded ? '' : 'line-clamp-2'}`}>
|
<p className={`text-slate-600 leading-relaxed font-medium ${isExpanded ? '' : 'line-clamp-3'}`}>
|
||||||
{ann.content}
|
{ann.content}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -688,56 +721,78 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => toggleExpand(ann.id)}
|
onClick={() => toggleExpand(ann.id)}
|
||||||
className="text-[#0F6E56] hover:underline font-bold flex items-center space-x-0.5 border-none bg-transparent cursor-pointer p-0 text-[10px]"
|
className="text-[#0F6E56] hover:text-[#0b523f] hover:underline font-bold flex items-center space-x-0.5 border-none bg-transparent cursor-pointer p-0 text-[10px] transition-colors"
|
||||||
>
|
>
|
||||||
<span>{isExpanded ? 'Show Less' : 'Read Full Description'}</span>
|
<span>{isExpanded ? 'Show Less' : 'Read Full Description'}</span>
|
||||||
{isExpanded ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
|
{isExpanded ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{ann.status === 'rejected' && ann.remarks && (
|
{ann.status === 'rejected' && ann.remarks && (
|
||||||
<div className="bg-rose-50 border border-rose-100 rounded-xl p-2.5 text-rose-800 text-[11px] font-semibold mt-1.5 leading-relaxed">
|
<div className="bg-rose-50/80 border border-rose-100 rounded-xl p-2.5 text-rose-800 text-[10px] font-semibold mt-1.5 leading-relaxed">
|
||||||
<strong>Remarks:</strong> {ann.remarks}
|
<span className="font-extrabold text-rose-900 block mb-0.5">Rejection Remarks:</span>
|
||||||
|
{ann.remarks}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Details metadata row (compact icons) */}
|
{/* Metadata Details container (Soft boxes/pills stacked vertically) */}
|
||||||
{details && (
|
{details && (
|
||||||
<div className="pt-2.5 border-t border-slate-100 grid grid-cols-3 gap-2 text-[10px] text-slate-500 font-bold">
|
<div className="pt-3 border-t border-slate-100/80 space-y-2 text-[10px] font-bold">
|
||||||
<div className="flex items-center space-x-1.5 min-w-0">
|
{/* Provided Items */}
|
||||||
<Gift className="w-3.5 h-3.5 text-rose-500 fill-rose-50 shrink-0" />
|
<div className="flex items-center space-x-2.5 bg-rose-50/40 border border-rose-100/50 p-2 rounded-xl">
|
||||||
<span className="truncate text-slate-700" title={details.provided_items}>
|
<div className="w-7 h-7 rounded-lg bg-rose-50 flex items-center justify-center text-rose-500 shrink-0 border border-rose-100">
|
||||||
|
<Gift className="w-3.5 h-3.5 fill-rose-500" />
|
||||||
|
</div>
|
||||||
|
<div className="min-w-0 leading-tight">
|
||||||
|
<div className="text-[8px] text-rose-400 font-extrabold uppercase tracking-wider">ITEMS PROVIDED</div>
|
||||||
|
<div className="truncate text-slate-700 font-bold text-xs" title={details.provided_items}>
|
||||||
{details.provided_items}
|
{details.provided_items}
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-1.5 min-w-0">
|
|
||||||
<Calendar className="w-3.5 h-3.5 text-amber-500 shrink-0" />
|
|
||||||
<span className="truncate text-slate-700" title={`${details.event_date} ${details.event_time}`}>
|
|
||||||
{details.event_date}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-1.5 min-w-0">
|
</div>
|
||||||
<MapPin className="w-3.5 h-3.5 text-blue-500 shrink-0" />
|
|
||||||
<span className="truncate text-slate-700" title={details.location_details}>
|
{/* Date & Time */}
|
||||||
|
<div className="flex items-center space-x-2.5 bg-amber-50/40 border border-amber-100/50 p-2 rounded-xl">
|
||||||
|
<div className="w-7 h-7 rounded-lg bg-amber-50 flex items-center justify-center text-amber-500 shrink-0 border border-amber-100">
|
||||||
|
<Calendar className="w-3.5 h-3.5 text-amber-600" />
|
||||||
|
</div>
|
||||||
|
<div className="min-w-0 leading-tight">
|
||||||
|
<div className="text-[8px] text-amber-500 font-extrabold uppercase tracking-wider">EVENT SCHEDULE</div>
|
||||||
|
<div className="truncate text-slate-700 font-bold text-xs" title={`${details.event_date} ${details.event_time}`}>
|
||||||
|
{details.event_date} ({details.event_time})
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Location */}
|
||||||
|
<div className="flex items-center space-x-2.5 bg-blue-50/40 border border-blue-100/50 p-2 rounded-xl">
|
||||||
|
<div className="w-7 h-7 rounded-lg bg-blue-50 flex items-center justify-center text-blue-500 shrink-0 border border-blue-100">
|
||||||
|
<MapPin className="w-3.5 h-3.5 text-blue-600" />
|
||||||
|
</div>
|
||||||
|
<div className="min-w-0 leading-tight">
|
||||||
|
<div className="text-[8px] text-blue-400 font-extrabold uppercase tracking-wider">LOCATION</div>
|
||||||
|
<div className="truncate text-slate-700 font-bold text-xs" title={details.location_details}>
|
||||||
{details.location_details}
|
{details.location_details}
|
||||||
</span>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Bottom Card Footer */}
|
{/* Bottom Card Footer */}
|
||||||
<div className="px-4 py-2 bg-slate-50 rounded-b-xl border-t border-slate-100 flex items-center justify-between text-[9px] text-slate-400 font-bold">
|
<div className="px-5 py-3 bg-slate-50/80 rounded-b-2xl border-t border-slate-100 flex items-center justify-between text-[9px] text-slate-400 font-bold">
|
||||||
<span>Published: {ann.created_at}</span>
|
<span>Published: {ann.created_at}</span>
|
||||||
{details?.location_pin && (
|
{details?.location_pin && (
|
||||||
<a
|
<a
|
||||||
href={details.location_pin}
|
href={details.location_pin}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="text-[#0F6E56] hover:underline flex items-center space-x-0.5"
|
className="text-[#0F6E56] hover:text-[#0b523f] hover:underline flex items-center space-x-0.5 bg-white border border-slate-200/80 hover:border-slate-300 py-1 px-2.5 rounded-lg shadow-sm font-extrabold transition-all hover:scale-[1.02] active:scale-[0.98]"
|
||||||
>
|
>
|
||||||
<span>View on Map</span>
|
<span>View on Map</span>
|
||||||
<MapPin className="w-2.5 h-2.5" />
|
<MapPin className="w-2.5 h-2.5 text-[#0F6E56]" />
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -100,7 +100,7 @@ export default function Announcements({ initialAnnouncements }) {
|
|||||||
|
|
||||||
const handleCreate = (e) => {
|
const handleCreate = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
post('/employer/announcements/create', {
|
post('/employer/events/create', {
|
||||||
preserveScroll: true,
|
preserveScroll: true,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
reset();
|
reset();
|
||||||
|
|||||||
@ -193,11 +193,11 @@
|
|||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
})->name('admin.reasons.delete');
|
})->name('admin.reasons.delete');
|
||||||
|
|
||||||
Route::get('/announcements', [\App\Http\Controllers\Admin\AdminExtraController::class, 'announcements'])->name('admin.announcements');
|
Route::get('/events', [\App\Http\Controllers\Admin\AdminExtraController::class, 'announcements'])->name('admin.events');
|
||||||
Route::post('/announcements/create', [\App\Http\Controllers\Admin\AdminExtraController::class, 'storeAnnouncement'])->name('admin.announcements.store');
|
Route::post('/events/create', [\App\Http\Controllers\Admin\AdminExtraController::class, 'storeAnnouncement'])->name('admin.events.store');
|
||||||
Route::post('/announcements/{id}/approve', [\App\Http\Controllers\Admin\AdminExtraController::class, 'approveAnnouncement'])->name('admin.announcements.approve');
|
Route::post('/events/{id}/approve', [\App\Http\Controllers\Admin\AdminExtraController::class, 'approveAnnouncement'])->name('admin.events.approve');
|
||||||
Route::post('/announcements/{id}/reject', [\App\Http\Controllers\Admin\AdminExtraController::class, 'rejectAnnouncement'])->name('admin.announcements.reject');
|
Route::post('/events/{id}/reject', [\App\Http\Controllers\Admin\AdminExtraController::class, 'rejectAnnouncement'])->name('admin.events.reject');
|
||||||
Route::delete('/announcements/{id}', [\App\Http\Controllers\Admin\AdminExtraController::class, 'deleteAnnouncement'])->name('admin.announcements.delete');
|
Route::delete('/events/{id}', [\App\Http\Controllers\Admin\AdminExtraController::class, 'deleteAnnouncement'])->name('admin.events.delete');
|
||||||
|
|
||||||
// New Modules Added
|
// New Modules Added
|
||||||
Route::get('/safety', [\App\Http\Controllers\Admin\AdminExtraController::class, 'safety'])->name('admin.safety');
|
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::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::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::get('/events', [\App\Http\Controllers\Employer\AnnouncementController::class, 'index'])->name('employer.events');
|
||||||
Route::post('/announcements/create', [\App\Http\Controllers\Employer\AnnouncementController::class, 'store'])->name('employer.announcements.store');
|
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::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');
|
Route::post('/profile/update', [\App\Http\Controllers\Employer\ProfileController::class, 'update'])->name('employer.profile.update');
|
||||||
|
|||||||
@ -288,7 +288,7 @@ public function test_admin_can_reject_announcement_with_remarks()
|
|||||||
|
|
||||||
$response = $this->actingAs($admin)
|
$response = $this->actingAs($admin)
|
||||||
->withSession(['user' => $admin])
|
->withSession(['user' => $admin])
|
||||||
->post('/admin/announcements/' . $announcement->id . '/reject', [
|
->post('/admin/events/' . $announcement->id . '/reject', [
|
||||||
'remarks' => 'Inappropriate content or location details.',
|
'remarks' => 'Inappropriate content or location details.',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user