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
2,205 changes: 2,176 additions & 29 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-router-dom": "^6.11.2"
},
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@unocss/preset-icons": "^0.52.4",
"@vitejs/plugin-react": "^3.1.0",
"autoprefixer": "^10.4.14",
"postcss": "^8.4.23",
"tailwindcss": "^3.3.2",
"vite": "^4.2.0"
}
}
6 changes: 6 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
88 changes: 40 additions & 48 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,51 @@
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Signup from "./pages/Signup";
import Login from "./pages/Login";
import Navbar from "./components/Navbar";
import ProblemSet from "./pages/ProblemSet";
import Problem from "./pages/Problem";

/*
* Temporary problems array schema
*/
const problems = [{
const problems = [
{
title: "201. Bitwise AND of Numbers Range",
difficulty: "Medium",
acceptance: "42%"
},{
acceptance: "42%",
},
{
title: "201. Bitwise AND of Numbers Range",
difficulty: "Medium",
acceptance: "412%"
},
{
title: "202. Happy Number",
difficulty: "Easy",
acceptance: "54.9%"
},
{
title: "203. Remove Linked List Elements",
difficulty: "Hard",
acceptance: "42%"
}];

acceptance: "412%",
},
{
title: "202. Happy Number",
difficulty: "Easy",
acceptance: "54.9%",
},
{
title: "203. Remove Linked List Elements",
difficulty: "Hard",
acceptance: "42%",
},
];

function App() {

/* Add routing here, routes look like -
/login - Login page
/signup - Signup page
/problemset/all/ - All problems (see problems array above)
/problems/:problem_slug - A single problem page
*/

return (
<div>
Finish the assignment! Look at the comments in App.jsx as a starting point
</div>
)
return (
<BrowserRouter>
<div className="bg-slate-100 h-screen flex flex-col">
<Navbar />
<Routes>
<Route path="/" element={<Signup />} />
<Route path="/signup" element={<Signup />} />
<Route path="/login" element={<Login />} />
<Route path="/problems" element={<ProblemSet />} />
<Route path="/problems/:problemId" element={<Problem />} />
</Routes>
</div>
</BrowserRouter>
);
}

// A demo component
function ProblemStatement(props) {
const title = props.title;
const acceptance = props.acceptance;
const difficulty = props.difficulty;

return <tr>
<td>
{title}
</td>
<td>
{acceptance}
</td>
<td>
{difficulty}
</td>
</tr>
}
export default App
export default App;
14 changes: 14 additions & 0 deletions src/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";

const Button = ({ text, onClick }) => {
return (
<button
onClick={onClick}
className="bg-gradient-to-tr from-slate-900 to-slate-500 hover:bg-gradient-to-bl text-white font-bold py-2 px-4 rounded"
>
{text}
</button>
);
};

export default Button;
22 changes: 22 additions & 0 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import { SiLeetcode } from "react-icons/si";
import { Link } from "react-router-dom";

const Navbar = () => {
return (
<nav className="p-4 bg-white shadow-sm">
<ul className="flex gap-8 justify-center">
<Link to="/">
<span className="flex items-center gap-1 font-mono">
<SiLeetcode className="text-xl" /> Neetcode
</span>
</Link>
<Link to="/problems">Problems</Link>
<Link to="/signup">Signup</Link>
<Link to="/login">Login</Link>
</ul>
</nav>
);
};

export default Navbar;
17 changes: 17 additions & 0 deletions src/components/Tag.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react";

const Tag = ({ difficulty }) => {
const color =
difficulty === "Easy"
? "text-green-500"
: difficulty === "Medium"
? "text-yellow-500"
: "text-red-500";
return (
<span className={`text-sm p-2 ${color}`}>
{difficulty}
</span>
);
};

export default Tag;
14 changes: 14 additions & 0 deletions src/components/TextInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";

const TextInput = ({ placeholder, onChange, type = "text" }) => {
return (
<input
className="p-3 outline outline-1 hover:outline-2 focus:outline-2 rounded-sm outline-slate-300 hover:outline-slate-400 focus:outline-slate-500"
onChange={onChange}
placeholder={placeholder}
type={type}
/>
);
};

export default TextInput;
42 changes: 42 additions & 0 deletions src/data/problemSet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export const problemSet = [
[
{
id: 1,
title: "201. Two Sum",
difficulty: "Hard",
acceptance: 56,
},
{
id: 2,
title: "283. Move Zeroes",
difficulty: "Easy",
acceptance: 62,
},
{
id: 3,
title: "15. 3Sum",
difficulty: "Medium",
acceptance: 29,
},
],
[
{
id: 4,
title: "1. Find Median from Data Stream",
difficulty: "Hard",
acceptance: 26,
},
{
id: 5,
title: "2. Add Two Numbers",
difficulty: "Medium",
acceptance: 72,
},
{
id: 6,
title: "3. Longest Substring Without Repeating Characters",
difficulty: "Medium",
acceptance: 55,
},
],
];
3 changes: 3 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
28 changes: 28 additions & 0 deletions src/pages/Login.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import TextInput from "../components/TextInput";
import Button from "../components/Button";
import { Link } from "react-router-dom";
import { SiLeetcode } from "react-icons/si";
const Login = () => {
return (
<div className="flex-grow flex items-center justify-center">
<form className="p-8 rounded-xl w-[30rem] bg-white flex flex-col gap-6">
<div className="text-slate-800 flex flex-col justify-center items-center gap-1">
<SiLeetcode className="text-5xl" />
<h1 className="font-mono text-2xl">Neetcode</h1>
</div>
<TextInput placeholder={"Username"} />
<TextInput placeholder={"Password"} type="password" />
<Button text={"Log In"} />
<div className="flex justify-center text-sm gap-2">
<p className="text-slate-500">Don't have an account?</p>
<Link className="text-slate-800 font-bold" to="/signup">
Signup
</Link>
</div>
</form>
</div>
);
};

export default Login;
36 changes: 36 additions & 0 deletions src/pages/Problem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { useParams } from "react-router-dom";
import Button from "../components/Button";

const Problem = () => {
const { problemId } = useParams();
return (
<div className="grid grid-cols-3 gap-4 m-4 h-full">
<div className="rounded-md bg-white h-full p-4">
<h1 className="text-xl">Problem Title</h1>
<p className="text-sm py-2">
Problem Description: ljalsdkj kjalskdfjlakf alkdfj akdj fakdfj alkdfj
akld fjalkdf jakldfjakldf jad
</p>
</div>
<div className="rounded-md bg-white col-span-2 p-4 flex flex-col gap-4">
<h1 className="text-xl">Code Here</h1>
<textarea
className="w-full flex-grow resize-none outline rounded-md outline-slate-400 focus:outline-slate-800 p-4"
placeholder="Code Here"
/>
<div className="w-full flex gap-4 flex">
<select className="rounded-md mr-auto outline-slate-400 focus:outline-slate-800 p-2">
<option value="cpp">C++</option>
<option value="java">Java</option>
<option value="python">Python</option>
</select>
<Button text="Run Code" />
<Button text="Submit" />
</div>
</div>
</div>
);
};

export default Problem;
82 changes: 82 additions & 0 deletions src/pages/ProblemSet.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { useEffect, useState } from "react";
import { problemSet } from "../data/problemSet.js";
import Tag from "../components/Tag.jsx";
import { AiOutlineLeft, AiOutlineRight } from "react-icons/ai";

const ProblemSet = () => {
const [page, setPage] = useState(0);

const onProblemClick = (problemId) => () => {
window.location.href = `/problems/${problemId}`;
};

const previousPage = () => setPage((page) => page - 1);
const nextPage = () => setPage((page) => page + 1);

useEffect(() => {
console.log(page);
}, [page]);

return (
<div className="m-12 bg-white rounded-md h-full">
<table className="w-full h-full flex flex-col">
<thead>
<tr className="grid grid-cols-4 px-6 py-2 border-b">
<th className="col-span-2 text-start">Title</th>
<th>Difficulty</th>
<th>Acceptance</th>
</tr>
</thead>
<tbody className="flex-grow">
{problemSet[page].length === 0 && (
<div className="flex items-center justify-center text-slate-500 py-4">
No Problems Available
</div>
)}
{problemSet[page].map((problem, index) => (
<tr
key={index}
onClick={onProblemClick(problem.id)}
className="hover:bg-slate-50 text-slate-600 text-sm cursor-pointer grid grid-cols-4 px-6 py-4 text-center"
>
<td className="col-span-2 text-start">{problem.title}</td>
<td>
<Tag difficulty={problem.difficulty} />
</td>
<td>{problem.acceptance}%</td>
</tr>
))}
</tbody>
<tfoot>
<tr className="flex flex-row-reverse items-center">
<td className="px-6 py-4">
<button
disabled={page === 1}
onClick={nextPage}
className={`bg-slate-600 text-white rounded-md p-2 hover:bg-slate-800 ${
page === 1 && "opacity-50 cursor-not-allowed"
}`}
>
<AiOutlineRight />
</button>
</td>
<td>{page + 1}</td>
<td className="px-6 py-4">
<button
disabled={page === 0}
className={`bg-slate-600 text-white rounded-md p-2 hover:bg-slate-800 ${
page === 0 && "opacity-50 cursor-not-allowed"
}`}
onClick={previousPage}
>
<AiOutlineLeft />
</button>
</td>
</tr>
</tfoot>
</table>
</div>
);
};

export default ProblemSet;
Loading