From 0798765a7478d9ac879c2c4c1b9c1eeefcab1f4c Mon Sep 17 00:00:00 2001 From: ShubhamMewara Date: Fri, 9 Aug 2024 21:08:47 +0530 Subject: [PATCH 1/2] removed code --- apps/web/.env.example | 11 +- apps/web/app/admin/code/[problemId]/page.tsx | 29 --- .../code/submission/[submissionId]/route.ts | 31 --- apps/web/app/api/code/submission/route.ts | 115 -------- apps/web/app/api/code/test/route.ts | 51 ---- apps/web/app/profile/submissions/page.tsx | 83 ------ .../components/AddProblemStatementForm.tsx | 124 --------- apps/web/components/AddTestCase.tsx | 97 ------- apps/web/components/AdminButton.tsx | 38 --- apps/web/components/BlogAppbar.tsx | 33 +-- apps/web/components/ContentSearch.tsx | 2 +- apps/web/components/LessonView.tsx | 42 +-- .../web/components/ProblemSubmissionTable.tsx | 113 -------- apps/web/components/admin/AddProblemCard.tsx | 18 +- apps/web/components/admin/AddTrackCard.tsx | 17 +- apps/web/components/admin/ProblemCard.tsx | 13 +- apps/web/components/admin/ProblemEditor.tsx | 4 +- .../admin/code/ProblemStatementForm.tsx | 109 -------- .../admin/code/ProblemStatements.tsx | 48 ---- .../admin/code/components/AddCaseDialog.tsx | 173 ------------ .../code/components/ArgumentNamesInput.tsx | 19 -- .../admin/code/components/CsvImportButton.tsx | 210 --------------- .../admin/code/components/FormFooter.tsx | 130 --------- .../admin/code/components/FormHeader.tsx | 13 - .../code/components/JsonImportButton.tsx | 175 ------------- .../code/components/LanguageDropDownInput.tsx | 58 ----- .../code/components/MainFunctionInput.tsx | 13 - .../code/components/NewProblemStatement.tsx | 29 --- .../code/components/ProblemEditInput.tsx | 48 ---- .../code/components/ProblemStatementCard.tsx | 52 ---- .../admin/code/components/TestCasesList.tsx | 69 ----- apps/web/components/code.tsx | 3 - apps/web/components/code/CodeEditor.tsx | 88 ------- .../components/code/CodeProblemRenderer.tsx | 65 ----- apps/web/components/code/CodeSubmitButton.tsx | 79 ------ apps/web/components/code/CodeTestButton.tsx | 68 ----- apps/web/components/code/Codebar.tsx | 33 --- .../components/code/ProblemStatementPanel.tsx | 83 ------ apps/web/components/code/RunCodeOutput.tsx | 131 ---------- .../submission/AcceptedSubmissionResult.tsx | 65 ----- .../submission/ErrorSubmissionResult.tsx | 41 --- .../submission/SubmissionCreatedAt.tsx | 16 -- .../submission/SubmissionDetail.tsx | 57 ---- .../components/submission/SubmissionList.tsx | 100 ------- .../submission/WrongSubmissionResult.tsx | 49 ---- apps/web/components/utils.tsx | 246 +++--------------- apps/web/hooks/useProblemStatement.ts | 30 --- apps/web/lib/code.ts | 97 ------- apps/web/package.json | 2 +- apps/web/screens/Admin.tsx | 5 - packages/common/package.json | 14 - .../20240809135031_removed_code/migration.sql | 58 +++++ packages/db/prisma/schema.prisma | 53 ---- packages/db/prisma/seed.ts | 41 +-- packages/db/prisma/seedsData.ts | 2 +- packages/store/src/atoms/adminPS.ts | 54 ---- packages/store/src/atoms/code.ts | 67 ----- packages/store/src/atoms/index.ts | 7 +- packages/store/src/atoms/tracks.ts | 23 -- packages/store/src/atoms/user.ts | 11 - packages/ui/package.json | 2 +- turbo.json | 11 +- 62 files changed, 127 insertions(+), 3441 deletions(-) delete mode 100644 apps/web/app/admin/code/[problemId]/page.tsx delete mode 100644 apps/web/app/api/code/submission/[submissionId]/route.ts delete mode 100644 apps/web/app/api/code/submission/route.ts delete mode 100644 apps/web/app/api/code/test/route.ts delete mode 100644 apps/web/app/profile/submissions/page.tsx delete mode 100644 apps/web/components/AddProblemStatementForm.tsx delete mode 100644 apps/web/components/AddTestCase.tsx delete mode 100644 apps/web/components/AdminButton.tsx delete mode 100644 apps/web/components/ProblemSubmissionTable.tsx delete mode 100644 apps/web/components/admin/code/ProblemStatementForm.tsx delete mode 100644 apps/web/components/admin/code/ProblemStatements.tsx delete mode 100644 apps/web/components/admin/code/components/AddCaseDialog.tsx delete mode 100644 apps/web/components/admin/code/components/ArgumentNamesInput.tsx delete mode 100644 apps/web/components/admin/code/components/CsvImportButton.tsx delete mode 100644 apps/web/components/admin/code/components/FormFooter.tsx delete mode 100644 apps/web/components/admin/code/components/FormHeader.tsx delete mode 100644 apps/web/components/admin/code/components/JsonImportButton.tsx delete mode 100644 apps/web/components/admin/code/components/LanguageDropDownInput.tsx delete mode 100644 apps/web/components/admin/code/components/MainFunctionInput.tsx delete mode 100644 apps/web/components/admin/code/components/NewProblemStatement.tsx delete mode 100644 apps/web/components/admin/code/components/ProblemEditInput.tsx delete mode 100644 apps/web/components/admin/code/components/ProblemStatementCard.tsx delete mode 100644 apps/web/components/admin/code/components/TestCasesList.tsx delete mode 100644 apps/web/components/code.tsx delete mode 100644 apps/web/components/code/CodeEditor.tsx delete mode 100644 apps/web/components/code/CodeProblemRenderer.tsx delete mode 100644 apps/web/components/code/CodeSubmitButton.tsx delete mode 100644 apps/web/components/code/CodeTestButton.tsx delete mode 100644 apps/web/components/code/Codebar.tsx delete mode 100644 apps/web/components/code/ProblemStatementPanel.tsx delete mode 100644 apps/web/components/code/RunCodeOutput.tsx delete mode 100644 apps/web/components/submission/AcceptedSubmissionResult.tsx delete mode 100644 apps/web/components/submission/ErrorSubmissionResult.tsx delete mode 100644 apps/web/components/submission/SubmissionCreatedAt.tsx delete mode 100644 apps/web/components/submission/SubmissionDetail.tsx delete mode 100644 apps/web/components/submission/SubmissionList.tsx delete mode 100644 apps/web/components/submission/WrongSubmissionResult.tsx delete mode 100644 apps/web/hooks/useProblemStatement.ts delete mode 100644 apps/web/lib/code.ts delete mode 100644 packages/common/package.json create mode 100644 packages/db/prisma/migrations/20240809135031_removed_code/migration.sql delete mode 100644 packages/store/src/atoms/adminPS.ts delete mode 100644 packages/store/src/atoms/code.ts delete mode 100644 packages/store/src/atoms/tracks.ts delete mode 100644 packages/store/src/atoms/user.ts diff --git a/apps/web/.env.example b/apps/web/.env.example index 4edb7c87..703891dc 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -4,17 +4,10 @@ GOOGLE_CLIENT_ID="" GOOGLE_CLIENT_SECRET="" NEXTAUTH_URL="http://localhost:3000" NEXTAUTH_SECRET="NEXTAUTH_SECRET" -NEXT_PUBLIC_JUDGE0_API_URL="http://localhost:2358" -CODE_SUBMISSION_RATE_LIMIT_COUNT=5 # Nums of submission allowed in the interval -CODE_SUBMISSION_RATE_LIMIT_INTERVAL=60000 #Interval in milliseconds (1 minute) -CODE_SUBMISSION_BACKOFF_DELAY=1000 # delay in ms -CODE_SUBMISSION_BACKOFF_MAX_RETRIES=5 # delay in ms - GOOGLEAI_API_KEY= - QDRANT_API_KEY= QDRANT_URL= +VECTOR_DIMENSION=768 # Upto 768 dimensions are supported -CACHE_EXPIRE=1800 # expiration time of the cache memory -VECTOR_DIMENSION=768 # Upto 768 dimensions are supported \ No newline at end of file +CACHE_EXPIRE=1800 # expiration time of the cache memory \ No newline at end of file diff --git a/apps/web/app/admin/code/[problemId]/page.tsx b/apps/web/app/admin/code/[problemId]/page.tsx deleted file mode 100644 index 704e8798..00000000 --- a/apps/web/app/admin/code/[problemId]/page.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import db from "@repo/db/client"; -import { AddProblemStatementForm } from "../../../../components/AddProblemStatementForm"; - -import { AppbarClient } from "../../../../components/AppbarClient"; - -export default async function AddProblemStatementPage({ params: { problemId } }: { params: { problemId: string } }) { - const problemInfo = await db.problem.findUnique({ - where: { id: problemId }, - }); - - const allLanguages = await db.codeLanguage.findMany(); - - if (!problemInfo) { - return

Could not find the problem

; - } - - if (!allLanguages) { - return

No Language Support Available

; - } - - return ( - <> - -
- -
- - ); -} diff --git a/apps/web/app/api/code/submission/[submissionId]/route.ts b/apps/web/app/api/code/submission/[submissionId]/route.ts deleted file mode 100644 index 17b420a1..00000000 --- a/apps/web/app/api/code/submission/[submissionId]/route.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { NextRequest, NextResponse } from "next/server"; -import db from "@repo/db/client"; -import { getServerSession } from "next-auth"; -import { authOptions } from "../../../../../lib/auth"; - -export async function GET(req: NextRequest, { params: { submissionId } }: { params: { submissionId: string } }) { - const session = await getServerSession(authOptions); - - if (!session || !session.user) { - return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); - } - - const userId = session.user.id; - const submission = await db.submission.findUnique({ - where: { - id: submissionId, - userId, - }, - include: { - problemStatement: { - include: { - testCases: true, - }, - }, - language: true, - lastTestCase: true, - }, - }); - - return NextResponse.json({ ...submission }); -} diff --git a/apps/web/app/api/code/submission/route.ts b/apps/web/app/api/code/submission/route.ts deleted file mode 100644 index 6bb96835..00000000 --- a/apps/web/app/api/code/submission/route.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { NextRequest, NextResponse } from "next/server"; -import db from "@repo/db/client"; -import { getServerSession } from "next-auth"; -import { authOptions, rateLimit } from "../../../../lib/auth"; -import { fetchSubmissions, processSubmissionData } from "../../../../lib/code"; - -const [rateLimitCount, rateLimitInterval] = [ - process.env.CODE_SUBMISSION_RATE_LIMIT_COUNT || 5, - process.env.CODE_SUBMISSION_RATE_LIMIT_INTERVAL || 60000, -]; - -const getInputString = (args: string[], funcName: string) => { - return `\n -console.log(${funcName}(${args.join(",")})) -`; -}; - -export async function POST(req: NextRequest) { - try { - const session = await getServerSession(authOptions); - - if (!session || !session.user) { - return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); - } - - const userId = session.user.id; - - if (!rateLimit(userId, Number(rateLimitCount), Number(rateLimitInterval))) { - return NextResponse.json({ message: "Rate Limit Exceeded. Please try again later." }, { status: 401 }); - } - - const { sourceCode, languageId, problemStatementId } = await req.json(); - - const problemStatement = await db.problemStatement.findFirst({ - where: { id: problemStatementId }, - include: { - testCases: true, - }, - }); - - if (!problemStatement) { - return NextResponse.json({ message: "Problem Statement not found" }, { status: 400 }); - } - - const { testCases, mainFuncName } = problemStatement; - - const submissions = testCases.map((testCase) => { - return { - source_code: atob(sourceCode) + getInputString(testCase.inputs, mainFuncName), - language_id: languageId, - expected_output: testCase.expectedOutput, - }; - }); - - const API_URL = `${process.env.JUDGE0_API_URL}/submissions/batch`; - const res = await fetch(API_URL, { - method: "POST", - body: JSON.stringify({ - submissions, - }), - headers: { - "Content-Type": "application/json", - }, - }); - - const data: any[] = await res.json(); - - const tokenMap: any = {}; - - data.forEach((submission, index) => { - tokenMap[submission.token] = testCases[index]; - }); - - const tokenString = data.map((props: any) => props.token).join(","); - - const processedSubmissions = await new Promise((resolve) => { - setTimeout(async () => { - fetchSubmissions(tokenString, resolve); - }, 1000); - }); - - const submissionData = - processedSubmissions.length > 0 - ? processSubmissionData({ - languageId, - userId, - sourceCode, - tokenMap, - problemStatementId, - processedSubmissions, - }) - : { - code: sourceCode, - codeLanguageId: languageId, - statusId: 5, - statusDesc: "Time Limit Exceeded", - runtime: 0, - memoryUsage: 0, - testCasesPassed: 0, - problemStatementId, - errorMessage: null, - lastTestCaseId: testCases[0]?.id, - stdout: null, - userId, - }; - - const submission = await db.submission.create({ - data: submissionData, - }); - return NextResponse.json({ submissionId: submission.id }); - } catch (error) { - console.error("Error occurred:", error); - return NextResponse.json({ message: "An error occurred. Please try again later." }, { status: 500 }); - } -} diff --git a/apps/web/app/api/code/test/route.ts b/apps/web/app/api/code/test/route.ts deleted file mode 100644 index a1f6be79..00000000 --- a/apps/web/app/api/code/test/route.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { NextRequest, NextResponse } from "next/server"; -import { getServerSession } from "next-auth"; -import { authOptions, rateLimit } from "../../../../lib/auth"; -import { fetchSubmissions } from "../../../../lib/code"; - -const [rateLimitCount, rateLimitInterval] = [ - process.env.CODE_SUBMISSION_RATE_LIMIT_COUNT || 5, - process.env.CODE_SUBMISSION_RATE_LIMIT_INTERVAL || 60000, -]; - -export async function POST(req: NextRequest) { - const session = await getServerSession(authOptions); - - if (!session || !session.user) { - return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); - } - - const userId = session.user.id; - - if (!rateLimit(userId, Number(rateLimitCount), Number(rateLimitInterval))) { - return NextResponse.json({ message: "Rate Limit Exceeded. Please try again later." }, { status: 401 }); - } - - const { submissions } = await req.json(); - - const API_URL = `${process.env.JUDGE0_API_URL}/submissions/batch`; - const res = await fetch(API_URL, { - method: "POST", - body: JSON.stringify({ - submissions, - }), - headers: { - "Content-Type": "application/json", - }, - }); - - const data: any[] = await res.json(); - const tokenString = data.map((props: any) => props.token).join(","); - - const processedSubmissions = await new Promise((resolve) => { - setTimeout(async () => { - fetchSubmissions(tokenString, resolve); - }, 1000); - }); - - if (processedSubmissions.length === 0) { - return NextResponse.json({ message: "Time Limit Exceeded" }, { status: 500 }); - } - - return NextResponse.json({ submissions: processedSubmissions }); -} diff --git a/apps/web/app/profile/submissions/page.tsx b/apps/web/app/profile/submissions/page.tsx deleted file mode 100644 index 77d61f2c..00000000 --- a/apps/web/app/profile/submissions/page.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import React from "react"; -import { getServerSession } from "next-auth"; -import { authOptions } from "../../../lib/auth"; -import db from "@repo/db/client"; - -import { redirect } from "next/navigation"; -import ProblemSubmissionTable from "../../../components/ProblemSubmissionTable"; -import { Braces } from "lucide-react"; - -export default async function Submissions() { - const session = await getServerSession(authOptions); - - if (!session || !session?.user) { - redirect("/"); - } - - const getAllSubmissions = async () => { - if (!session || !session.user) { - return null; - } - - const userId = session.user.id; - const submissions = await db.submission.findMany({ - where: { - userId, - }, - include: { - language: true, - }, - orderBy: { - createdAt: "desc", - }, - }); - return submissions; - }; - - async function fetchProblemStatements(problemStatementIds: string[] | undefined) { - const uniqueProblemStatementIds: string[] = [...new Set(problemStatementIds)]; - const fetchedProblemStatements = await db.problemStatement.findMany({ - where: { - id: { - in: uniqueProblemStatementIds, - }, - }, - include: { - submissions: true, - problem: { - select: { - title: true, - description: true, - trackProblems: true, - }, - }, - }, - }); - - return fetchedProblemStatements; - } - - const submissions = await getAllSubmissions(); - - const acceptedSubmissions = submissions?.filter((submission) => submission.statusId <= 3); - const problemStatementIds = acceptedSubmissions?.map((submission) => submission.problemStatementId); - - const problemStatements = await fetchProblemStatements(problemStatementIds); - - return ( - <> -
-
-

- - Submissions -

- - This page shows you the accepted submission you have made so far - -
-
- - - ); -} diff --git a/apps/web/components/AddProblemStatementForm.tsx b/apps/web/components/AddProblemStatementForm.tsx deleted file mode 100644 index 85b7f17c..00000000 --- a/apps/web/components/AddProblemStatementForm.tsx +++ /dev/null @@ -1,124 +0,0 @@ -"use client"; -import { useState } from "react"; -import { Problem, CodeLanguage } from "@prisma/client"; -import { Input, Button, Label, Checkbox, Card, CardContent } from "@repo/ui"; -import AddTestCase from "./AddTestCase"; -import { useRecoilValue } from "recoil"; -import { adminTestCasesState } from "@repo/store"; -import { createProblemStatement } from "./utils"; - -export const AddProblemStatementForm = ({ problem, languages }: { problem: Problem; languages: CodeLanguage[] }) => { - const adminTestCases = useRecoilValue(adminTestCasesState); - const [mainFuncName, setMainFuncName] = useState(""); - const [argumentNames, setArgumentNames] = useState(""); - const [supportedLanguages, setSupportedLanguages] = useState([]); - - const handleLanguage = (checked: boolean, language: CodeLanguage) => { - if (checked) { - setSupportedLanguages((prev) => [...prev, language]); - } else { - setSupportedLanguages((prev) => prev.filter((l) => l.id !== language.id)); - } - }; - - const handleAddPS = async () => { - await createProblemStatement({ - problemStatement: { argumentNames: argumentNames.trim().split(","), mainFuncName, problemId: problem.id }, - languages: supportedLanguages, - testCases: adminTestCases, - }); - }; - return ( - <> -
-

{problem.title}

- -
-
-
-
- - { - setMainFuncName(event.target.value); - }} - /> -
-
- - { - setArgumentNames(event.target.value); - }} - /> -
- -
-
- - a.trim())} - /> -
- {adminTestCases.length > 0 ? ( -
- {adminTestCases.map((testCase) => ( - - -
-
- Inputs - {argumentNames - .trim() - .split(",") - .map((arg, index) => ( -
- {arg} -
{testCase.inputs[index]}
-
- ))} -
-
- Expected Output -
{testCase.expectedOutput}
-
-
-
-
- ))} -
- ) : ( - No Test Cases Added - )} -
-
-
- - {languages.map((language) => { - const { id, label } = language; - return ( -
- handleLanguage(checked as boolean, language)} - /> - -
- ); - })} -
-
- - ); -}; diff --git a/apps/web/components/AddTestCase.tsx b/apps/web/components/AddTestCase.tsx deleted file mode 100644 index c42fb88e..00000000 --- a/apps/web/components/AddTestCase.tsx +++ /dev/null @@ -1,97 +0,0 @@ -"use client"; -import { - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, - Input, - Button, - Label, -} from "@repo/ui"; -import { useState } from "react"; -import { useSetRecoilState } from "recoil"; -import { adminTestCasesState } from "@repo/store"; - -const AddTestCase = ({ argNames, disabled }: { argNames: string[]; disabled: boolean }) => { - const [expectedOutput, setExpectedOutput] = useState(""); - const [inputValues, setInputValues] = useState<{ [key: string]: string }>({}); - const [open, setOpen] = useState(false); - const setAdminTestCases = useSetRecoilState(adminTestCasesState); - - const handleInputValuesChange = (event: React.ChangeEvent, argName: string) => { - const { value } = event.target; - setInputValues((prev) => { - // Remove the key from inputValues if the value is empty - if (value.trim() === "") { - const { [argName]: removedKey, ...rest } = prev; - return rest; - } - return { ...prev, [argName]: value }; - }); - }; - - const handleCreateTestCase = async () => { - const inputs = argNames.map((argName) => inputValues[argName] || ""); - setAdminTestCases((prev) => [...prev, { inputs, expectedOutput }]); - setOpen(false); - setInputValues({}); - setExpectedOutput(""); - }; - - return ( - - - - - - - Add a Test Case - -
-
- Input: -
- {argNames.map((argName) => ( -
- - handleInputValuesChange(event, argName)} - /> -
- ))} -
-
-
- Expected Output - { - setExpectedOutput(event.target.value); - }} - /> -
-
- - - -
-
- ); -}; - -export default AddTestCase; diff --git a/apps/web/components/AdminButton.tsx b/apps/web/components/AdminButton.tsx deleted file mode 100644 index c3193593..00000000 --- a/apps/web/components/AdminButton.tsx +++ /dev/null @@ -1,38 +0,0 @@ -"use client"; - -import { useEffect, useState } from "react"; -import { Button } from "@repo/ui"; -import { useRouter } from "next/navigation"; - -export const AdminButton = () => { - const [admin, _setAdmin] = useState(false); - const router = useRouter(); - - //TODO: propagate to state - async function fetchUserDetailsClient() { - try { - return []; - } catch (e) { - return []; - } - } - - useEffect(() => { - fetchUserDetailsClient(); - }); - - return ( -
- {admin ? ( - - ) : null} -
- ); -}; diff --git a/apps/web/components/BlogAppbar.tsx b/apps/web/components/BlogAppbar.tsx index 3f5d71c4..f5150c78 100644 --- a/apps/web/components/BlogAppbar.tsx +++ b/apps/web/components/BlogAppbar.tsx @@ -1,39 +1,22 @@ "use client"; - import { Button } from "@repo/ui"; -import { Problem, Track, CodeLanguage, ProblemStatement, TestCase } from "@prisma/client"; +import { Problem, Track } from "@prisma/client"; import { useEffect, useState } from "react"; import Link from "next/link"; -import { ChevronLeftIcon, ChevronRightIcon, DownloadIcon } from "@radix-ui/react-icons"; +import { DownloadIcon } from "@radix-ui/react-icons"; import { ModeToggle } from "./ModeToggle"; -import { PageToggle } from "./PageToggle"; import { useRouter } from "next/navigation"; import UserAccountDropDown from "./UserAccountDropDown"; -import { Codebar } from "../components/code/Codebar"; import Pagination from "./Pagination"; export const BlogAppbar = ({ - problem, track, problemIndex }: { - problem: Problem & { notionRecordMap: any } & { - problemStatement?: - | (ProblemStatement & { - languagesSupported: CodeLanguage[]; - testCases: TestCase[]; - }) - | null; - }; + problem: Problem & { notionRecordMap: any }; track: Track & { problems: Problem[] }; problemIndex: number }) => { - let totalPages = Array.from({ length: track.problems.length }, (_, i) => i + 1); - - function setTheme(arg0: string) { - throw new Error("Function not implemented."); - } - const router = useRouter(); const [prevScrollPos, setPrevScrollPos] = useState(0); @@ -55,14 +38,7 @@ export const BlogAppbar = ({ setVisible(prevScrollPos > currentScrollPos || currentScrollPos < 50); setScrollingDown(prevScrollPos < currentScrollPos); setPrevScrollPos(currentScrollPos); - }, 90); // Adjust the delay (in milliseconds) as needed - - const handleScroll = () => { - const currentScrollPos = window.scrollY; - setVisible(prevScrollPos > currentScrollPos || currentScrollPos < 50); - setScrollingDown(prevScrollPos < currentScrollPos); - setPrevScrollPos(currentScrollPos); - }; + }, 90); useEffect(() => { window.addEventListener("scroll", debouncedHandleScroll); @@ -108,7 +84,6 @@ export const BlogAppbar = ({

{track.title} ({problemIndex + 1} / {track.problems.length})

- {problem.type === "Code" && problem.problemStatement && }
diff --git a/apps/web/components/ContentSearch.tsx b/apps/web/components/ContentSearch.tsx index badae7af..9ed8d58c 100644 --- a/apps/web/components/ContentSearch.tsx +++ b/apps/web/components/ContentSearch.tsx @@ -1,5 +1,5 @@ "use client"; -import { useCallback, useEffect, useRef, useState, useDeferredValue } from "react"; +import { useEffect, useRef, useState, useDeferredValue } from "react"; import Link from "next/link"; import { Cross2Icon, MagnifyingGlassIcon } from "@radix-ui/react-icons"; import { diff --git a/apps/web/components/LessonView.tsx b/apps/web/components/LessonView.tsx index 41df456b..dc683c06 100644 --- a/apps/web/components/LessonView.tsx +++ b/apps/web/components/LessonView.tsx @@ -1,36 +1,11 @@ import { Blog } from "./Blog"; -import { Problem, Track, ProblemStatement, CodeLanguage, TestCase } from "@prisma/client"; +import { Problem, Track } from "@prisma/client"; import MCQRenderer from "./mcq/MCQRenderer"; import RedirectToLoginCard from "./RedirectToLoginCard"; - -import db from "@repo/db/client"; import { getServerSession } from "next-auth"; import { authOptions } from "../lib/auth"; -import { CodeProblemRenderer } from "./code/CodeProblemRenderer"; import { AppbarClient } from "./AppbarClient"; -const getSubmissions = async (problemStatementId: string) => { - const session = await getServerSession(authOptions); - - if (!session || !session.user) { - return null; - } - - const userId = session.user.id; - const submissions = await db.submission.findMany({ - where: { - problemStatementId, - userId, - }, - include: { - language: true, - }, - orderBy: { - createdAt: "desc", - }, - }); - return submissions; -}; export const LessonView = async ({ problem, @@ -38,14 +13,7 @@ export const LessonView = async ({ showAppBar, isPdfRequested, }: { - problem: Problem & { notionRecordMap: any } & { - problemStatement: - | (ProblemStatement & { - languagesSupported: CodeLanguage[]; - testCases: TestCase[]; - }) - | null; - }; + problem: Problem & { notionRecordMap: any } track: Track & { problems: Problem[] }; showAppBar?: Boolean; isPdfRequested?: Boolean; @@ -68,12 +36,6 @@ export const LessonView = async ({ if (problem.type === "MCQ") { return ; } - if (problem.type === "Code" && problem.problemStatement) { - const submissions = await getSubmissions(problem.problemStatement.id); - return ( - - ); - } if (problem.type === "Blog") { return ( diff --git a/apps/web/components/ProblemSubmissionTable.tsx b/apps/web/components/ProblemSubmissionTable.tsx deleted file mode 100644 index 1c796f80..00000000 --- a/apps/web/components/ProblemSubmissionTable.tsx +++ /dev/null @@ -1,113 +0,0 @@ -"use client"; -import React from "react"; -import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@repo/ui"; -import { Clock4, CodeXml } from "lucide-react"; -import { useRouter } from "next/navigation"; -import { Submission } from "@prisma/client"; -import { ProblemStatement } from "@prisma/client"; - -interface ProblemSubmissionTableProps { - problemStatements: ProblemStatement[]; -} - -export default function ProblemSubmissionTable({ problemStatements }: ProblemSubmissionTableProps) { - function getTimeFromDateTime(dateTime: Date) { - const now = new Date(); - const diffInMs = now.getTime() - dateTime.getTime(); - - // Handle edge cases for "just now" and "a minute ago" - if (diffInMs < 60000) { - // Less than a minute - return "just now"; - } else if (diffInMs < 120000) { - // Between 1 and 2 minutes - return "a minute ago"; - } - - const seconds = Math.floor(diffInMs / 1000); - const minutes = Math.floor(seconds / 60); - const hours = Math.floor(minutes / 60); - const days = Math.floor(hours / 24); - - if (days === 1) { - return "yesterday"; - } else if (days > 1) { - return new Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", year: "numeric" }).format(dateTime); - } else if (hours > 0) { - return `${hours} hours ago`; - } else if (minutes > 0) { - return `${minutes} minutes ago`; - } - } - - problemStatements.sort((a: any, b: any) => { - const latestSubmissionA = a.submissions - .filter((sub: Submission) => sub.statusId <= 3) - .sort((x: Submission, y: Submission) => new Date(y.createdAt).getTime() - new Date(x.createdAt).getTime())[0]; - const latestSubmissionB = b.submissions - .filter((sub: Submission) => sub.statusId <= 3) - .sort((x: Submission, y: Submission) => new Date(y.createdAt).getTime() - new Date(x.createdAt).getTime())[0]; - - return new Date(latestSubmissionB.createdAt).getTime() - new Date(latestSubmissionA.createdAt).getTime(); - }); - - const router = useRouter(); - return ( -
- {problemStatements && problemStatements?.length > 0 ? ( -
- - - - -
- Problem - -
-
- - - Submitted - - -
-
- - {problemStatements?.map(({ id, problem, problemId, submissions }: any) => { - return ( - router.push(`/tracks/${problem.trackProblems[0].trackId}/${problemId}`)} - > - -
- {problem.title} -
-
- - - {submissions.length > 0 && - getTimeFromDateTime( - submissions - .filter((sub: Submission) => sub.statusId >= 1 && sub.statusId <= 3) - .sort( - (a: Submission, b: Submission) => - new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() - ) - .map((sub: Submission) => sub.createdAt)[0] - )} - - -
- ); - })} -
-
-
- ) : ( -
No Submission Yet!
- )} -
- ); -} diff --git a/apps/web/components/admin/AddProblemCard.tsx b/apps/web/components/admin/AddProblemCard.tsx index c619d673..dd5b2e84 100644 --- a/apps/web/components/admin/AddProblemCard.tsx +++ b/apps/web/components/admin/AddProblemCard.tsx @@ -16,7 +16,7 @@ import { useToast, } from "@repo/ui"; import { ProblemType } from "@prisma/client"; -import { createProblem, createProblemStatement } from "../utils"; +import { createProblem } from "../utils"; interface Problem { id: string; @@ -36,9 +36,6 @@ const AddProblemCard = () => { const handleCreateProblem = async () => { const problem = await createProblem({ title, description, type, notionDocId }); - if (problem?.type === "Code") { - handleCreatePsStatement(problem.id); - } if (problem) { newProblems.push(problem); toast({ @@ -54,18 +51,6 @@ const AddProblemCard = () => { }); }; - const handleCreatePsStatement = async (id: string) => { - const newPS = await createProblemStatement({ - problemStatement: { - argumentNames: [], - mainFuncName: "", - problemId: id, - }, - languages: [], - testCases: [], - }); - }; - return (
@@ -78,7 +63,6 @@ const AddProblemCard = () => { - Code Blog MCQ diff --git a/apps/web/components/admin/AddTrackCard.tsx b/apps/web/components/admin/AddTrackCard.tsx index 75a70993..a38a8d31 100644 --- a/apps/web/components/admin/AddTrackCard.tsx +++ b/apps/web/components/admin/AddTrackCard.tsx @@ -13,6 +13,7 @@ const AddTrackCard = ({ categories }: { categories: Categories[] }) => { const [image, setImage] = useState(""); const [hidden, setHidden] = useState(false); const [selectedCategory, setSelectedCategory] = useState([]); + const [cohort, setCohort] = useState(3); const { toast } = useToast(); function handleFilterButton(category: string) { @@ -58,6 +59,15 @@ const AddTrackCard = ({ categories }: { categories: Categories[] }) => { setImage(event.target.value); }} /> + { + setCohort(parseInt(event.target.value)); + }} + />
{categories.map((category, i) => (
diff --git a/apps/web/components/admin/ProblemCard.tsx b/apps/web/components/admin/ProblemCard.tsx index 51bd1645..4b96fb31 100644 --- a/apps/web/components/admin/ProblemCard.tsx +++ b/apps/web/components/admin/ProblemCard.tsx @@ -14,12 +14,10 @@ import { SelectTrigger, SelectValue, } from "@repo/ui"; -import { Problem, ProblemStatement } from "@prisma/client"; +import { Problem, ProblemType } from "@prisma/client"; import { updateProblem } from "../utils"; -import { useRouter } from "next/navigation"; -const ProblemCard = ({ problem }: { problem: Problem & { problemStatement: ProblemStatement | null } }) => { - const router = useRouter(); +const ProblemCard = ({ problem }: { problem: Problem }) => { const [isEditing, setIsEditing] = useState(false); const [id, setId] = useState(problem.id); const [title, setTitle] = useState(problem.title); @@ -51,11 +49,6 @@ const ProblemCard = ({ problem }: { problem: Problem & { problemStatement: Probl {title}
- {problem.type === "Code" && !problem.problemStatement && ( - - )} @@ -93,7 +86,7 @@ const ProblemCard = ({ problem }: { problem: Problem & { problemStatement: Probl setInputs(e.target.value.split("|"))} - className="col-span-3" - /> -
-
- - setExpectedOutput(e.target.value)} - className="col-span-3" - /> -
-
- - -
- - NOTE: Inputs / Arguments are seperated using pipe("|") - - - - - - - - - ); -} diff --git a/apps/web/components/admin/code/components/ArgumentNamesInput.tsx b/apps/web/components/admin/code/components/ArgumentNamesInput.tsx deleted file mode 100644 index a02b4a31..00000000 --- a/apps/web/components/admin/code/components/ArgumentNamesInput.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useRecoilState } from "recoil"; -import { argumentNames } from "@repo/store"; -import { Label, Input } from "@repo/ui"; - -export default function ArgumentNamesInput() { - const [LargumentNames, setArgumentNames] = useRecoilState(argumentNames); - - return ( -
- - { - setArgumentNames(e.target.value.split("|")); - }} - /> -
- ); -} diff --git a/apps/web/components/admin/code/components/CsvImportButton.tsx b/apps/web/components/admin/code/components/CsvImportButton.tsx deleted file mode 100644 index 2bc2dba5..00000000 --- a/apps/web/components/admin/code/components/CsvImportButton.tsx +++ /dev/null @@ -1,210 +0,0 @@ -import { - argumentNames, - globalLanguagesSupported, - languagesSupported, - mainFuncName, - problem, - problemId, - problemStatementId, - problemStatementsAtom, - testCases, -} from "@repo/store"; -import { - Button, - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, - Label, - Textarea, - useToast, -} from "@repo/ui"; - -import { useRecoilValue, useSetRecoilState, useRecoilState } from "recoil"; -import { useState } from "react"; -import { ProblemStatement, CodeLanguage } from "prisma/prisma-client"; -import { createProblem, createProblemStatement, createTestCase } from "../../../utils"; -import { refetch } from "../ProblemStatements"; -import { TestCase, ProblemType } from "@prisma/client"; - -interface Problem { - id: string; - title: string; - description: string; - type: ProblemType; - notionDocId: string; -} - -export default function CsvImportButton() { - const { toast } = useToast(); - const [LtestCases, setTestCases] = useRecoilState(testCases); - const LargumentNames = useRecoilValue(argumentNames); - const LmainFuncName = useRecoilValue(mainFuncName); - const setProblemId = useSetRecoilState(problemId); - const Lproblem = useRecoilValue(problem); - const LlanguagesSupported = useRecoilValue(languagesSupported); - const [LproblemStatementId, setProblemStatementId] = useRecoilState(problemStatementId); - const LglobalLanguagesSupported = useRecoilValue(globalLanguagesSupported); - const setproblemStatements = useSetRecoilState(problemStatementsAtom); - const sampleInput: string[] = ["arg1", "arg2", "arg3", "arg4", "arg5", "arg6", "arg7", "arg8", "arg9", "arg10"]; - const sampleCSV: string = - sampleInput.slice(0, LargumentNames.length).join(",") + - ",[0,1]" + - "," + - sampleInput.slice(0, LargumentNames.length).join(",") + - ",[0,1]"; - const [inputCSV, setInputCSV] = useState(""); - const [isDialogOpen, setIsDialogOpen] = useState(false); - - async function handleCaseAdd(inputs: string[], expectedOutput: string) { - if (inputs.length === LargumentNames.length) { - try { - const createdTestCase: TestCase | null = await createTestCase(inputs, expectedOutput, LproblemStatementId); - createdTestCase ? setTestCases((prev: TestCase[]) => [...prev, createdTestCase]) : null; - } catch (e) {} - } else { - toast({ - title: "Invalid CSV", - description: "Arguments and inputs size cannot be different and file should be a valid JSON", - variant: "destructive", - }); - } - } - - const splitCsvString = (inputString: string): string[] => { - const objects: string[] = []; - let currentObject: string = ""; - let depth: number = 0; - - for (const char of inputString) { - if (char === "[" || char === "{") { - depth++; - } else if (char === "]" || char === "}") { - depth--; - } - - if (char === "," && depth === 0) { - objects.push(currentObject.trim()); - currentObject = ""; - } else { - currentObject += char; - } - } - - if (currentObject.trim() !== "") { - objects.push(currentObject.trim()); - } - - return objects; - }; - - const importCSV = async () => { - const promiseArr: Promise[] = []; - const inputArr: string[] = inputCSV.split("\n"); - const testCasesFromCSV: Omit[] = []; - inputArr.forEach((input: string) => { - const expectedOutput: string | undefined = splitCsvString(input).pop(); - testCasesFromCSV.push({ - inputs: splitCsvString(input).slice(0, LargumentNames.length), - expectedOutput: expectedOutput ?? "", - }); - }); - testCasesFromCSV.forEach((testCase) => { - promiseArr.push(handleCaseAdd(testCase.inputs, testCase.expectedOutput)); - }); - - Promise.all(promiseArr).then(() => { - refetch().then((data: ProblemStatement[]) => { - setproblemStatements(data); - setIsDialogOpen(false); - setInputCSV(""); - }); - }); - }; - - const handleCreateProblem = async () => { - const createdProblem: Problem | null = await createProblem({ - title: Lproblem.title, - description: Lproblem.description, - type: "Code", - notionDocId: Lproblem.notionDocId, - }); - !createdProblem ? toast({ title: "Oops! Cannot create problem", description: "Unexpected error occured" }) : null; - if (createdProblem?.type === "Code") { - handleCreatePsStatement(createdProblem.id); - } - if (createdProblem) { - toast({ - title: "Added problem", - description: "Problem added", - }); - return; - } - - toast({ - title: "Couldn't add problem", - description: "Please try again later", - }); - }; - - const handleCreatePsStatement = async (id: string) => { - const newPS: ProblemStatement | null = await createProblemStatement({ - problemStatement: { - argumentNames: LargumentNames, - mainFuncName: LmainFuncName, - problemId: id, - }, - languages: LglobalLanguagesSupported.filter((lang) => LlanguagesSupported.map(({ id }) => id).includes(lang.id)), - testCases: LtestCases, - }); - if (newPS !== null && newPS !== undefined) { - setProblemStatementId(newPS.id); - setProblemId(newPS.problemId); - } - }; - - return ( - - - - - - - Sample TestCase.json - {!inputCSV &&
Sample: {sampleCSV}
} -
-
-
- -