Add shippedby to event feed

This commit is contained in:
2025-01-09 11:10:49 -05:00
parent 254a9a6511
commit 225e63a985
3 changed files with 78 additions and 135 deletions

View File

@@ -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:', {
datetime: event.attributes?.datetime orderId: rawProps.OrderId,
}; shippedBy: rawProps.ShippedBy,
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
} }
}; };

View File

@@ -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>
)} </div>
{details.ShippingStreet2 && ( <div className="text-sm text-gray-500">
<p className="text-sm text-muted-foreground">{details.ShippingStreet2}</p> {formatShipMethodSimple(details.ShipMethod)}
)} {event.event_properties?.ShippedBy && (
<p className="text-sm text-muted-foreground"> <>
{details.ShippingCity}, {details.ShippingState} {details.ShippingZip} <span className="text-sm text-gray-500"> </span>
</p> <span className="text-sm font-medium text-blue-600 dark:text-blue-400">Shipped by {event.event_properties.ShippedBy}</span>
{details.ShippingCountry !== "US" && ( </>
<p className="text-sm text-muted-foreground">{details.ShippingCountry}</p> )}
)} </div>
</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>
<Card className="mt-6">
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium">Shipped Items</CardTitle>
</CardHeader>
<CardContent>
<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>
</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);

View File

@@ -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);