First commit
This commit is contained in:
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Node.js dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
27161
package-lock.json
generated
Normal file
27161
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
30
package.json
Normal file
30
package.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "app",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Pugs Pugs Pugs",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "react-scripts test",
|
||||||
|
"start": "react-scripts start",
|
||||||
|
"build": "react-scripts build",
|
||||||
|
"eject": "react-scripts eject"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"react-dom": "^19.1.0",
|
||||||
|
"react-scripts": "^5.0.1"
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
11
public/index.html
Normal file
11
public/index.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>React Drag-and-Drop</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
66
src/App.css
Normal file
66
src/App.css
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f4f4f9;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
text-align: center;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropzone {
|
||||||
|
width: 300px;
|
||||||
|
padding: 20px;
|
||||||
|
border: 2px dashed #aaa;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropzone:hover {
|
||||||
|
background-color: #f0f8ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropzone.awaitingDepart {
|
||||||
|
background-color: #e3f2fd; /* Light blue */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropzone.runway {
|
||||||
|
width: 300px;
|
||||||
|
height: 150px;
|
||||||
|
background-color: #ffebee; /* Light red */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropzone.local {
|
||||||
|
background-color: #e8f5e9; /* Light green */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropzone.circuit {
|
||||||
|
background-color: #fff3e0; /* Light orange */
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
padding: 15px;
|
||||||
|
margin: 10px 0;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
cursor: grab;
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:active {
|
||||||
|
transform: scale(1.02);
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
111
src/App.js
Normal file
111
src/App.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import "./App.css";
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
const [zones, setZones] = useState({
|
||||||
|
awaitingDepart: [
|
||||||
|
{ id: "1", registration: "G-ARYK", type: "C172", pob: 1 },
|
||||||
|
{ id: "2", registration: "G-BIBT", type: "AA5", pob: 2 },
|
||||||
|
{ id: "3", registration: "G-BAMC", type: "C150", pob: 2 },
|
||||||
|
{ id: "4", registration: "G-GOHI", type: "C208", pob: 12 },
|
||||||
|
],
|
||||||
|
runway: [],
|
||||||
|
local: [],
|
||||||
|
circuit: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleDragStart = (e, card, sourceZone) => {
|
||||||
|
e.dataTransfer.setData("card", JSON.stringify(card));
|
||||||
|
e.dataTransfer.setData("sourceZone", sourceZone);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDrop = (e, targetZone) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const card = JSON.parse(e.dataTransfer.getData("card"));
|
||||||
|
const sourceZone = e.dataTransfer.getData("sourceZone");
|
||||||
|
|
||||||
|
// Prevent multiple cards in the runway zone
|
||||||
|
if (targetZone === "runway" && zones.runway.length > 0) {
|
||||||
|
alert("The runway can only hold one card at a time.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent duplication if the card is already in the target zone
|
||||||
|
if (zones[targetZone].some((item) => item.id === card.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update zones
|
||||||
|
setZones((prevZones) => {
|
||||||
|
const updatedSourceZone = prevZones[sourceZone].filter(
|
||||||
|
(item) => item.id !== card.id
|
||||||
|
);
|
||||||
|
const updatedTargetZone = [...prevZones[targetZone], card];
|
||||||
|
|
||||||
|
return {
|
||||||
|
...prevZones,
|
||||||
|
[sourceZone]: updatedSourceZone,
|
||||||
|
[targetZone]: updatedTargetZone,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDragOver = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderCards = (cards, sourceZone) =>
|
||||||
|
cards.map((card) => (
|
||||||
|
<div
|
||||||
|
key={card.id}
|
||||||
|
className="card"
|
||||||
|
draggable
|
||||||
|
onDragStart={(e) => handleDragStart(e, card, sourceZone)}
|
||||||
|
>
|
||||||
|
{card.registration}
|
||||||
|
<br />
|
||||||
|
Type: {card.type}
|
||||||
|
<br />
|
||||||
|
{card.pob} POB
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<div
|
||||||
|
className="dropzone awaitingDepart"
|
||||||
|
onDragOver={handleDragOver}
|
||||||
|
onDrop={(e) => handleDrop(e, "awaitingDepart")}
|
||||||
|
>
|
||||||
|
<h3>Awaiting Depart</h3>
|
||||||
|
{renderCards(zones.awaitingDepart, "awaitingDepart")}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="dropzone runway"
|
||||||
|
onDragOver={handleDragOver}
|
||||||
|
onDrop={(e) => handleDrop(e, "runway")}
|
||||||
|
>
|
||||||
|
<h3>Active Runway</h3>
|
||||||
|
{renderCards(zones.runway, "runway")}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="dropzone local"
|
||||||
|
onDragOver={handleDragOver}
|
||||||
|
onDrop={(e) => handleDrop(e, "local")}
|
||||||
|
>
|
||||||
|
<h3>Local</h3>
|
||||||
|
{renderCards(zones.local, "local")}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="dropzone circuit"
|
||||||
|
onDragOver={handleDragOver}
|
||||||
|
onDrop={(e) => handleDrop(e, "circuit")}
|
||||||
|
>
|
||||||
|
<h3>Circuit</h3>
|
||||||
|
{renderCards(zones.circuit, "circuit")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
5
src/index.css
Normal file
5
src/index.css
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/* filepath: /home/jamesp/app/src/index.css */
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
11
src/index.js
Normal file
11
src/index.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom/client"; // Updated import for React 18
|
||||||
|
import App from "./App";
|
||||||
|
import "./index.css"; // Optional: Add global styles here
|
||||||
|
|
||||||
|
const root = ReactDOM.createRoot(document.getElementById("root")); // Updated to use createRoot
|
||||||
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user