@@ -78,6 +78,8 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ shipment }) => {
7878 return < Pause className = "w-4 h-4" /> ;
7979 case "delivered" :
8080 return < CheckCircle className = "w-4 h-4" /> ;
81+ case "pending-delivery" :
82+ return < Clock className = "w-4 h-4" /> ;
8183 default :
8284 return < AlertCircle className = "w-4 h-4" /> ;
8385 }
@@ -98,6 +100,8 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ shipment }) => {
98100 return "text-orange-400 bg-orange-500" ;
99101 case "delivered" :
100102 return "text-green-400 bg-green-500" ;
103+ case "pending-delivery" :
104+ return "text-gray-400 bg-gray-500" ;
101105 default :
102106 return "text-gray-400 bg-gray-500" ;
103107 }
@@ -123,15 +127,6 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ shipment }) => {
123127 } ) ;
124128 } ;
125129
126- const STATUS_ORDER = [
127- "pending" ,
128- "processing" ,
129- "shipped" ,
130- "in transit" ,
131- "on hold" ,
132- "delivered" ,
133- ] ;
134-
135130 const STATUS_LABELS : Record < string , string > = {
136131 pending : "Order Confirmed & Pending" ,
137132 processing : "Processing" ,
@@ -141,26 +136,16 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ shipment }) => {
141136 delivered : "Delivered" ,
142137 } ;
143138
144- // Build timeline events
139+ // Build timeline events - chronological order based on actual history
145140 const buildTimeline = ( ) : TimelineEvent [ ] => {
146141 const events : TimelineEvent [ ] = [ ] ;
147142 const sentDate = new Date ( shipment . dateSent ) ;
148143 const deliveryDate = new Date ( shipment . deliveryDate ) ;
149144
150- // Group history by status (case-insensitive)
151- const historyByStatus : Record < string , LocationUpdate [ ] > = { } ;
152- ( Array . isArray ( shipment . history ) ? shipment . history : [ ] ) . forEach (
153- ( entry ) => {
154- const status = entry . status ?. toLowerCase ( ) || "pending" ;
155- if ( ! historyByStatus [ status ] ) historyByStatus [ status ] = [ ] ;
156- historyByStatus [ status ] . push ( entry ) ;
157- }
158- ) ;
159-
160- // Always add Pending (first)
145+ // Always start with creation/pending event
161146 events . push ( {
162- id : "pending " ,
163- title : STATUS_LABELS [ "pending" ] ,
147+ id : "created " ,
148+ title : "Order Created & Confirmed" ,
164149 location : `${ shipment . sender ?. city || "Unknown" } , ${
165150 shipment . sender ?. country || "Unknown"
166151 } `,
@@ -171,49 +156,66 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ shipment }) => {
171156 isFixed : true ,
172157 } ) ;
173158
174- // Add only statuses that exist in history (except pending/delivered)
175- STATUS_ORDER . slice ( 1 , - 1 ) . forEach ( ( status ) => {
176- const entries = historyByStatus [ status ] || [ ] ;
177- if ( entries . length > 0 ) {
178- // Use the latest entry for this status
179- const latest = entries . reduce ( ( a , b ) =>
180- new Date ( a . time ) . getTime ( ) > new Date ( b . time ) . getTime ( ) ? a : b
181- ) ;
182- events . push ( {
183- id : status ,
184- title :
185- STATUS_LABELS [ status ] +
186- ( latest . description ? ` - ${ latest . description } ` : "" ) ,
187- location :
188- latest . city && latest . country
189- ? `${ latest . city } , ${ latest . country } `
190- : latest . location
191- ? `${ latest . location . lat ?. toFixed ( 2 ) ?? "" } , ${
192- latest . location . lng ?. toFixed ( 2 ) ?? ""
193- } `
194- : "Unknown" ,
195- date : latest . time ? formatDate ( latest . time ) : "" ,
196- time : latest . time ? formatTime ( latest . time ) : "" ,
197- status,
198- completed : true ,
199- isFixed : false ,
200- } ) ;
201- }
202- } ) ;
159+ // Add all history entries in chronological order
160+ if ( Array . isArray ( shipment . history ) && shipment . history . length > 0 ) {
161+ // Sort history by time (chronological order)
162+ const sortedHistory = [ ...shipment . history ] . sort (
163+ ( a , b ) => new Date ( a . time ) . getTime ( ) - new Date ( b . time ) . getTime ( )
164+ ) ;
203165
204- // Always add Delivered (last)
205- events . push ( {
206- id : "delivered" ,
207- title : STATUS_LABELS [ "delivered" ] ,
208- location : `${ shipment . receiver ?. city || "Unknown" } , ${
209- shipment . receiver ?. country || "Unknown"
210- } `,
211- date : formatDate ( deliveryDate ) ,
212- time : formatTime ( deliveryDate ) ,
213- status : "delivered" ,
214- completed : shipment . status ?. toLowerCase ( ) === "delivered" ,
215- isFixed : true ,
216- } ) ;
166+ sortedHistory . forEach ( ( entry , index ) => {
167+ if ( entry . status ) {
168+ const entryTime = new Date ( entry . time ) ;
169+ events . push ( {
170+ id : `history-${ index } ` ,
171+ title : STATUS_LABELS [ entry . status . toLowerCase ( ) ] || entry . status ,
172+ location :
173+ entry . city && entry . country
174+ ? `${ entry . city } , ${ entry . country } `
175+ : entry . location
176+ ? `${ entry . location . lat ?. toFixed ( 2 ) ?? "" } , ${
177+ entry . location . lng ?. toFixed ( 2 ) ?? ""
178+ } `
179+ : entry . description || "Unknown" ,
180+ date : formatDate ( entryTime ) ,
181+ time : formatTime ( entryTime ) ,
182+ status : entry . status . toLowerCase ( ) ,
183+ completed : true ,
184+ isFixed : false ,
185+ } ) ;
186+ }
187+ } ) ;
188+ }
189+
190+ // Add delivery event (only if status is delivered)
191+ if ( shipment . status ?. toLowerCase ( ) === "delivered" ) {
192+ events . push ( {
193+ id : "delivered" ,
194+ title : STATUS_LABELS [ "delivered" ] ,
195+ location : `${ shipment . receiver ?. city || "Unknown" } , ${
196+ shipment . receiver ?. country || "Unknown"
197+ } `,
198+ date : formatDate ( deliveryDate ) ,
199+ time : formatTime ( deliveryDate ) ,
200+ status : "delivered" ,
201+ completed : true ,
202+ isFixed : true ,
203+ } ) ;
204+ } else {
205+ // Add expected delivery as pending event
206+ events . push ( {
207+ id : "expected-delivery" ,
208+ title : "Expected Delivery" ,
209+ location : `${ shipment . receiver ?. city || "Unknown" } , ${
210+ shipment . receiver ?. country || "Unknown"
211+ } `,
212+ date : formatDate ( deliveryDate ) ,
213+ time : formatTime ( deliveryDate ) ,
214+ status : "pending-delivery" ,
215+ completed : false ,
216+ isFixed : true ,
217+ } ) ;
218+ }
217219
218220 return events ;
219221 } ;
@@ -334,11 +336,11 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ shipment }) => {
334336 < div className = "mt-8 p-4 bg-gray-50 dark:bg-zinc-800/30 border border-gray-200 dark:border-zinc-700 rounded-lg" >
335337 < div className = "flex justify-between items-center text-sm" >
336338 < span className = "text-gray-600 dark:text-zinc-400" >
337- Total Updates: { timeline . length - 2 } { " " }
338- { /* Exclude fixed pending /delivery */ }
339+ Total Updates: { timeline . filter ( ( event ) => ! event . isFixed ) . length } { " " }
340+ { /* Exclude fixed creation /delivery events */ }
339341 </ span >
340342 < span className = "text-gray-600 dark:text-zinc-400" >
341- Status:{ " " }
343+ Current Status:{ " " }
342344 < span className = "text-gray-900 dark:text-white font-medium capitalize" >
343345 { shipment . status }
344346 </ span >
0 commit comments