Skip to content

Commit 52b7209

Browse files
authored
Merge pull request #86 from codegasms/feat/submit-on-submit
Submit on submit
2 parents e6ef4be + a13eec2 commit 52b7209

File tree

11 files changed

+763
-88
lines changed

11 files changed

+763
-88
lines changed

app/[orgId]/contests/[id]/page.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,9 @@ export default function ContestDetailsPage() {
225225
{contestData.problems.map(
226226
(problem: { id: string; title: string }) => (
227227
<li key={problem.id}>
228-
<Link href={`/${orgId}/problems/${problem.id}`}>
228+
<Link
229+
href={`/${orgId}/contests/${contestId}/problems/${problem.id}`}
230+
>
229231
<Button
230232
variant="link"
231233
className="p-0 h-auto text-primary hover:text-primary/80"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { CodeEditor } from "@/components/code-editor";
2+
import { notFound } from "next/navigation";
3+
4+
async function getProblem(orgId: string, contestId: string, problemId: string) {
5+
console.log(
6+
`ENV: ${process.env.NEXT_PUBLIC_APP_URL}`,
7+
orgId,
8+
contestId,
9+
problemId,
10+
);
11+
12+
try {
13+
// Fetch the problem with contest context
14+
const response = await fetch(
15+
`${process.env.NEXT_PUBLIC_APP_URL}/api/orgs/${orgId}/contests/${contestId}/problems/${problemId}`,
16+
{
17+
cache: "no-store",
18+
},
19+
);
20+
21+
if (!response.ok) {
22+
throw new Error("Failed to fetch problem");
23+
}
24+
25+
const problem = await response.json();
26+
27+
// Add the contest ID to the problem data
28+
return {
29+
...problem,
30+
contestNameId: contestId,
31+
orgId,
32+
};
33+
} catch (error) {
34+
console.error("Error fetching problem:", error);
35+
return null;
36+
}
37+
}
38+
39+
export default async function Page({
40+
params,
41+
}: {
42+
params: { orgId: string; id: string; problemId: string };
43+
}) {
44+
const problem = await getProblem(params.orgId, params.id, params.problemId);
45+
46+
if (!problem) {
47+
notFound();
48+
}
49+
50+
return (
51+
<>
52+
<CodeEditor problem={problem} />
53+
</>
54+
);
55+
}

app/[orgId]/problems/[id]/page.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ async function getProblem(orgId: string, problemId: string) {
1919
throw new Error("Failed to fetch problem");
2020
}
2121

22-
return response.json();
22+
// Return the problem without adding contestId
23+
const problem = await response.json();
24+
return {
25+
...problem,
26+
orgId,
27+
// No contestId here, as this is a standalone problem
28+
};
2329
} catch (error) {
2430
console.error("Error fetching problem:", error);
2531
return null;

app/api/me/service.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ interface Org {
1010
}
1111

1212
interface User {
13-
_id: number;
13+
id: number;
1414
email: string;
1515
name: string;
16+
nameId: string;
1617
orgs: Org[];
1718
isSuperuser: boolean;
1819
}
@@ -23,6 +24,7 @@ export async function getUserWithOrgs(userId: number): Promise<User | null> {
2324
userId: users.id,
2425
email: users.email,
2526
name: users.name,
27+
nameId: users.nameId,
2628
isSuperuser: users.isSuperuser,
2729
orgId: orgs.id,
2830
orgName: orgs.name,
@@ -42,9 +44,10 @@ export async function getUserWithOrgs(userId: number): Promise<User | null> {
4244
const userData = result[0];
4345

4446
return {
45-
_id: userData.userId,
47+
id: userData.userId,
4648
email: userData.email,
4749
name: userData.name,
50+
nameId: userData.nameId,
4851
isSuperuser: userData.isSuperuser,
4952
orgs: result
5053
.filter((row) => row.orgId !== null) // Filter out null orgs from left join

app/api/orgs/[orgId]/contests/[contestId]/problems/[problemId]/route.ts

+78-21
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,98 @@ import { z } from "zod";
33
import { NameIdSchema } from "@/lib/validations";
44
import { getOrgIdFromNameId, getContestIdFromNameId } from "@/app/api/service";
55
import * as problemService from "./service";
6+
import { db } from "@/db/drizzle";
7+
import { problems, contestProblems, contests, testCases } from "@/db/schema";
8+
import { eq, and } from "drizzle-orm";
9+
import { IdSchema } from "@/app/api/types";
610

711
export async function GET(
8-
_req: NextRequest,
12+
request: NextRequest,
913
{
1014
params,
1115
}: { params: { orgId: string; contestId: string; problemId: string } },
1216
) {
1317
try {
14-
const orgId = await getOrgIdFromNameId(NameIdSchema.parse(params.orgId));
15-
const contestId = await getContestIdFromNameId(
16-
orgId,
17-
NameIdSchema.parse(params.contestId),
18-
);
19-
const problemCode = NameIdSchema.parse(params.problemId);
18+
// Parse and validate parameters
19+
const orgNameId = NameIdSchema.parse(params.orgId);
20+
const contestNameId = NameIdSchema.parse(params.contestId);
21+
const problemId = params.problemId;
22+
23+
// Get numeric orgId
24+
const orgId = await getOrgIdFromNameId(orgNameId);
25+
26+
// Find the contest by nameId
27+
const contestResult = await db
28+
.select({ id: contests.id })
29+
.from(contests)
30+
.where(
31+
and(
32+
eq(contests.nameId, contestNameId),
33+
eq(contests.organizerId, orgId),
34+
eq(contests.organizerKind, "org"),
35+
),
36+
)
37+
.limit(1);
38+
39+
if (contestResult.length === 0) {
40+
return NextResponse.json(
41+
{ message: "Contest not found" },
42+
{ status: 404 },
43+
);
44+
}
45+
46+
const contestId = contestResult[0].id;
47+
48+
// Find the problem and its associated contest problem
49+
const problemResult = await db
50+
.select({
51+
problem: problems,
52+
contestProblem: contestProblems,
53+
})
54+
.from(problems)
55+
.innerJoin(
56+
contestProblems,
57+
and(
58+
eq(contestProblems.problemId, problems.id),
59+
eq(contestProblems.contestId, contestId),
60+
),
61+
)
62+
.where(eq(problems.code, problemId))
63+
.limit(1);
64+
65+
if (problemResult.length === 0) {
66+
return NextResponse.json(
67+
{ message: "Problem not found in this contest" },
68+
{ status: 404 },
69+
);
70+
}
2071

21-
const problem = await problemService.getContestProblem(
72+
// Get test cases for the problem
73+
const testCasesResult = await db
74+
.select()
75+
.from(testCases)
76+
.where(eq(testCases.problemId, problemResult[0].problem.id));
77+
78+
// Combine the data
79+
const problem = {
80+
...problemResult[0].problem,
81+
contestProblemId: problemResult[0].contestProblem.id,
82+
testCases: testCasesResult.map((tc) => ({
83+
input: tc.input,
84+
output: tc.output,
85+
kind: tc.kind,
86+
})),
87+
orgId,
2288
contestId,
23-
problemCode,
24-
);
89+
};
90+
2591
return NextResponse.json(problem);
2692
} catch (error) {
2793
if (error instanceof z.ZodError) {
28-
return NextResponse.json({ error: error.errors }, { status: 400 });
29-
}
30-
if (error instanceof Error) {
31-
if (
32-
error.message === "Organization not found" ||
33-
error.message === "Contest not found" ||
34-
error.message === "Problem not found"
35-
) {
36-
return NextResponse.json({ error: error.message }, { status: 404 });
37-
}
94+
return NextResponse.json({ errors: error.errors }, { status: 400 });
3895
}
3996
return NextResponse.json(
40-
{ error: "Failed to fetch contest problem" },
97+
{ message: "Failed to fetch problem" },
4198
{ status: 500 },
4299
);
43100
}

app/api/orgs/[orgId]/submissions/route.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,17 @@ export async function POST(
6868
{ params }: { params: { orgId: string } },
6969
) {
7070
try {
71-
const orgId = IdSchema.parse(params.orgId);
72-
const data = createSubmissionSchema.parse(await request.json());
71+
const orgNameId = NameIdSchema.parse(params.orgId);
72+
const orgId = await getOrgIdFromNameId(orgNameId);
73+
74+
const requestData = await request.json();
75+
console.log("requestData", requestData);
76+
77+
// Parse the submission data including the userId and contestNameId
78+
const data = createSubmissionSchema.parse(requestData);
79+
console.log("data", data);
7380

81+
// Pass the data to the service which will handle the contestNameId
7482
const submission = await submissionService.createSubmission(orgId, data);
7583
return NextResponse.json(submission, { status: 201 });
7684
} catch (error) {

0 commit comments

Comments
 (0)