Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions app/api/leetcode/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { NextResponse } from "next/server"

import { fetchLeetCodeContributions, parseLeetCodeUsername } from "@/lib/leetcode"

export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const rawInput = searchParams.get("user") ?? searchParams.get("username") ?? ""

const username = parseLeetCodeUsername(rawInput)
if (!username) {
return NextResponse.json(
{ error: "Enter a valid LeetCode username or profile link." },
{ status: 400 }
)
}

try {
const result = await fetchLeetCodeContributions(username)
return NextResponse.json(result)
} catch (error) {
const message =
error instanceof Error ? error.message : "Failed to load contributions."
const status = message.includes("not found") ? 404 : 500
return NextResponse.json({ error: message }, { status })
}
}
24 changes: 24 additions & 0 deletions app/leetcode/[username]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { LeetCodeGraphLoader } from "@/components/leetcode-graph/leetcode-graph-loader"
import { parseLeetCodeUsername } from "@/lib/leetcode"
import { notFound } from "next/navigation"

type LeetCodeUserPageProps = {
params: Promise<{ username: string }>
}

export default async function LeetCodeUserPage({
params,
}: LeetCodeUserPageProps) {
const { username } = await params
const parsed = parseLeetCodeUsername(username)

if (!parsed) {
notFound()
}

return (
<main className="h-svh overflow-hidden bg-[#010409] text-white">
<LeetCodeGraphLoader initialUsername={parsed} />
</main>
)
}
9 changes: 9 additions & 0 deletions app/leetcode/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { LeetCodeGraphLoader } from "@/components/leetcode-graph/leetcode-graph-loader"

export default function Page() {
return (
<main className="h-svh overflow-hidden bg-[#010409] text-white">
<LeetCodeGraphLoader />
</main>
)
}
9 changes: 9 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import Link from "next/link"

import { ContributionGraphLoader } from "@/components/contribution-graph/contribution-graph-loader"

export default function Page() {
return (
<main className="h-svh overflow-hidden bg-[#010409] text-white">
<ContributionGraphLoader />

<Link
href="/leetcode"
className="pointer-events-auto fixed top-3 right-3 z-20 rounded-none border border-emerald-100/25 bg-black/70 px-3 py-2 text-xs font-medium text-emerald-50 shadow-lg shadow-black/30 backdrop-blur-sm hover:bg-emerald-400/10"
>
Check your leetcode here
</Link>
</main>
)
}
27 changes: 27 additions & 0 deletions components/leetcode-graph/leetcode-graph-loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Suspense } from "react"

import { LeetCodeGraph } from "@/components/leetcode-graph/leetcode-graph"

type LeetCodeGraphLoaderProps = {
initialUsername?: string
}

function LeetCodeGraphFallback() {
return (
<section className="relative h-full w-full overflow-hidden bg-[#010409]">
<div className="flex h-full flex-col items-center justify-center gap-2 px-6 text-center text-sm text-emerald-100/60">
<p>Loading contribution graph...</p>
</div>
</section>
)
}

export function LeetCodeGraphLoader({
initialUsername,
}: LeetCodeGraphLoaderProps) {
return (
<Suspense fallback={<LeetCodeGraphFallback />}>
<LeetCodeGraph initialUsername={initialUsername} />
</Suspense>
)
}
Loading