Skip to content

Commit 75c9426

Browse files
authored
Job posts fix (#155)
* JobsPage UI Fixes * JobSearch UI Fixes * Jobs Page minor UI Fix * package-lock auto update * Jobs Card UI Updated * Jobs Card UI Updated * Jobs Grid Updated * Jobs Page minor UI Fix * Prisma fixes * Jobs: search bar width increased * Jobs Page minor UI Fix * Jobs Search: button width increased * ESLint issue fixed * prisma connection fixes
1 parent 43c95a9 commit 75c9426

File tree

10 files changed

+135
-103
lines changed

10 files changed

+135
-103
lines changed

src/app/api/jobs/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export async function GET(req: NextRequest) {
8686
}
8787

8888
const [jobs, totalJobs] = await Promise.all([
89-
prisma.job.findMany({
89+
(prisma as any).job.findMany({
9090
where,
9191
orderBy,
9292
skip,
@@ -109,7 +109,7 @@ export async function GET(req: NextRequest) {
109109
expiresAt: true,
110110
},
111111
}),
112-
prisma.job.count({ where }),
112+
(prisma as any).job.count({ where }),
113113
])
114114

115115
// Shuffle jobs if random sorting is requested
@@ -184,7 +184,7 @@ export async function POST(req: NextRequest) {
184184
const expiresAt = new Date()
185185
expiresAt.setDate(expiresAt.getDate() + 30)
186186

187-
const job = await prisma.job.create({
187+
const job = await (prisma as any).job.create({
188188
data: {
189189
title,
190190
company,

src/app/jobs/page.tsx

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,22 @@ export default async function JobsRoute({
4545
<div className="grid-background pointer-events-none absolute inset-0 -z-10 opacity-[0.08]" />
4646
<div className="mx-auto flex max-w-6xl flex-col gap-10 px-6 py-20 sm:py-24 md:flex-row md:items-center md:gap-16">
4747
<div className="flex-1 text-center md:text-left">
48-
<span className="mb-4 inline-flex items-center gap-2 rounded-full border border-neutral-800 bg-neutral-900/60 px-4 py-1 text-xs font-medium uppercase tracking-wide text-neutral-400">
48+
<span className="mb-4 inline-flex items-center gap-2 rounded-full border border-dashed border-neutral-100/15 bg-neutral-900/60 px-4 py-1 font-mono text-xs font-medium uppercase tracking-wide text-neutral-400">
4949
Curated devtool roles
5050
</span>
51-
<h1 className="mb-6 text-4xl font-semibold tracking-tight text-neutral-50 sm:text-5xl md:text-6xl">
52-
Find your next
53-
<br className="hidden md:block" /> devtools move
51+
<h1 className="mb-4 text-2xl font-bold tracking-tight md:text-5xl">
52+
<span className="bg-gradient-to-b from-neutral-700 to-neutral-200 bg-clip-text text-transparent">
53+
Find your next
54+
<br className="hidden md:block" /> devtools move
55+
</span>
5456
</h1>
55-
<p className="mx-auto max-w-xl text-base leading-relaxed text-neutral-400 md:mx-0">
57+
<p className="mx-auto max-w-sm text-base leading-relaxed text-neutral-400 md:mx-0">
5658
Weekly drops of developer marketing, DevRel, DX, and AI platform
5759
roles hand-picked for founders, community builders, and product
5860
storytellers.
5961
</p>
6062
<div className="mt-8 flex flex-col items-center gap-4 text-sm text-neutral-400 md:flex-row md:items-center md:justify-start">
61-
<div className="flex items-center gap-3 rounded-lg border border-neutral-800 bg-neutral-900/60 px-4 py-3">
63+
<div className="flex items-center gap-3 border border-dashed border-neutral-100/15 bg-neutral-900/60 px-3 py-2.5">
6264
<div className="text-left">
6365
<p className="text-xs uppercase tracking-wide text-neutral-500">
6466
Featured
@@ -68,7 +70,7 @@ export default async function JobsRoute({
6870
</p>
6971
</div>
7072
</div>
71-
<div className="flex items-center gap-3 rounded-lg border border-neutral-800 bg-neutral-900/60 px-4 py-3">
73+
<div className="flex items-center gap-3 border border-dashed border-neutral-100/15 bg-neutral-900/60 px-3 py-2.5">
7274
<div className="text-left">
7375
<p className="text-xs uppercase tracking-wide text-neutral-500">
7476
Updated
@@ -80,31 +82,33 @@ export default async function JobsRoute({
8082
</div>
8183
</div>
8284
</div>
83-
<div className="flex w-full flex-1 flex-col gap-6 rounded-2xl border border-neutral-800 bg-neutral-900/60 p-6 text-left shadow-lg backdrop-blur md:max-w-sm">
85+
<div className="flex w-full flex-1 flex-col gap-6 border border-dashed border-neutral-100/15 bg-neutral-900/60 p-4 text-left shadow-lg backdrop-blur md:max-w-sm">
8486
<div>
85-
<h2 className="text-base font-semibold text-neutral-100">
87+
<h2 className="mb-1.5 text-base font-semibold text-neutral-100">
8688
Showcase a role in front of builders
8789
</h2>
88-
<p className="mt-2 text-sm text-neutral-400">
90+
<p className="text-sm text-neutral-400">
8991
Submit a devtools job and we will feature it for 45 days across
9092
the site, jobs feed, and ByteSizedBets newsletter.
9193
</p>
9294
</div>
93-
<Link
94-
href="/jobs/submit"
95-
className="inline-flex items-center justify-center rounded-lg bg-neutral-100 px-5 py-2.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-200"
96-
>
97-
Submit a role
98-
</Link>
99-
<p className="text-xs text-neutral-500">
100-
Includes newsletter mention + social amplification.
101-
</p>
95+
<div>
96+
<Link
97+
href="/jobs/submit"
98+
className="mb-2 flex items-center justify-center bg-neutral-100 px-5 py-2.5 text-sm font-semibold text-neutral-900 transition hover:bg-neutral-200"
99+
>
100+
Submit a role
101+
</Link>
102+
<p className="text-xs text-neutral-500">
103+
Includes newsletter mention + social amplification.
104+
</p>
105+
</div>
102106
</div>
103107
</div>
104108
</div>
105109

106110
<div className="py-16">
107-
<div className="mx-auto max-w-5xl px-6">
111+
<div className="mx-auto max-w-6xl px-6">
108112
<JobSearch searchParams={searchParamsSync} />
109113
</div>
110114
</div>

src/components/jobs/JobCard.tsx

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ const JobCard: React.FC<JobCardProps> = ({ job }) => {
4444
rel="noopener noreferrer"
4545
className="group block h-full"
4646
>
47-
<Card className="relative flex h-full flex-col overflow-hidden border border-neutral-900 bg-neutral-900/50 shadow-lg transition-all duration-300 hover:border-neutral-800 hover:shadow-xl">
48-
<CardHeader className="space-y-4 border-b border-neutral-900 pb-5">
47+
<Card className="relative flex h-full flex-col border border-dashed border-neutral-100/15 bg-neutral-900/50 transition-all duration-300 hover:border-solid">
48+
{job.featured && (
49+
<span className="absolute -right-2 -top-3 z-20 inline-flex items-center gap-1 rounded-full border border-amber-600 bg-amber-950 px-2.5 py-0.5 text-xs font-semibold text-amber-300">
50+
<Sparkles className="size-3" /> Hot role
51+
</span>
52+
)}
53+
<CardHeader className="space-y-4 border-b border-neutral-900 p-4">
4954
<div className="flex items-start gap-4">
5055
{job.companyLogo && !imageError ? (
5156
<img
@@ -62,42 +67,37 @@ const JobCard: React.FC<JobCardProps> = ({ job }) => {
6267
)}
6368
<div className="min-w-0 flex-1">
6469
<div className="flex flex-wrap items-center gap-2">
65-
<h3 className="text-lg font-semibold leading-tight text-neutral-100 group-hover:text-white">
70+
<h3 className="text-lg font-semibold leading-tight tracking-tight text-neutral-100 group-hover:text-white">
6671
{job.title}
6772
</h3>
68-
{job.featured && (
69-
<span className="inline-flex items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/15 px-2.5 py-0.5 text-xs font-semibold text-amber-300">
70-
<Sparkles className="size-3" /> Hot role
71-
</span>
72-
)}
7373
</div>
7474
<p className="mt-1 text-sm text-neutral-400">{job.company}</p>
7575
</div>
7676
</div>
7777
</CardHeader>
7878

79-
<CardContent className="flex flex-1 flex-col gap-6 py-6">
79+
<CardContent className="flex flex-1 flex-col gap-6 p-4">
8080
<p className="line-clamp-3 text-sm leading-relaxed text-neutral-300">
8181
{job.description}
8282
</p>
8383

8484
<div className="grid grid-cols-1 gap-3 text-xs font-medium text-neutral-400 sm:grid-cols-2">
85-
<div className="flex items-center gap-2 rounded-lg border border-neutral-900 bg-neutral-900/60 px-3 py-2">
86-
<MapPin className="size-4 text-neutral-500" />
85+
<div className="flex items-center gap-2 border border-dashed border-neutral-100/15 bg-neutral-900/60 p-2">
86+
<MapPin className="size-4 text-neutral-600" />
8787
<span>{job.location}</span>
8888
</div>
89-
<div className="flex items-center gap-2 rounded-lg border border-neutral-900 bg-neutral-900/60 px-3 py-2">
90-
<Clock className="size-4 text-neutral-500" />
89+
<div className="flex items-center gap-2 border border-dashed border-neutral-100/15 bg-neutral-900/60 p-2">
90+
<Clock className="size-4 text-neutral-600" />
9191
<span>{formatJobType(job.type)}</span>
9292
</div>
9393
{job.salary && (
94-
<div className="flex items-center gap-2 rounded-lg border border-neutral-900 bg-neutral-900/60 px-3 py-2">
95-
<DollarSign className="size-4 text-neutral-500" />
94+
<div className="flex items-center gap-2 border border-dashed border-neutral-100/15 bg-neutral-900/60 p-2">
95+
<DollarSign className="size-4 text-neutral-600" />
9696
<span className="text-neutral-200">{job.salary}</span>
9797
</div>
9898
)}
99-
<div className="flex items-center gap-2 rounded-lg border border-neutral-900 bg-neutral-900/60 px-3 py-2">
100-
<Calendar className="size-4 text-neutral-500" />
99+
<div className="flex items-center gap-2 border border-dashed border-neutral-100/15 bg-neutral-900/60 p-2">
100+
<Calendar className="size-4 text-neutral-600" />
101101
<span>Posted {formatDate(job.createdAt)}</span>
102102
</div>
103103
</div>
@@ -108,15 +108,15 @@ const JobCard: React.FC<JobCardProps> = ({ job }) => {
108108
<Badge
109109
key={category}
110110
variant="secondary"
111-
className="rounded-full border border-neutral-900 bg-neutral-900/70 px-3 py-1 text-xs font-medium text-neutral-300"
111+
className="rounded-full border border-neutral-900 bg-neutral-900/70 px-3 py-1.5 text-xs font-medium leading-none text-neutral-400"
112112
>
113113
{category}
114114
</Badge>
115115
))}
116116
{job.categories.length > 3 && (
117117
<Badge
118118
variant="secondary"
119-
className="rounded-full border border-neutral-900 bg-neutral-900/70 px-3 py-1 text-xs font-medium text-neutral-400"
119+
className="rounded-full border border-neutral-900 bg-neutral-900/70 px-3 py-1.5 text-xs font-medium leading-none text-neutral-400"
120120
>
121121
+{job.categories.length - 3} more
122122
</Badge>
@@ -125,9 +125,11 @@ const JobCard: React.FC<JobCardProps> = ({ job }) => {
125125
)}
126126
</CardContent>
127127

128-
<CardFooter className="mt-auto flex items-center justify-between border-t border-neutral-900 bg-neutral-900/40 px-6 py-4 text-xs text-neutral-400">
129-
<span>Expires {formatDate(job.expiresAt)}</span>
130-
<span className="inline-flex items-center gap-1 text-neutral-300">
128+
<CardFooter className="mt-auto flex items-center justify-between border-t border-neutral-900 bg-neutral-900/40 px-4 py-3 text-xs">
129+
<span className="text-neutral-500">
130+
Expires {formatDate(job.expiresAt)}
131+
</span>
132+
<span className="inline-flex items-center gap-1 text-neutral-400">
131133
View role
132134
<ArrowUpRight className="size-3" />
133135
</span>

src/components/jobs/JobSearch.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const JobSearch: React.FC<JobSearchProps> = ({ searchParams }) => {
8282
const hasActiveFilters = search || location || type || featured
8383

8484
return (
85-
<div className="mx-auto w-full max-w-6xl rounded-2xl border border-neutral-900 bg-neutral-900/40 px-4 py-6 shadow-lg backdrop-blur md:px-8">
85+
<div className="mx-auto w-full max-w-6xl border border-dashed border-neutral-100/15 bg-neutral-900/40 px-4 py-6 shadow-lg backdrop-blur md:px-8">
8686
<div className="mb-6 flex flex-col gap-4 md:flex-row">
8787
<div className="relative flex-1">
8888
<Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-neutral-500" />
@@ -91,7 +91,7 @@ const JobSearch: React.FC<JobSearchProps> = ({ searchParams }) => {
9191
value={search}
9292
onChange={(e) => setSearch(e.target.value)}
9393
onKeyDown={(e) => e.key === "Enter" && updateURL()}
94-
className="border-neutral-900 bg-neutral-950/70 pl-10 text-neutral-200 placeholder:text-neutral-500 focus:border-neutral-700"
94+
className="rounded-none border-dashed border-neutral-100/15 bg-neutral-950/70 pl-10 text-neutral-200 placeholder:text-neutral-500 focus:border-neutral-700"
9595
/>
9696
</div>
9797

@@ -102,13 +102,13 @@ const JobSearch: React.FC<JobSearchProps> = ({ searchParams }) => {
102102
value={location}
103103
onChange={(e) => setLocation(e.target.value)}
104104
onKeyDown={(e) => e.key === "Enter" && updateURL()}
105-
className="border-neutral-900 bg-neutral-950/70 pl-10 text-neutral-200 placeholder:text-neutral-500 focus:border-neutral-700"
105+
className="rounded-none border-dashed border-neutral-100/15 bg-neutral-950/70 pl-10 text-neutral-200 placeholder:text-neutral-500 focus:border-neutral-700"
106106
/>
107107
</div>
108108

109109
<Button
110110
onClick={updateURL}
111-
className="bg-neutral-100 text-neutral-900 hover:bg-neutral-200"
111+
className="bg-neutral-100 px-6 text-neutral-900 hover:bg-neutral-200"
112112
>
113113
<Search className="mr-2 size-4" />
114114
Search

src/components/jobs/JobSkeleton.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,35 @@ const JobSkeleton: React.FC = () => {
66
<Card className="size-full max-w-sm overflow-hidden border-neutral-100/15 opacity-90">
77
<CardHeader className="pb-2">
88
<div className="flex items-center gap-3">
9-
<div className="size-10 rounded border border-neutral-100/15 bg-neutral-800 animate-pulse" />
9+
<div className="size-10 animate-pulse rounded border border-neutral-100/15 bg-neutral-800" />
1010
<div className="space-y-2">
11-
<div className="h-5 w-32 bg-neutral-800 rounded animate-pulse" />
12-
<div className="h-4 w-24 bg-neutral-800 rounded animate-pulse" />
11+
<div className="h-5 w-32 animate-pulse rounded bg-neutral-800" />
12+
<div className="h-4 w-24 animate-pulse rounded bg-neutral-800" />
1313
</div>
1414
</div>
1515
</CardHeader>
1616

1717
<CardContent className="space-y-3">
1818
<div className="space-y-2">
19-
<div className="h-3 w-full bg-neutral-800 rounded animate-pulse" />
20-
<div className="h-3 w-3/4 bg-neutral-800 rounded animate-pulse" />
19+
<div className="h-3 w-full animate-pulse rounded bg-neutral-800" />
20+
<div className="h-3 w-3/4 animate-pulse rounded bg-neutral-800" />
2121
</div>
2222

2323
<div className="flex gap-2">
24-
<div className="h-4 w-16 bg-neutral-800 rounded animate-pulse" />
25-
<div className="h-4 w-20 bg-neutral-800 rounded animate-pulse" />
26-
<div className="h-4 w-16 bg-neutral-800 rounded animate-pulse" />
24+
<div className="h-4 w-16 animate-pulse rounded bg-neutral-800" />
25+
<div className="h-4 w-20 animate-pulse rounded bg-neutral-800" />
26+
<div className="h-4 w-16 animate-pulse rounded bg-neutral-800" />
2727
</div>
2828

2929
<div className="flex gap-1.5">
30-
<div className="h-5 w-16 bg-neutral-800 rounded animate-pulse" />
31-
<div className="h-5 w-20 bg-neutral-800 rounded animate-pulse" />
30+
<div className="h-5 w-16 animate-pulse rounded bg-neutral-800" />
31+
<div className="h-5 w-20 animate-pulse rounded bg-neutral-800" />
3232
</div>
3333
</CardContent>
3434

3535
<CardFooter className="flex items-center justify-between py-3">
36-
<div className="h-3 w-20 bg-neutral-800 rounded animate-pulse" />
37-
<div className="h-3 w-24 bg-neutral-800 rounded animate-pulse" />
36+
<div className="h-3 w-20 animate-pulse rounded bg-neutral-800" />
37+
<div className="h-3 w-24 animate-pulse rounded bg-neutral-800" />
3838
</CardFooter>
3939
</Card>
4040
)

0 commit comments

Comments
 (0)