Skip to content

Commit 3dee1e3

Browse files
committedJul 22, 2024·
starter code
1 parent 33560b4 commit 3dee1e3

File tree

10 files changed

+284
-44
lines changed

10 files changed

+284
-44
lines changed
 

‎src/App.jsx

+4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import React from "react";
22
import Navbar from "./components/Navbar/Navbar";
3+
// import Hero from "./components/Hero/Hero";
4+
import Simulator from "./components/Simulator/Simulator";
35

46
const App = () => {
57
return (
68
<>
79
<div>
810
<Navbar />
11+
{/* <Hero /> */}
12+
<Simulator />
913
</div>
1014
</>
1115
);

‎src/components/Navbar/Navbar.jsx

+31-33
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,39 @@
1-
import React from "react";
1+
import React, { useState } from "react";
2+
import { HiMiniSquares2X2 } from "react-icons/hi2";
23
import { IoRocketSharp } from "react-icons/io5";
4+
import ResponsiveMenu from "./ResponsiveMenu";
35

46
const Navbar = () => {
7+
const [showMenu, setShowMenu] = useState(false);
8+
const toggleMenu = () => setShowMenu(!showMenu);
9+
510
return (
6-
<div className="bg-primary text-white py-6">
7-
<div className="container flex justify-between items-center">
8-
{/* Logo */}
9-
<h1 className="text-3xl font-semibold flex justify-center items-center gap-2">
10-
<IoRocketSharp />
11-
Space
12-
</h1>
13-
{/* Menu */}
14-
<ul className="hidden md:flex flex-row items-center gap-4 lg:gap-8 text-lg">
15-
<li>
16-
<a
17-
href="#"
18-
className="inline-block px-3 py-2 hover:text-yellow-400 transition-colors duration-200"
19-
>
20-
Home
21-
</a>
22-
</li>
23-
<li>
24-
<a
25-
href="#"
26-
className="inline-block px-3 py-2 hover:text-yellow-400 transition-colors duration-200"
27-
>
28-
Algorithm
29-
</a>
30-
</li>
31-
<li>
32-
<button className="border border-white px-6 py-2 rounded-full hover:shadow-custom-inset hover:bg-secondary hover:border-transparent transition-all duration-200">
33-
Simulate
11+
<>
12+
<nav className="bg-gray-500 text-white py-3 z-50 relative">
13+
<div className="container flex justify-center items-center">
14+
<h1 className="text-3xl font-semibold flex justify-center items-center gap-2">
15+
<IoRocketSharp />
16+
Pilot
17+
</h1>
18+
<p className="absolute text-gray-300 right-[10%] bottom-0 p-1 hover:text-yellow-500 cursor-pointer">
19+
Algorithm
20+
</p>
21+
<p className="absolute text-gray-300 left-[10%] bottom-0 p-1 hover:text-yellow-500 cursor-pointer">
22+
mTSP Problem
23+
</p>
24+
25+
{/* Hamburger Menu */}
26+
<div className="md:hidden">
27+
<button onClick={toggleMenu}>
28+
<HiMiniSquares2X2 className="text-2xl" />
3429
</button>
35-
</li>
36-
</ul>
37-
</div>
38-
</div>
30+
</div>
31+
</div>
32+
</nav>
33+
34+
{/* Mobile Menu */}
35+
<ResponsiveMenu showMenu={showMenu} />
36+
</>
3937
);
4038
};
4139

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from "react";
2+
3+
const ResponsiveMenu = ({ showMenu }) => {
4+
return (
5+
<div
6+
className={`${
7+
showMenu ? "top-20 opacity-100" : "top-[-100%] opacity-0"
8+
} h-auto w-full bg-white/40 backdrop-blur-md fixed top-0 z-40`}
9+
>
10+
<nav className="my-10 text-2xl font-semibold text-center">
11+
<ul className="space-y-10">
12+
<li>
13+
<a href="#">Home</a>
14+
</li>
15+
<li>
16+
<a href="#">Algorithm</a>
17+
</li>
18+
<li>
19+
<a href="#">Simulate</a>
20+
</li>
21+
</ul>
22+
</nav>
23+
</div>
24+
);
25+
};
26+
27+
export default ResponsiveMenu;

‎src/components/Simulator/Axes.jsx

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from "react";
2+
3+
const Axes = () => {
4+
const horizontalMarks = Array.from(
5+
{ length: 19 },
6+
(_, i) => `${(i + 1) * 5}%`
7+
).filter((val) => val !== "50%");
8+
const verticalMarks = Array.from(
9+
{ length: 19 },
10+
(_, i) => `${(i + 1) * 5}%`
11+
).filter((val) => val !== "50%");
12+
13+
return (
14+
<>
15+
<div className="absolute w-full h-[1px] bg-white top-[calc(50%-0.5px)] z-10">
16+
{horizontalMarks.map((left) => (
17+
<div
18+
key={left}
19+
className="absolute h-[6px] w-[2px] bg-white"
20+
style={{ left: `calc(${left} - 1px)`, top: "-2.5px" }}
21+
/>
22+
))}
23+
</div>
24+
<div className="absolute h-full w-[1px] bg-white left-[calc(50%-0.5px)] z-10">
25+
{verticalMarks.map((top) => (
26+
<div
27+
key={top}
28+
className="absolute h-[2px] w-[6px] bg-white"
29+
style={{ top: `calc(${top} - 1px)`, left: "-2.5px" }}
30+
/>
31+
))}
32+
</div>
33+
</>
34+
);
35+
};
36+
37+
const HorizontalAxis = ({ y }) => {
38+
const Y = ((1 - y) * 50).toFixed(1);
39+
40+
return (
41+
<div
42+
className={`absolute w-full h-[1px] bg-[rgb(150,150,150)]`}
43+
style={{ top: `calc(${Y}% - 0.5px)` }}
44+
></div>
45+
);
46+
};
47+
48+
const VerticalAxis = ({ x }) => {
49+
const X = (x * 50).toFixed(1);
50+
51+
return (
52+
<div
53+
className={`absolute h-full w-[1px] bg-[rgb(150,150,150)]`}
54+
style={{ left: `calc(${X}% - 0.5px)` }}
55+
></div>
56+
);
57+
};
58+
59+
export { Axes, HorizontalAxis, VerticalAxis };

‎src/components/Simulator/List.jsx

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from "react";
2+
import { FaRegCircleXmark } from "react-icons/fa6";
3+
4+
const List = ({ coordinates }) => {
5+
return (
6+
<div className="w-[220px] bg-gray-50">
7+
<div className="flex justify-center items-center p-3 bg-gray-200">
8+
Selected Points
9+
</div>
10+
<div className="h-[500px] overflow-y-auto border-2">
11+
{coordinates
12+
.filter(({ select }) => select)
13+
.map(({ x, y, select, setSelect }, index) => (
14+
<div
15+
key={index}
16+
className="p-2 border-b flex justify-between items-center"
17+
>
18+
<p>{`(${x}, ${y})`}</p>
19+
<p
20+
className="text-gray-400 hover:text-gray-500"
21+
onClick={() => setSelect(!select)}
22+
>
23+
<FaRegCircleXmark />
24+
</p>
25+
</div>
26+
))}
27+
</div>
28+
</div>
29+
);
30+
};
31+
32+
export default List;

‎src/components/Simulator/Plane.jsx

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from "react";
2+
import { Axes, HorizontalAxis, VerticalAxis } from "./Axes";
3+
import Point from "./Point";
4+
5+
const Plane = ({ coordinates }) => {
6+
return (
7+
<div className="h-[600px] w-[600px] rounded-[50%] bg-[rgb(130,130,130)] relative overflow-hidden flex justify-center items-center">
8+
<Axes />
9+
{/* 20 HorizontalAxis components */}
10+
{Array(40)
11+
.fill()
12+
.map((_, i) => (
13+
<HorizontalAxis key={i} y={1 - i / 20} />
14+
))}
15+
{/* 20 VerticalAxis components */}
16+
{Array(40)
17+
.fill()
18+
.map((_, i) => (
19+
<VerticalAxis key={i} x={i / 20} />
20+
))}
21+
22+
{/* Point components : x, y in metres */}
23+
{coordinates.map(
24+
({ x, y, select, setSelect }, index) =>
25+
x * x + y * y < 1000 * 1000 && (
26+
<Point
27+
key={index}
28+
x={x}
29+
y={y}
30+
select={select}
31+
setSelect={setSelect}
32+
/>
33+
)
34+
)}
35+
</div>
36+
);
37+
};
38+
39+
export default Plane;

‎src/components/Simulator/Point.jsx

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from "react";
2+
3+
const Point = ({ x, y, select, setSelect }) => {
4+
// x and y are in the range of [0, 1000m]
5+
const X = x * 0.3;
6+
const Y = y * -0.3;
7+
8+
return (
9+
<>
10+
<div
11+
className={`${
12+
select ? "opacity-100" : "hover:opacity-30"
13+
} absolute w-[10px] h-[10px] z-20 opacity-0 rounded-full flex justify-center items-center bg-black`}
14+
style={{ transform: `translate(${X}px, ${Y}px)` }}
15+
onClick={() => setSelect(!select)}
16+
/>
17+
</>
18+
);
19+
};
20+
21+
export default Point;
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { useState } from "react";
2+
import Plane from "./Plane";
3+
import List from "./List";
4+
5+
const coordinate = (x, y) => {
6+
const [select, setSelect] = useState(false);
7+
return { x, y, select, setSelect };
8+
};
9+
10+
const Simulator = () => {
11+
const coordinates = [];
12+
for (let x = -1000; x <= 1000; x += 50) {
13+
for (let y = -1000; y <= 1000; y += 50) {
14+
if (x * x + y * y >= 1000 * 1000 || (x === 0 && y === 0)) continue;
15+
coordinates.push(coordinate(x, y));
16+
}
17+
}
18+
19+
const [duration, setDuration] = useState(20);
20+
const [speed, setSpeed] = useState(10);
21+
22+
const simulate = () => {
23+
console.log("Simulation started");
24+
};
25+
26+
return (
27+
<div className="h-full w-full p-5 flex justify-center space-x-10">
28+
<Plane coordinates={coordinates} />
29+
<List coordinates={coordinates} />
30+
<div className="flex flex-col space-y-5">
31+
<div className="border flex">
32+
<div className="bg-gray-200 py-3 w-[130px] text-center">
33+
Duration {"(min)"}
34+
</div>
35+
<input
36+
type="number"
37+
className="w-[80px] text-center bg-gray-50 outline-none"
38+
value={duration}
39+
onChange={(e) => setDuration(e.target.value)}
40+
/>
41+
</div>
42+
<div className="border flex">
43+
<div className="bg-gray-200 py-3 w-[130px] text-center">
44+
Speed {"(m/s)"}
45+
</div>
46+
<input
47+
type="number"
48+
className="w-[80px] text-center bg-gray-50 outline-none"
49+
value={speed}
50+
onChange={(e) => setSpeed(e.target.value)}
51+
/>
52+
</div>
53+
<button
54+
className="bg-blue-500 text-white px-5 py-2 rounded-md"
55+
onClick={simulate}
56+
>
57+
Simulate
58+
</button>
59+
</div>
60+
</div>
61+
);
62+
};
63+
64+
export default Simulator;

‎src/main.jsx

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
import React from 'react'
2-
import ReactDOM from 'react-dom/client'
3-
import App from './App.jsx'
4-
import './index.css'
1+
import React from "react";
2+
import ReactDOM from "react-dom/client";
3+
import App from "./App.jsx";
4+
import "./index.css";
55

6-
ReactDOM.createRoot(document.getElementById('root')).render(
7-
<React.StrictMode>
8-
<App />
9-
</React.StrictMode>,
10-
)
6+
ReactDOM.createRoot(document.getElementById("root")).render(<App />);

‎tailwind.config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export default {
1616
padding: {
1717
DEFAULT: "1rem",
1818
sm: "2rem",
19-
lg: "4rem",
20-
xl: "5rem",
19+
lg: "3rem",
20+
xl: "4rem",
2121
"2xl": "6rem",
2222
},
2323
},

0 commit comments

Comments
 (0)
Please sign in to comment.