PNG IHDR x sBIT|d pHYs + tEXtSoftware www.inkscape.org< ,tEXtComment
<!DOCTYPE html>
<html dir="ltr" lang="en-US" class="scroll-smooth">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>Tracking Result | Unity Parcel Service</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Leaflet CSS (For Map) -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<!-- Fonts & Icons -->
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://unpkg.com/lucide@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.13.3/dist/cdn.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: { sans: ['Raleway', 'sans-serif'] },
colors: {
primary: { 50: '#eff6ff', 100: '#dbeafe', 500: '#3b82f6', 600: '#2563eb', 700: '#1d4ed8', 900: '#1e3a8a' }
}
}
}
}
</script>
<style>
[x-cloak] { display: none !important; }
.leaflet-popup-content-wrapper { padding: 0; border-radius: 12px; }
.ticker-line { stroke-dasharray: 10, 10; animation: dash 30s linear infinite; }
@keyframes dash { to { stroke-dashoffset: -1000; } }
@media print {
body * { visibility: hidden; }
#printable-area, #printable-area * { visibility: visible; }
#printable-area { position: absolute; left: 0; top: 0; width: 100%; }
.no-print { display: none !important; }
}
</style>
</head>
<body class="font-sans bg-gray-50 text-gray-800 flex flex-col min-h-screen" x-data="{ mobileMenuOpen: false }">
<!-- Preloader -->
<div id="preloader" class="fixed inset-0 bg-white z-[9999] flex items-center justify-center transition-opacity duration-500">
<div class="text-center">
<div class="w-16 h-16 border-4 border-blue-600 border-t-transparent rounded-full animate-spin mx-auto"></div>
<p class="mt-4 text-gray-500 font-medium">Loading Shipment...</p>
</div>
</div>
<!-- Header -->
<header class="relative bg-white shadow-md z-50 no-print">
<div class="bg-primary-700 text-white py-2">
<div class="max-w-7xl mx-auto px-4 flex justify-between items-center text-sm">
<div class="flex gap-6">
<span class="flex items-center gap-2"><i class="fas fa-clock text-blue-200"></i> Open 24/7</span>
</div>
<div class="flex gap-4">
<a href="mailto:support@titanwaveexpressservice.com" class="flex items-center gap-2 hover:text-blue-200"><i class="fas fa-envelope"></i> support@titanwaveexpressservice.com</a>
</div>
</div>
</div>
<nav class="max-w-7xl mx-auto px-4 h-20 flex justify-between items-center">
<a href="index.php" class="flex items-center gap-2">
<div class="bg-primary-600 h-10 w-10 flex items-center justify-center rounded text-white font-bold text-xl"><i class="fas fa-box"></i></div>
<div class="flex flex-col -space-y-1">
<span class="text-2xl font-bold text-primary-700">Unity</span>
<span class="text-xs font-bold text-red-500 tracking-widest uppercase">Parcel Service</span>
</div>
</a>
<div class="hidden lg:flex gap-8 items-center">
<a href="index.php" class="font-medium hover:text-primary-600">Home</a>
<a href="#" class="font-medium hover:text-primary-600">About</a>
<a href="tracking.php" class="font-medium text-primary-600">Track</a>
<a href="../admin/login.php" class="font-medium hover:text-primary-600">Login</a>
</div>
<button @click="mobileMenuOpen = !mobileMenuOpen" class="lg:hidden text-2xl text-gray-600"><i class="fas fa-bars"></i></button>
</nav>
<!-- Mobile Menu -->
<div x-show="mobileMenuOpen" x-cloak class="lg:hidden border-t bg-white p-4 space-y-3">
<a href="index.php" class="block py-2">Home</a>
<a href="tracking.php" class="block py-2 text-primary-600 font-bold">Track Shipment</a>
<a href="../admin/login.php" class="block py-2">Staff Login</a>
</div>
</header>
<!-- Main Content -->
<main class="flex-grow py-10 px-4">
<div class="max-w-7xl mx-auto space-y-8">
<!-- Search Bar (Only shows if no ID provided) -->
<div id="search-container" class="hidden max-w-2xl mx-auto text-center py-20">
<h1 class="text-3xl font-bold text-gray-900 mb-4">Track Your Shipment</h1>
<p class="text-gray-500 mb-8">Enter your tracking number to see real-time updates.</p>
<div class="flex gap-2">
<input type="text" id="manual-id" placeholder="Enter Tracking ID (e.g. TRK-123)" class="w-full p-4 border border-gray-300 rounded-lg shadow-sm focus:ring-2 focus:ring-primary-500 outline-none">
<button onclick="manualSearch()" class="bg-primary-600 text-white px-8 rounded-lg font-bold hover:bg-primary-700">Track</button>
</div>
</div>
<!-- Error Message -->
<div id="error-msg" class="hidden bg-red-50 border-l-4 border-red-500 p-4 rounded shadow-sm max-w-3xl mx-auto">
<div class="flex items-center gap-3">
<i class="fas fa-exclamation-circle text-red-500 text-xl"></i>
<div>
<h3 class="text-red-800 font-bold">Shipment Not Found</h3>
<p class="text-red-600 text-sm" id="error-text">Please check the tracking ID and try again.</p>
<p class="text-xs text-gray-400 mt-1">Debug: <span id="debug-url">...</span></p>
</div>
</div>
<button onclick="window.location.href='tracking.php'" class="mt-3 text-sm font-bold text-red-700 hover:underline">Try Another ID</button>
</div>
<!-- Tracking Results -->
<div id="printable-area" class="hidden space-y-8 animate-fade-in">
<!-- Header & Print -->
<div class="flex flex-col md:flex-row justify-between items-center gap-4 no-print">
<div>
<h1 class="text-2xl font-bold text-gray-900 flex items-center gap-2">
<i data-lucide="box" class="text-primary-600"></i> Tracking Information
</h1>
<p class="text-sm text-gray-500 mt-1">ID: <span id="display-tracking-id-top" class="font-mono font-bold text-gray-900">...</span></p>
</div>
<div class="flex gap-3">
<button onclick="location.reload()" class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 text-sm font-bold"><i class="fas fa-sync-alt mr-2"></i> Refresh</button>
<button onclick="window.print()" class="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 text-sm font-bold shadow-sm"><i class="fas fa-print mr-2"></i> Print Invoice</button>
</div>
</div>
<!-- Status Card -->
<div class="bg-white rounded-xl shadow-lg border border-gray-200 overflow-hidden">
<div class="bg-primary-700 p-6 text-white flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
<div>
<span class="text-blue-200 text-xs uppercase font-bold tracking-wider">Tracking Number</span>
<h2 class="text-3xl font-bold mt-1" id="display-tracking-id">...</h2>
</div>
<div class="bg-white/10 backdrop-blur-sm px-5 py-2 rounded-lg border border-white/20">
<span class="text-blue-100 text-sm mr-2">Status:</span>
<span class="font-bold text-white uppercase tracking-wide" id="display-status-header">...</span>
</div>
</div>
<!-- Info Grid -->
<div class="p-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<div class="p-4 bg-gray-50 rounded-lg border border-gray-100">
<h3 class="text-primary-600 font-bold text-sm mb-2 flex items-center gap-2"><i class="fas fa-user-circle"></i> Sender</h3>
<p id="display-sender-name" class="font-bold text-gray-900">...</p>
<p id="display-sender-location" class="text-sm text-gray-500 mt-1">...</p>
</div>
<div class="p-4 bg-gray-50 rounded-lg border border-gray-100">
<h3 class="text-primary-600 font-bold text-sm mb-2 flex items-center gap-2"><i class="fas fa-map-marker-alt"></i> Receiver</h3>
<p id="display-receiver-name" class="font-bold text-gray-900">...</p>
<p id="display-receiver-location" class="text-sm text-gray-500 mt-1">...</p>
</div>
<div class="p-4 bg-gray-50 rounded-lg border border-gray-100">
<h3 class="text-primary-600 font-bold text-sm mb-2 flex items-center gap-2"><i class="fas fa-info-circle"></i> Details</h3>
<p class="text-sm text-gray-600">Type: <span id="display-type" class="font-bold text-gray-900">...</span></p>
<p class="text-sm text-gray-600 mt-1">Weight: <span id="display-weight" class="font-bold text-gray-900">...</span></p>
</div>
<div class="p-4 bg-gray-50 rounded-lg border border-gray-100">
<h3 class="text-primary-600 font-bold text-sm mb-2 flex items-center gap-2"><i class="fas fa-shipping-fast"></i> Delivery</h3>
<p class="text-sm text-gray-600">Mode: <span id="display-mode" class="font-bold text-gray-900">...</span></p>
<p class="text-sm text-gray-600 mt-1">Est: <span id="display-date" class="font-bold text-gray-900">...</span></p>
</div>
</div>
</div>
<!-- Map & History -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div class="lg:col-span-2 bg-white rounded-xl shadow-lg border border-gray-200 overflow-hidden">
<div class="h-[500px] w-full bg-gray-100 relative z-0" id="map"></div>
</div>
<div class="bg-white rounded-xl shadow-lg border border-gray-200 overflow-hidden flex flex-col h-[500px]">
<div class="p-4 border-b border-gray-100 bg-gray-50 font-bold text-gray-700 flex items-center gap-2">
<i class="fas fa-history text-primary-600"></i> Shipment History
</div>
<div class="flex-1 overflow-y-auto p-6 custom-scrollbar relative">
<div id="history-container" class="space-y-6 relative pl-2">
<!-- History injected here -->
</div>
</div>
</div>
</div>
<!-- Payment Section -->
<div id="payment-section" class="hidden bg-white rounded-xl shadow-lg border-l-4 border-red-500 overflow-hidden ring-1 ring-gray-200">
<div class="p-6 flex flex-col md:flex-row justify-between items-center gap-6">
<div class="flex items-start gap-4">
<div class="p-3 bg-red-100 text-red-600 rounded-full"><i class="fas fa-exclamation-triangle text-xl"></i></div>
<div>
<h3 class="text-xl font-bold text-gray-900">Payment Required</h3>
<p class="text-gray-600 mt-1">Outstanding charges found. Please clear dues to proceed.</p>
</div>
</div>
<div class="text-right">
<p class="text-sm text-gray-500 uppercase font-bold">Total Due</p>
<p id="display-amount" class="text-3xl font-black text-red-600">$0.00</p>
</div>
</div>
<div class="bg-gray-50 p-6 border-t border-gray-100">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-white p-4 rounded-lg border border-gray-200 shadow-sm">
<h4 class="font-bold text-gray-800 mb-2 flex items-center gap-2"><i class="fas fa-university text-blue-500"></i> Bank Transfer</h4>
<p id="display-bank-details" class="text-sm font-mono text-gray-600 whitespace-pre-line">Loading...</p>
</div>
<div class="bg-white p-4 rounded-lg border border-gray-200 shadow-sm">
<h4 class="font-bold text-gray-800 mb-2 flex items-center gap-2"><i class="fab fa-bitcoin text-orange-500"></i> Crypto (USDT)</h4>
<div class="flex items-center gap-2 bg-gray-100 p-2 rounded border border-gray-200">
<code id="display-crypto-details" class="text-xs break-all text-gray-700 flex-1">...</code>
<button onclick="copyCrypto()" class="text-gray-500 hover:text-blue-600"><i class="fas fa-copy"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="bg-gray-900 text-gray-400 py-10 mt-auto no-print">
<div class="max-w-7xl mx-auto px-4 text-center">
<p class="mb-4 text-white font-bold text-lg">Unity Parcel Service</p>
<p class="text-sm mb-6">Global Logistics & Transportation Solutions.</p>
<div class="flex justify-center gap-6 text-sm">
<a href="#" class="hover:text-white">Privacy Policy</a>
<a href="#" class="hover:text-white">Terms of Service</a>
<a href="../admin/login.php" class="hover:text-white">Staff Login</a>
</div>
<p class="text-xs mt-8 text-gray-600">© 2025 Unity Parcel Service. All rights reserved.</p>
</div>
</footer>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
lucide.createIcons();
let map;
// --- 1. Logic ---
const urlParams = new URLSearchParams(window.location.search);
const trackingId = urlParams.get('id');
// Hide preloader after init
window.addEventListener('load', () => {
setTimeout(() => {
const preloader = document.getElementById('preloader');
if(preloader) preloader.style.opacity = '0';
setTimeout(() => { if(preloader) preloader.style.display = 'none'; }, 500);
}, 800);
});
if(trackingId) {
fetchTrackingData(trackingId);
} else {
document.getElementById('search-container').classList.remove('hidden');
}
function manualSearch() {
const id = document.getElementById('manual-id').value;
if(id) window.location.href = `?id=${id}`;
}
// --- 2. API Call ---
async function fetchTrackingData(id) {
const apiPath = '../api/track.php';
try {
const response = await fetch(`${apiPath}?id=${id}`);
const fullUrl = new URL(`${apiPath}?id=${id}`, window.location.href).href;
if(document.getElementById('debug-url')) document.getElementById('debug-url').innerText = fullUrl;
if (!response.ok) throw new Error("Server Error");
const text = await response.text();
let data;
try { data = JSON.parse(text); }
catch (e) { throw new Error("Invalid Data from Server"); }
if (data.found) {
renderPage(data);
} else {
document.getElementById('error-msg').classList.remove('hidden');
}
} catch (error) {
console.error(error);
alert(error.message);
}
}
// --- 3. Render ---
function renderPage(data) {
document.getElementById('printable-area').classList.remove('hidden');
document.getElementById('search-container').classList.add('hidden');
const set = (id, txt) => { const el = document.getElementById(id); if(el) el.innerText = txt; };
set('display-tracking-id', data.trackingId);
set('display-tracking-id-top', data.trackingId);
set('display-status-header', data.status.current);
set('display-sender-name', data.details.sender);
set('display-sender-location', data.origin.name);
set('display-receiver-name', data.details.receiver);
set('display-receiver-location', data.destination.name);
set('display-type', data.details.type);
set('display-weight', data.details.weight);
set('display-mode', data.details.mode);
set('display-date', data.details.dates.pickup);
// Payment
const paySec = document.getElementById('payment-section');
if(data.payment.required) {
paySec.classList.remove('hidden');
set('display-amount', '$' + data.payment.amount);
set('display-bank-details', data.payment.bankDetails);
set('display-crypto-details', data.payment.cryptoWallet);
}
// History
const histContainer = document.getElementById('history-container');
let histHTML = '<div class="absolute left-[15px] top-2 bottom-0 w-0.5 bg-gray-200"></div>';
data.history.forEach(item => {
histHTML += `
<div class="relative flex gap-4 mb-6 z-10">
<div class="w-8 h-8 rounded-full bg-${item.color}-500 text-white flex items-center justify-center shadow-md border-2 border-white shrink-0">
<i class="fas fa-${item.icon === 'truck' ? 'truck' : item.icon === 'check' ? 'check' : 'info'} text-xs"></i>
</div>
<div>
<p class="text-xs text-gray-500 font-bold">${item.date}</p>
<p class="font-bold text-gray-800 text-sm">${item.status}</p>
<p class="text-sm text-gray-600">${item.description}</p>
<p class="text-xs text-gray-400 mt-1"><i class="fas fa-map-marker-alt"></i> ${item.location}</p>
</div>
</div>`;
});
histContainer.innerHTML = histHTML;
initMap(data);
}
// --- 4. Map ---
function initMap(data) {
if(map) map.remove();
map = L.map('map', { center: [20, 0], zoom: 2, attributionControl: false });
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
attribution: 'OpenStreetMap'
}).addTo(map);
const origin = data.origin.coords;
const dest = data.destination.coords;
const current = data.currentLocation.coords;
// Ticker Line
const latlngs = [origin, current, dest];
L.polyline(latlngs, { className: 'ticker-line', color: '#fbbf24', weight: 4 }).addTo(map);
// Markers
const icon = (c) => L.divIcon({
className: 'bg-transparent border-none',
html: `<div class="w-4 h-4 rounded-full bg-${c}-500 border-2 border-white shadow-lg ${c==='yellow'?'animate-pulse':''}"></div>`
});
L.marker(origin, { icon: icon('blue') }).addTo(map).bindPopup('Origin');
L.marker(dest, { icon: icon('green') }).addTo(map).bindPopup('Destination');
L.marker(current, { icon: icon('yellow') }).addTo(map).bindPopup('Current').openPopup();
map.fitBounds(L.polyline(latlngs).getBounds(), { padding: [50, 50] });
}
function copyCrypto() {
navigator.clipboard.writeText(document.getElementById('display-crypto-details').innerText);
alert('Wallet Copied');
}
</script>
</body>
</html>
b IDATxytVսϓ22 A@IR:hCiZ[v*E:WũZA ^dQeQ @ !jZ'>gsV仿$|?g)&x-E