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;