diff --git a/README.md b/README.md index 83f3a207..f8249222 100644 --- a/README.md +++ b/README.md @@ -1,8 +1 @@ -## Full stack assignment - -### Video - -Link to video - https://www.youtube.com/watch?v=569YZm0X5-0 - -### Where to start? -Look at App.jsx inside the src/ folder +Frontend for my fork of peetcode diff --git a/package-lock.json b/package-lock.json index cd606935..4a36cfa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.0", "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^6.11.2" }, "devDependencies": { "@types/react": "^18.0.28", @@ -766,6 +767,14 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, + "node_modules/@remix-run/router": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.2.tgz", + "integrity": "sha512-LzqpSrMK/3JBAVBI9u3NWtOhWNw5AMQfrUFYB0+bDHTSw17z++WJLsPsxAuK+oSddsxk4d7F/JcdDPM1M5YAhA==", + "engines": { + "node": ">=14" + } + }, "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -1226,6 +1235,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.11.2.tgz", + "integrity": "sha512-74z9xUSaSX07t3LM+pS6Un0T55ibUE/79CzfZpy5wsPDZaea1F8QkrsiyRnA2YQ7LwE/umaydzXZV80iDCPkMg==", + "dependencies": { + "@remix-run/router": "1.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.11.2.tgz", + "integrity": "sha512-JNbKtAeh1VSJQnH6RvBDNhxNwemRj7KxCzc5jb7zvDSKRnPWIFj9pO+eXqjM69gQJ0r46hSz1x4l9y0651DKWw==", + "dependencies": { + "@remix-run/router": "1.6.2", + "react-router": "6.11.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -1853,6 +1892,11 @@ } } }, + "@remix-run/router": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.2.tgz", + "integrity": "sha512-LzqpSrMK/3JBAVBI9u3NWtOhWNw5AMQfrUFYB0+bDHTSw17z++WJLsPsxAuK+oSddsxk4d7F/JcdDPM1M5YAhA==" + }, "@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", @@ -2176,6 +2220,23 @@ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true }, + "react-router": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.11.2.tgz", + "integrity": "sha512-74z9xUSaSX07t3LM+pS6Un0T55ibUE/79CzfZpy5wsPDZaea1F8QkrsiyRnA2YQ7LwE/umaydzXZV80iDCPkMg==", + "requires": { + "@remix-run/router": "1.6.2" + } + }, + "react-router-dom": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.11.2.tgz", + "integrity": "sha512-JNbKtAeh1VSJQnH6RvBDNhxNwemRj7KxCzc5jb7zvDSKRnPWIFj9pO+eXqjM69gQJ0r46hSz1x4l9y0651DKWw==", + "requires": { + "@remix-run/router": "1.6.2", + "react-router": "6.11.2" + } + }, "resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", diff --git a/package.json b/package.json index 154dd4dd..208323e3 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ }, "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^6.11.2" }, "devDependencies": { "@types/react": "^18.0.28", diff --git a/src/App.jsx b/src/App.jsx index 7743965b..4ba2c9b9 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,25 +1,13 @@ +import { BrowserRouter, Routes, Route } from 'react-router-dom'; +import Layout from './pages/layout/Layout.jsx'; +import Home from './pages/home/Home.jsx'; +import Login from './pages/login/Login.jsx'; +import Signup from './pages/signup/Signup.jsx'; +import Problemsets from './pages/problemsets/Problemsets.jsx'; +import Problems from './pages/problems/Problems.jsx'; /* * Temporary problems array schema */ -const problems = [{ - title: "201. Bitwise AND of Numbers Range", - difficulty: "Medium", - 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%" - }]; function App() { @@ -32,28 +20,18 @@ function App() { */ return ( -
- Finish the assignment! Look at the comments in App.jsx as a starting point -
+ + + }> + } /> + } /> + } /> + } /> + }/> + + + ) } -// A demo component -function ProblemStatement(props) { - const title = props.title; - const acceptance = props.acceptance; - const difficulty = props.difficulty; - - return - - {title} - - - {acceptance} - - - {difficulty} - - -} export default App diff --git a/src/components/userform/UserForm.css b/src/components/userform/UserForm.css new file mode 100644 index 00000000..bf730891 --- /dev/null +++ b/src/components/userform/UserForm.css @@ -0,0 +1,51 @@ +button { + width: 10rem; + font-size: 1.2rem; +} + +form { + align-items: center; + display: flex; + flex-direction: column; + justfiy-content: center; + width: 100%; +} + +label { + align-items: center; + display: flex; + font-size: 1.2rem; +} + +input { + width: 14rem; + font-size: 1.2rem; +} + +.body { + height: 720px; + align-items: center; +} + +.field { + display: flex; + justify-content: space-around; + width: 100%; +} + +.form-box { + align-items: center; + border-color: black; + border-radius: 2rem; + border-style: solid; + border-width: 0.4rem; + display: flex; + flex-direction: column; + justify-content: space-around; + width: 30rem; + height: 20rem; +} + +.form-type { + text-transform: capitalize; +} \ No newline at end of file diff --git a/src/components/userform/UserForm.jsx b/src/components/userform/UserForm.jsx new file mode 100644 index 00000000..b83f94bb --- /dev/null +++ b/src/components/userform/UserForm.jsx @@ -0,0 +1,24 @@ +import "./UserForm.css"; +import { useRef } from "react"; + +export default function UserForm( {type, onClick} ) { + const usernameRef = useRef(); + const passwordRef = useRef(); + + return ( +
+

{type}

+
+ + +
+
+ + +
+
+ +
+
+ ) +} diff --git a/src/constants/constants.js b/src/constants/constants.js new file mode 100644 index 00000000..0120a6e0 --- /dev/null +++ b/src/constants/constants.js @@ -0,0 +1,3 @@ +export const backendURL = "http://localhost:3000"; +export const languages = ["c", "python", "javascript", "java"]; + diff --git a/src/pages/home/BlogData.jsx b/src/pages/home/BlogData.jsx new file mode 100644 index 00000000..19c36caa --- /dev/null +++ b/src/pages/home/BlogData.jsx @@ -0,0 +1,74 @@ +const blogData = [ + { + title : "Why use C++", + date : "10 July 2023", + content : "C++ is very fast" + }, + { + title : "Why use C++", + date : "10 July 2023", + content : "C++ is very fast" + }, + { + title : "Why use C++ users hate Java", + date : "2 July 2023", + content : "Java is very verbose" + }, + { + title : "Why Java is better than C++", + date : "5 March 2023", + content : "No Pointers and cross platforms" + }, + { + title : "Why Ai will take your job", + date : "1 March 2023", + content : "Because Ai can do alot of automation, that required humans" + }, + { + title : "What jobs will Ai Create", + date : "28 Feb 2023", + content : "Ai and Ml engineering jobs" + }, + { + title : "Is Python the real chad or Javascript", + date : "15 Feb 2023", + content : "Its like asking is IronMan better than Thor or Captain America" + }, + { + title : "Why use C++", + date : "10 July 2023", + content : "C++ is very fast" + }, + { + title : "Why use C++", + date : "10 July 2023", + content : "C++ is very fast" + }, + { + title : "Why use C++ users hate Java", + date : "2 July 2023", + content : "Java is very verbose" + }, + { + title : "Why Java is better than C++", + date : "5 March 2023", + content : "No Pointers and cross platforms" + }, + { + title : "Why Ai will take your job", + date : "1 March 2023", + content : "Because Ai can do alot of automation, that required humans" + }, + { + title : "What jobs will Ai Create", + date : "28 Feb 2023", + content : "Ai and Ml engineering jobs" + }, + { + title : "Is Python the real chad or Javascript", + date : "15 Feb 2023", + content : "Its like asking is IronMan better than Thor or Captain America" + }, +] + +export default blogData; diff --git a/src/pages/home/Home.css b/src/pages/home/Home.css new file mode 100644 index 00000000..829060d3 --- /dev/null +++ b/src/pages/home/Home.css @@ -0,0 +1,29 @@ +.blog { + background-color: var(--secondary); + border-style: solid solid none solid; + border-width: 5px; + display: flex; + height: 7rem; + flex-direction: column; + justify-content: space-around; + padding: 1rem; + box-shadow: 10px 10px 8px #888888; +} +.blog:first-child { + border-radius: 1rem 1rem 0 0; +} +.blog:last-child { + border-style: solid; + border-radius: 0 0 1rem 1rem; +} + +.blogs { + margin-top: 4rem; + margin-bottom: 7rem; + +} + +.main { + width: 100%; +} + diff --git a/src/pages/home/Home.jsx b/src/pages/home/Home.jsx new file mode 100644 index 00000000..82074a00 --- /dev/null +++ b/src/pages/home/Home.jsx @@ -0,0 +1,28 @@ +import blogData from "./BlogData.jsx"; +import "./Home.css"; + +function Blogs( {blogData} ) { + const blogs = blogData.map((blog, key) => { + return ( +
  • +

    {blog.date}

    +

    {blog.title}

    +

    {blog.content}

    +
  • + ) + }) + + return ( +
      + {blogs} +
    + ) +} + +export default function Home() { + return ( +
    + +
    + ) +} diff --git a/src/pages/layout/Layout.css b/src/pages/layout/Layout.css new file mode 100644 index 00000000..60ab1f2c --- /dev/null +++ b/src/pages/layout/Layout.css @@ -0,0 +1,70 @@ +:root { + font-size: 16px; + --primary: #C4DFDF; + --secondary: #D2E9E9; +} + +* { + margin: 0; + padding: 0; +} + +a { + text-decoration: none; +} + +li { + list-style: none; +} + +.body { + display: flex; + justify-content: center; + width: 100%; + height: max-content; +} + +.container { + margin-left: auto; + margin-right: auto; + width: 90%; +} + +.fill-page { + height: 100%; +} + +.nav { + display: flex; + flex-direction: row; +} + +.navbar { + background-color: var(--primary); + display: flex; + justify-content: center; + width: 100%; + height: 5rem; +} + +.brand { + align-items: center; + display: flex; + font-size: 3rem; +} + +.nav-item { + align-items: center; + display: flex; + font-size: 1.5rem; + justify-content: center; +} + +.nav-list { + display: flex; + justify-content: space-between; + width: 24rem; + height: 100%; + margin: 0 0 0 auto; +} + diff --git a/src/pages/layout/Layout.jsx b/src/pages/layout/Layout.jsx new file mode 100644 index 00000000..abf8517e --- /dev/null +++ b/src/pages/layout/Layout.jsx @@ -0,0 +1,28 @@ +import { useState } from 'react'; +import { Outlet, Link } from 'react-router-dom'; +import './Layout.css'; + +function Navbar() { + return ( +
    +
    +
    Peetcode
    +
      +
    1. Home
    2. +
    3. Login
    4. +
    5. Signup
    6. +
    7. Problemsets
    8. +
    +
    +
    + ) +} + +export default function Layout() { + return ( + <> + + + + ) +} diff --git a/src/pages/login/Login.css b/src/pages/login/Login.css new file mode 100644 index 00000000..755ca2ad --- /dev/null +++ b/src/pages/login/Login.css @@ -0,0 +1,6 @@ +.center { + display: flex; + justify-content: center; + align-items: center; + margin-top: 13rem; +} diff --git a/src/pages/login/Login.jsx b/src/pages/login/Login.jsx new file mode 100644 index 00000000..2a389cf2 --- /dev/null +++ b/src/pages/login/Login.jsx @@ -0,0 +1,36 @@ +import { backendURL } from "../../constants/constants.js"; +import { useState } from "react"; +import UserForm from "../../components/userform/UserForm.jsx"; +import "./Login.css"; + +export default function Login() { + const [message, setMessage] = useState(""); + + async function handleLogin(username, password) { + const response = await fetch( + `${backendURL}/login`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + username: username, + password: password + }) + }) + const json = await response.json(); + localStorage.setItem("token", json.token); + setMessage(() => json.message); + } + + return ( + <> +
    + +
    +

    + {message} +

    + + ) +} diff --git a/src/pages/problems/CodeArea.jsx b/src/pages/problems/CodeArea.jsx new file mode 100644 index 00000000..bb3c9ea4 --- /dev/null +++ b/src/pages/problems/CodeArea.jsx @@ -0,0 +1,40 @@ +import { useRef, useState } from "react"; +import { backendURL, languages } from "../../constants/constants.js" +import { useParams } from 'react-router-dom'; + + +async function handleSubmit(id, language, code) { + fetch(`${backendURL}/problems/${id}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": localStorage.getItem("token") + }, + body: JSON.stringify({ + id, + language, + code + }) + }) +} + +export default function CodeArea({ updateData }) { + const [language, setLanguage] = useState("c") + const codeRef = useRef(null); + const { id } = useParams(); + + return ( +
    + +
    +