Skip to content

Commit 4e10300

Browse files
committed
improve applicant table ui
1 parent f4b284b commit 4e10300

13 files changed

Lines changed: 1271 additions & 783 deletions

‎apps/codebility/app/home/applicants/_components/_table/applicantActionButton.tsx‎

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
DialogTitle,
1616
} from "@/components/ui/dialog";
1717
import { useToast } from "@/components/ui/use-toast";
18+
import { cn } from "@/lib/utils";
1819
import {
1920
CheckCircle2Icon,
2021
Loader2Icon,
@@ -394,106 +395,132 @@ export default function ApplicantActionButton({
394395
<DropdownMenuTrigger asChild>
395396
<Button
396397
variant="ghost"
397-
className="h-6 w-6 p-0 text-gray-400 hover:text-gray-300"
398+
size="sm"
399+
className="h-8 w-8 rounded-full p-0 text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-100"
398400
>
399401
<span className="sr-only">More actions</span>
400-
<MoreHorizontalIcon className="h-3 w-3" />
402+
<MoreHorizontalIcon className="h-4 w-4" />
401403
</Button>
402404
</DropdownMenuTrigger>
403405
<DropdownMenuContent
404406
align="end"
405-
className="dark:bg-dark-200 min-w-[160px] bg-white"
407+
className="min-w-[200px] rounded-lg border border-gray-200 bg-white p-1 shadow-lg dark:border-gray-700 dark:bg-gray-800"
406408
>
407-
<DropdownMenuLabel>Actions</DropdownMenuLabel>
408-
<DropdownMenuSeparator />
409+
<DropdownMenuLabel className="px-3 py-2 text-sm font-semibold text-gray-900 dark:text-gray-100">
410+
Actions
411+
</DropdownMenuLabel>
412+
<DropdownMenuSeparator className="bg-gray-200 dark:bg-gray-700" />
409413

410414
{/* Primary Actions */}
411415
<DropdownMenuItem
412-
className="text-black-500 dark:text-light-800 cursor-pointer"
416+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-gray-700 transition-colors hover:bg-blue-50 hover:text-blue-700 focus:bg-blue-50 focus:text-blue-700 dark:text-gray-300 dark:hover:bg-blue-900/20 dark:hover:text-blue-300"
413417
onClick={handleViewDetails}
414418
>
419+
<svg className="mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
420+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
421+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
422+
</svg>
415423
View Details
416424
</DropdownMenuItem>
417425

418426
<DropdownMenuItem
419-
className="text-black-500 dark:text-light-800 cursor-pointer"
427+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-gray-700 transition-colors hover:bg-gray-50 hover:text-gray-900 focus:bg-gray-50 focus:text-gray-900 dark:text-gray-300 dark:hover:bg-gray-700 dark:hover:text-gray-100"
420428
onClick={handleEditApplicant}
421429
>
430+
<svg className="mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
431+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
432+
</svg>
422433
Edit Applicant
423434
</DropdownMenuItem>
424435

425-
<DropdownMenuSeparator />
436+
<DropdownMenuSeparator className="bg-gray-200 dark:bg-gray-700" />
426437

427438
{/* Status Change Actions */}
428439
{applicant.application_status !== "applying" && (
429440
<DropdownMenuItem
430-
className="text-black-500 dark:text-light-800 cursor-pointer"
441+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-gray-700 transition-colors hover:bg-gray-50 hover:text-gray-900 focus:bg-gray-50 focus:text-gray-900 dark:text-gray-300 dark:hover:bg-gray-700 dark:hover:text-gray-100"
431442
onClick={() => {
432443
setDialogState("applying");
433444
setIsDialogOpen(true);
434445
}}
435446
>
447+
<svg className="mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
448+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
449+
</svg>
436450
Move to Applying
437451
</DropdownMenuItem>
438452
)}
439453

440454
{applicant.application_status !== "testing" && (
441455
<DropdownMenuItem
442-
className="text-black-500 dark:text-light-800 cursor-pointer"
456+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-amber-700 transition-colors hover:bg-amber-50 hover:text-amber-800 focus:bg-amber-50 focus:text-amber-800 dark:text-amber-400 dark:hover:bg-amber-900/20 dark:hover:text-amber-300"
443457
onClick={() => {
444458
setDialogState("testing");
445459
setIsDialogOpen(true);
446460
}}
447461
>
462+
<svg className="mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
463+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
464+
</svg>
448465
Move to Testing
449466
</DropdownMenuItem>
450467
)}
451468

452469
{applicant.application_status !== "onboarding" && (
453470
<DropdownMenuItem
454-
className="text-black-500 dark:text-light-800 cursor-pointer"
471+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-emerald-700 transition-colors hover:bg-emerald-50 hover:text-emerald-800 focus:bg-emerald-50 focus:text-emerald-800 dark:text-emerald-400 dark:hover:bg-emerald-900/20 dark:hover:text-emerald-300"
455472
onClick={() => {
456473
setDialogState("onboarding");
457474
setIsDialogOpen(true);
458475
}}
459476
>
477+
<svg className="mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
478+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
479+
</svg>
460480
Move to Onboarding
461481
</DropdownMenuItem>
462482
)}
463483

464484
{applicant.application_status !== "denied" && (
465485
<DropdownMenuItem
466-
className="text-red-500 dark:text-red-400 cursor-pointer"
486+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-red-700 transition-colors hover:bg-red-50 hover:text-red-800 focus:bg-red-50 focus:text-red-800 dark:text-red-400 dark:hover:bg-red-900/20 dark:hover:text-red-300"
467487
onClick={() => {
468488
setDialogState("denied");
469489
setIsDialogOpen(true);
470490
}}
471491
>
492+
<svg className="mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
493+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
494+
</svg>
472495
Move to Denied
473496
</DropdownMenuItem>
474497
)}
475498

476-
<DropdownMenuSeparator />
499+
<DropdownMenuSeparator className="bg-gray-200 dark:bg-gray-700" />
477500

478501
{/* Test Actions - only show for testing status */}
479502
{applicant.application_status === "testing" && (
480503
<>
481504
<DropdownMenuItem
482-
className="text-green-500 dark:text-green-400 cursor-pointer"
505+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-green-700 transition-colors hover:bg-green-50 hover:text-green-800 focus:bg-green-50 focus:text-green-800 dark:text-green-400 dark:hover:bg-green-900/20 dark:hover:text-green-300"
483506
onClick={() => {
484507
setDialogState("pass");
485508
setIsDialogOpen(true);
486509
}}
487510
>
511+
<CheckCircle2Icon className="mr-2 h-4 w-4" />
488512
Pass Test
489513
</DropdownMenuItem>
490514
<DropdownMenuItem
491-
className="text-red-500 dark:text-red-400 cursor-pointer"
515+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-red-700 transition-colors hover:bg-red-50 hover:text-red-800 focus:bg-red-50 focus:text-red-800 dark:text-red-400 dark:hover:bg-red-900/20 dark:hover:text-red-300"
492516
onClick={() => {
493517
setDialogState("fail");
494518
setIsDialogOpen(true);
495519
}}
496520
>
521+
<svg className="mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
522+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
523+
</svg>
497524
Fail Test
498525
</DropdownMenuItem>
499526
</>
@@ -503,25 +530,29 @@ export default function ApplicantActionButton({
503530
{applicant.application_status === "onboarding" && (
504531
<>
505532
<DropdownMenuItem
506-
className="text-green-500 dark:text-green-400 cursor-pointer"
533+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-green-700 transition-colors hover:bg-green-50 hover:text-green-800 focus:bg-green-50 focus:text-green-800 dark:text-green-400 dark:hover:bg-green-900/20 dark:hover:text-green-300"
507534
onClick={() => {
508535
setDialogState("accept");
509536
setIsDialogOpen(true);
510537
}}
511538
>
539+
<CheckCircle2Icon className="mr-2 h-4 w-4" />
512540
Accept Applicant
513541
</DropdownMenuItem>
514542
<DropdownMenuItem
515-
className="text-red-500 dark:text-red-400 cursor-pointer"
543+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-red-700 transition-colors hover:bg-red-50 hover:text-red-800 focus:bg-red-50 focus:text-red-800 dark:text-red-400 dark:hover:bg-red-900/20 dark:hover:text-red-300"
516544
onClick={() => {
517545
setDialogState("deny");
518546
setIsDialogOpen(true);
519547
}}
520548
>
549+
<svg className="mr-2 h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
550+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
551+
</svg>
521552
Deny Applicant
522553
</DropdownMenuItem>
523554
<DropdownMenuItem
524-
className="text-black-500 dark:text-light-800 cursor-pointer"
555+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-blue-700 transition-colors hover:bg-blue-50 hover:text-blue-800 focus:bg-blue-50 focus:text-blue-800 dark:text-blue-400 dark:hover:bg-blue-900/20 dark:hover:text-blue-300"
525556
onClick={() => {
526557
setDialogState("remindToOnboarding");
527558
setIsDialogOpen(true);
@@ -536,7 +567,7 @@ export default function ApplicantActionButton({
536567
{/* Remind to Take Test - show for testing and applying status */}
537568
{(applicant.application_status === "testing" || applicant.application_status === "applying") && (
538569
<DropdownMenuItem
539-
className="text-black-500 dark:text-light-800 cursor-pointer"
570+
className="cursor-pointer rounded-md px-3 py-2 text-sm text-blue-700 transition-colors hover:bg-blue-50 hover:text-blue-800 focus:bg-blue-50 focus:text-blue-800 dark:text-blue-400 dark:hover:bg-blue-900/20 dark:hover:text-blue-300"
540571
onClick={() => {
541572
setDialogState("remindToTakeTest");
542573
setIsDialogOpen(true);
@@ -557,28 +588,37 @@ export default function ApplicantActionButton({
557588
setIsLoading(false); // Reset loading state when dialog closes
558589
}
559590
}}>
560-
<DialogContent>
591+
<DialogContent className="rounded-lg border border-gray-200 bg-white shadow-xl dark:border-gray-700 dark:bg-gray-900">
561592
<DialogHeader>
562-
<DialogTitle>{getDialogTitle()}</DialogTitle>
563-
<DialogDescription>
593+
<DialogTitle className="text-lg font-semibold text-gray-900 dark:text-gray-100">
594+
{getDialogTitle()}
595+
</DialogTitle>
596+
<DialogDescription className="text-sm text-gray-600 dark:text-gray-400">
564597
{getDialogDescription()}
565598
</DialogDescription>
566599
</DialogHeader>
567-
<DialogFooter>
600+
<DialogFooter className="gap-3">
568601
<Button
569602
variant="outline"
570603
onClick={() => {
571604
setIsDialogOpen(false);
572605
setDialogState(null);
573606
setIsLoading(false);
574607
}}
608+
className="border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800"
575609
>
576610
Cancel
577611
</Button>
578612
<Button
579613
onClick={handleConfirmAction}
580614
disabled={isLoading}
581615
variant={dialogState === "delete" || dialogState === "denied" || dialogState === "fail" || dialogState === "deny" ? "destructive" : "default"}
616+
className={cn(
617+
"min-w-[100px]",
618+
(dialogState === "delete" || dialogState === "denied" || dialogState === "fail" || dialogState === "deny")
619+
? "bg-red-600 hover:bg-red-700 dark:bg-red-700 dark:hover:bg-red-800"
620+
: "bg-blue-600 hover:bg-blue-700 dark:bg-blue-700 dark:hover:bg-blue-800"
621+
)}
582622
>
583623
{isLoading ? (
584624
<>

0 commit comments

Comments
 (0)