Skip to content

Commit 601939e

Browse files
Zeff01claude
andcommitted
Optimize in-house table layout and improve page structure across application
- Implemented PageContainer component for consistent page structure across all pages - Fixed layout spacing issues by removing padding from main layout and adding it to individual pages - Redesigned navbar with glassmorphism effect for modern, sleek appearance - Optimized in-house table with smaller fonts (text-xs) and reduced padding (px-1 py-1) - Increased pagination to 50 items per page for better content display - Made all UI elements in in-house table more compact (badges, buttons, icons) - Fixed weird spacing issues across dashboard, applicants, kanban, clients, and settings pages - Enhanced performance with prefetching and memoization in sidebar navigation - Improved page loading animation to only cover content area, not sidebar 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent caee24e commit 601939e

24 files changed

Lines changed: 401 additions & 443 deletions

File tree

‎apps/codebility/app/home/_components/LeftSidebar.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const LeftSidebar = () => {
9999
initial={false}
100100
animate={isToggleOpen ? "open" : "closed"}
101101
variants={sidebarVariants}
102-
className="background-navbar sticky left-0 top-0 z-40 hidden h-screen flex-col gap-8 overflow-hidden p-1 shadow-lg lg:flex"
102+
className="background-navbar sticky left-0 top-0 z-40 hidden h-screen flex-col gap-8 overflow-hidden p-1 border-r border-gray-200 dark:border-gray-800 lg:flex"
103103
role="complementary"
104104
aria-label="Main navigation sidebar"
105105
>

‎apps/codebility/app/home/_components/Navbar.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const Navbar = () => {
5757
return (
5858
<>
5959
<nav
60-
className="background-navbar fixed top-0 z-20 w-full shadow-sm"
60+
className="fixed top-0 z-20 w-full bg-white/80 dark:bg-gray-950/80 backdrop-blur-xl border-b border-gray-200/50 dark:border-gray-800/50 shadow-sm"
6161
role="banner"
6262
>
6363
<div className="flex w-full min-w-full items-center justify-end px-8 py-2">
@@ -106,10 +106,10 @@ const Navbar = () => {
106106
className="hidden flex-col items-end md:flex"
107107
aria-hidden="true"
108108
>
109-
<p className="capitalize dark:text-white">
109+
<p className="capitalize text-gray-900 dark:text-gray-100">
110110
{first_name} {last_name}
111111
</p>
112-
<p className="text-dark100_light900 text-sm">{email_address}</p>
112+
<p className="text-gray-600 dark:text-gray-400 text-sm">{email_address}</p>
113113
</div>
114114
<div className="from-customViolet-300 to-customBlue-500 relative size-[44px] rounded-full bg-gradient-to-b p-[1.5px]">
115115
<Image
@@ -122,7 +122,7 @@ const Navbar = () => {
122122
/>
123123
</div>
124124
<IconDropdown
125-
className="hidden invert dark:invert-0 md:block"
125+
className="hidden text-gray-600 dark:text-gray-400 md:block"
126126
aria-hidden="true"
127127
/>
128128
<span className="sr-only">
@@ -131,7 +131,7 @@ const Navbar = () => {
131131
</DropdownMenuTrigger>
132132

133133
<DropdownMenuContent
134-
className="dark:bg-dark-100 absolute -left-24 top-3 border-white dark:border-zinc-700 md:w-[200px]"
134+
className="bg-white dark:bg-gray-800 absolute -left-24 top-3 border-gray-200 dark:border-gray-700 md:w-[200px] shadow-lg"
135135
role="menu"
136136
aria-label="User account options"
137137
>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { ReactNode } from "react";
2+
import { cn } from "@/lib/utils";
3+
4+
interface PageContainerProps {
5+
children: ReactNode;
6+
className?: string;
7+
maxWidth?: "sm" | "md" | "lg" | "xl" | "2xl" | "7xl" | "full";
8+
noPadding?: boolean;
9+
}
10+
11+
export default function PageContainer({
12+
children,
13+
className,
14+
maxWidth = "7xl",
15+
noPadding = false
16+
}: PageContainerProps) {
17+
const maxWidthClasses = {
18+
sm: "max-w-screen-sm",
19+
md: "max-w-screen-md",
20+
lg: "max-w-screen-lg",
21+
xl: "max-w-screen-xl",
22+
"2xl": "max-w-screen-2xl",
23+
"7xl": "max-w-7xl",
24+
full: "max-w-full"
25+
};
26+
27+
return (
28+
<div className={cn(
29+
"min-h-screen bg-white dark:bg-gray-950",
30+
className
31+
)}>
32+
<div className={cn(
33+
"mx-auto h-full",
34+
maxWidthClasses[maxWidth],
35+
!noPadding && "px-2 pt-6 pb-6 sm:px-4 sm:pt-8 sm:pb-8 md:px-8 md:pt-10 md:pb-10 lg:px-12 lg:pt-12 lg:pb-12",
36+
"max-md:pb-14", // Extra bottom padding for mobile navigation
37+
className?.includes("flex") && "flex flex-col"
38+
)}>
39+
{children}
40+
</div>
41+
</div>
42+
);
43+
}

‎apps/codebility/app/home/_components/PageLoadingAnimation.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { motion } from "framer-motion";
44

55
export default function PageLoadingAnimation() {
66
return (
7-
<div className="fixed inset-0 z-50 flex items-center justify-center bg-white dark:bg-gray-950">
7+
<div className="absolute inset-0 z-50 flex items-center justify-center bg-white dark:bg-gray-950 min-h-[400px]">
88
{/* Background gradient animation */}
99
<motion.div
1010
className="absolute inset-0 opacity-30"

‎apps/codebility/app/home/_components/PageTransitionWrapper.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export default function PageTransitionWrapper({ children }: PageTransitionWrappe
6767
}, [pathname, displayedPathname, animationEnabled, animationDuration]);
6868

6969
return (
70-
<>
70+
<div className="relative min-h-[400px]">
7171
<AnimatePresence mode="wait">
7272
{isLoading && (
7373
<motion.div
@@ -77,6 +77,7 @@ export default function PageTransitionWrapper({ children }: PageTransitionWrappe
7777
opacity: 0,
7878
transition: { duration: 0.3, ease: "easeOut" }
7979
}}
80+
className="absolute inset-0"
8081
>
8182
<PageLoadingAnimation />
8283
</motion.div>
@@ -97,6 +98,6 @@ export default function PageTransitionWrapper({ children }: PageTransitionWrappe
9798
>
9899
{children}
99100
</motion.div>
100-
</>
101+
</div>
101102
);
102103
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const applicantsColumns: ColumnDef<NewApplicantType>[] = [
4949
id: "applicant",
5050
accessorKey: "first_name",
5151
meta: {
52-
className: "min-w-[200px]",
52+
className: "min-w-[250px] max-w-[350px]",
5353
},
5454
header: ({ column }) => {
5555
return (
@@ -97,7 +97,7 @@ export const applicantsColumns: ColumnDef<NewApplicantType>[] = [
9797
);
9898
},
9999
meta: {
100-
className: "w-32",
100+
className: "min-w-[120px] max-w-[150px]",
101101
},
102102
},
103103
{
@@ -413,5 +413,8 @@ export const applicantsColumns: ColumnDef<NewApplicantType>[] = [
413413
</div>
414414
);
415415
},
416+
meta: {
417+
className: "w-16 max-w-[64px]",
418+
},
416419
},
417420
];

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ function ApplicantDataTableComponent<TData extends NewApplicantType, TValue>({
173173
</div>
174174

175175
{/* Table for larger screens */}
176-
<Table className="hidden xl:table table-fixed">
176+
<Table className="hidden xl:table table-auto">
177177
{/* Table header */}
178178
<TableHeader>
179179
{table.getHeaderGroups().map((headerGroup) => (
Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { Suspense } from "react";
22
import AsyncErrorBoundary from "@/components/AsyncErrorBoundary";
3+
import PageContainer from "../_components/PageContainer";
34

45
import NewApplicantFetchComp from "./_components/applicantFetchComp";
56
import ApplicantsLoading from "./loading";
@@ -9,20 +10,22 @@ export const revalidate = 0;
910

1011
export default async function NewApplicants() {
1112
return (
12-
<AsyncErrorBoundary
13-
fallback={
14-
<div className="flex min-h-[400px] flex-col items-center justify-center p-8 text-center">
15-
<div className="mb-4 text-4xl">📋</div>
16-
<h2 className="mb-2 text-xl font-semibold">Failed to load applicants</h2>
17-
<p className="text-gray-600 dark:text-gray-400">
18-
We couldn't load the applicants data. Please try refreshing the page.
19-
</p>
20-
</div>
21-
}
22-
>
23-
<Suspense fallback={<ApplicantsLoading />}>
24-
<NewApplicantFetchComp />
25-
</Suspense>
26-
</AsyncErrorBoundary>
13+
<PageContainer>
14+
<AsyncErrorBoundary
15+
fallback={
16+
<div className="flex min-h-[400px] flex-col items-center justify-center p-8 text-center">
17+
<div className="mb-4 text-4xl">📋</div>
18+
<h2 className="mb-2 text-xl font-semibold">Failed to load applicants</h2>
19+
<p className="text-gray-600 dark:text-gray-400">
20+
We couldn't load the applicants data. Please try refreshing the page.
21+
</p>
22+
</div>
23+
}
24+
>
25+
<Suspense fallback={<ApplicantsLoading />}>
26+
<NewApplicantFetchComp />
27+
</Suspense>
28+
</AsyncErrorBoundary>
29+
</PageContainer>
2730
);
2831
}

‎apps/codebility/app/home/clients/page.tsx‎

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import H1 from "@/components/shared/dashboard/H1";
22
import AsyncErrorBoundary from "@/components/AsyncErrorBoundary";
33
import { getClients } from "@/lib/server/codev.service";
44
import { Client } from "@/types/home/codev";
5+
import PageContainer from "../_components/PageContainer";
56

67
import ClientButtons from "./_components/ClientsButton";
78
import ClientCards from "./_components/ClientsCard";
@@ -21,32 +22,34 @@ export default async function Clients() {
2122
});
2223

2324
return (
24-
<AsyncErrorBoundary
25-
fallback={
26-
<div className="flex min-h-[400px] flex-col items-center justify-center p-8 text-center">
27-
<div className="mb-4 text-4xl">👥</div>
28-
<h2 className="mb-2 text-xl font-semibold">Unable to load clients</h2>
29-
<p className="text-gray-600 dark:text-gray-400">
30-
We couldn't retrieve your client list. Please check your connection and try again.
31-
</p>
32-
</div>
33-
}
34-
>
35-
<div className="mx-auto flex max-w-screen-xl flex-col gap-4">
36-
<div className="flex flex-row justify-between gap-4">
37-
<H1>Clients</H1>
38-
<div className="flex items-center gap-4">
39-
<ClientButtons />
25+
<PageContainer maxWidth="xl">
26+
<AsyncErrorBoundary
27+
fallback={
28+
<div className="flex min-h-[400px] flex-col items-center justify-center p-8 text-center">
29+
<div className="mb-4 text-4xl">👥</div>
30+
<h2 className="mb-2 text-xl font-semibold">Unable to load clients</h2>
31+
<p className="text-gray-600 dark:text-gray-400">
32+
We couldn't retrieve your client list. Please check your connection and try again.
33+
</p>
34+
</div>
35+
}
36+
>
37+
<div className="flex flex-col gap-4">
38+
<div className="flex flex-row justify-between gap-4">
39+
<H1>Clients</H1>
40+
<div className="flex items-center gap-4">
41+
<ClientButtons />
42+
</div>
4043
</div>
41-
</div>
4244

43-
{error ? (
44-
<div className="text-white">ERROR</div>
45-
) : (
46-
// Pass our sorted array to the client-card component
47-
<ClientCards clients={clients} />
48-
)}
49-
</div>
50-
</AsyncErrorBoundary>
45+
{error ? (
46+
<div className="text-white">ERROR</div>
47+
) : (
48+
// Pass our sorted array to the client-card component
49+
<ClientCards clients={clients} />
50+
)}
51+
</div>
52+
</AsyncErrorBoundary>
53+
</PageContainer>
5154
);
5255
}

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

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
} from "@codevs/ui/select";
1919
import { Switch } from "@codevs/ui/switch";
2020
import { useToast } from "@/components/ui/use-toast";
21+
import { updateJobListing } from "../actions";
2122
import {
2223
Dialog,
2324
DialogContent,
@@ -89,31 +90,21 @@ export default function EditJobModal({ job, isOpen, onClose, onJobUpdated }: Edi
8990
.map(req => req.trim())
9091
.filter(req => req.length > 0);
9192

92-
// Import Supabase client
93-
const { createClientClientComponent } = await import("@/utils/supabase/client");
94-
const supabase = createClientClientComponent();
95-
96-
// Update the job in the database
97-
const { data: updatedJob, error } = await supabase
98-
.from('job_listings')
99-
.update({
100-
title: data.title,
101-
department: data.department,
102-
location: data.location,
103-
type: data.type,
104-
level: data.level,
105-
description: data.description,
106-
requirements: requirementsArray,
107-
salary_range: data.salary_range || null,
108-
remote: data.remote,
109-
updated_at: new Date().toISOString(),
110-
})
111-
.eq('id', job.id)
112-
.select()
113-
.single();
93+
// Use server action to update the job
94+
const result = await updateJobListing(job.id, {
95+
title: data.title,
96+
department: data.department,
97+
location: data.location,
98+
type: data.type,
99+
level: data.level,
100+
description: data.description,
101+
requirements: requirementsArray,
102+
salary_range: data.salary_range || null,
103+
remote: data.remote,
104+
});
114105

115-
if (error) {
116-
throw error;
106+
if (!result.success) {
107+
throw new Error(result.error || "Failed to update job");
117108
}
118109

119110
toast({

0 commit comments

Comments
 (0)