import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { getSSEConnection, setupSSECleanup, SSEClient } 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;
}
@Component({
selector: 'app-order-tracker',
template: `
{{ error }}
Loading order status...
Order #{{ orderState.orderId }}
Status: {{ getStatusText(orderState.orderStatus) }}
`,
styles: [`
.order-tracker {
padding: 1rem;
border: 1px solid #eee;
border-radius: 4px;
}
.error {
color: red;
}
.loading {
color: #888;
}
`]
})
export class OrderTrackerComponent implements OnInit, OnDestroy {
@Input() orderId!: string;
@Input() authToken!: string;
orderState: OrderState | null = null;
error: string | null = null;
private client: SSEClient | null = null;
ngOnInit(): void {
// API base URL
const apiBaseUrl = 'https://api.example.com';
// SSE URL
const sseUrl = `${apiBaseUrl}/events/orders/${this.orderId}`;
// Get or create a connection for this order
this.client = getSSEConnection(sseUrl, `order-${this.orderId}`, {
headers: {
'X-Signed-Auth': this.authToken
},
debug: true
});
// Listen for order state changes
this.client.on('orderStateChanged', (event: any) => {
try {
const data = event.parsedData as OrderStateChangedMessage;
console.log('Order state changed:', data);
// Update state with new order state
this.orderState = data.currentState;
// If order is ended, close the connection
if (data.currentState && data.currentState.orderStatus === 1111) {
console.log(`Order ${this.orderId} ended, closing SSE connection`);
this.client?.close();
}
} catch (err) {
this.error = 'Error parsing order state data';
console.error('Error parsing order state data:', err);
}
});
// Listen for connection errors
this.client.on('error', (event: any) => {
this.error = 'SSE connection error';
console.error('SSE connection error:', event.detail);
});
}
ngOnDestroy(): void {
// Clean up on destroy
if (this.client) {
this.client.close();
this.client = null;
}
}
// Helper function to get status text from status code
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})`;
}
}
}