From 5dd7b2ef7747f6fcb7ebbb47371060413e5f0f0c Mon Sep 17 00:00:00 2001 From: Hardik Prakash Date: Tue, 5 Nov 2024 18:15:58 +0530 Subject: [PATCH] Add vehicle tracking features with Leaflet and Tailwind CSS integration --- package-lock.json | 36 +++++++++++++++++++++ package.json | 5 +++ src/App.js | 25 --------------- src/App.jsx | 16 ++++++++++ src/components/InventoryDashboard.jsx | 46 +++++++++++++++++++++++++++ src/components/ScanSimulator.jsx | 25 +++++++++++++++ src/components/VehicleMap.jsx | 41 ++++++++++++++++++++++++ src/index.css | 16 ++-------- tailwind.config.js | 11 +++++++ 9 files changed, 183 insertions(+), 38 deletions(-) delete mode 100644 src/App.js create mode 100644 src/App.jsx create mode 100644 src/components/InventoryDashboard.jsx create mode 100644 src/components/ScanSimulator.jsx create mode 100644 src/components/VehicleMap.jsx create mode 100644 tailwind.config.js diff --git a/package-lock.json b/package-lock.json index 6f45ad2..de7251b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,15 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "leaflet": "^1.9.4", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-leaflet": "^4.2.1", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "tailwindcss": "^3.4.14" } }, "node_modules/@adobe/css-tools": { @@ -3138,6 +3143,17 @@ } } }, + "node_modules/@react-leaflet/core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz", + "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==", + "license": "Hippocratic-2.1", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -11301,6 +11317,12 @@ "shell-quote": "^1.8.1" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -14094,6 +14116,20 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "license": "MIT" }, + "node_modules/react-leaflet": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz", + "integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==", + "license": "Hippocratic-2.1", + "dependencies": { + "@react-leaflet/core": "^2.1.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", diff --git a/package.json b/package.json index e706ebe..b0064ff 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,10 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "leaflet": "^1.9.4", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-leaflet": "^4.2.1", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, @@ -34,5 +36,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "tailwindcss": "^3.4.14" } } diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 3784575..0000000 --- a/src/App.js +++ /dev/null @@ -1,25 +0,0 @@ -import logo from './logo.svg'; -import './App.css'; - -function App() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); -} - -export default App; diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..793efd8 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,16 @@ +// src/App.js +import React from 'react'; +import InventoryDashboard from './components/InventoryDashboard'; +import VehicleMap from './components/VehicleMap'; + +function App() { + return ( +
+ +

Vehicle Tracking

+ +
+ ); +} + +export default App; diff --git a/src/components/InventoryDashboard.jsx b/src/components/InventoryDashboard.jsx new file mode 100644 index 0000000..bc7cff4 --- /dev/null +++ b/src/components/InventoryDashboard.jsx @@ -0,0 +1,46 @@ +import React, { useEffect, useState } from 'react'; + +function InventoryDashboard() { + const [inventory, setInventory] = useState([]); + + useEffect(() => { + // Fetch inventory data on component mount + fetch('http://localhost:8000/api/inventory') + .then(response => response.json()) + .then(data => setInventory(data)) + .catch(error => console.error('Error fetching inventory:', error)); + }, []); + + const updateStock = (itemId, quantity) => { + fetch('http://localhost:8000/api/inventory/update', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ item_id: itemId, quantity: quantity }) + }) + .then(response => response.json()) + .then(data => { + console.log(data.message); + setInventory(inventory.map(item => + item.id === itemId ? { ...item, stock_level: item.stock_level + quantity } : item + )); + }) + .catch(error => console.error('Error updating stock:', error)); + }; + + return ( +
+

Inventory Dashboard

+ +
+ ); +} + +export default InventoryDashboard; diff --git a/src/components/ScanSimulator.jsx b/src/components/ScanSimulator.jsx new file mode 100644 index 0000000..621162a --- /dev/null +++ b/src/components/ScanSimulator.jsx @@ -0,0 +1,25 @@ +import React, { useState } from 'react'; + +function ScanSimulator({ itemId }) { + const [message, setMessage] = useState(""); + + const simulateScan = () => { + fetch(`http://localhost:8000/api/scan`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ item_id: itemId }) + }) + .then(response => response.json()) + .then(data => setMessage(data.message)) + .catch(error => console.error('Error simulating scan:', error)); + }; + + return ( +
+ + {message &&

{message}

} +
+ ); +} + +export default ScanSimulator; diff --git a/src/components/VehicleMap.jsx b/src/components/VehicleMap.jsx new file mode 100644 index 0000000..d3a187a --- /dev/null +++ b/src/components/VehicleMap.jsx @@ -0,0 +1,41 @@ +import React, { useEffect, useState } from 'react'; +import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'; +import 'leaflet/dist/leaflet.css'; + +function VehicleMap({ vehicleId }) { + const [location, setLocation] = useState(null); + + useEffect(() => { + const fetchLocation = () => { + fetch(`http://localhost:8000/gps/update`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ vehicle_id: vehicleId }) + }) + .then(response => response.json()) + .then(data => setLocation(data.location)) + .catch(error => console.error("Error fetching location:", error)); + }; + + const intervalId = setInterval(fetchLocation, 5000); + return () => clearInterval(intervalId); + }, [vehicleId]); + + if (!location) return

Loading vehicle location...

; + + return ( + + + + + Vehicle {vehicleId} is here. + + + + ); +} + +export default VehicleMap; diff --git a/src/index.css b/src/index.css index ec2585e..b5c61c9 100644 --- a/src/index.css +++ b/src/index.css @@ -1,13 +1,3 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..c0958ec --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./src/**/*.{js,jsx,ts,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], +} +