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})`; } } }