115 lines
3.1 KiB
TypeScript
115 lines
3.1 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { getSSEConnection, setupSSECleanup } from 'sse-client';
|
|
|
|
// Set up SSE cleanup once at the application level
|
|
setupSSECleanup();
|
|
|
|
// Define the order state type
|
|
interface OrderState {
|
|
orderId: string;
|
|
orderStatus: number;
|
|
preparationState: {
|
|
utcStarted: string;
|
|
utcEnded: string | null;
|
|
};
|
|
deliveryState: {
|
|
utcStarted: string | null;
|
|
utcEnded: string | null;
|
|
};
|
|
// Add other properties as needed
|
|
}
|
|
|
|
// Define the order state changed message type
|
|
interface OrderStateChangedMessage {
|
|
messageType: string;
|
|
orderId: string;
|
|
prevState: OrderState;
|
|
currentState: OrderState;
|
|
}
|
|
|
|
const OrderTracker: React.FC<{ orderId: string, authToken: string }> = ({ orderId, authToken }) => {
|
|
const [orderState, setOrderState] = useState<OrderState | null>(null);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
// API base URL
|
|
const apiBaseUrl = 'https://api.example.com';
|
|
|
|
// SSE URL
|
|
const sseUrl = `${apiBaseUrl}/events/orders/${orderId}`;
|
|
|
|
// Get or create a connection for this order
|
|
const client = getSSEConnection(sseUrl, `order-${orderId}`, {
|
|
headers: {
|
|
'X-Signed-Auth': authToken
|
|
},
|
|
debug: true
|
|
});
|
|
|
|
// Listen for order state changes
|
|
client.on('orderStateChanged', (event) => {
|
|
try {
|
|
const data = event.parsedData as OrderStateChangedMessage;
|
|
console.log('Order state changed:', data);
|
|
|
|
// Update state with new order state
|
|
setOrderState(data.currentState);
|
|
|
|
// If order is ended, close the connection
|
|
if (data.currentState && data.currentState.orderStatus === 1111) {
|
|
console.log(`Order ${orderId} ended, closing SSE connection`);
|
|
client.close();
|
|
}
|
|
} catch (err) {
|
|
setError('Error parsing order state data');
|
|
console.error('Error parsing order state data:', err);
|
|
}
|
|
});
|
|
|
|
// Listen for connection errors
|
|
client.on('error', (event) => {
|
|
setError('SSE connection error');
|
|
console.error('SSE connection error:', event.detail);
|
|
});
|
|
|
|
// Clean up on unmount
|
|
return () => {
|
|
client.close();
|
|
};
|
|
}, [orderId, authToken]);
|
|
|
|
if (error) {
|
|
return <div className="error">{error}</div>;
|
|
}
|
|
|
|
if (!orderState) {
|
|
return <div className="loading">Loading order status...</div>;
|
|
}
|
|
|
|
return (
|
|
<div className="order-tracker">
|
|
<h2>Order #{orderState.orderId}</h2>
|
|
<div className="order-status">
|
|
Status: {getStatusText(orderState.orderStatus)}
|
|
</div>
|
|
{/* Render other order details */}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// Helper function to get status text from status code
|
|
function getStatusText(status: number): string {
|
|
switch (status) {
|
|
case 0: return 'Created';
|
|
case 10: return 'Accepted';
|
|
case 20: return 'Preparing';
|
|
case 30: return 'Ready for Pickup';
|
|
case 40: return 'Out for Delivery';
|
|
case 50: return 'Delivered';
|
|
case 1111: return 'Completed';
|
|
default: return `Unknown (${status})`;
|
|
}
|
|
}
|
|
|
|
export default OrderTracker;
|