diff --git a/client/src/App.css b/client/src/App.css index 35ac68f..f8c8f40 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -15,7 +15,6 @@ p , a { .flex-row { display: flex; - justify-content: center; align-items: center; flex-direction: row; } diff --git a/client/src/Components/AllProblems/AllProblems.jsx b/client/src/Components/AllProblems/AllProblems.jsx index 1e16e6b..3db1215 100644 --- a/client/src/Components/AllProblems/AllProblems.jsx +++ b/client/src/Components/AllProblems/AllProblems.jsx @@ -1,50 +1,70 @@ import React, {useEffect, useState} from 'react' -import { Link } from 'react-router-dom' +import {Link} from 'react-router-dom' import "./AllProblems.css" -import { backendUrl } from "../../constants.js"; +import {backendUrl} from "../../constants.js"; +import Loader from "../../Constants/Loader/Loader.jsx"; const AllProblemsPage = () => { - const [problems, setProblems] = useState([]); - - const init = async () => { - const response = await fetch(`${backendUrl}/problems`, { - method: "GET", - }); - - const json = await response.json(); - setProblems(json.problems); - } - - useEffect(() => { - init() - }, []); - - return ( -
- - - - - - - - - - {problems.map((prob,index) => ( - - - - - - - - ))} - - -
TitleDifficultyAcceptance
{prob.title}{prob.difficulty}{prob.acceptance}
-
- ) + const [problems, setProblems] = useState([]); + const [problemsFetched, setProblemsFetched] = useState(false) + + const init = async () => { + const response = await fetch(`${backendUrl}/problems`, { + method: "GET", + }); + + await response + .json() + .then((json) => { + setProblems(json.problems); + setProblemsFetched(true) + }) + .catch((e) => { + console.log("error", e, response) + }); + + } + + useEffect(() => { + init() + console.log("initial load", problems) + }, []); + + function renderProblemTable() { + if (problemsFetched) { + return ( + + + Title + Difficulty + Acceptance + + + {problems.map((prob, index) => ( + + + {prob.title} + + {prob.difficulty} + {prob.acceptance} + + ))} + + + ) + } + + return () + } + + return ( +
+ + {renderProblemTable()} +
+
+ ) } export default AllProblemsPage \ No newline at end of file diff --git a/client/src/Components/ProblemsPage/ProblemsPage.css b/client/src/Components/ProblemsPage/ProblemsPage.css index a6bc696..033cc11 100644 --- a/client/src/Components/ProblemsPage/ProblemsPage.css +++ b/client/src/Components/ProblemsPage/ProblemsPage.css @@ -4,6 +4,32 @@ align-items: flex-start; } +.tab { + border-bottom: 2px solid rgba(0, 0, 0, 0.1); + border-radius: 0.5em 0.5em 0 0; + margin: 0; + padding: 1.5em 1em; +} + +.tab.inactive { + color: grey; + font-weight: lighter; +} + +.tab.active { + border-bottom: 2px solid black; + color: black; + font-weight: bolder; +} + +.submission.wrong.answer { + color: red; +} + +.submission.accepted { + color: green; +} + .ques , .code { width: 50%; min-height: 65vh; diff --git a/client/src/Components/ProblemsPage/ProblemsPage.jsx b/client/src/Components/ProblemsPage/ProblemsPage.jsx index 66cedf3..73f27d2 100644 --- a/client/src/Components/ProblemsPage/ProblemsPage.jsx +++ b/client/src/Components/ProblemsPage/ProblemsPage.jsx @@ -1,86 +1,172 @@ import React, {useEffect, useState} from 'react' -import { useParams } from 'react-router-dom' +import {useParams} from 'react-router-dom' import "./ProblemsPage.css" import {backendUrl} from "../../constants.js"; +import Loader from "../../Constants/Loader/Loader.jsx"; const ProblemsPage = () => { - const [CodeSeg, setCodeSeg] = useState("") ; - const { pid } = useParams() ; - const cleanId = pid.substring(1) ; - const [problem, setProblem] = useState(null); - const [submission, setSubmission] = useState(""); + const [CodeSeg, setCodeSeg] = useState(""); + const {pid} = useParams(); + const cleanId = pid.substring(1); + const [problem, setProblem] = useState(null); + const [submission, setSubmission] = useState(""); + const [activeTab, setActiveTab] = useState("description"); + const [submissions, setSubmissions] = useState([]); + const [isSubmissionsLoaded, setIsSubmissionsLoaded] = useState(false) const init = async () => { - const response = await fetch(`${backendUrl}/problem/` + cleanId, { - method: "GET", - }); + const response = await fetch(`${backendUrl}/problem/` + cleanId, { + method: "GET", + }); - const json = await response.json(); - setProblem(json.problem); + const json = await response.json(); + setProblem(json.problem); } - useEffect(() => { - init(); - }, []) - // console.log(cleanId) ; + useEffect(() => { + init(); + }, []) + useEffect(() => { + fetchProblemSubmissions() + }, [activeTab]) - const handleKey = (event) => { - if (event.key == "Tab"){ - event.preventDefault() ; - const { selectionStart , selectionEnd , value } = event.target ; - const val = value.substring(0,selectionStart) + "\t" + value.substring(selectionStart) ; - event.target.value = val; - event.target.selectionStart = event.target.selectionEnd = selectionStart+1; + const fetchProblemSubmissions = async () => { + const response = await fetch(`${backendUrl}/submissions/${cleanId}`, { + method: "GET", + headers: { + "authorization": localStorage.getItem("token") + } + }); + + await response.json() + .then(json => { + const submissions = json.submissions + submissions.forEach(s => { + if (s.status === "AC") { + s.status = "Accepted" + } else if (s.status === "WA") { + s.status = "Wrong Answer" + } + }) + + setSubmissions(submissions) + setIsSubmissionsLoaded(true) + }) + .catch(error => { + return error; + }); + + } + + const handleKey = (event) => { + if (event.key == "Tab") { + event.preventDefault(); + const {selectionStart, selectionEnd, value} = event.target; + const val = value.substring(0, selectionStart) + "\t" + value.substring(selectionStart); + event.target.value = val; + event.target.selectionStart = event.target.selectionEnd = selectionStart + 1; + } + setCodeSeg(event.value); } - setCodeSeg(event.value) ; - } - - return ( -
- - { - problem? ( -
-
-

{problem.title}

-
Description
-

{problem.description}

- Input : {problem.exampleIn} - Output : {problem.exampleOut} + + function renderDescription() { + if (activeTab !== "description") { + setActiveTab("description") + setIsSubmissionsLoaded(false) + } + return ( +
+
+
Description
+
renderSubmissions()}>Submissions
+
+

{problem.description}

+ Input : {problem.exampleIn} + Output : {problem.exampleOut}
-
-

Code Here

-
- - -
+ ) + } + + function renderSubmissions() { + if (activeTab !== "submission") { + setActiveTab("submission") + } + return ( +
+
+
renderDescription()}>Description
+
Submissions
+
+ { + isSubmissionsLoaded ? + + + { + submissions.map((s, idx) => { + return ( + + + + + ) + }) + } + +
{s.status}{s.submission}
+ + : + } + +
-
- ) : - (
The searched Question Doesn't exist
) - } - -
- - ) + ); + } + + return ( +
+ + { + problem ? ( +
+
+

{problem.title}

+ {activeTab === "description" ? renderDescription() : renderSubmissions()} +
+
+

Code Here

+
+ + +
+
+
+ ) : + (
The searched Question Doesn't exist
) + } + +
+ + ) } export default ProblemsPage \ No newline at end of file diff --git a/client/src/Constants/Loader/Loader.css b/client/src/Constants/Loader/Loader.css new file mode 100644 index 0000000..c55558b --- /dev/null +++ b/client/src/Constants/Loader/Loader.css @@ -0,0 +1,26 @@ +.loader-container { + display: flex; + justify-content: center; + align-items: center; +} + +.loader { + top: calc(50% - 4em); + left: calc(50% - 4em); + width: 6em; + height: 6em; + border: 1.1em solid rgba(0, 0, 0, 0.2); + border-left: 1.1em solid #000000; + border-radius: 50%; + animation: load8 1.1s infinite linear; + transition: opacity 0.3s; +} + +@keyframes load8 { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/client/src/Constants/Loader/Loader.jsx b/client/src/Constants/Loader/Loader.jsx new file mode 100644 index 0000000..78ae24c --- /dev/null +++ b/client/src/Constants/Loader/Loader.jsx @@ -0,0 +1,13 @@ +import React from "react"; + +import './Loader.css' + +const Loader = () => { + return ( +
+
+
+ ) +} + +export default Loader \ No newline at end of file