Skip to content

Commit 85d4546

Browse files
Fixed bugs in all of job listing options.
1 parent 4aacc4a commit 85d4546

2 files changed

Lines changed: 191 additions & 61 deletions

File tree

‎apps/codebility/app/home/hire/_components/JobListingsTable.tsx‎

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ import {
1010
Users,
1111
Calendar,
1212
MapPin,
13-
DollarSign,
1413
User,
1514
MoreHorizontal,
16-
CheckCircle,
1715
XCircle,
1816
RotateCcw
1917
} from "lucide-react";
@@ -47,6 +45,7 @@ import {
4745
AccordionItem,
4846
AccordionTrigger
4947
} from "@codevs/ui/accordion"
48+
5049
interface JobWithApplicationCount extends JobListing {
5150
application_count?: number;
5251
status?: "active" | "closed" | "draft";
@@ -67,6 +66,7 @@ export default function JobListingsTable() {
6766
const [editingJob, setEditingJob] = useState<JobListing | null>(null);
6867
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
6968
const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'closed' | 'draft'>('all');
69+
const [openDropdown, setOpenDropdown] = useState<string | null>(null);
7070

7171
// Check if user is admin (role_id 1 or 4)
7272
const isAdmin = user?.role_id === 1 || user?.role_id === 4;
@@ -86,6 +86,10 @@ export default function JobListingsTable() {
8686
setLoading(true);
8787
const supabase = createClientClientComponent();
8888

89+
if (!supabase) {
90+
throw new Error("Failed to initialize Supabase client");
91+
}
92+
8993
// Fetch job listings with creator details
9094
const { data: jobsData, error: jobsError } = await supabase
9195
.from('job_listings')
@@ -144,10 +148,15 @@ export default function JobListingsTable() {
144148
};
145149

146150
const handleDelete = async (jobId: string) => {
151+
console.log("Delete button clicked for job ID:", jobId);
152+
147153
if (confirm("Are you sure you want to delete this job listing? This action cannot be undone.")) {
148154
try {
155+
console.log("User confirmed deletion, calling deleteJobListing...");
149156
const result = await deleteJobListing(jobId);
150157

158+
console.log("Delete result:", result);
159+
151160
if (!result.success) {
152161
throw new Error(result.error || "Failed to delete job");
153162
}
@@ -167,10 +176,14 @@ export default function JobListingsTable() {
167176
variant: "destructive",
168177
});
169178
}
179+
} else {
180+
console.log("User cancelled deletion");
170181
}
171182
};
172183

173184
const handleEdit = (job: JobListing) => {
185+
// Close dropdown first
186+
setOpenDropdown(null);
174187
setEditingJob(job);
175188
setIsEditModalOpen(true);
176189
};
@@ -195,6 +208,9 @@ export default function JobListingsTable() {
195208
};
196209

197210
const handleStatusChange = async (jobId: string, newStatus: "active" | "closed" | "draft") => {
211+
// Close dropdown first
212+
setOpenDropdown(null);
213+
198214
try {
199215
const result = await updateJobListingStatus(jobId, newStatus);
200216

@@ -211,7 +227,7 @@ export default function JobListingsTable() {
211227
)
212228
);
213229

214-
const statusText = newStatus === 'closed' ? 'closed' : 'reopened';
230+
const statusText = newStatus === 'closed' ? 'closed' : newStatus === 'active' ? 'reopened' : 'updated';
215231
toast({
216232
title: `Job ${statusText}`,
217233
description: `The job listing has been ${statusText} successfully.`,
@@ -269,6 +285,11 @@ export default function JobListingsTable() {
269285
}
270286
};
271287

288+
// Check if user can modify a specific job
289+
const canModifyJob = (job: JobWithApplicationCount) => {
290+
return isAdmin || job.created_by?.id === user?.id;
291+
};
292+
272293
if (loading) {
273294
return (
274295
<div className="rounded-lg border border-gray-800 bg-gray-900/50 overflow-hidden p-8">
@@ -406,14 +427,16 @@ export default function JobListingsTable() {
406427
<div className="flex items-center justify-end gap-2">
407428
<Button
408429
variant="outline"
409-
410430
onClick={() => handleViewApplications(job.id)}
411431
className="h-8 bg-background border-border text-foreground transition-colors hover:bg-accent"
412432
>
413433
<Eye className="mr-2 h-3 w-3" />
414434
Applications
415435
</Button>
416-
<DropdownMenu>
436+
<DropdownMenu
437+
open={openDropdown === job.id}
438+
onOpenChange={(open) => setOpenDropdown(open ? job.id : null)}
439+
>
417440
<DropdownMenuTrigger asChild>
418441
<Button
419442
variant="ghost"
@@ -425,42 +448,41 @@ export default function JobListingsTable() {
425448
</Button>
426449
</DropdownMenuTrigger>
427450
<DropdownMenuContent align="end" className="bg-popover border-border">
428-
{(isAdmin || job.created_by?.id === user?.id) && (
451+
{canModifyJob(job) ? (
429452
<>
430453
<DropdownMenuItem
431454
onClick={() => handleEdit(job)}
432-
className="text-foreground hover:text-foreground hover:bg-accent"
455+
className="text-foreground hover:text-foreground hover:bg-accent cursor-pointer"
433456
>
434457
<Edit className="mr-2 h-4 w-4" />
435458
Edit Listing
436459
</DropdownMenuItem>
437460
{job.status === 'active' ? (
438461
<DropdownMenuItem
439462
onClick={() => handleStatusChange(job.id, 'closed')}
440-
className="text-orange-500 hover:text-orange-400 hover:bg-accent"
463+
className="text-orange-500 hover:text-orange-400 hover:bg-accent cursor-pointer"
441464
>
442465
<XCircle className="mr-2 h-4 w-4" />
443466
Mark as Closed
444467
</DropdownMenuItem>
445468
) : (
446469
<DropdownMenuItem
447470
onClick={() => handleStatusChange(job.id, 'active')}
448-
className="text-green-500 hover:text-green-400 hover:bg-accent"
471+
className="text-green-500 hover:text-green-400 hover:bg-accent cursor-pointer"
449472
>
450473
<RotateCcw className="mr-2 h-4 w-4" />
451474
Reopen Position
452475
</DropdownMenuItem>
453476
)}
454477
<DropdownMenuItem
455478
onClick={() => handleDelete(job.id)}
456-
className="text-destructive hover:text-destructive hover:bg-accent "
479+
className="text-destructive hover:text-destructive hover:bg-accent cursor-pointer"
457480
>
458481
<Trash2 className="mr-2 h-4 w-4" />
459482
Delete
460483
</DropdownMenuItem>
461484
</>
462-
)}
463-
{!isAdmin && job.created_by?.id !== user?.id && (
485+
) : (
464486
<DropdownMenuItem disabled className="text-gray-500">
465487
No actions available
466488
</DropdownMenuItem>
@@ -528,7 +550,7 @@ export default function JobListingsTable() {
528550
>
529551
<Users className="h-3.5 w-3.5" />
530552
<span className="font-medium">{job.application_count || 0}</span>
531-
<span className="text-xs ml-1 group-hover:opacity-100">
553+
<span className="text-xs ml-1 group-hover:opacity-100">
532554
View
533555
</span>
534556
</button>
@@ -597,37 +619,35 @@ export default function JobListingsTable() {
597619
</div>
598620
</div>
599621

600-
601-
602-
603622
{/* Actions */}
604623
<div className="flex justify-end gap-2 pt-2 border-t border-border">
605624
<Button
606625
variant="outline"
607-
608626
onClick={() => handleViewApplications(job.id)}
609627
className="h-8 text-xs text-foreground border hover:bg-muted"
610628
>
611629
<Eye className="mr-2 h-3 w-3" />
612630
Applications
613631
</Button>
614-
<DropdownMenu modal={false}>
632+
<DropdownMenu
633+
modal={false}
634+
open={openDropdown === `mobile-${job.id}`}
635+
onOpenChange={(open) => setOpenDropdown(open ? `mobile-${job.id}` : null)}
636+
>
615637
<DropdownMenuTrigger asChild>
616638
<Button
617639
variant="ghost"
618-
619640
className="h-8 text-xs text-foreground hover:bg-muted"
620641
>
621642
<MoreHorizontal className="h-4 w-4" />
622643
</Button>
623644
</DropdownMenuTrigger>
624645
<DropdownMenuContent align="end" className="bg-popover border-border dark:bg-gray-900 dark:border-gray-800">
625-
{(isAdmin || job.created_by?.id === user?.id) && (
646+
{canModifyJob(job) ? (
626647
<>
627648
<DropdownMenuItem
628-
onClick={(e) => {
649+
onSelect={(e) => {
629650
e.preventDefault();
630-
e.stopPropagation();
631651
handleEdit(job);
632652
}}
633653
className="text-gray-300 hover:text-white hover:bg-gray-800 cursor-pointer"
@@ -637,9 +657,8 @@ export default function JobListingsTable() {
637657
</DropdownMenuItem>
638658
{job.status === 'active' ? (
639659
<DropdownMenuItem
640-
onClick={(e) => {
660+
onSelect={(e) => {
641661
e.preventDefault();
642-
e.stopPropagation();
643662
handleStatusChange(job.id, 'closed');
644663
}}
645664
className="text-orange-400 hover:text-orange-300 hover:bg-gray-800 cursor-pointer"
@@ -649,9 +668,8 @@ export default function JobListingsTable() {
649668
</DropdownMenuItem>
650669
) : (
651670
<DropdownMenuItem
652-
onClick={(e) => {
671+
onSelect={(e) => {
653672
e.preventDefault();
654-
e.stopPropagation();
655673
handleStatusChange(job.id, 'active');
656674
}}
657675
className="text-green-400 hover:text-green-300 hover:bg-gray-800 cursor-pointer"
@@ -661,9 +679,8 @@ export default function JobListingsTable() {
661679
</DropdownMenuItem>
662680
)}
663681
<DropdownMenuItem
664-
onClick={(e) => {
682+
onSelect={(e) => {
665683
e.preventDefault();
666-
e.stopPropagation();
667684
handleDelete(job.id);
668685
}}
669686
className="text-red-400 hover:text-red-300 hover:bg-gray-800 cursor-pointer"
@@ -672,8 +689,7 @@ export default function JobListingsTable() {
672689
Delete
673690
</DropdownMenuItem>
674691
</>
675-
)}
676-
{!isAdmin && job.created_by?.id !== user?.id && (
692+
) : (
677693
<DropdownMenuItem disabled className="text-gray-500">
678694
No actions available
679695
</DropdownMenuItem>

0 commit comments

Comments
 (0)