@@ -61,6 +61,23 @@ export default async function AdminOrdersPage({
6161 const hasNext = all . length > PAGE_SIZE ;
6262 const items = all . slice ( 0 , PAGE_SIZE ) ;
6363
64+ const viewModels = items . map ( order => {
65+ const currency = orderCurrency ( order , locale ) ;
66+ const totalMinor = pickMinor ( order ?. totalAmountMinor , order ?. totalAmount ) ;
67+
68+ return {
69+ id : order . id ,
70+ createdAt : formatDate ( order . createdAt , locale ) ,
71+ paymentStatus : order . paymentStatus ,
72+ totalFormatted :
73+ totalMinor === null ? '-' : formatMoney ( totalMinor , currency , locale ) ,
74+ itemCount : order . itemCount ,
75+ paymentProvider : order . paymentProvider ?? '-' ,
76+ viewHref : `/shop/admin/orders/${ order . id } ` ,
77+ viewAriaLabel : `View order ${ order . id } ` ,
78+ } ;
79+ } ) ;
80+
6481 return (
6582 < >
6683 < ShopAdminTopbar />
@@ -91,84 +108,72 @@ export default async function AdminOrdersPage({
91108 < section className = "mt-6" aria-label = "Orders list" >
92109 { /* Mobile cards */ }
93110 < div className = "md:hidden" >
94- { items . length === 0 ? (
111+ { viewModels . length === 0 ? (
95112 < div className = "rounded-md border border-border p-4 text-sm text-muted-foreground" >
96113 No orders yet.
97114 </ div >
98115 ) : (
99116 < ul className = "space-y-3" >
100- { items . map ( order => {
101- const currency = orderCurrency ( order , locale ) ;
102- const totalMinor = pickMinor (
103- order ?. totalAmountMinor ,
104- order ?. totalAmount
105- ) ;
106- const totalFormatted =
107- totalMinor === null
108- ? '-'
109- : formatMoney ( totalMinor , currency , locale ) ;
110-
111- return (
112- < li
113- key = { order . id }
114- className = "rounded-lg border border-border bg-background p-4"
115- >
116- < div className = "flex items-start justify-between gap-3" >
117- < div className = "min-w-0" >
118- < div className = "text-xs text-muted-foreground" >
119- { formatDate ( order . createdAt , locale ) }
120- </ div >
121- < div className = "mt-1" >
122- < span className = "inline-flex rounded-full bg-muted px-2 py-1 text-xs font-medium text-foreground" >
123- { order . paymentStatus }
124- </ span >
125- </ div >
117+ { viewModels . map ( vm => (
118+ < li
119+ key = { vm . id }
120+ className = "rounded-lg border border-border bg-background p-4"
121+ >
122+ < div className = "flex items-start justify-between gap-3" >
123+ < div className = "min-w-0" >
124+ < div className = "text-xs text-muted-foreground" >
125+ { vm . createdAt }
126126 </ div >
127-
128- < div className = "shrink-0 whitespace-nowrap text-right text-sm font-medium text-foreground" >
129- { totalFormatted }
127+ < div className = "mt-1" >
128+ < span className = "inline-flex rounded-full bg-muted px-2 py-1 text-xs font-medium text-foreground" >
129+ { vm . paymentStatus }
130+ </ span >
130131 </ div >
131132 </ div >
132133
133- < dl className = "mt-3 grid grid-cols-2 gap-x-3 gap-y-2 text-xs" >
134- < div >
135- < dt className = "text-muted-foreground" > Items</ dt >
136- < dd className = "text-foreground" > { order . itemCount } </ dd >
137- </ div >
134+ < div className = "shrink-0 whitespace-nowrap text-right text-sm font-medium text-foreground" >
135+ { vm . totalFormatted }
136+ </ div >
137+ </ div >
138138
139- < div className = "min-w-0" >
140- < dt className = "text-muted-foreground" > Provider</ dt >
141- < dd
142- className = "truncate text-foreground"
143- title = { order . paymentProvider ?? '-' }
144- >
145- { order . paymentProvider ?? '-' }
146- </ dd >
147- </ div >
139+ < dl className = "mt-3 grid grid-cols-2 gap-x-3 gap-y-2 text-xs" >
140+ < div >
141+ < dt className = "text-muted-foreground" > Items</ dt >
142+ < dd className = "text-foreground" > { vm . itemCount } </ dd >
143+ </ div >
148144
149- < div className = "col-span-2" >
150- < dt className = "text-muted-foreground" > Order ID</ dt >
151- < dd
152- className = "break-all font-mono text-[11px] text-muted-foreground"
153- title = { order . id }
154- >
155- { order . id }
156- </ dd >
157- </ div >
158- </ dl >
145+ < div className = "min-w-0" >
146+ < dt className = "text-muted-foreground" > Provider</ dt >
147+ < dd
148+ className = "truncate text-foreground"
149+ title = { vm . paymentProvider }
150+ >
151+ { vm . paymentProvider }
152+ </ dd >
153+ </ div >
159154
160- < div className = "mt-3 " >
161- < Link
162- href = { `/shop/admin/orders/ ${ order . id } ` }
163- className = "inline-flex items-center justify-center rounded-md border border-border px-2 py-1 text-xs font-medium text-foreground transition-colors hover:bg-secondary "
164- aria-label = { `View order ${ order . id } ` }
155+ < div className = "col-span-2 " >
156+ < dt className = "text-muted-foreground" > Order ID </ dt >
157+ < dd
158+ className = "break-all font-mono text-[11px] text-muted-foreground "
159+ title = { vm . id }
165160 >
166- View
167- </ Link >
161+ { vm . id }
162+ </ dd >
168163 </ div >
169- </ li >
170- ) ;
171- } ) }
164+ </ dl >
165+
166+ < div className = "mt-3" >
167+ < Link
168+ href = { vm . viewHref }
169+ className = "inline-flex items-center justify-center rounded-md border border-border px-2 py-1 text-xs font-medium text-foreground transition-colors hover:bg-secondary"
170+ aria-label = { vm . viewAriaLabel }
171+ >
172+ View
173+ </ Link >
174+ </ div >
175+ </ li >
176+ ) ) }
172177 </ ul >
173178 ) }
174179 </ div >
@@ -227,7 +232,7 @@ export default async function AdminOrdersPage({
227232 </ thead >
228233
229234 < tbody className = "divide-y divide-border" >
230- { items . length === 0 ? (
235+ { viewModels . length === 0 ? (
231236 < tr >
232237 < td
233238 className = "px-3 py-6 text-muted-foreground"
@@ -237,57 +242,45 @@ export default async function AdminOrdersPage({
237242 </ td >
238243 </ tr >
239244 ) : (
240- items . map ( order => {
241- const currency = orderCurrency ( order , locale ) ;
242- const totalMinor = pickMinor (
243- order ?. totalAmountMinor ,
244- order ?. totalAmount
245- ) ;
246- const totalFormatted =
247- totalMinor === null
248- ? '-'
249- : formatMoney ( totalMinor , currency , locale ) ;
250-
251- return (
252- < tr key = { order . id } className = "hover:bg-muted/50" >
253- < td className = "px-3 py-2 text-muted-foreground whitespace-nowrap" >
254- { formatDate ( order . createdAt , locale ) }
255- </ td >
256-
257- < td className = "px-3 py-2 whitespace-nowrap" >
258- < span className = "inline-flex rounded-full bg-muted px-2 py-1 text-xs font-medium text-foreground" >
259- { order . paymentStatus }
260- </ span >
261- </ td >
262-
263- < td className = "px-3 py-2 text-foreground whitespace-nowrap" >
264- { totalFormatted }
265- </ td >
266-
267- < td className = "px-3 py-2 text-muted-foreground whitespace-nowrap" >
268- { order . itemCount }
269- </ td >
270-
271- < td className = "px-3 py-2 text-muted-foreground whitespace-nowrap" >
272- { order . paymentProvider ?? '-' }
273- </ td >
274-
275- < td className = "px-3 py-2 font-mono text-xs text-muted-foreground break-all" >
276- { order . id }
277- </ td >
278-
279- < td className = "px-3 py-2 whitespace-nowrap" >
280- < Link
281- href = { `/shop/admin/orders/${ order . id } ` }
282- className = "rounded-md border border-border px-2 py-1 text-xs font-medium text-foreground transition-colors hover:bg-secondary"
283- aria-label = { `View order ${ order . id } ` }
284- >
285- View
286- </ Link >
287- </ td >
288- </ tr >
289- ) ;
290- } )
245+ viewModels . map ( vm => (
246+ < tr key = { vm . id } className = "hover:bg-muted/50" >
247+ < td className = "px-3 py-2 text-muted-foreground whitespace-nowrap" >
248+ { vm . createdAt }
249+ </ td >
250+
251+ < td className = "px-3 py-2 whitespace-nowrap" >
252+ < span className = "inline-flex rounded-full bg-muted px-2 py-1 text-xs font-medium text-foreground" >
253+ { vm . paymentStatus }
254+ </ span >
255+ </ td >
256+
257+ < td className = "px-3 py-2 text-foreground whitespace-nowrap" >
258+ { vm . totalFormatted }
259+ </ td >
260+
261+ < td className = "px-3 py-2 text-muted-foreground whitespace-nowrap" >
262+ { vm . itemCount }
263+ </ td >
264+
265+ < td className = "px-3 py-2 text-muted-foreground whitespace-nowrap" >
266+ { vm . paymentProvider }
267+ </ td >
268+
269+ < td className = "px-3 py-2 font-mono text-xs text-muted-foreground break-all" >
270+ { vm . id }
271+ </ td >
272+
273+ < td className = "px-3 py-2 whitespace-nowrap" >
274+ < Link
275+ href = { vm . viewHref }
276+ className = "rounded-md border border-border px-2 py-1 text-xs font-medium text-foreground transition-colors hover:bg-secondary"
277+ aria-label = { vm . viewAriaLabel }
278+ >
279+ View
280+ </ Link >
281+ </ td >
282+ </ tr >
283+ ) )
291284 ) }
292285 </ tbody >
293286 </ table >
0 commit comments