diff --git a/src/App.jsx b/src/App.jsx index 793efd8..14d0153 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,14 +1,35 @@ -// src/App.js import React from 'react'; import InventoryDashboard from './components/InventoryDashboard'; import VehicleMap from './components/VehicleMap'; +import JourneyHistory from './components/JourneyHistory'; +import AlertsPanel from './components/AlertsPanel'; function App() { return ( -
- -

Vehicle Tracking

- +
+
+

SupplySync Dashboard

+

Manage inventory, track vehicles, and view journey history and alerts.

+
+ +
+
+ +
+ +
+

Vehicle Tracking

+ +
+ +
+ +
+ +
+ +
+
); } diff --git a/src/components/AlertsPanel.jsx b/src/components/AlertsPanel.jsx new file mode 100644 index 0000000..5059693 --- /dev/null +++ b/src/components/AlertsPanel.jsx @@ -0,0 +1,38 @@ +import React, { useEffect, useState } from "react"; +import { fetchAlerts } from "../services/api"; + +const AlertsPanel = () => { + const [alerts, setAlerts] = useState([]); + + useEffect(() => { + const interval = setInterval(async () => { + try { + const data = await fetchAlerts(); + setAlerts(data); + } catch (error) { + console.error("Error fetching alerts:", error); + } + }, 10000); + + return () => clearInterval(interval); + }, []); + + return ( +
+

Active Alerts

+
    + {alerts.map((alert) => ( +
  • + {alert.alert_type}:{" "} + {alert.description} +
  • + ))} +
+
+ ); +}; + +export default AlertsPanel; diff --git a/src/components/InventoryDashboard.jsx b/src/components/InventoryDashboard.jsx index bc7cff4..d13c4a6 100644 --- a/src/components/InventoryDashboard.jsx +++ b/src/components/InventoryDashboard.jsx @@ -4,7 +4,6 @@ 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)) @@ -28,14 +27,29 @@ function InventoryDashboard() { }; return ( -
-

Inventory Dashboard

-
    +
    +

    Inventory Dashboard

    +
      {inventory.map(item => ( -
    • - {item.item_name} - Stock: {item.stock_level} - - +
    • +
      + {item.item_name} - + Stock: {item.stock_level} +
      +
      + + +
    • ))}
    diff --git a/src/components/JourneyHistory.jsx b/src/components/JourneyHistory.jsx new file mode 100644 index 0000000..12f4a05 --- /dev/null +++ b/src/components/JourneyHistory.jsx @@ -0,0 +1,74 @@ +import React, { useEffect, useState } from "react"; +import { + MapContainer, + TileLayer, + Marker, + Popup, + Polyline, +} from "react-leaflet"; +import "leaflet/dist/leaflet.css"; + +function JourneyHistory({ vehicleId }) { + const [history, setHistory] = useState([]); + + useEffect(() => { + fetch(`http://localhost:8000/gps/history?vehicle_id=${vehicleId}`) + .then((response) => response.json()) + .then((data) => setHistory(data.journey_history)) + .catch((error) => + console.error("Error fetching journey history:", error) + ); + }, [vehicleId]); + + if (!history.length) + return ( +

    + Loading journey history... +

    + ); + + const routeCoordinates = history.map((point) => [ + point.latitude, + point.longitude, + ]); + + return ( +
    +

    + Journey History +

    + + + + {history.map((point, index) => ( + + +
    + + Checkpoint {index + 1} + +
    + + {new Date(point.timestamp).toLocaleString()} + +
    +
    +
    + ))} +
    +
    + ); +} + +export default JourneyHistory; diff --git a/src/components/ScanSimulator.jsx b/src/components/ScanSimulator.jsx index 621162a..d684e65 100644 --- a/src/components/ScanSimulator.jsx +++ b/src/components/ScanSimulator.jsx @@ -15,9 +15,15 @@ function ScanSimulator({ itemId }) { }; return ( -
    - - {message &&

    {message}

    } +
    +

    Scan Simulator

    + + {message &&

    {message}

    }
    ); } diff --git a/src/components/VehicleMap.jsx b/src/components/VehicleMap.jsx index d3a187a..bcae491 100644 --- a/src/components/VehicleMap.jsx +++ b/src/components/VehicleMap.jsx @@ -21,20 +21,27 @@ function VehicleMap({ vehicleId }) { return () => clearInterval(intervalId); }, [vehicleId]); - if (!location) return

    Loading vehicle location...

    ; + if (!location) return

    Loading vehicle location...

    ; return ( - - - - - Vehicle {vehicleId} is here. - - - +
    +

    Vehicle Map

    + + + + + Vehicle {vehicleId} is here. + + + +
    ); } diff --git a/src/services/api.js b/src/services/api.js new file mode 100644 index 0000000..0b9c3ee --- /dev/null +++ b/src/services/api.js @@ -0,0 +1,23 @@ +import axios from "axios"; + +const API_BASE_URL = "http://localhost:8000"; + +export const updateGPSLocation = async (vehicleId) => { + try { + const response = await axios.post(`${API_BASE_URL}/gps/update`, { vehicle_id: vehicleId }); + return response.data; + } catch (error) { + console.error("Error updating GPS location:", error); + throw error; + } +}; + +export const fetchAlerts = async () => { + try { + const response = await axios.get(`${API_BASE_URL}/alerts`); + return response.data; + } catch (error) { + console.error("Error fetching alerts:", error); + throw error; + } +};