├── .eslintrc.json ├── .gitignore ├── .prettierrc.json ├── README.md ├── package-lock.json ├── package.json ├── public ├── assets │ ├── c-active.png │ ├── c-inactive.png │ ├── clear-icon.png │ ├── java-active.png │ ├── java-inactive.png │ ├── js-active.png │ ├── js-inactive.png │ ├── main-logo.png │ ├── py-active.png │ └── py-inactive.png ├── index.html ├── manifest.json └── robots.txt ├── src ├── App.css ├── App.js ├── components │ ├── Footer.js │ ├── LeftContainer.js │ ├── Main.css │ ├── Main.js │ ├── NavBar.js │ ├── Popup │ │ ├── index.js │ │ └── index.module.css │ ├── Prompt │ │ ├── index.js │ │ └── index.module.css │ ├── RightContainer.js │ ├── SelectBar.js │ ├── SplashScreen │ │ ├── index.js │ │ └── index.module.css │ └── ThemeToggler │ │ ├── index.js │ │ └── index.module.css ├── context │ ├── Providers │ │ ├── BoilerplateProvider.js │ │ └── Themeprovider.js │ └── reducers │ │ ├── BoilerplateReducer.js │ │ └── ThemeReducer.js ├── icons │ ├── CPlusPlus.jsx │ ├── Copy.jsx │ ├── Download.jsx │ ├── GitHub.jsx │ ├── Info.jsx │ ├── Play.jsx │ ├── Reset.jsx │ └── Upload.jsx ├── index.css ├── index.js └── utils │ ├── controlledEditorConfig.js │ └── downloadFile.js └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": ["plugin:react/recommended", "airbnb"], 7 | "parserOptions": { 8 | "ecmaFeatures": { 9 | "jsx": true 10 | }, 11 | "ecmaVersion": 6, 12 | "sourceType": "module" 13 | }, 14 | "plugins": ["react"], 15 | "rules": { 16 | "linebreak-style": 0, 17 | "global-require": 0, 18 | "eslint linebreak-style": [0, "error", "windows"], 19 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 20 | "react/function-component-definition": [ 21 | 2, 22 | { "namedComponents": "arrow-function" } 23 | ], 24 | "jsx-a11y/click-events-have-key-events": 0, 25 | "jsx-a11y/no-noninteractive-element-interactions": 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.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 | /editor-backend 8 | /editor-backend/node_modules 9 | /backend 10 | /backend/node_modules 11 | # testing 12 | /coverage 13 | 14 | # production 15 | /build 16 | 17 | # misc 18 | .DS_Store 19 | .env.local 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "all", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Online Editor 2 | 3 | ## About Project 4 | Welcome to the frontend repository of `online compiler`. This project aims at creating a modern open source compiler. Currently, the project has support for three programming languages ( C++, Java, Python ) and use API at backend to get result of code. 5 | 6 | ## Tech Stack 7 | 8 | - [Frontend Repository](https://github.com/NegiAkash890/editor-frontend/tree/main) 9 | - [Backend Repository](https://github.com/NegiAkash890/editor-backend) 10 | 11 | ## Prequisite knowledge 12 | 13 | Contributors willing to participate in development need to have a certain amount of prerequisite knowledge before they start working on the editor. If you are new to web development ,here is the checklist: 14 | 15 | - Web technologies: If you are new to HTML, CSS, JavaScript, etc., check out our Learn [web development](https://developer.mozilla.org/en-US/docs/Learn) tutorials. 16 | - Open source: If you've never contributed to an [open source project](https://developer.mozilla.org/en-US/docs/MDN/Contribute/Open_source_etiquette) before, start from here. 17 | - GitHub: [GitHub](https://developer.mozilla.org/en-US/docs/MDN/Contribute/GitHub_beginners) for complete beginners will get you started. 18 | 19 | ## Setting Project Locally and Contributing 20 | 21 | **1.** Start by making a fork of the repository. Click on the symbol at the top right corner. 22 | 23 | **2.** Start by making a fork of the repository 24 | ```bash 25 | git clone https://github.com//editor-frontend 26 | ``` 27 | **3.** Set upstream command: 28 | 29 | ```bash 30 | git remote add upstream https://github.com/NegiAkash890/editor-frontend.git 31 | ``` 32 | **4.** Navigate to the new project directory: 33 | 34 | ```bash 35 | cd editor-frontend 36 | ``` 37 | **5.** Create a new branch: 38 | 39 | ```bash 40 | git checkout -b YourBranchName 41 | ``` 42 | **6.** Run 43 | ```bash 44 | npm install 45 | ``` 46 | **7.** Stage your changes and commit: 47 | 48 | ```bash 49 | git add . 50 | ``` 51 | ```bash 52 | git commit -m "" 53 | ``` 54 | 55 | **8.** Push your local commits to the remote repository: 56 | 57 | ```bash 58 | git push origin YourBranchName 59 | ``` 60 | **9.** Create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)! 61 | 62 | **10.** **Congratulations!** You've made your first contribution! 63 | 64 | ## 💥 Issues 65 | 66 | For major changes, you are welcome to [open an issue](https://github.com/EddieHubCommunity/LinkFree/issues/new/choose) about what you would like to contribute. Enhancements are always encouraged and appreciated. 67 | 68 | 69 | ## LightHouse Stats 70 | 71 | ![image](https://user-images.githubusercontent.com/55234838/146677734-1b808513-d9ae-4770-b29e-2598072ccb74.png) 72 | 73 | 74 | ## Future Updates 75 | 76 | 1. Extending support for more languages 77 | 2. Making project PWA compatible 78 | 79 | ## ✨ Our valuable Contributors👩‍💻👨‍💻 : 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage": "https://editor.akashnegi.in", 3 | "name": "compiler", 4 | "version": "0.1.0", 5 | "private": true, 6 | "dependencies": { 7 | "axios": "^0.21.1", 8 | "codemirror": "^5.65.0", 9 | "prop-types": "^15.7.2", 10 | "react": "^17.0.2", 11 | "react-codemirror2-react-17": "^1.0.0", 12 | "react-copy-to-clipboard": "^5.0.4", 13 | "react-dom": "^17.0.2", 14 | "react-icons": "^4.3.1", 15 | "react-loader": "^2.4.7", 16 | "react-loader-spinner": "^4.0.0", 17 | "react-scripts": "4.0.3", 18 | "react-spinners": "^0.11.0", 19 | "reactjs-popup": "^2.0.5", 20 | "web-vitals": "^1.0.1" 21 | }, 22 | "scripts": { 23 | "predeploy": "npm run build", 24 | "deploy": "gh-pages -d build", 25 | "test": "react-scripts test", 26 | "eject": "react-scripts eject", 27 | "start": "export SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts start", 28 | "build": "export SET NODE_OPTIONS=--openssl-legacy-provider && react-scripts build" 29 | }, 30 | "eslintConfig": { 31 | "extends": [ 32 | "react-app", 33 | "react-app/jest" 34 | ] 35 | }, 36 | "browserslist": { 37 | "production": [ 38 | ">0.2%", 39 | "not dead", 40 | "not op_mini all" 41 | ], 42 | "development": [ 43 | "last 1 chrome version", 44 | "last 1 firefox version", 45 | "last 1 safari version" 46 | ] 47 | }, 48 | "devDependencies": { 49 | "eslint": "^7.32.0", 50 | "eslint-config-airbnb": "^19.0.2", 51 | "eslint-plugin-import": "^2.25.3", 52 | "eslint-plugin-jsx-a11y": "^6.5.1", 53 | "eslint-plugin-react": "^7.27.1", 54 | "eslint-plugin-react-hooks": "^4.3.0", 55 | "gh-pages": "^3.2.3", 56 | "prettier": "^2.5.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /public/assets/c-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/c-active.png -------------------------------------------------------------------------------- /public/assets/c-inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/c-inactive.png -------------------------------------------------------------------------------- /public/assets/clear-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/clear-icon.png -------------------------------------------------------------------------------- /public/assets/java-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/java-active.png -------------------------------------------------------------------------------- /public/assets/java-inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/java-inactive.png -------------------------------------------------------------------------------- /public/assets/js-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/js-active.png -------------------------------------------------------------------------------- /public/assets/js-inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/js-inactive.png -------------------------------------------------------------------------------- /public/assets/main-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/main-logo.png -------------------------------------------------------------------------------- /public/assets/py-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/py-active.png -------------------------------------------------------------------------------- /public/assets/py-inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NegiAkash890/editor-frontend/e5dc4dd472bdb10d79d0073c29202934fa2cd0e0/public/assets/py-inactive.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Online Compiler 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Editor", 3 | "name": "Online Code Editor", 4 | "icons": [ 5 | { 6 | "src": "main-logo.png", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "main-logo.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "main-logo.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | /* Top Navigation */ 2 | .top__nav { 3 | display: flex; 4 | background-color: #eee; 5 | position: fixed; 6 | min-height: 70px; 7 | padding: 0rem 1.25rem; 8 | margin-bottom: 6.25rem; 9 | width: 100%; 10 | justify-content: space-between; 11 | align-items: center; 12 | z-index: 999; 13 | } 14 | 15 | .info__section { 16 | width: 5rem; 17 | display: flex; 18 | justify-content: space-between; 19 | align-items: center; 20 | } 21 | 22 | .info__section > img{ 23 | margin-left: 0.625rem; 24 | } 25 | 26 | .logo__info { 27 | display: flex; 28 | align-items: center; 29 | } 30 | 31 | #logo__name { 32 | margin-left: 0.625rem; 33 | } 34 | 35 | /* Media Queries */ 36 | @media screen and (max-width: 600px) { 37 | #logo__name { 38 | font-size: 0.9rem; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import Footer from './components/Footer'; 3 | import Main from './components/Main'; 4 | import NavBar from './components/NavBar'; 5 | import './App.css'; 6 | import Preloader from './components/SplashScreen'; 7 | 8 | const App = () => { 9 | const [isLoading, setIsLoading] = useState(true); 10 | useEffect(() => { 11 | setTimeout(() => { 12 | setIsLoading(false); 13 | }, 2000); 14 | }, []); 15 | 16 | return isLoading ? ( 17 | 18 | ) : ( 19 |
20 | 21 |
22 |
23 |
24 | ); 25 | }; 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Footer = () =>
; 4 | 5 | export default Footer; 6 | -------------------------------------------------------------------------------- /src/components/LeftContainer.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | /* eslint no-unused-vars: 0 */ 3 | import axios from 'axios'; 4 | import React, { useState, useEffect, useRef } from 'react'; 5 | import { CopyToClipboard } from 'react-copy-to-clipboard'; 6 | import PropTypes from 'prop-types'; 7 | import { Controlled as ControlledEditor } from 'react-codemirror2-react-17'; 8 | import 'codemirror/lib/codemirror.css'; 9 | import 'codemirror/theme/eclipse.css'; 10 | import 'codemirror/theme/dracula.css'; 11 | import 'codemirror/mode/clike/clike'; 12 | import 'codemirror/mode/python/python'; 13 | import 'codemirror/mode/javascript/javascript'; 14 | import 'codemirror/addon/edit/closebrackets'; 15 | import { useTheme } from '../context/Providers/Themeprovider'; 16 | import downloadFile from '../utils/downloadFile'; 17 | import defaultConfig from '../utils/controlledEditorConfig'; 18 | import { useBoilerplate } from '../context/Providers/BoilerplateProvider'; 19 | import ResetPrompt from './Prompt'; 20 | import Upload from '../icons/Upload'; 21 | import Play from '../icons/Play'; 22 | import Download from '../icons/Download'; 23 | import Copy from '../icons/Copy'; 24 | 25 | const LeftContainer = ({ 26 | pre, ext, updateOutput, updateLoading, 27 | }) => { 28 | const [_copied, setCopied] = useState(false); 29 | const [code, setCode] = useState(pre); 30 | const [defaultTextAreaInput, setInput] = useState(null); 31 | const [fileinput, setFileInput] = useState(); 32 | const [mode, setMode] = useState(ext); 33 | const hiddenFileInput = useRef(null); 34 | const { theme } = useTheme(); 35 | const { boilerplateCode } = useBoilerplate(); 36 | 37 | useEffect(() => { 38 | setTimeout(() => { 39 | setCode(pre); 40 | }, 0.5); 41 | }, [pre]); 42 | 43 | useEffect(() => { 44 | const cachedUserCode = localStorage.getItem(mode); 45 | if (cachedUserCode) { 46 | setCode(cachedUserCode); 47 | } 48 | }, [mode]); 49 | 50 | // set the language mode as per the file extension 51 | const setLanguageMode = () => { 52 | let newMode = ''; 53 | switch (ext) { 54 | case 'cpp': 55 | newMode = 'text/x-c++src'; 56 | break; 57 | case 'java': 58 | newMode = 'text/x-java'; 59 | break; 60 | case 'py': 61 | newMode = 'text/x-python'; 62 | break; 63 | case 'js': 64 | newMode = 'text/javascript'; 65 | break; 66 | default: 67 | } 68 | setMode((prevMode) => { 69 | localStorage.setItem(prevMode, code); 70 | return newMode; 71 | }); 72 | }; 73 | 74 | useEffect(() => { 75 | setLanguageMode(); 76 | }, [ext]); 77 | 78 | useEffect(() => { 79 | axios 80 | .get('https://main--editor-backend-compile.netlify.app/.netlify/functions/api') 81 | .then((_) => console.log('Ping')) 82 | .catch((error) => console.error('Error:', error)); 83 | }, []); 84 | 85 | const showFile = (e) => { 86 | e.preventDefault(); 87 | const reader = new FileReader(); 88 | reader.onload = (ev) => { 89 | const text = ev.target.result; 90 | setFileInput(text); 91 | }; 92 | reader.readAsText(e.target.files[0]); 93 | }; 94 | 95 | useEffect(() => { 96 | setCode(fileinput); 97 | }, [fileinput]); 98 | 99 | const handleClick = () => { 100 | hiddenFileInput.current.click(); 101 | }; 102 | 103 | const downloadTxtFile = () => downloadFile(code, 'myCode', ext); 104 | 105 | const handleControlledBeforeChangeCallBack = (_, __, value) => { 106 | setCode(value); 107 | }; 108 | 109 | const handleTextAreaChange = (e) => setInput(e.target.value); 110 | 111 | const handleResetCode = () => { 112 | localStorage.removeItem(mode); 113 | setCode(boilerplateCode); 114 | }; 115 | 116 | const handleSubmit = (e) => { 117 | e.preventDefault(); 118 | updateLoading('true'); 119 | const data = { 120 | language: ext, 121 | code, 122 | input: defaultTextAreaInput, 123 | }; 124 | 125 | axios 126 | .post('https://main--editor-backend-compile.netlify.app/.netlify/functions/api/compile', data) 127 | .then((res) => { 128 | updateLoading('false'); 129 | if (res.data.result.stderr) { 130 | return updateOutput(res.data.result.stderr, 'error'); 131 | } 132 | return updateOutput(res.data.result.stdout, 'response'); 133 | }) 134 | .catch((err) => { 135 | updateOutput(err, 'error'); 136 | }); 137 | }; 138 | 139 | const config = defaultConfig(mode, theme, handleSubmit); 140 | const copyToClipBoard = () => { 141 | setCopied(true); 142 | setTimeout(() => { 143 | setCopied((currentState) => !currentState); 144 | }, 1000); 145 | }; 146 | return ( 147 |
148 |
149 |
150 | 151 | code. 152 | {ext} 153 | 154 |
155 |
156 | 160 | 166 | 170 |
171 |
172 |
176 |
177 |

Editor

178 |
179 | 180 | 184 | 185 | 186 | 190 | 191 |
192 |
193 |
194 | 200 |