Skip to content
Merged
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
8 changes: 4 additions & 4 deletions apps/web/app/(pages)/code-review/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export default function CodeReviewPage() {
size="lg"
className="bg-neutral-900 text-white hover:bg-neutral-800 dark:bg-white dark:text-neutral-900 dark:hover:bg-neutral-200 active:scale-[0.97] transition-transform duration-150"
>
<Link href="https://supercodeai.vercel.app/dashboard">
<Link href="/review">
Try Code Review
<ArrowRight className="ml-2 h-4 w-4" />
</Link>
Expand All @@ -244,8 +244,8 @@ export default function CodeReviewPage() {
size="lg"
className="active:scale-[0.97] transition-transform duration-150"
>
<Link href="https://cal.com/yash-dewasthale/talk-to-founder">
Book a demo
<Link href="/review">
How it works
<ArrowRight className="ml-2 h-4 w-4" />
</Link>
</Button>
Expand Down Expand Up @@ -450,7 +450,7 @@ export default function CodeReviewPage() {
<div>
<div className="font-medium text-neutral-900 dark:text-white">Learning System</div>
<div className="mt-1 text-sm text-neutral-500 dark:text-neutral-400">
Gets smarter with every review, adapting to your team's style.
Gets smarter with every review, adapting to your team&apos;s style.
</div>
</div>
</div>
Expand Down
16 changes: 16 additions & 0 deletions apps/web/app/api/public-reviews/publish/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { auth } from "@/lib/auth"
import { getGithubTokenForUser } from "@/modules/github/lib/github"
import { createPublicReviewPublishHandler } from "@/modules/reviews/public-review-publish"
import { createPublicReviewPublishStore } from "@/modules/reviews/public-review-publish-store"
import { createPublicReviewStore } from "@/modules/reviews/public-review-store"

export const runtime = "nodejs"
export const maxDuration = 120
export const dynamic = "force-dynamic"

export const POST = createPublicReviewPublishHandler({
getSession: (headers) => auth.api.getSession({ headers }),
getToken: getGithubTokenForUser,
cache: createPublicReviewStore(),
store: createPublicReviewPublishStore(),
})
42 changes: 42 additions & 0 deletions apps/web/app/api/public-reviews/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { publicReviewErrorResponse, PublicReviewError } from "@/modules/reviews/public-review-errors"
import { assertPublicReviewSameOrigin, publicReviewSubject, readPublicReviewBody } from "@/modules/reviews/public-review-request"
import { createPublicReviewService } from "@/modules/reviews/public-review-service"
import { createPublicReviewStore } from "@/modules/reviews/public-review-store"

export const runtime = "nodejs"
export const maxDuration = 300
export const dynamic = "force-dynamic"

const reviewPublicPr = createPublicReviewService({ store: createPublicReviewStore() })

export async function GET(request: Request): Promise<Response> {
try {
const urls = new URL(request.url).searchParams.getAll("url")
if (urls.length !== 1) throw new PublicReviewError("Enter one public GitHub pull request URL.", 400)
const payload = await reviewPublicPr({
url: urls[0],
subject: publicReviewSubject(request),
generate: false,
signal: AbortSignal.any([request.signal, AbortSignal.timeout(60_000)]),
})
return Response.json(payload, { headers: { "Cache-Control": "no-store" } })
} catch (error) {
return publicReviewErrorResponse(error)
}
}

export async function POST(request: Request): Promise<Response> {
try {
assertPublicReviewSameOrigin(request)
const { url } = await readPublicReviewBody(request)
const payload = await reviewPublicPr({
url,
subject: publicReviewSubject(request),
generate: true,
signal: AbortSignal.any([request.signal, AbortSignal.timeout(240_000)]),
})
return Response.json(payload, { headers: { "Cache-Control": "no-store" } })
} catch (error) {
return publicReviewErrorResponse(error)
}
}
27 changes: 27 additions & 0 deletions apps/web/app/review/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Metadata } from "next"

import { PublicReviewPage } from "@/modules/reviews/public-review-page"

export const metadata: Metadata = {
title: "Free Public PR Review — Supercode",
description:
"Paste a public GitHub pull request and get a free AI code review. Explore the analysis and diff with no account or GitHub installation required.",
alternates: { canonical: "/review" },
openGraph: {
title: "A second set of eyes for your next PR — Supercode Review",
description:
"Review public GitHub pull requests for free. No sign-up, no installation. Just a PR link.",
images: ["/code-review-og-img.png"],
},
}

export default async function ReviewPage({
searchParams,
}: {
searchParams: Promise<{ pr?: string | string[] }>
}) {
const params = await searchParams
const initialUrl = typeof params.pr === "string" ? params.pr.slice(0, 2048) : ""

return <PublicReviewPage initialUrl={initialUrl} />
}
Loading
Loading