├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── netlify.toml ├── package-lock.json ├── package.json ├── public ├── favicon │ ├── about.txt │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ └── site.webmanifest └── index.html └── src ├── App.js ├── assets ├── atcoder.png ├── codechef.png ├── codeforces.png ├── csacademy.png ├── geeksforgeeks.png ├── google.png ├── hackerearth.png ├── hackerrank.png ├── leetcode.png ├── placeholder.png └── topcoder.png ├── components ├── Footer.js ├── Header.js ├── LeetCode │ ├── ProblemsGraph.js │ └── UserInfo.js ├── PlatformCard.js ├── RankGraph.js ├── SubmissionList.js └── UserInfo.js ├── index.css ├── index.js ├── pages ├── Blog │ ├── Blog.css │ └── Blog.js ├── CodeForces │ ├── CodeForces.css │ └── CodeForces.js ├── Contests │ ├── Contests.css │ ├── Ongoing.js │ └── Upcoming.js ├── Error404 │ ├── Error.css │ └── Error.js ├── Home │ └── Home.js ├── LeetCode │ ├── LeetCode.css │ └── LeetCode.js └── UserStats │ ├── UserStats.css │ └── UserStats.js └── utils └── Colors.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines for UpCoding-Web 👨💻 2 | 3 | ## 👨💻 Prerequisite Skills to Contribute 4 | 5 | - [Git](https://git-scm.com/) 6 | - [Basic JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) 7 | 8 | ### Contribute in Documents 9 | 10 | - [Markdown](https://www.markdownguide.org/basic-syntax/) 11 | 12 | --- 13 | 14 | ## 💥 How to Contribute 15 | 16 | [](https://github.com/sahanmndl/UpCoding-Web/pulls) 17 | [](https://github.com/sahanmndl/UpCoding-Web) 18 | 19 | - Take a look at the existing [Issues](https://github.com/sahanmndl/UpCoding-Web/issues) or [create a new issue](https://github.com/sahanmndl/UpCoding-Web/issues/new/choose)! 20 | - [Fork the Repo](https://github.com/sahanmndl/UpCoding-Web/fork). Then, create a branch for any issue that you are working on. Finally, commit your work. 21 | - Create a **[Pull Request](https://github.com/sahanmndl/UpCoding-Web/compare)** (_PR_), which will be promptly reviewed and given suggestions for improvements by the community. 22 | - Add screenshots or screen captures to your Pull Request to help us understand the effects of the changes proposed in your PR. 23 | 24 | --- 25 | 26 | ## ⭐ HOW TO MAKE A PULL REQUEST: 27 | 28 | **1.** Start by making a Fork of the [**UpCoding-Web**](https://github.com/sahanmndl/UpCoding-Web) repository. Click on the Fork symbol at the top right corner. 29 | 30 | **2.** Clone your new fork of the repository in the terminal/CLI on your computer with the following command: 31 | 32 | ```bash 33 | git clone https://github.com//UpCoding-Web 34 | ``` 35 | 36 | **3.** Navigate to the newly created LinkFree project directory: 37 | 38 | ```bash 39 | cd UpCoding-Web 40 | ``` 41 | 42 | **4.** Create a new branch: 43 | 44 | ```bash 45 | git checkout -b YourBranchName 46 | ``` 47 | 48 | ⚠️ **Make sure** not to run the commands `git add .` or `git add *`. Instead, stage your changes for each file/folder 49 | 50 | **5.** Add those changes to the branch you just created using the git add command: 51 | 52 | ```bash 53 | git add . 54 | ``` 55 | 56 | - After git add command see status with git status command: 57 | 58 | ```bash 59 | git status 60 | ``` 61 | 62 | **6.** Now commit those changes using the git commit command:: 63 | 64 | ```bash 65 | git commit -m "" 66 | ``` 67 | 68 | **7.** Push your local commits to the remote repository: 69 | 70 | ```bash 71 | git push origin YourBranchName 72 | ``` 73 | 74 | **8.** Create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)! 75 | 76 | **9.** **Congratulations!** You've made your first contribution to [**UpCoding-Web**](https://github.com/sahanmndl/UpCoding-Web/graphs/contributors)! 🙌🏼 77 | 78 | **_:trophy: After this, the maintainers will review the PR and will merge it if it helps move the UpCoding project forward. Otherwise, it will be given constructive feedback and suggestions for the changes needed to add the PR to the codebase._** 79 | 80 | --- 81 | 82 | ## Style Guide for Git Commit Messages :memo: 83 | 84 | **How you can add more value to your contribution logs:** 85 | 86 | - Use the present tense. (Example: "Add feature" instead of "Added feature") 87 | - Use the imperative mood. (Example: "Move item to...", instead of "Moves item to...") 88 | - Limit the first line (also called the Subject Line) to _50 characters or less_. 89 | - Capitalize the Subject Line. 90 | - Separate subject from body with a blank line. 91 | - Do not end the subject line with a period. 92 | - Wrap the body at _72 characters_. 93 | - Use the body to explain the _what_, _why_, _vs_, and _how_. 94 | - Reference [Issues](https://github.com/sahanmndl/UpCoding-Web/issues) and [Pull Requests](https://github.com/sahanmndl/UpCoding-Web/pulls) liberally after the first line. 95 | 96 | --- 97 | 98 | ## 💥 Issues 99 | 100 | In order to discuss changes, you are welcome to [open an issue](https://github.com/sahanmndl/UpCoding-Web/issues/new/choose) about what you would like to contribute. Enhancements are always encouraged and appreciated. 101 | 102 | ## All the best! 🥇 103 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Sahan Mondal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UpCoding 2 | 3 |  4 |  5 | 6 | Mobile App: (https://github.com/sahanmndl/UpCoding) 7 | 8 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 9 | 10 | ## Available Scripts 11 | 12 | In the project directory, you must install a package: 13 | 14 | ### `npm install` 15 | 16 | To start the website in your localhost : 17 | 18 | ### `npm start` 19 | 20 | Runs the app in the development mode.\ 21 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 22 | 23 | The page will reload when you make changes.\ 24 | You may also see any lint errors in the console. 25 | 26 | ### `npm run build` 27 | 28 | Builds the app for production to the `build` folder.\ 29 | It correctly bundles React in production mode and optimizes the build for the best performance. 30 | 31 | The build is minified and the filenames include the hashes.\ 32 | Your app is ready to be deployed! 33 | 34 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 35 | 36 | 37 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [[redirects]] 2 | from = "/*" 3 | to = "/" 4 | status = 200 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "upcoding", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@emotion/react": "^11.10.4", 7 | "@emotion/styled": "^11.10.4", 8 | "@mui/icons-material": "^5.10.6", 9 | "@mui/lab": "^5.0.0-alpha.102", 10 | "@mui/material": "^5.10.8", 11 | "@testing-library/jest-dom": "^5.16.5", 12 | "@testing-library/react": "^13.4.0", 13 | "@testing-library/user-event": "^13.5.0", 14 | "calendar-link": "^2.2.0", 15 | "chart.js": "^4.4.0", 16 | "moment": "^2.29.4", 17 | "react": "^18.2.0", 18 | "react-chartjs-2": "^5.2.0", 19 | "react-dom": "^18.2.0", 20 | "react-dropdown": "^1.11.0", 21 | "react-helmet": "^6.1.0", 22 | "react-router-dom": "^6.4.2", 23 | "react-scripts": "5.0.1", 24 | "web-vitals": "^2.1.4" 25 | }, 26 | "scripts": { 27 | "start": "react-scripts start", 28 | "build": "react-scripts build", 29 | "test": "react-scripts test", 30 | "postbuild": "react-snap", 31 | "eject": "react-scripts eject" 32 | }, 33 | "eslintConfig": { 34 | "extends": [ 35 | "react-app", 36 | "react-app/jest" 37 | ] 38 | }, 39 | "browserslist": { 40 | "production": [ 41 | ">0.2%", 42 | "not dead", 43 | "not op_mini all" 44 | ], 45 | "development": [ 46 | "last 1 chrome version", 47 | "last 1 firefox version", 48 | "last 1 safari version" 49 | ] 50 | }, 51 | "devDependencies": { 52 | "react-snap": "^1.23.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /public/favicon/about.txt: -------------------------------------------------------------------------------- 1 | This favicon was generated using the following graphics from Twitter Twemoji: 2 | 3 | - Graphics Title: 1f4bb.svg 4 | - Graphics Author: Copyright 2020 Twitter, Inc and other contributors (https://github.com/twitter/twemoji) 5 | - Graphics Source: https://github.com/twitter/twemoji/blob/master/assets/svg/1f4bb.svg 6 | - Graphics License: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/) 7 | -------------------------------------------------------------------------------- /public/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/public/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/favicon/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/public/favicon/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/public/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /public/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/public/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/public/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/public/favicon/favicon.ico -------------------------------------------------------------------------------- /public/favicon/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | UpCoding 13 | 14 | 15 | You need to enable JavaScript to run this app. 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | 2 | import React, { Component } from 'react'; 3 | import Home from "./pages/Home/Home"; 4 | import { Helmet } from 'react-helmet'; 5 | 6 | 7 | function App() { 8 | return ( 9 | 10 | ); 11 | } 12 | 13 | export default App; 14 | -------------------------------------------------------------------------------- /src/assets/atcoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/atcoder.png -------------------------------------------------------------------------------- /src/assets/codechef.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/codechef.png -------------------------------------------------------------------------------- /src/assets/codeforces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/codeforces.png -------------------------------------------------------------------------------- /src/assets/csacademy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/csacademy.png -------------------------------------------------------------------------------- /src/assets/geeksforgeeks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/geeksforgeeks.png -------------------------------------------------------------------------------- /src/assets/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/google.png -------------------------------------------------------------------------------- /src/assets/hackerearth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/hackerearth.png -------------------------------------------------------------------------------- /src/assets/hackerrank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/hackerrank.png -------------------------------------------------------------------------------- /src/assets/leetcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/leetcode.png -------------------------------------------------------------------------------- /src/assets/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/placeholder.png -------------------------------------------------------------------------------- /src/assets/topcoder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahanmndl/UpCoding-Web/987cb0e851d8d4c53a9fc76bbb6a39696799b8b0/src/assets/topcoder.png -------------------------------------------------------------------------------- /src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import { React } from "react"; 2 | import { Box, Typography, IconButton } from "@mui/material"; 3 | import Colors from "../utils/Colors"; 4 | import { Code, Facebook, GitHub, Instagram, Twitter } from "@mui/icons-material"; 5 | 6 | const Footer = ({darkmode}) => { 7 | return ( 8 | 14 | 15 | 18 | 25 | UPCODING 26 | 27 | 28 | 29 | 32 | window.open( 33 | "https://instagram.com/", 34 | "_blank" 35 | ) 36 | } 37 | > 38 | 39 | 40 | 43 | window.open( 44 | "https://github.com/sahanmndl/UpCoding-Web", 45 | "_blank" 46 | ) 47 | } 48 | > 49 | 50 | 51 | 54 | window.open( 55 | "https://twitter.com/", 56 | "_blank" 57 | ) 58 | } 59 | > 60 | 61 | 62 | 65 | window.open( 66 | "https://facebook.com/", 67 | "_blank" 68 | ) 69 | } 70 | > 71 | 72 | 73 | 74 | 75 | 76 | © Copyright 2023. All rights are reserved. 77 | 78 | 79 | 80 | ); 81 | }; 82 | 83 | export default Footer; 84 | -------------------------------------------------------------------------------- /src/components/Header.js: -------------------------------------------------------------------------------- 1 | import { React, useMemo } from "react"; 2 | import { Code, GitHub } from "@mui/icons-material"; 3 | import { 4 | AppBar, 5 | Box, 6 | Button, 7 | IconButton, 8 | Toolbar, 9 | Typography, 10 | MenuItem, 11 | ListItemIcon, 12 | TextField, 13 | InputAdornment, 14 | Select, 15 | ListSubheader, 16 | } from "@mui/material"; 17 | import { Link, useLocation } from "react-router-dom"; 18 | import Colors from "../utils/Colors"; 19 | import { styled } from "@mui/material/styles"; 20 | import FormGroup from "@mui/material/FormGroup"; 21 | import FormControlLabel from "@mui/material/FormControlLabel"; 22 | import Switch from "@mui/material/Switch"; 23 | import { useState } from "react"; 24 | import SearchIcon from "@mui/icons-material/Search"; 25 | import Tooltip from "@mui/material/Tooltip"; 26 | 27 | const MaterialUISwitch = styled(Switch)(({ theme }) => ({ 28 | width: 62, 29 | height: 34, 30 | padding: 7, 31 | "& .MuiSwitch-switchBase": { 32 | margin: 1, 33 | padding: 0, 34 | transform: "translateX(6px)", 35 | "&.Mui-checked": { 36 | color: "#fff", 37 | transform: "translateX(22px)", 38 | "& .MuiSwitch-thumb:before": { 39 | backgroundImage: `url('data:image/svg+xml;utf8,')`, 42 | }, 43 | "& + .MuiSwitch-track": { 44 | opacity: 1, 45 | backgroundColor: theme.palette.mode === "dark" ? "#8796A5" : "#aab4be", 46 | }, 47 | }, 48 | }, 49 | "& .MuiSwitch-thumb": { 50 | backgroundColor: theme.palette.mode === "dark" ? "#003892" : "#001e3c", 51 | width: 32, 52 | height: 32, 53 | "&:before": { 54 | content: "''", 55 | position: "absolute", 56 | width: "100%", 57 | height: "100%", 58 | left: 0, 59 | top: 0, 60 | backgroundRepeat: "no-repeat", 61 | backgroundPosition: "center", 62 | backgroundImage: `url('data:image/svg+xml;utf8,')`, 65 | }, 66 | }, 67 | "& .MuiSwitch-track": { 68 | opacity: 1, 69 | backgroundColor: theme.palette.mode === "dark" ? "#8796A5" : "#aab4be", 70 | borderRadius: 20 / 2, 71 | }, 72 | })); 73 | 74 | const customSelectStyle = { 75 | "& .MuiOutlinedInput-notchedOutline": { 76 | border: "none", // Remove the border 77 | }, 78 | "&:hover .MuiOutlinedInput-notchedOutline": { 79 | border: "none", // Remove the hover border as well 80 | }, 81 | "& .MuiSelect-select": { 82 | paddingRight: "24px", // Add some space for the arrow icon 83 | }, 84 | }; 85 | 86 | const Header = ({ darkmode, toggle }) => { 87 | const location = useLocation(); 88 | const [anchorEl, setAnchorEl] = useState(null); 89 | const [searchQuery, setSearchQuery] = useState(""); 90 | 91 | const containsText = (text, searchText) => 92 | text.toLowerCase().indexOf(searchText.toLowerCase()) > -1; 93 | 94 | const allOptions = [ 95 | // "Leetcode", 96 | // "Codeforces", 97 | // "GeeksForGeeks" 98 | { 99 | value: "leetcode", 100 | label: "LeetCode", 101 | url: "https://leetcode.com/problemset/all/", 102 | icon: require("../assets/leetcode.png"), 103 | }, 104 | { 105 | value: "codeforces", 106 | label: "Codeforces", 107 | url: "https://codeforces.com/problemset", 108 | icon: require("../assets/codeforces.png"), 109 | }, 110 | { 111 | value: "geeksforgeeks", 112 | label: "GeeksForGeeks", 113 | url: "https://practice.geeksforgeeks.org/explore?page=1&sortBy=submissions", 114 | icon: require("../assets/geeksforgeeks.png"), 115 | }, 116 | ]; 117 | 118 | const [selectedOption, setSelectedOption] = useState(allOptions[0]); 119 | 120 | const [searchText, setSearchText] = useState(""); 121 | const displayedOptions = useMemo( 122 | () => allOptions.filter((option) => containsText(option.label, searchText)), 123 | [searchText] 124 | ); 125 | 126 | const handleSearchInputChange = (event) => { 127 | setSearchQuery(event.target.value); 128 | }; 129 | 130 | const handleMenuClick = (event) => { 131 | setAnchorEl(event.currentTarget); 132 | }; 133 | 134 | const handleMenuClose = () => { 135 | setAnchorEl(null); 136 | }; 137 | 138 | const handleMenuItemClick = (url) => { 139 | window.open(url, "_blank"); 140 | handleMenuClose(); 141 | }; 142 | 143 | return ( 144 | 156 | 160 | 163 | 166 | 177 | UPCODING 178 | 179 | 180 | 183 | 184 | 187 | 199 | Upcoming 200 | 201 | 202 | 203 | 204 | 207 | 219 | Ongoing 220 | 221 | 222 | 223 | 224 | 227 | 239 | User Stats 240 | 241 | 242 | 243 | 244 | { 252 | const selected = allOptions.find( 253 | (option) => option.label === e.target.value 254 | ); 255 | setSelectedOption(selected); 256 | }} 257 | onClose={() => setSearchText("")} 258 | renderValue={() => "Practice"} 259 | > 260 | 261 | 270 | 271 | 272 | ), 273 | }} 274 | onChange={(e) => setSearchText(e.target.value)} 275 | onKeyDown={(e) => { 276 | if (e.key !== "Escape") { 277 | // Prevents autoselecting item while typing (default Select behaviour) 278 | e.stopPropagation(); 279 | } 280 | }} 281 | /> 282 | 283 | {displayedOptions.map((option, i) => ( 284 | { 288 | window.open(option.url, "_blank"); 289 | handleMenuClose(); 290 | }} 291 | > 292 | 293 | 299 | 300 | {option.label} 301 | 302 | ))} 303 | 304 | 305 | 306 | 307 | 310 | window.open( 311 | "https://github.com/sahanmndl/UpCoding-Web", 312 | "_blank" 313 | ) 314 | } 315 | > 316 | 317 | 318 | 319 | 320 | 321 | 322 | 329 | } 330 | /> 331 | 332 | 333 | 334 | 335 | 336 | ); 337 | }; 338 | 339 | export default Header; 340 | -------------------------------------------------------------------------------- /src/components/LeetCode/ProblemsGraph.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Bar } from "react-chartjs-2"; 3 | import { CategoryScale } from "chart.js"; 4 | import Chart from "chart.js/auto"; 5 | 6 | const ProblemsGraph = ({ darkmode, params }) => { 7 | const options = { 8 | plugins: { 9 | title: { 10 | display: true, 11 | text: 'Chart.js Bar Chart - Stacked', 12 | }, 13 | }, 14 | responsive: true, 15 | scales: { 16 | x: { 17 | stacked: true, 18 | }, 19 | y: { 20 | stacked: true, 21 | }, 22 | }, 23 | }; 24 | 25 | const data = { 26 | labels: ["Easy", "Medium", "Hard"], 27 | datasets: [ 28 | { 29 | label: "Completed", 30 | data: [params.easySolved, params.mediumSolved, params.hardSolved], 31 | backgroundColor: "#0000ff", 32 | }, 33 | { 34 | label: "Missing", 35 | data: [params.totalEasy - params.easySolved, params.totalMedium - params.mediumSolved, params.totalHard - params.hardSolved], 36 | backgroundColor: "#0000ff40", 37 | 38 | }, 39 | ] 40 | } 41 | 42 | return ( 43 | <> 44 | 45 | > 46 | ); 47 | }; 48 | 49 | export default ProblemsGraph; 50 | -------------------------------------------------------------------------------- /src/components/LeetCode/UserInfo.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Avatar, 4 | Stack, 5 | TableContainer, 6 | TableRow, 7 | TableCell, 8 | TableBody, 9 | Table, 10 | } from "@mui/material"; 11 | 12 | const UserInfo = ({ darkmode, params }) => { 13 | const candidate = [ 14 | { label: "Easy Problems", value: params.easySolved + " / " + params.totalEasy }, 15 | { label: "Medium Problems", value: params.mediumSolved + " / " + params.totalMedium }, 16 | { label: "Hard Problems", value: params.hardSolved + " / " + params.totalHard }, 17 | { label: "Acceptance Rate", value: params.acceptanceRate + "%" }, 18 | { label: "Ranking", value: params.ranking }, 19 | { label: "Contribution Points", value: params.contributionPoints }, 20 | { label: "Reputation", value: params.reputation }, 21 | ]; 22 | return ( 23 | <> 24 | 29 | 30 | 38 | 39 | 44 | @{params.username} 45 | 46 | 52 | {candidate.map((info, index) => ( 53 | 63 | {info.label} 64 | {" : "} 65 | {info.value} 66 | 67 | ))} 68 | 69 | > 70 | ); 71 | }; 72 | 73 | export default UserInfo; 74 | -------------------------------------------------------------------------------- /src/components/PlatformCard.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Button, 4 | Card, 5 | CardActions, 6 | CardContent, 7 | CardMedia, 8 | Typography, 9 | } from "@mui/material"; 10 | 11 | const PlatformCard = ({ image, caption, darkmode, children }) => { 12 | return ( 13 | 14 | 24 | 25 | 26 | {caption} 27 | 28 | 29 | Check user statistics on {caption} 30 | 31 | 32 | 33 | {children} 34 | 35 | 36 | ); 37 | }; 38 | 39 | export default PlatformCard; 40 | -------------------------------------------------------------------------------- /src/components/RankGraph.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Line } from "react-chartjs-2"; 3 | import { CategoryScale } from "chart.js"; 4 | import Chart from "chart.js/auto"; 5 | 6 | const RankGraph = ({ darkmode, params }) => { 7 | const formatTime = (seconds) => { 8 | var newDate = new Date(); 9 | newDate.setTime(seconds * 1000); 10 | const dateString = newDate.toJSON().slice(0, 10); 11 | return dateString; 12 | }; 13 | 14 | const data = { 15 | labels: params.map((item) => formatTime(item.ratingUpdateTimeSeconds)), 16 | datasets: [ 17 | { 18 | label: "Rating", 19 | data: params.map((item) => item.newRating), 20 | fill: false, 21 | backgroundColor: "rgba(75,192,192,0.2)", 22 | borderColor: "rgba(75,192,192,1)", 23 | }, 24 | ], 25 | }; 26 | 27 | const options = { 28 | scales: { 29 | y: { 30 | min: 1000, 31 | max: 4000, 32 | ticks: { 33 | stepSize: 200, 34 | }, 35 | }, 36 | }, 37 | legend: { 38 | position: "bottom", 39 | }, 40 | }; 41 | 42 | const canvasBackgroundColor = { 43 | id: "canvasBackgroundColor", 44 | beforeDraw: (chart, args, options) => { 45 | const { 46 | ctx, 47 | chartArea: { top, bottom, left, right, width, height }, 48 | scales: { x, y }, 49 | } = chart; 50 | 51 | const bgColor = (low, high, color) => { 52 | ctx.fillStyle = color; 53 | ctx.fillRect( 54 | left, 55 | y.getPixelForValue(high), 56 | width, 57 | y.getPixelForValue(low) - y.getPixelForValue(high) 58 | ); 59 | }; 60 | bgColor(1000, 4000, "rgb(255,255,255,1)"); 61 | bgColor(3000, 4000, "rgb(170,0,0,0.5)"); 62 | bgColor(2600, 3000, "rgb(255,51,51,0.5)"); 63 | bgColor(2400, 2600, "rgb(255,119,119,0.5)"); 64 | bgColor(2300, 2400, "rgb(255,187,85,0.5)"); 65 | bgColor(2100, 2300, "rgb(255,204,136,0.5)"); 66 | bgColor(1900, 2100, "rgb(255,136,255,0.5)"); 67 | bgColor(1600, 1900, "rgb(170,170,255,0.5)"); 68 | bgColor(1400, 1600, "rgb(119,221,187,0.5)"); 69 | bgColor(1200, 1400, "rgb(119,255,119,0.5)"); 70 | bgColor(1000, 1200, "rgb(204,204,204,0.5)"); 71 | }, 72 | }; 73 | 74 | return ( 75 | <> 76 | 77 | > 78 | ); 79 | }; 80 | 81 | export default RankGraph; 82 | -------------------------------------------------------------------------------- /src/components/SubmissionList.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { List, ListItem, ListItemText, Typography } from "@mui/material"; 3 | 4 | const SubmissionList = ({ darkmode, params }) => { 5 | return ( 6 | <> 7 | 13 | Recent Submissions 14 | 15 | } 26 | > 27 | {params.map((subs, index) => ( 28 | 29 | 33 | 39 | Points: {subs.problem.points} 40 | 41 | {" | Rating:" + subs.problem.rating} 42 | 43 | {subs.verdict} 44 | 45 | } 46 | /> 47 | 48 | ))} 49 | 50 | > 51 | ); 52 | }; 53 | 54 | export default SubmissionList; 55 | -------------------------------------------------------------------------------- /src/components/UserInfo.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Avatar, 4 | Stack, 5 | TableContainer, 6 | TableRow, 7 | TableCell, 8 | TableBody, 9 | Table, 10 | } from "@mui/material"; 11 | 12 | const UserInfo = ({ darkmode, params }) => { 13 | const candidate = [ 14 | { label: "Rating", value: params.rating }, 15 | { label: "Highest Rating", value: params.maxRating }, 16 | { label: "Rank", value: params.rank }, 17 | { label: "Highest Rank", value: params.maxRank }, 18 | { label: "Friends", value: params.friendOfCount }, 19 | { label: "Organization", value: params.organization }, 20 | { label: "Contribution", value: params.contribution }, 21 | ]; 22 | return ( 23 | <> 24 | 29 | 30 | 38 | {params.firstName} {params.lastName}{" "} 39 | 40 | 45 | @{params.handle} 46 | 47 | 53 | {candidate.map((info, index) => ( 54 | 64 | {info.label} 65 | {" : "} 66 | {info.value} 67 | 68 | ))} 69 | 70 | > 71 | ); 72 | }; 73 | 74 | export default UserInfo; 75 | 76 | // firstname, lastname, avatar, handle, contribution, org, maxrank, rank, maxrating, rating, 77 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render( 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /src/pages/Blog/Blog.css: -------------------------------------------------------------------------------- 1 | .Blog-container { 2 | padding-left: 7.5%; 3 | padding-right: 7.5%; 4 | padding-top: 2.5%; 5 | padding-bottom: 2.5%; 6 | height: 92vh; 7 | max-width: 100vw; 8 | overflow-x: hidden; 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | } -------------------------------------------------------------------------------- /src/pages/Blog/Blog.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Blog.css'; 3 | import { Stack } from '@mui/material'; 4 | import codechefLogo from '../../assets/codechef.png'; 5 | import codeforcesLogo from '../../assets/codeforces.png'; 6 | import leetcodeLogo from '../../assets/leetcode.png'; 7 | import PlatformCard from '../../components/PlatformCard'; 8 | import { Helmet } from 'react-helmet'; 9 | 10 | const Blog = ({ darkmode }) => { 11 | 12 | return ( 13 | 14 | 15 | Practice 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | export default Blog -------------------------------------------------------------------------------- /src/pages/CodeForces/CodeForces.css: -------------------------------------------------------------------------------- 1 | .search-form { 2 | margin-top: 20px; 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | gap: 20px; 7 | } 8 | 9 | .response-container { 10 | padding-left: 7.5%; 11 | padding-right: 7.5%; 12 | padding-top: 2.5%; 13 | padding-bottom: 2.5%; 14 | display: flex; 15 | margin-top: 30px; 16 | gap: 20px; 17 | } 18 | 19 | .user-container { 20 | gap: 20px; 21 | width: 20%; 22 | } 23 | 24 | .rank-container { 25 | width: 50%; 26 | } 27 | 28 | .Submission-container { 29 | width: 30%; 30 | } 31 | 32 | .error-container { 33 | display: flex; 34 | justify-content: center; 35 | color: red; 36 | } 37 | -------------------------------------------------------------------------------- /src/pages/CodeForces/CodeForces.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { TextField, Button, Box } from "@mui/material"; 3 | import UserInfo from "../../components/UserInfo"; 4 | import RankGraph from "../../components/RankGraph"; 5 | import SubmissionList from "../../components/SubmissionList"; 6 | import "./CodeForces.css"; 7 | 8 | const CodeForces = ({ darkmode }) => { 9 | const requestOptions = { 10 | method: "GET", 11 | redirect: "follow", 12 | }; 13 | 14 | const [name, setName] = useState(); 15 | const [result, setResult] = useState(); 16 | const [rating, setRating] = useState(); 17 | const [status, setStatus] = useState(); 18 | const [found, setFound] = useState(true); 19 | const handleChange = (event) => { 20 | setName(event.target.value); 21 | }; 22 | const handleSubmit = () => { 23 | fetch( 24 | "https://codeforces.com/api/user.info?" + 25 | new URLSearchParams({ 26 | handles: name, 27 | }), 28 | requestOptions 29 | ) 30 | .then((response) => response.text()) 31 | .then((result) => { 32 | setResult(JSON.parse(result).result[0]); 33 | setFound(true); 34 | }) 35 | .catch((error) => { 36 | setFound(false); 37 | setResult(null); 38 | }); 39 | 40 | fetch( 41 | "https://codeforces.com/api/user.rating?" + 42 | new URLSearchParams({ 43 | handle: name, 44 | }), 45 | requestOptions 46 | ) 47 | .then((response) => response.text()) 48 | .then((result) => { 49 | setRating(JSON.parse(result).result); 50 | }) 51 | .catch((error) => setRating(null)); 52 | 53 | fetch( 54 | "https://codeforces.com/api/user.status?" + 55 | new URLSearchParams({ 56 | handle: name, 57 | from: 1, 58 | count: 10, 59 | }), 60 | requestOptions 61 | ) 62 | .then((response) => response.text()) 63 | .then((result) => { 64 | setStatus(JSON.parse(result).result); 65 | }) 66 | .catch((error) => setStatus(null)); 67 | }; 68 | 69 | return ( 70 | <> 71 | :not(style)": { m: 1, width: "25ch" }, 75 | }} 76 | noValidate 77 | autoComplete="off" 78 | className="search-form" 79 | > 80 | 86 | 87 | Search 88 | 89 | 90 | {!found && User not found!} 91 | 92 | 93 | {result && } 94 | 95 | 96 | {rating && } 97 | 98 | 99 | {status && } 100 | 101 | 102 | > 103 | ); 104 | }; 105 | 106 | export default CodeForces; 107 | -------------------------------------------------------------------------------- /src/pages/Contests/Contests.css: -------------------------------------------------------------------------------- 1 | .container { 2 | padding-left: 7.5%; 3 | padding-right: 7.5%; 4 | padding-top: 2.5%; 5 | padding-bottom: 2.5%; 6 | max-width: 100vw; 7 | overflow-x: hidden; 8 | display: flex; 9 | align-items: center; 10 | justify-content: center; 11 | } -------------------------------------------------------------------------------- /src/pages/Contests/Ongoing.js: -------------------------------------------------------------------------------- 1 | import { 2 | IconButton, 3 | Paper, 4 | Table, 5 | TableBody, 6 | TableCell, 7 | TableContainer, 8 | TableHead, 9 | TableRow, 10 | Tooltip, 11 | } from '@mui/material'; 12 | import Link from '@mui/material/Link'; 13 | import React, { useEffect, useRef, useState } from 'react'; 14 | import atcoderLogo from '../../assets/atcoder.png'; 15 | import codechefLogo from '../../assets/codechef.png'; 16 | import codeforcesLogo from '../../assets/codeforces.png'; 17 | import csacademyLogo from '../../assets/csacademy.png'; 18 | import googleLogo from '../../assets/google.png'; 19 | import hackerearthLogo from '../../assets/hackerearth.png'; 20 | import hackerrankLogo from '../../assets/hackerrank.png'; 21 | import leetcodeLogo from '../../assets/leetcode.png'; 22 | import topcoderLogo from '../../assets/topcoder.png'; 23 | import placeholderLogo from '../../assets/placeholder.png'; 24 | import './Contests.css'; 25 | import Button from '@mui/material/Button'; 26 | import ButtonGroup from '@mui/material/ButtonGroup'; 27 | import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; 28 | import ClickAwayListener from '@mui/material/ClickAwayListener'; 29 | import Grow from '@mui/material/Grow'; 30 | import Popper from '@mui/material/Popper'; 31 | import MenuItem from '@mui/material/MenuItem'; 32 | import MenuList from '@mui/material/MenuList'; 33 | import Colors from '../../utils/Colors'; 34 | import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; 35 | import { google } from "calendar-link"; 36 | import { Helmet } from 'react-helmet'; 37 | 38 | const Ongoing = ({ darkmode }) => { 39 | 40 | Contests Today 41 | 42 | 43 | 44 | 45 | const [contests, setContests] = useState([]) 46 | const [filterContests, setFilterContests] = useState([]) 47 | const [error, setError] = useState(null) 48 | const [loading, setLoading] = useState(true) 49 | const [refresh, setRefresh] = useState(false) 50 | 51 | const anchorRef = useRef(null); 52 | const [open, setOpen] = useState(false); 53 | const [selectedIndex, setSelectedIndex] = useState(0); 54 | var options = ["ALL"]; 55 | 56 | //Fetch contests from API 57 | const fetchAllContests = async () => { 58 | try { 59 | const response = await fetch(`https://kontests.net/api/v1/all`); 60 | const json = await response.json(); 61 | setContests([...json].filter(contest => contest.status === "CODING")); 62 | setFilterContests([...json].filter(contest => contest.status === "CODING")) 63 | 64 | } catch (e) { 65 | console.log(e); 66 | setError(e); 67 | } finally { 68 | setLoading(false); 69 | setRefresh(false); 70 | } 71 | } 72 | 73 | const keyGenerator = () => 74 | '_' + Math.random().toString(36).substr(2, 9) 75 | ///////////////////////////////////// 76 | 77 | //Dropdown menu to filter contests 78 | contests.map((i) => { 79 | return options.push(i.site); 80 | }) 81 | options = options.filter((v, i, a) => a.indexOf(v) === i) 82 | 83 | const handleMenuItemClick = (event, index, option) => { 84 | setSelectedIndex(index) 85 | setOpen(false) 86 | if (option !== "ALL") { 87 | setFilterContests(contests.filter((i) => { 88 | console.log(i.site, option) 89 | return i.site === option 90 | })) 91 | } else { 92 | setFilterContests(contests) 93 | } 94 | } 95 | 96 | const handleToggle = () => { 97 | setOpen((prevOpen) => !prevOpen) 98 | } 99 | 100 | const handleClose = (event) => { 101 | if (anchorRef.current && anchorRef.current.contains(event.target)) { 102 | return 103 | } 104 | setOpen(false); 105 | } 106 | ////////////////////////////////////////// 107 | 108 | //Display duration time 109 | const formatDurationTime = (s) => { 110 | let years = Math.floor(s / 31536000); 111 | let months = Math.floor((s % 31536000) / 2592000); 112 | let days = Math.floor(((s % 31536000) % 2592000) / 86400); 113 | let hours = Math.floor((s % (3600 * 24)) / 3600); 114 | let minutes = Math.floor((s % 3600) / 60); 115 | let seconds = Math.floor(s % 60); 116 | 117 | let ans = ""; 118 | if(years >= 1) { 119 | if(years > 1) 120 | ans += years + " yrs "; 121 | else if(years === 1) 122 | ans += years + " yr "; 123 | if(months > 1) 124 | ans += months + " mos"; 125 | else if(months === 1) 126 | ans += months + " mo"; 127 | } else if(months >= 1) { 128 | if(months > 1) 129 | ans += months + " mos "; 130 | else if(months === 1) 131 | ans += months + " mo "; 132 | if(days > 1) 133 | ans += days + " days"; 134 | else if(days === 1) 135 | ans += days + " day"; 136 | } else if(days >= 1) { 137 | if(days > 1) 138 | ans += days + " days "; 139 | else if(days === 1) 140 | ans += days + " day "; 141 | if(hours > 1) 142 | ans += hours + " hrs"; 143 | else if(hours === 1) 144 | ans += hours + " hr"; 145 | } else { 146 | hours = ("0" + hours).slice(-2); 147 | minutes = ("0" + minutes).slice(-2); 148 | seconds = ("0" + seconds).slice(-2); 149 | ans = hours + ":" + minutes + ":" + seconds; 150 | } 151 | 152 | return ans; 153 | } 154 | /////////////////////////////////////// 155 | 156 | useEffect(() => { 157 | fetchAllContests(); 158 | }, []); 159 | 160 | return ( 161 | 162 | 163 | 164 | 165 | 166 | Ongoing Contests 167 | 168 | Site : 169 | 170 | 178 | 179 | 180 | 181 | 191 | {({ TransitionProps, placement }) => ( 192 | 199 | 200 | 201 | 202 | {options.map((option, index) => ( 203 | handleMenuItemClick(event, index, option)} 208 | > 209 | {option} 210 | 211 | ))} 212 | 213 | 214 | 215 | 216 | )} 217 | 218 | 219 | Start 220 | End 221 | Duration 222 | 223 | 224 | 225 | {filterContests.map((item) => ( 226 | 234 | 235 | 236 | 256 | 261 | 262 | {item.name} 263 | 264 | 265 | 266 | { 267 | window.open( 268 | google({ 269 | title: item.name, 270 | start: item.start_time, 271 | end: item.end_time 272 | }), 273 | "_blank" 274 | ) 275 | }}> 276 | 284 | 285 | 286 | 287 | 288 | 289 | {item.site} 290 | 291 | 292 | {new Date(item.start_time).toLocaleString("en-IN", { timeZone: 'Asia/Kolkata' })} 293 | 294 | 295 | {new Date(item.end_time).toLocaleString("en-IN", { timeZone: 'Asia/Kolkata' })} 296 | 297 | 298 | {formatDurationTime(item.duration)} 299 | 300 | 301 | ))} 302 | 303 | 304 | 305 | 306 | ); 307 | } 308 | 309 | export default Ongoing -------------------------------------------------------------------------------- /src/pages/Contests/Upcoming.js: -------------------------------------------------------------------------------- 1 | import { 2 | IconButton, 3 | Paper, 4 | Table, 5 | TableBody, 6 | TableCell, 7 | TableContainer, 8 | TableHead, 9 | TableRow, 10 | Tooltip, 11 | } from "@mui/material"; 12 | import Link from "@mui/material/Link"; 13 | import React, { useEffect, useRef, useState } from "react"; 14 | import atcoderLogo from "../../assets/atcoder.png"; 15 | import codechefLogo from "../../assets/codechef.png"; 16 | import codeforcesLogo from "../../assets/codeforces.png"; 17 | import csacademyLogo from "../../assets/csacademy.png"; 18 | import googleLogo from "../../assets/google.png"; 19 | import hackerearthLogo from "../../assets/hackerearth.png"; 20 | import hackerrankLogo from "../../assets/hackerrank.png"; 21 | import leetcodeLogo from "../../assets/leetcode.png"; 22 | import topcoderLogo from "../../assets/topcoder.png"; 23 | import placeholderLogo from "../../assets/placeholder.png"; 24 | import "./Contests.css"; 25 | import Button from "@mui/material/Button"; 26 | import ButtonGroup from "@mui/material/ButtonGroup"; 27 | import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; 28 | import ClickAwayListener from "@mui/material/ClickAwayListener"; 29 | import Grow from "@mui/material/Grow"; 30 | import Popper from "@mui/material/Popper"; 31 | import MenuItem from "@mui/material/MenuItem"; 32 | import MenuList from "@mui/material/MenuList"; 33 | import Colors from "../../utils/Colors"; 34 | import CalendarMonthIcon from "@mui/icons-material/CalendarMonth"; 35 | import { google } from "calendar-link"; 36 | import { Helmet } from "react-helmet"; 37 | 38 | const Upcoming = ({ darkmode }) => { 39 | 40 | Contests in a week 41 | 45 | ; 46 | 47 | const [contests, setContests] = useState([]); 48 | const [filterContests, setFilterContests] = useState([]); 49 | const [error, setError] = useState(null); 50 | const [loading, setLoading] = useState(true); 51 | const [refresh, setRefresh] = useState(false); 52 | 53 | const anchorRef = useRef(null); 54 | const [open, setOpen] = useState(false); 55 | const [selectedIndex, setSelectedIndex] = useState(0); 56 | var options = ["ALL"]; 57 | 58 | //Fetch Contests from API 59 | const fetchAllContests = async () => { 60 | try { 61 | const response = await fetch(`https://kontests.net/api/v1/all`); 62 | const json = await response.json(); 63 | setContests([...json].filter((contest) => contest.status === "BEFORE")); 64 | setFilterContests( 65 | [...json].filter((contest) => contest.status === "BEFORE"), 66 | ); 67 | } catch (e) { 68 | console.log(e); 69 | setError(e); 70 | } finally { 71 | setLoading(false); 72 | setRefresh(false); 73 | } 74 | }; 75 | 76 | const keyGenerator = () => "_" + Math.random().toString(36).substr(2, 9); 77 | ////////////////////////////////////////////// 78 | 79 | //Dropdown menu to filter contests 80 | contests.map((i) => { 81 | return options.push(i.site); 82 | }); 83 | options = options.filter((v, i, a) => a.indexOf(v) === i); 84 | 85 | const handleMenuItemClick = (event, index, option) => { 86 | setSelectedIndex(index); 87 | console.log(option); 88 | setOpen(false); 89 | if (option !== "ALL") { 90 | setFilterContests( 91 | contests.filter((i) => { 92 | console.log(i.site, option); 93 | return i.site === option; 94 | }), 95 | ); 96 | } else { 97 | setFilterContests(contests); 98 | } 99 | }; 100 | 101 | const handleToggle = () => { 102 | setOpen((prevOpen) => !prevOpen); 103 | }; 104 | 105 | const handleClose = (event) => { 106 | if (anchorRef.current && anchorRef.current.contains(event.target)) { 107 | return; 108 | } 109 | 110 | setOpen(false); 111 | }; 112 | ///////////////////////////////////////////// 113 | 114 | //Display duration time 115 | const formatDurationTime = (s) => { 116 | let years = Math.floor(s / 31536000); 117 | let months = Math.floor((s % 31536000) / 2592000); 118 | let days = Math.floor(((s % 31536000) % 2592000) / 86400); 119 | let hours = Math.floor((s % (3600 * 24)) / 3600); 120 | let minutes = Math.floor((s % 3600) / 60); 121 | let seconds = Math.floor(s % 60); 122 | 123 | let ans = ""; 124 | if (years >= 1) { 125 | if (years > 1) ans += years + " yrs "; 126 | else if (years === 1) ans += years + " yr "; 127 | if (months > 1) ans += months + " mos"; 128 | else if (months === 1) ans += months + " mo"; 129 | } else if (months >= 1) { 130 | if (months > 1) ans += months + " mos "; 131 | else if (months === 1) ans += months + " mo "; 132 | if (days > 1) ans += days + " days"; 133 | else if (days === 1) ans += days + " day"; 134 | } else if (days >= 1) { 135 | if (days > 1) ans += days + " days "; 136 | else if (days === 1) ans += days + " day "; 137 | if (hours > 1) ans += hours + " hrs"; 138 | else if (hours === 1) ans += hours + " hr"; 139 | } else { 140 | hours = ("0" + hours).slice(-2); 141 | minutes = ("0" + minutes).slice(-2); 142 | seconds = ("0" + seconds).slice(-2); 143 | ans = hours + ":" + minutes + ":" + seconds; 144 | } 145 | 146 | return ans; 147 | }; 148 | 149 | function formatDateTimeForCodeChef(dateTimeString) { 150 | const dateParts = dateTimeString.split(/[- :]/); // Split the string into parts 151 | const year = parseInt(dateParts[0], 10); 152 | const month = parseInt(dateParts[1], 10) - 1; // Month is zero-based 153 | const day = parseInt(dateParts[2], 10); 154 | const hours = parseInt(dateParts[3], 10); 155 | const minutes = parseInt(dateParts[4], 10); 156 | const seconds = parseInt(dateParts[5], 10); 157 | 158 | const date = new Date(Date.UTC(year, month, day, hours, minutes, seconds)); 159 | 160 | // Format the date as "7/10/2023" 161 | const formattedDate = `${date.getDate()}/${ 162 | date.getMonth() + 1 163 | }/${date.getFullYear()}`; 164 | 165 | // Format the time as "5:30:00 pm" 166 | const formattedTime = `${date.getHours() % 12 || 12}:${date 167 | .getMinutes() 168 | .toString() 169 | .padStart(2, "0")}:${date.getSeconds().toString().padStart(2, "0")} ${ 170 | date.getHours() < 12 ? "am" : "pm" 171 | }`; 172 | 173 | // Combine the formatted date and time 174 | const formattedDateTime = `${formattedDate}, ${formattedTime}`; 175 | 176 | return formattedDateTime; 177 | } 178 | 179 | /////////////////////////////////////////////// 180 | 181 | useEffect(() => { 182 | fetchAllContests(); 183 | }, []); 184 | 185 | return ( 186 | 187 | 191 | 192 | 193 | 194 | 195 | Upcoming Contests 196 | 197 | 198 | Site : 199 | 205 | 213 | 214 | 215 | 216 | 224 | {({ TransitionProps, placement }) => ( 225 | 234 | 235 | 236 | 237 | {options.map((option, index) => ( 238 | 243 | handleMenuItemClick(event, index, option) 244 | } 245 | > 246 | {option} 247 | 248 | ))} 249 | 250 | 251 | 252 | 253 | )} 254 | 255 | 256 | 257 | Start 258 | 259 | 260 | End 261 | 262 | 263 | Duration 264 | 265 | 266 | 267 | 268 | {filterContests.map((item) => ( 269 | 281 | 282 | 289 | 322 | 327 | 333 | {item.name} 334 | 335 | 336 | 341 | { 343 | window.open( 344 | google({ 345 | title: item.name, 346 | start: item.start_time, 347 | end: item.end_time, 348 | }), 349 | "_blank", 350 | ); 351 | }} 352 | > 353 | 361 | 362 | 363 | 364 | 365 | {item.site} 366 | 367 | {item.site != "CodeChef" 368 | ? new Date(item.start_time).toLocaleString("en-IN", { 369 | timeZone: "Asia/Kolkata", 370 | }) 371 | : formatDateTimeForCodeChef(item.start_time)} 372 | 373 | 374 | {item.site != "CodeChef" 375 | ? new Date(item.end_time).toLocaleString("en-IN", { 376 | timeZone: "Asia/Kolkata", 377 | }) 378 | : formatDateTimeForCodeChef(item.end_time)} 379 | 380 | 381 | {formatDurationTime(item.duration)} 382 | 383 | 384 | ))} 385 | 386 | 387 | 388 | 389 | ); 390 | }; 391 | 392 | export default Upcoming; 393 | -------------------------------------------------------------------------------- /src/pages/Error404/Error.css: -------------------------------------------------------------------------------- 1 | /*====================== 2 | 404 page 3 | =======================*/ 4 | 5 | 6 | .page_404{ padding:40px 0; background:#fff; font-family: 'Arvo', serif; 7 | } 8 | 9 | .page_404 img{ width:100%;} 10 | 11 | .four_zero_four_bg{ 12 | 13 | background-image: url(https://cdn.dribbble.com/users/285475/screenshots/2083086/dribbble_1.gif); 14 | height: 400px; 15 | background-position: center; 16 | } 17 | 18 | 19 | .four_zero_four_bg h1{ 20 | font-size:80px; 21 | } 22 | 23 | .four_zero_four_bg h3{ 24 | font-size:80px; 25 | } 26 | 27 | .link_404{ 28 | color: #fff!important; 29 | padding: 10px 20px; 30 | background: #39ac31; 31 | margin: 20px 0; 32 | display: inline-block;} 33 | .contant_box_404{ margin-top:-50px; 34 | display: flex; 35 | flex-direction: column; 36 | justify-content: center; 37 | align-items: center; 38 | } -------------------------------------------------------------------------------- /src/pages/Error404/Error.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import './Error.css'; 3 | import { Link } from "react-router-dom"; 4 | const Error = () => { 5 | return ( 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 404 14 | 15 | 16 | 17 | Look like you're lost 18 | 19 | the page you are looking for not avaible! 20 | 21 | 22 | Go to Home 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | }; 33 | 34 | export default Error; 35 | -------------------------------------------------------------------------------- /src/pages/Home/Home.js: -------------------------------------------------------------------------------- 1 | import { React, useState, useEffect } from "react"; 2 | import Header from "../../components/Header"; 3 | import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; 4 | import Upcoming from "../Contests/Upcoming"; 5 | import Ongoing from "../Contests/Ongoing"; 6 | import UserStats from "../UserStats/UserStats.js"; 7 | import { ThemeProvider, createTheme } from "@mui/material/styles"; 8 | import CssBaseline from "@mui/material/CssBaseline"; 9 | import Error from "../Error404/Error"; 10 | import { Helmet } from "react-helmet"; 11 | import CodeForces from "../CodeForces/CodeForces"; 12 | import LeetCode from '../LeetCode/LeetCode'; 13 | import Footer from "../../components/Footer"; 14 | import { Box } from "@mui/material"; 15 | 16 | const darkTheme = createTheme({ 17 | palette: { 18 | mode: "dark", 19 | }, 20 | components: { 21 | MuiCssBaseline: { 22 | styleOverrides: { 23 | body: { 24 | scrollbarColor: "#686868 #686868", 25 | "&::-webkit-scrollbar, & *::-webkit-scrollbar": { 26 | backgroundColor: "#424242", 27 | }, 28 | "&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": { 29 | borderRadius: 20, 30 | backgroundColor: "#636363", 31 | minHeight: 15, 32 | }, 33 | "&::-webkit-scrollbar-thumb:hover, & *::-webkit-scrollbar-thumb:hover": 34 | { 35 | backgroundColor: "#4F4F4F", 36 | }, 37 | "&::-webkit-scrollbar-corner, & *::-webkit-scrollbar-corner": { 38 | backgroundColor: "#686868", 39 | }, 40 | }, 41 | }, 42 | }, 43 | }, 44 | }); 45 | 46 | const lightTheme = createTheme({ 47 | palette: { 48 | mode: "light", 49 | }, 50 | components: { 51 | MuiCssBaseline: { 52 | styleOverrides: { 53 | body: { 54 | scrollbarColor: "#C1C1C1 #C1C1C1", 55 | "&::-webkit-scrollbar, & *::-webkit-scrollbar": { 56 | backgroundColor: "#F1F1F1", 57 | }, 58 | "&::-webkit-scrollbar-thumb, & *::-webkit-scrollbar-thumb": { 59 | borderRadius: 20, 60 | backgroundColor: "#C1C1C1", 61 | minHeight: 15, 62 | }, 63 | "&::-webkit-scrollbar-thumb:hover, & *::-webkit-scrollbar-thumb:hover": 64 | { 65 | backgroundColor: "#B5B5B5", 66 | }, 67 | "&::-webkit-scrollbar-corner, & *::-webkit-scrollbar-corner": { 68 | backgroundColor: "#C1C1C1", 69 | }, 70 | }, 71 | }, 72 | }, 73 | }, 74 | }); 75 | 76 | const Home = () => { 77 | const [darkmode, setDarkmode] = useState(false); 78 | const toggle = () => { 79 | setDarkmode(!darkmode); 80 | const g = localStorage.getItem("dark-mode"); 81 | if (g === "off") localStorage.setItem("dark-mode", "on"); 82 | else localStorage.setItem("dark-mode", "off"); 83 | }; 84 | useEffect(() => { 85 | const dm = localStorage.getItem("dark-mode"); 86 | if (dm != null) { 87 | if (dm === "on") setDarkmode(true); 88 | else setDarkmode(false); 89 | } 90 | }, []); 91 | 92 | return ( 93 | 94 | 95 | UpCoding-Competitive Coding Contest 96 | 100 | 104 | 105 | 106 | 107 | 108 | 113 | 114 | 115 | 116 | 117 | } 118 | /> 119 | 124 | 125 | 126 | 127 | 128 | } 129 | /> 130 | 135 | 136 | 137 | 138 | 139 | } 140 | /> 141 | 146 | 147 | 148 | 149 | 150 | } 151 | /> 152 | 157 | 158 | 159 | 160 | 161 | } 162 | /> 163 | } /> 164 | 165 | 166 | 167 | ); 168 | }; 169 | 170 | export default Home; 171 | -------------------------------------------------------------------------------- /src/pages/LeetCode/LeetCode.css: -------------------------------------------------------------------------------- 1 | .search-form { 2 | margin-top: 20px; 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | gap: 20px; 7 | } 8 | 9 | .response-container { 10 | padding-left: 7.5%; 11 | padding-right: 7.5%; 12 | padding-top: 2.5%; 13 | padding-bottom: 2.5%; 14 | display: flex; 15 | margin-top: 30px; 16 | gap: 20px; 17 | } 18 | 19 | .user-container { 20 | gap: 20px; 21 | width: 20%; 22 | } 23 | 24 | .rank-container { 25 | width: 50%; 26 | } 27 | 28 | .Submission-container { 29 | width: 30%; 30 | } 31 | 32 | .error-container { 33 | display: flex; 34 | justify-content: center; 35 | color: red; 36 | } 37 | -------------------------------------------------------------------------------- /src/pages/LeetCode/LeetCode.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { TextField, Button, Box } from "@mui/material"; 3 | import UserInfo from "../../components/LeetCode/UserInfo"; 4 | import ProblemsGraph from "../../components/LeetCode/ProblemsGraph"; 5 | import SubmissionList from "../../components/SubmissionList"; 6 | import "./LeetCode.css"; 7 | 8 | const LeetCode = ({ darkmode }) => { 9 | const requestOptions = { 10 | method: "GET", 11 | redirect: "follow", 12 | }; 13 | 14 | const [name, setName] = useState(); 15 | const [result, setResult] = useState(); 16 | const [found, setFound] = useState(true); 17 | const handleChange = (event) => { 18 | setName(event.target.value); 19 | }; 20 | const handleSubmit = () => { 21 | 22 | fetch( 23 | "https://leetcode-stats-api.herokuapp.com/" + name, 24 | requestOptions 25 | ) 26 | .then((response) => response.json()) 27 | .then((result) => { 28 | result["username"] = name; 29 | setResult(result); 30 | setFound(true); 31 | }) 32 | .catch((error) => { 33 | setFound(false); 34 | setResult(null); 35 | }); 36 | 37 | var query = ` 38 | query recentAcSubmissions($username: String!, $limit: Int!) { 39 | recentAcSubmissionList(username: $username, limit: $limit) { 40 | id 41 | title 42 | titleSlug 43 | timestamp 44 | } 45 | } 46 | `; 47 | 48 | fetch("https://leetcode.com/graphql", { 49 | method: 'POST', 50 | headers: { 51 | "Content-Type": "application/json", 52 | "Accept": "application/json", 53 | }, 54 | body: JSON.stringify({ 55 | query: query, 56 | variables: { 57 | username: "andrefpoliveira", 58 | limit: 10, 59 | } 60 | }) 61 | }) 62 | .then(response => response.json()) 63 | .then(result => console.log(result)) 64 | .catch(error => console.log('error', error)); 65 | }; 66 | 67 | return ( 68 | <> 69 | :not(style)": { m: 1, width: "25ch" }, 73 | }} 74 | noValidate 75 | autoComplete="off" 76 | className="search-form" 77 | > 78 | 84 | 85 | Search 86 | 87 | 88 | {!found && User not found!} 89 | 90 | 91 | {result && } 92 | 93 | 94 | {result && } 95 | 96 | {/* 97 | {status && } 98 | */} 99 | 100 | > 101 | ); 102 | }; 103 | 104 | export default LeetCode; 105 | -------------------------------------------------------------------------------- /src/pages/UserStats/UserStats.css: -------------------------------------------------------------------------------- 1 | .userstats-container { 2 | padding-left: 7.5%; 3 | padding-right: 7.5%; 4 | padding-top: 2.5%; 5 | padding-bottom: 2.5%; 6 | height: 92vh; 7 | max-width: 100vw; 8 | overflow-x: hidden; 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | } -------------------------------------------------------------------------------- /src/pages/UserStats/UserStats.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./UserStats.css"; 3 | import { Stack } from "@mui/material"; 4 | import codechefLogo from "../../assets/codechef.png"; 5 | import codeforcesLogo from "../../assets/codeforces.png"; 6 | import leetcodeLogo from "../../assets/leetcode.png"; 7 | import PlatformCard from "../../components/PlatformCard"; 8 | import { Helmet } from "react-helmet"; 9 | import { Link } from "react-router-dom"; 10 | 11 | const UserStats = ({ darkmode }) => { 12 | return ( 13 | 14 | 15 | Stats Codechef Codeforces Leetcode 16 | 20 | 24 | 25 | 26 | 27 | 33 | Let's Go} 38 | /> 39 | Let's Go} 44 | /> 45 | 46 | 47 | ); 48 | }; 49 | 50 | export default UserStats; 51 | -------------------------------------------------------------------------------- /src/utils/Colors.js: -------------------------------------------------------------------------------- 1 | export default { 2 | GREEN: "#DFF0D8", 3 | BLUE1: "#458BCB", 4 | BLUE2: "#5BC0DE", 5 | BLUE3: "#007AFF", 6 | GRAY1: "#777777", 7 | GRAY2: "#A1A1A1", 8 | GRAY3: "#F8F8F8", 9 | NIGHT_GREEN: "#1DB954", 10 | DARK: "#121212", 11 | WHITE:"#ffffff" 12 | } --------------------------------------------------------------------------------
262 | {item.name} 263 |
333 | {item.name} 334 |
the page you are looking for not avaible!