@@ -5,25 +5,22 @@ import React, { useState, useTransition } from 'react';
55
66import { Mappings , Utils } from '@o2s/utils.frontend' ;
77
8- import { cn } from '@o2s/ui/lib/utils' ;
9-
108import { toast } from '@o2s/ui/hooks/use-toast' ;
119
1210import { useGlobalContext } from '@o2s/ui/providers/GlobalProvider' ;
1311
12+ import { DataList } from '@o2s/ui/components/DataList' ;
13+ import type { DataListColumnConfig } from '@o2s/ui/components/DataList' ;
1414import { FiltersSection } from '@o2s/ui/components/Filters' ;
1515import { NoResults } from '@o2s/ui/components/NoResults' ;
1616import { Pagination } from '@o2s/ui/components/Pagination' ;
17- import { Price } from '@o2s/ui/components/Price' ;
1817
19- import { Badge } from '@o2s/ui/elements/badge' ;
2018import { Button } from '@o2s/ui/elements/button' ;
2119import { Link } from '@o2s/ui/elements/link' ;
2220import { LoadingOverlay } from '@o2s/ui/elements/loading-overlay' ;
2321import { Separator } from '@o2s/ui/elements/separator' ;
24- import { Table , TableBody , TableCell , TableHead , TableHeader , TableRow } from '@o2s/ui/elements/table' ;
2522
26- import { Request } from '../api-harmonization/invoice-list.client' ;
23+ import { Model , Request } from '../api-harmonization/invoice-list.client' ;
2724import { sdk } from '../sdk' ;
2825
2926import { InvoiceListPureProps } from './InvoiceList.types' ;
@@ -74,6 +71,65 @@ export const InvoiceListPure: React.FC<InvoiceListPureProps> = ({ locale, access
7471 }
7572 } ;
7673
74+ // Define columns configuration outside JSX for better readability
75+ const columns = data . table . data . columns . map ( ( column ) => {
76+ switch ( column . id ) {
77+ case 'type' :
78+ return {
79+ ...column ,
80+ type : 'text' ,
81+ cellClassName : 'max-w-[100px] md:max-w-sm' ,
82+ } ;
83+ case 'paymentStatus' :
84+ return {
85+ ...column ,
86+ type : 'badge' ,
87+ variant : ( value : string ) =>
88+ Mappings . InvoiceBadge . invoiceBadgePaymentStatusVariants [
89+ value as keyof typeof Mappings . InvoiceBadge . invoiceBadgePaymentStatusVariants
90+ ] ,
91+ } ;
92+ case 'paymentDueDate' :
93+ return {
94+ ...column ,
95+ type : 'date' ,
96+ } ;
97+ case 'totalAmountDue' :
98+ case 'totalNetAmountDue' :
99+ return {
100+ ...column ,
101+ type : 'price' ,
102+ headerClassName : 'text-right' ,
103+ cellClassName : 'text-right' ,
104+ config : { currencyKey : 'currency' } ,
105+ } ;
106+ default :
107+ return {
108+ ...column ,
109+ type : 'text' ,
110+ } ;
111+ }
112+ } ) as DataListColumnConfig < Model . Invoice > [ ] ;
113+
114+ const actions = data . table . data . actions
115+ ? {
116+ ...data . table . data . actions ,
117+ render : ( invoice : Model . Invoice ) => (
118+ < Link asChild >
119+ < Button
120+ variant = "link"
121+ className = "flex items-center justify-end gap-2"
122+ onClick = { ( ) => handleDownload ( invoice . id ) }
123+ aria-description = { data . downloadButtonAriaDescription ?. replace ( '{id}' , invoice . id ) }
124+ >
125+ < Download className = "h-4 w-4" />
126+ { data . table . data . actions ! . label }
127+ </ Button >
128+ </ Link >
129+ ) ,
130+ }
131+ : undefined ;
132+
77133 return (
78134 < div className = "w-full" >
79135 { initialData . length > 0 ? (
@@ -91,121 +147,12 @@ export const InvoiceListPure: React.FC<InvoiceListPureProps> = ({ locale, access
91147 < LoadingOverlay isActive = { isPending } >
92148 { data . invoices . data . length ? (
93149 < div className = "flex flex-col gap-6" >
94- < Table >
95- < TableHeader >
96- < TableRow >
97- { data . table . data . columns . map ( ( column ) => (
98- < TableHead
99- key = { column . id }
100- className = { cn (
101- 'py-3 px-4 text-sm text-muted-foreground md:text-nowrap' ,
102- column . id === 'totalAmountDue' && 'text-right' ,
103- column . id === 'totalNetAmountDue' && 'text-right' ,
104- ) }
105- >
106- { column . title }
107- </ TableHead >
108- ) ) }
109- { data . table . data . actions && (
110- < TableHead className = "py-3 px-4 text-sm text-muted-foreground md:text-nowrap" >
111- { data . table . data . actions . title }
112- </ TableHead >
113- ) }
114- </ TableRow >
115- </ TableHeader >
116- < TableBody >
117- { data . invoices . data . map ( ( invoice ) => {
118- return (
119- < TableRow key = { invoice . id } >
120- { data . table . data . columns . map ( ( column ) => {
121- switch ( column . id ) {
122- case 'type' :
123- return (
124- < TableCell
125- key = { column . id }
126- className = "max-w-[100px] md:max-w-sm truncate whitespace-nowrap"
127- >
128- { invoice [ column . id ] . displayValue }
129- </ TableCell >
130- ) ;
131- case 'id' :
132- return (
133- < TableCell
134- key = { column . id }
135- className = "truncate whitespace-nowrap"
136- >
137- { invoice [ column . id ] }
138- </ TableCell >
139- ) ;
140- case 'paymentStatus' :
141- return (
142- < TableCell
143- key = { column . id }
144- className = "whitespace-nowrap"
145- >
146- < Badge
147- variant = {
148- Mappings . InvoiceBadge
149- . invoiceBadgePaymentStatusVariants [
150- invoice . paymentStatus . value
151- ]
152- }
153- >
154- { invoice [ column . id ] . displayValue }
155- </ Badge >
156- </ TableCell >
157- ) ;
158- case 'paymentDueDate' :
159- return (
160- < TableCell
161- key = { column . id }
162- className = "whitespace-nowrap truncate"
163- >
164- { invoice [ column . id ] . displayValue }
165- </ TableCell >
166- ) ;
167- case 'totalAmountDue' :
168- case 'totalNetAmountDue' :
169- return (
170- < TableCell
171- key = { column . id }
172- className = "whitespace-nowrap text-right truncate"
173- >
174- < Price
175- price = { {
176- value : invoice [ column . id ] . value ,
177- currency : invoice . currency ,
178- } }
179- />
180- </ TableCell >
181- ) ;
182- default :
183- return null ;
184- }
185- } ) }
186- { data . table . data . actions && (
187- < TableCell className = "py-0" >
188- < Link asChild >
189- < Button
190- variant = "link"
191- className = "flex items-center justify-end gap-2"
192- onClick = { ( ) => handleDownload ( invoice . id ) }
193- aria-description = { data . downloadButtonAriaDescription ?. replace (
194- '{id}' ,
195- invoice . id ,
196- ) }
197- >
198- < Download className = "h-4 w-4" />
199- { data . table . data . actions . label }
200- </ Button >
201- </ Link >
202- </ TableCell >
203- ) }
204- </ TableRow >
205- ) ;
206- } ) }
207- </ TableBody >
208- </ Table >
150+ < DataList
151+ data = { data . invoices . data }
152+ getRowKey = { ( invoice ) => invoice . id }
153+ columns = { columns }
154+ actions = { actions }
155+ />
209156
210157 { data . pagination && (
211158 < Pagination
0 commit comments