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