Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import './App.css';
import ScamAnalyzer from './ScamAnalyzer';
import FakeNewsAnalyzer from './FakeNewsAnalyzer';
import FBIGame from './FBIGame';
import SupplyChainPlatform from './SupplyChainPlatform';

function App() {
const [view, setView] = useState('scam');
Expand All @@ -15,12 +16,14 @@ function App() {
<button className={view === 'scam' ? 'active' : ''} onClick={() => setView('scam')}>Scam Analyzer</button>
<button className={view === 'fake-news' ? 'active' : ''} onClick={() => setView('fake-news')}>Fake News Analyzer</button>
<button className={view === 'fbi-game' ? 'active' : ''} onClick={() => setView('fbi-game')}>FBI AR Game</button>
<button className={view === 'supply-chain' ? 'active' : ''} onClick={() => setView('supply-chain')}>Supply Chain</button>
</nav>
</header>
<main>
{view === 'scam' && <ScamAnalyzer />}
{view === 'fake-news' && <FakeNewsAnalyzer />}
{view === 'fbi-game' && <FBIGame />}
{view === 'supply-chain' && <SupplyChainPlatform />}
</main>
</div>
);
Expand Down
188 changes: 188 additions & 0 deletions src/SupplyChainPlatform.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import React, { useState, useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { XR, ARButton, Controllers, Hands } from '@react-three/xr';
import { OrbitControls, Text, Sky, ContactShadows, Environment, Float, Box } from '@react-three/drei';
import * as THREE from 'three';
import { ethers } from 'ethers';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): Pulling in the full ethers bundle on the client for a mock hash may be unnecessarily heavy.

Since this hash is only for a simulated log, pulling in all of ethers just for ethers.id is likely overkill for the client bundle. You could instead:

  • Use a built-in option like crypto.subtle.digest (for modern browsers), or
  • Implement a small deterministic string hash suitable for demo data.

This reduces bundle size and keeps the frontend snappier.


// --- Components ---

// Digital Twin: Warehouse / Cargo Box
function CargoBox({ position, color, speed = 0.01 }) {
const meshRef = useRef();
const [hovered, setHovered] = useState(false);

useFrame((state) => {
if (meshRef.current) {
// Move box back and forth to simulate movement in a warehouse
meshRef.current.position.z += speed * Math.sin(state.clock.elapsedTime);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The cargo box Z-position update will drift over time instead of oscillating around a fixed point.

Since you're incrementing position.z each frame, you're effectively integrating the sine over time. Instead, cache the starting Z and compute position relative to it:

const baseZ = useRef(position[2]);

useFrame((state) => {
  if (meshRef.current) {
    meshRef.current.position.z = baseZ.current + speed * Math.sin(state.clock.elapsedTime);
  }
});

This keeps the motion bounded around the initial Z position.

}
});

return (
<Float speed={2} rotationIntensity={0.5} floatIntensity={0.5}>
<Box
ref={meshRef}
position={position}
args={[0.5, 0.5, 0.5]}
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
>
<meshStandardMaterial color={hovered ? 'orange' : color} />
</Box>
</Float>
);
}

// Digital Twin: Warehouse Floor
function Warehouse() {
return (
<group>
<mesh rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
<planeGeometry args={[20, 20]} />
<meshStandardMaterial color="#222" />
</mesh>
<gridHelper args={[20, 20, 0xffffff, 0x444444]} rotation={[-Math.PI / 2, 0, 0]} />

{/* Some shelving units simulated by boxes */}
<Box position={[-2, 0.5, -2]} args={[1, 1, 4]}>
<meshStandardMaterial color="#555" />
</Box>
<Box position={[2, 0.5, -2]} args={[1, 1, 4]}>
<meshStandardMaterial color="#555" />
</Box>

{/* Moving Cargo */}
<CargoBox position={[-1, 0.5, 0]} color="#8B4513" speed={0.02} />
<CargoBox position={[1, 0.5, -1]} color="#CD853F" speed={0.015} />
<CargoBox position={[0, 0.5, -2]} color="#DEB887" speed={0.01} />
</group>
);
}

// --- Main Component ---

const INCOTERMS_DATA = {
"EXW": "Ex Works: Buyer takes all risk from seller's door.",
"FOB": "Free On Board: Seller covers costs until goods are on ship.",
"CIF": "Cost, Insurance, and Freight: Seller pays to destination port.",
"DDP": "Delivered Duty Paid: Seller covers all costs including taxes."
};

export default function SupplyChainPlatform() {
const [activeTab, setActiveTab] = useState('twin');
const [selectedTerm, setSelectedTerm] = useState('EXW');
const [trackingId, setTrackingId] = useState('');
const [aiStatus, setAiStatus] = useState('Idle');
const [blockchainLog, setBlockchainLog] = useState([]);

const logToBlockchain = async (event) => {
setAiStatus('Securing data on blockchain...');
// Simulate ethers interaction
const hash = ethers.id(event + Date.now());
const newLog = { event, hash: hash.substring(0, 16) + '...', time: new Date().toLocaleTimeString() };
setBlockchainLog([newLog, ...blockchainLog].slice(0, 5));
Comment on lines +83 to +84
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): State update for blockchainLog can suffer from stale closures under rapid consecutive calls.

setBlockchainLog([newLog, ...blockchainLog]) uses the value of blockchainLog captured when logToBlockchain was defined, so rapid consecutive calls can overwrite each other and drop entries. Use a functional update so each call sees the latest state:

setBlockchainLog(prev => [newLog, ...prev].slice(0, 5));

await new Promise(r => setTimeout(r, 800));
setAiStatus('Data Verified.');
};

const runAIPrediction = () => {
setAiStatus('AI Analyzing supply chain routes...');
setTimeout(() => {
setAiStatus('Optimal route found: Route A-7 via Singapore. Delay Probability: 5%.');
logToBlockchain('Route Optimization Run');
}, 1500);
};

return (
<div className="supply-chain-container" style={{ color: 'white', textAlign: 'left', padding: '20px' }}>
<h2>Supply Chain & Digital Twin Platform</h2>

<div className="tabs" style={{ marginBottom: '20px', display: 'flex', gap: '10px' }}>
<button onClick={() => setActiveTab('twin')}>Digital Twin (3D)</button>
<button onClick={() => setActiveTab('incoterms')}>Incoterms</button>
<button onClick={() => setActiveTab('logistics')}>Logistics AI</button>
</div>

{activeTab === 'twin' && (
<div style={{ width: '100%', height: '500px', background: '#000', borderRadius: '10px', overflow: 'hidden', position: 'relative' }}>
<ARButton />
<Canvas shadows camera={{ position: [5, 5, 5], fov: 50 }}>
<XR>
<Sky sunPosition={[100, 20, 100]} />
<Environment preset="warehouse" />
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} castShadow />

<Warehouse />

<Text position={[0, 4, -5]} fontSize={0.5} color="white">
Warehouse Digital Twin
</Text>

<Controllers />
<Hands />
<OrbitControls />
<ContactShadows opacity={0.4} scale={20} blur={2} far={4.5} />
</XR>
</Canvas>
<div style={{ position: 'absolute', bottom: 10, left: 10, background: 'rgba(0,0,0,0.6)', padding: '10px', fontSize: '12px' }}>
Interactive 3D Simulation. Use mouse to rotate. Box movement simulates AGVs (Automated Guided Vehicles).
</div>
</div>
)}

{activeTab === 'incoterms' && (
<div style={{ background: '#222', padding: '20px', borderRadius: '10px' }}>
<h3>Incoterms 2020 Navigator</h3>
<select
value={selectedTerm}
onChange={(e) => setSelectedTerm(e.target.value)}
style={{ padding: '10px', borderRadius: '5px', width: '100%', marginBottom: '20px' }}
>
{Object.keys(INCOTERMS_DATA).map(term => (
<option key={term} value={term}>{term}</option>
))}
</select>
<div style={{ padding: '20px', border: '1px solid #444', borderRadius: '5px' }}>
<strong>{selectedTerm}:</strong> {INCOTERMS_DATA[selectedTerm]}
</div>
</div>
)}

{activeTab === 'logistics' && (
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>
<div style={{ background: '#222', padding: '20px', borderRadius: '10px' }}>
<h3>Logistics Optimizer</h3>
<input
type="text"
placeholder="Enter Tracking ID (e.g. SHIP-123)"
value={trackingId}
onChange={(e) => setTrackingId(e.target.value)}
style={{ padding: '10px', width: '80%', marginBottom: '10px' }}
/>
<button onClick={runAIPrediction} style={{ display: 'block' }}>Run AI Analysis</button>
<p style={{ marginTop: '20px', color: '#aaa' }}>Status: <span style={{ color: '#00ff00' }}>{aiStatus}</span></p>
</div>

<div style={{ background: '#222', padding: '20px', borderRadius: '10px' }}>
<h3>Blockchain Audit Trail</h3>
<ul style={{ listStyle: 'none', padding: 0 }}>
{blockchainLog.length === 0 && <li>No entries yet.</li>}
{blockchainLog.map((log, i) => (
<li key={i} style={{ fontSize: '12px', borderBottom: '1px solid #333', padding: '5px 0' }}>
[{log.time}] {log.event} <br/>
<small style={{ color: '#888' }}>Hash: {log.hash}</small>
</li>
))}
</ul>
</div>
</div>
)}

<footer style={{ marginTop: '30px', fontSize: '12px', color: '#666' }}>
Supply Chain AI Services Software v1.0.0 | Integrated with Digital Twin & Web3 Ledger.
</footer>
</div>
);
}
61 changes: 61 additions & 0 deletions supply_chain_platform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Supply Chain & Logistics AI Platform

This platform provides a suite of tools for managing supply chain logistics, including a Digital Twin simulation, Incoterms navigator, and AI-driven logistics optimization.

## Features

1. **Digital Twin (3D Simulation):**
* A real-time 3D representation of a warehouse environment.
* Visualizes Automated Guided Vehicles (AGVs) and cargo movement.
* Built with React Three Fiber and Three.js.
* Supports AR/VR modes.

2. **Incoterms Navigator:**
* Comprehensive guide to Incoterms 2020 (EXW, FOB, CIF, DDP, etc.).
* Clarifies responsibilities and risks for buyers and sellers.

3. **AI Logistics Engine:**
* **Delay Predictor:** Uses heuristics to predict shipment delays based on distance and weather conditions.
* **Inventory Risk Analysis:** Analyzes stock levels against demand forecasts to identify stockout risks.
* **Route Optimization:** Simulates optimal routing for logistics efficiency.

4. **Blockchain Audit Trail:**
* Secures logistics events on a decentralized ledger using Ethers.js.
* Provides a transparent and immutable history of supply chain operations.

## Components

### CLI Tool (Python)
Located in `supply_chain_platform/supply_chain_main.py`.
Provides a command-line interface for:
- Incoterms lookup.
- AI Delay prediction.
- Inventory risk assessment.

**Usage:**
```bash
python3 supply_chain_platform/supply_chain_main.py
```

### Web Interface (React)
Integrated into the main application dashboard under the "Supply Chain" tab.
Includes:
- **Digital Twin View**: Interactive 3D warehouse.
- **Incoterms Navigator**: Interactive dropdown guide.
- **Logistics AI Dashboard**: Real-time AI analysis and Blockchain logging.

## File Structure
```
supply_chain_platform/
├── supply_chain_main.py # Main CLI application
├── ai_logistics_engine.py # Mock AI logic for logistics
├── incoterms_data.json # Database of trade terms
└── README.md # This documentation
src/
└── SupplyChainPlatform.jsx # React frontend component
```

## Future Enhancements
- Integration with real-time IoT sensors for live Digital Twin updates.
- Advanced NLP for automated Incoterm selection from contracts.
- Real blockchain integration with Ethereum/Polygon testnets.
42 changes: 42 additions & 0 deletions supply_chain_platform/ai_logistics_engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import random
import time

class AILogisticsEngine:
"""Mock AI Engine for Logistics Optimization."""

def predict_delivery_delay(self, route_distance, weather_condition):
"""Predicts delay based on route distance and weather."""
# Simple heuristic-based 'AI'
base_delay = route_distance / 1000 # 1 hour per 1000km base

weather_multipliers = {
"clear": 1.0,
"rain": 1.2,
"storm": 2.0,
"snow": 1.8
}

multiplier = weather_multipliers.get(weather_condition.lower(), 1.0)
predicted_delay = base_delay * multiplier * random.uniform(0.9, 1.1)

return round(predicted_delay, 2)

def optimize_route(self, checkpoints):
"""Simulates route optimization (Traveling Salesman Problem mock)."""
# Just shuffles for simulation
optimized = list(checkpoints)
random.shuffle(optimized)
return optimized

def analyze_supply_chain_risk(self, inventory_level, demand_forecast):
"""Analyzes risk of stockout."""
if inventory_level < (demand_forecast * 0.5):
return "HIGH: Risk of stockout within 48 hours."
elif inventory_level < demand_forecast:
return "MEDIUM: Low stock, replenishment recommended."
else:
return "LOW: Healthy inventory levels."

if __name__ == "__main__":
engine = AILogisticsEngine()
print(f"Predicted Delay: {engine.predict_delivery_delay(5000, 'storm')} hours")
22 changes: 22 additions & 0 deletions supply_chain_platform/incoterms_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"EXW": {
"name": "Ex Works",
"description": "The seller makes the goods available at their premises. The buyer bears all costs and risks of moving the goods to the destination.",
"responsibilities": "Buyer covers all costs and risks from the seller's door."
},
"FOB": {
"name": "Free On Board",
"description": "The seller delivers the goods on board the vessel nominated by the buyer at the named port of shipment.",
"responsibilities": "Seller covers costs until goods are on the ship. Buyer covers everything after."
},
"CIF": {
"name": "Cost, Insurance, and Freight",
"description": "The seller delivers the goods on board the vessel and pays the costs and freight to bring the goods to the named port of destination.",
"responsibilities": "Seller covers freight and insurance to the destination port."
},
"DDP": {
"name": "Delivered Duty Paid",
"description": "The seller delivers the goods to the buyer, cleared for import and not unloaded from any arriving means of transport at the named place of destination.",
"responsibilities": "Seller covers all costs and risks including import duties and taxes."
}
}
Loading
Loading