Add shippedby to event feed
This commit is contained in:
@@ -1339,58 +1339,62 @@ export class EventsService {
|
|||||||
event.attributes?.metric_id;
|
event.attributes?.metric_id;
|
||||||
|
|
||||||
// Extract properties from all possible locations
|
// Extract properties from all possible locations
|
||||||
const rawProps = {
|
const rawProps = event.attributes?.event_properties || {};
|
||||||
...(event.attributes?.event_properties || {}),
|
|
||||||
...(event.attributes?.properties || {}),
|
// Only log for shipped orders and only show relevant fields
|
||||||
...(event.attributes?.profile || {}),
|
if (event.relationships?.metric?.data?.id === METRIC_IDS.SHIPPED_ORDER) {
|
||||||
value: event.attributes?.value,
|
console.log('[EventsService] Shipped Order:', {
|
||||||
|
orderId: rawProps.OrderId,
|
||||||
|
shippedBy: rawProps.ShippedBy,
|
||||||
datetime: event.attributes?.datetime
|
datetime: event.attributes?.datetime
|
||||||
};
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Normalize shipping data
|
// Normalize shipping data
|
||||||
const shippingData = {
|
const shippingData = {
|
||||||
name: rawProps.ShippingName || rawProps.shipping_name || rawProps.shipping?.name,
|
ShippingName: rawProps.ShippingName,
|
||||||
street1: rawProps.ShippingStreet1 || rawProps.shipping_street1 || rawProps.shipping?.street1,
|
ShippingStreet1: rawProps.ShippingStreet1,
|
||||||
street2: rawProps.ShippingStreet2 || rawProps.shipping_street2 || rawProps.shipping?.street2,
|
ShippingStreet2: rawProps.ShippingStreet2,
|
||||||
city: rawProps.ShippingCity || rawProps.shipping_city || rawProps.shipping?.city,
|
ShippingCity: rawProps.ShippingCity,
|
||||||
state: rawProps.ShippingState || rawProps.shipping_state || rawProps.shipping?.state,
|
ShippingState: rawProps.ShippingState,
|
||||||
zip: rawProps.ShippingZip || rawProps.shipping_zip || rawProps.shipping?.zip,
|
ShippingZip: rawProps.ShippingZip,
|
||||||
country: rawProps.ShippingCountry || rawProps.shipping_country || rawProps.shipping?.country,
|
ShippingCountry: rawProps.ShippingCountry,
|
||||||
method: rawProps.ShipMethod || rawProps.shipping_method || rawProps.shipping?.method,
|
ShipMethod: rawProps.ShipMethod,
|
||||||
tracking: rawProps.TrackingNumber || rawProps.tracking_number
|
TrackingNumber: rawProps.TrackingNumber,
|
||||||
|
ShippedBy: rawProps.ShippedBy
|
||||||
};
|
};
|
||||||
|
|
||||||
// Normalize payment data
|
// Normalize payment data
|
||||||
const paymentData = {
|
const paymentData = {
|
||||||
method: rawProps.PaymentMethod || rawProps.payment_method || rawProps.payment?.method,
|
method: rawProps.PaymentMethod,
|
||||||
name: rawProps.PaymentName || rawProps.payment_name || rawProps.payment?.name,
|
name: rawProps.PaymentName,
|
||||||
amount: Number(rawProps.PaymentAmount || rawProps.payment_amount || rawProps.payment?.amount || 0)
|
amount: Number(rawProps.PaymentAmount || 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Normalize order flags
|
// Normalize order flags
|
||||||
const orderFlags = {
|
const orderFlags = {
|
||||||
type: rawProps.OrderType || rawProps.order_type || 'standard',
|
type: rawProps.OrderType || 'standard',
|
||||||
hasPreorder: Boolean(rawProps.HasPreorder || rawProps.has_preorder || rawProps.preorder),
|
hasPreorder: Boolean(rawProps.HasPreorder),
|
||||||
localPickup: Boolean(rawProps.LocalPickup || rawProps.local_pickup || rawProps.pickup),
|
localPickup: Boolean(rawProps.LocalPickup),
|
||||||
isOnHold: Boolean(rawProps.IsOnHold || rawProps.is_on_hold || rawProps.on_hold),
|
isOnHold: Boolean(rawProps.IsOnHold),
|
||||||
hasDigiItem: Boolean(rawProps.HasDigiItem || rawProps.has_digital_item || rawProps.digital_item),
|
hasDigiItem: Boolean(rawProps.HasDigiItem),
|
||||||
hasNotions: Boolean(rawProps.HasNotions || rawProps.has_notions || rawProps.notions),
|
hasNotions: Boolean(rawProps.HasNotions),
|
||||||
hasDigitalGC: Boolean(rawProps.HasDigitalGC || rawProps.has_digital_gc || rawProps.gift_card),
|
hasDigitalGC: Boolean(rawProps.HasDigitalGC),
|
||||||
stillOwes: Boolean(rawProps.StillOwes || rawProps.still_owes || rawProps.balance_due)
|
stillOwes: Boolean(rawProps.StillOwes)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Normalize refund/cancel data
|
// Normalize refund/cancel data
|
||||||
const refundData = {
|
const refundData = {
|
||||||
reason: rawProps.CancelReason || rawProps.cancel_reason || rawProps.reason,
|
reason: rawProps.CancelReason,
|
||||||
message: rawProps.CancelMessage || rawProps.cancel_message || rawProps.message,
|
message: rawProps.CancelMessage,
|
||||||
orderMessage: rawProps.OrderMessage || rawProps.order_message || rawProps.note
|
orderMessage: rawProps.OrderMessage
|
||||||
};
|
};
|
||||||
|
|
||||||
// Transform items
|
// Transform items
|
||||||
const items = this._transformItems(rawProps.Items || rawProps.items || rawProps.line_items || []);
|
const items = this._transformItems(rawProps.Items || []);
|
||||||
|
|
||||||
// Calculate totals
|
// Calculate totals
|
||||||
const totalAmount = Number(rawProps.TotalAmount || rawProps.PaymentAmount || rawProps.total_amount || rawProps.value || 0);
|
const totalAmount = Number(rawProps.TotalAmount || rawProps.PaymentAmount || rawProps.value || 0);
|
||||||
const itemCount = items.reduce((sum, item) => sum + Number(item.Quantity || item.QuantityOrdered || 1), 0);
|
const itemCount = items.reduce((sum, item) => sum + Number(item.Quantity || item.QuantityOrdered || 1), 0);
|
||||||
|
|
||||||
const transformed = {
|
const transformed = {
|
||||||
@@ -1408,29 +1412,10 @@ export class EventsService {
|
|||||||
},
|
},
|
||||||
relationships: event.relationships,
|
relationships: event.relationships,
|
||||||
event_properties: {
|
event_properties: {
|
||||||
// Basic properties
|
...rawProps, // Include all original properties
|
||||||
EmailAddress: rawProps.EmailAddress || rawProps.email,
|
Items: items, // Override with transformed items
|
||||||
FirstName: rawProps.FirstName || rawProps.first_name,
|
|
||||||
LastName: rawProps.LastName || rawProps.last_name,
|
|
||||||
OrderId: rawProps.OrderId || rawProps.FromOrder || rawProps.order_id,
|
|
||||||
TotalAmount: totalAmount,
|
TotalAmount: totalAmount,
|
||||||
ItemCount: itemCount,
|
ItemCount: itemCount
|
||||||
Items: items,
|
|
||||||
|
|
||||||
// Shipping information
|
|
||||||
...shippingData,
|
|
||||||
|
|
||||||
// Payment information
|
|
||||||
...paymentData,
|
|
||||||
|
|
||||||
// Order flags
|
|
||||||
...orderFlags,
|
|
||||||
|
|
||||||
// Refund/cancel information
|
|
||||||
...refundData,
|
|
||||||
|
|
||||||
// Original properties (for backward compatibility)
|
|
||||||
...rawProps
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -679,72 +679,26 @@ const EventDialog = ({ event, children }) => {
|
|||||||
|
|
||||||
{event.metric_id === METRIC_IDS.SHIPPED_ORDER && (
|
{event.metric_id === METRIC_IDS.SHIPPED_ORDER && (
|
||||||
<>
|
<>
|
||||||
<div className="grid gap-6 sm:grid-cols-2">
|
<div className="mt-1">
|
||||||
<Card>
|
<div className="flex items-center gap-2">
|
||||||
<CardHeader className="pb-2">
|
<span className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
<CardTitle className="text-sm font-medium">Shipping Address</CardTitle>
|
{toTitleCase(details.ShippingName)}
|
||||||
</CardHeader>
|
</span>
|
||||||
<CardContent className="space-y-1">
|
<span className="text-sm text-gray-500">•</span>
|
||||||
<p className="text-sm font-medium">{details.ShippingName}</p>
|
<span className="text-sm text-gray-500">
|
||||||
{details.ShippingStreet1 && (
|
#{details.OrderId}
|
||||||
<p className="text-sm text-muted-foreground">{details.ShippingStreet1}</p>
|
</span>
|
||||||
)}
|
|
||||||
{details.ShippingStreet2 && (
|
|
||||||
<p className="text-sm text-muted-foreground">{details.ShippingStreet2}</p>
|
|
||||||
)}
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
{details.ShippingCity}, {details.ShippingState} {details.ShippingZip}
|
|
||||||
</p>
|
|
||||||
{details.ShippingCountry !== "US" && (
|
|
||||||
<p className="text-sm text-muted-foreground">{details.ShippingCountry}</p>
|
|
||||||
)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card>
|
|
||||||
<CardHeader className="pb-2">
|
|
||||||
<CardTitle className="text-sm font-medium">Tracking Information</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent className="space-y-1">
|
|
||||||
<p className="text-sm font-medium">{details.TrackingNumber}</p>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
{formatShipMethod(details.ShipMethod)}
|
|
||||||
</p>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-sm text-gray-500">
|
||||||
<Card className="mt-6">
|
{formatShipMethodSimple(details.ShipMethod)}
|
||||||
<CardHeader className="pb-2">
|
{event.event_properties?.ShippedBy && (
|
||||||
<CardTitle className="text-sm font-medium">Shipped Items</CardTitle>
|
<>
|
||||||
</CardHeader>
|
<span className="text-sm text-gray-500"> • </span>
|
||||||
<CardContent>
|
<span className="text-sm font-medium text-blue-600 dark:text-blue-400">Shipped by {event.event_properties.ShippedBy}</span>
|
||||||
<div className="divide-y">
|
</>
|
||||||
{details.Items?.map((item, i) => (
|
|
||||||
<div key={i} className="flex gap-4 py-4 first:pt-0 last:pb-0">
|
|
||||||
{item.ImgThumb && (
|
|
||||||
<img
|
|
||||||
src={item.ImgThumb}
|
|
||||||
alt={item.ProductName}
|
|
||||||
className="w-16 h-16 object-cover rounded bg-muted"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div className="flex-1 min-w-0">
|
|
||||||
<p className="font-medium text-sm">{item.ProductName}</p>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
Shipped: {item.QuantitySent} of {item.QuantityOrdered}
|
|
||||||
</p>
|
|
||||||
{item.QuantityBackordered > 0 && (
|
|
||||||
<Badge variant="secondary" className="mt-2">
|
|
||||||
{item.QuantityBackordered} Backordered
|
|
||||||
</Badge>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -1038,15 +992,19 @@ const EventCard = ({ event }) => {
|
|||||||
<span className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
<span className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
{toTitleCase(details.ShippingName)}
|
{toTitleCase(details.ShippingName)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
<span className="text-sm text-gray-500">•</span>
|
||||||
<div className="flex items-center gap-2 text-sm text-gray-500">
|
|
||||||
<span className="text-sm text-gray-500">
|
<span className="text-sm text-gray-500">
|
||||||
#{details.OrderId}
|
#{details.OrderId}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-sm text-gray-500">•</span>
|
</div>
|
||||||
<span className="font-medium text-blue-600 dark:text-blue-400">
|
<div className="text-sm text-gray-500">
|
||||||
{formatShipMethodSimple(details.ShipMethod)}
|
{formatShipMethodSimple(details.ShipMethod)}
|
||||||
</span>
|
{event.event_properties?.ShippedBy && (
|
||||||
|
<>
|
||||||
|
<span className="text-sm text-gray-500"> • </span>
|
||||||
|
<span className="text-sm font-medium text-blue-600 dark:text-blue-400">Shipped by {event.event_properties.ShippedBy}</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@@ -1179,14 +1137,12 @@ const EventFeed = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ensure we have the datetime field in the response
|
// Keep the original event structure intact
|
||||||
const processedEvents = (response.data.data || []).map((event) => ({
|
const processedEvents = (response.data.data || []).map((event) => ({
|
||||||
...event,
|
...event,
|
||||||
datetime: event.attributes?.datetime || event.datetime,
|
datetime: event.attributes?.datetime || event.datetime,
|
||||||
event_properties: {
|
// Don't spread event_properties to preserve the nested structure
|
||||||
...event.event_properties,
|
event_properties: event.attributes?.event_properties || {}
|
||||||
datetime: event.attributes?.datetime || event.datetime,
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setEvents(processedEvents);
|
setEvents(processedEvents);
|
||||||
|
|||||||
@@ -250,6 +250,11 @@ const EventCard = ({ event }) => {
|
|||||||
#{details.OrderId} • {formatShipMethodSimple(details.ShipMethod)}
|
#{details.OrderId} • {formatShipMethodSimple(details.ShipMethod)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{event.event_properties?.ShippedBy && (
|
||||||
|
<div className={`text-sm font-medium ${eventType.textColor} opacity-90 truncate mt-1`}>
|
||||||
|
Shipped by {event.event_properties.ShippedBy}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -369,10 +374,7 @@ const MiniEventFeed = ({
|
|||||||
const processedEvents = (response.data.data || []).map((event) => ({
|
const processedEvents = (response.data.data || []).map((event) => ({
|
||||||
...event,
|
...event,
|
||||||
datetime: event.attributes?.datetime || event.datetime,
|
datetime: event.attributes?.datetime || event.datetime,
|
||||||
event_properties: {
|
event_properties: event.attributes?.event_properties || {}
|
||||||
...event.event_properties,
|
|
||||||
datetime: event.attributes?.datetime || event.datetime,
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setEvents(processedEvents);
|
setEvents(processedEvents);
|
||||||
|
|||||||
Reference in New Issue
Block a user