Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions frontend/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],
rules: {
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
25 changes: 25 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
package-lock.json
36 changes: 36 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Vercel Clone

This project is a clone of Vercel, built with React and Vite. It provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

## Project Structure

The frontend directory structure is as follows:
frontend/ .eslintrc.cjs index.html package.json
public/ src/ App.jsx
components/ Button.jsx ErrorBoundary.jsx Header.jsx Input.jsx Welcome.jsx index.css main.jsx
service/ apiService.js
View/ Home.jsx Logs.jsx Submission.jsx vite.config.js


## Setup

To set up the frontend project, follow these steps:

1. Navigate to the `frontend` directory.
2. Run `npm install` to install the project dependencies.

## Boot

To start the frontend project, run `npm run dev` in the `frontend` directory. This will start the Vite development server.

## Dependencies

The frontend project uses the following dependencies:

- React for building the UI.
- Vite for building the project and providing a development server.
- Axios for making HTTP requests.
- Socket.io-client for real-time communication with the server.
- @emotion/react and @emotion/styled for styling components.

For more information, refer to the `package.json` file in the `frontend` directory.
13 changes: 13 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vercel Clone</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
31 changes: 31 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "vercel-clone",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"axios": "^1.6.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.0",
"socket.io-client": "^4.7.4"
},
"devDependencies": {
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.56.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"vite": "^5.1.0"
}
}
1 change: 1 addition & 0 deletions frontend/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import styled from "@emotion/styled";
import Header from "./components/Header";
import Home from "./View/Home";
import Logs from "./View/Logs";
import Submission from "./View/Submission";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";

function App() {
const Styled = styled.div`
width: 100vw;
height: 100vh;
overflow: hidden;
.header {
height: 80px;
}
.body {
height: calc(100% - 80px);
display: flex;
justify-content: center;
align-items: center;
overflow-x: hidden;
overflow-y: auto;
}
`;

return (
<Router>
<Styled>
<Header />
<div className="body">
<Routes>
<Route path="*" element={<Home />} />
<Route path="/logs" element={<Logs />} />
<Route path="/submission" element={<Submission />} />
</Routes>
</div>
</Styled>
</Router>
);
}

export default App;
20 changes: 20 additions & 0 deletions frontend/src/View/Home.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import styled from "@emotion/styled";
import React from "react";
import Welcome from "../components/Welcome";

const Home = () => {
const Styled = styled.div`
padding: 20px;
text-align: center;
@media (max-width: 768px) {
padding: 10px;
}
`;
return (
<Styled>
<Welcome />
</Styled>
);
};

export default Home;
105 changes: 105 additions & 0 deletions frontend/src/View/Logs.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import styled from "@emotion/styled";
import React, { useEffect, useMemo, useState } from "react";
import socketIO from "socket.io-client";
import Input from "../components/Input";
import Button from "../components/Button";

function Logs({ defaultRepo = "" }) {
const Styled = useMemo(
() => styled.div`
padding: 20px;
text-align: center;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
@media (max-width: 768px) {
padding: 10px;
}
.log-container {
min-height: 200px;
width: fit-content;
max-height: 400px;
@media (max-width: 768px) {
max-height: 300px;
}
width: calc(100% - 40px);
background: #000;
color: #fff;
overflow-y: auto;
padding: 10px;
border-radius: 8px;
text-align: left;
font-size: 8px;
}
.error-text {
margin: 4px 2px;
color: red;
font-size: 12px;
text-align: center;
}
.title {
margin: 8px 0px;
}
`,
[]
);
const [repoText, setRepoText] = useState(defaultRepo);
const [repo, setRepo] = useState(defaultRepo);
const [error, setError] = useState("");
const [logs, setLogs] = useState([
"Build Successfull..",
"Build Started...",
"Fetching Repo...",
]);

// const socket = socketIO.connect("http://localhost:4000");
// useEffect(() => {
// socket.on("messageResponse", (data) => setLogs([...messages, data]));
// }, [socket]);
const handleRepoChange = (event) => {
setRepoText(event.target.value);
};
const handleRepoSubmit = () => {
const githubRepoRegex = /^https:\/\/github\.com\/[^\/]+\/[^\/]+$/;
if (!githubRepoRegex.test(repoText)) {
setError("Invalid! GitHub repo link.");
setRepo("");
} else {
setError("");
setRepo(repoText);
}
};

return (
<Styled>
<div>
<Input
value={repoText}
onChange={handleRepoChange}
placeholder={"Repo Link"}
/>
{error && <div className="error-text">{error}</div>}
</div>
<Button onClick={handleRepoSubmit} text={"Refresh"} />
{repo === "" ? (
<div className="title">No Repo Selected</div>
) : (
<>
<div className="title">Showing logs for: {repo}</div>
<div className="log-container">
{logs.map((log, index) => (
<div key={index} className="log-line">
{log}
</div>
))}
</div>
</>
)}
</Styled>
);
}

export default Logs;
69 changes: 69 additions & 0 deletions frontend/src/View/Submission.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import styled from "@emotion/styled";
import React, { useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import Input from "../components/Input";
import Button from "../components/Button";

const SubmissionPage = () => {
const [repoLink, setRepoLink] = useState("");
const [error, setError] = useState("");
const navigate = useNavigate();

useEffect(() => {
document.title = "Submit Your Repo - Vercel Clone";
}, []);

const handleChange = (event) => {
setRepoLink(event.target.value);
};

const handleSubmit = () => {
console.log(repoLink);
const githubRepoRegex = /^https:\/\/github\.com\/[^\/]+\/[^\/]+$/;
if (!githubRepoRegex.test(repoLink)) {
setError("Invalid! GitHub repo link.");
} else {
setError("");
navigate("/logs");
}
};
const Styled = useMemo(
() => styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
gap: 12px;
@media (max-width: 768px) {
padding: 10px;
}
.error-text {
margin: 4px 2px;
color: red;
font-size: 12px;
text-align: center;
}
`,
[error]
);
return (
<Styled>
<div className="title"></div>

<div className="label">GitHub Repo Link:</div>
<div>
<Input
type="text"
value={repoLink}
onChange={handleChange}
placeholder="https://github.com/username/repo"
/>
{error && <div className="error-text">{error}</div>}
</div>
<Button onClick={handleSubmit} text={"Submit"} />
</Styled>
);
};

export default SubmissionPage;
Loading