149 lines
3.6 KiB
Vue

<template>
<div class="order-tracker">
<div v-if="error" class="error">{{ error }}</div>
<div v-else-if="!orderState" class="loading">Loading order status...</div>
<div v-else>
<h2>Order #{{ orderState.orderId }}</h2>
<div class="order-status">
Status: {{ getStatusText(orderState.orderStatus) }}
</div>
<!-- Render other order details -->
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
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;
}
export default defineComponent({
name: 'OrderTracker',
props: {
orderId: {
type: String,
required: true
},
authToken: {
type: String,
required: true
}
},
setup(props) {
const orderState = ref<OrderState | null>(null);
const error = ref<string | null>(null);
let client: any = null;
onMounted(() => {
// API base URL
const apiBaseUrl = 'https://api.example.com';
// SSE URL
const sseUrl = `${apiBaseUrl}/events/orders/${props.orderId}`;
// Get or create a connection for this order
client = getSSEConnection(sseUrl, `order-${props.orderId}`, {
headers: {
'X-Signed-Auth': props.authToken
},
debug: true
});
// Listen for order state changes
client.on('orderStateChanged', (event: any) => {
try {
const data = event.parsedData as OrderStateChangedMessage;
console.log('Order state changed:', data);
// Update state with new order state
orderState.value = data.currentState;
// If order is ended, close the connection
if (data.currentState && data.currentState.orderStatus === 1111) {
console.log(`Order ${props.orderId} ended, closing SSE connection`);
client.close();
}
} catch (err) {
error.value = 'Error parsing order state data';
console.error('Error parsing order state data:', err);
}
});
// Listen for connection errors
client.on('error', (event: any) => {
error.value = 'SSE connection error';
console.error('SSE connection error:', event.detail);
});
});
onUnmounted(() => {
// Clean up on unmount
if (client) {
client.close();
}
});
// Helper function to get status text from status code
const 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})`;
}
};
return {
orderState,
error,
getStatusText
};
}
});
</script>
<style scoped>
.order-tracker {
padding: 1rem;
border: 1px solid #eee;
border-radius: 4px;
}
.error {
color: red;
}
.loading {
color: #888;
}
</style>