Update paddle, and support invoice line item
This commit is contained in:
128
frontend/src/components/LineItemsTable.tsx
Normal file
128
frontend/src/components/LineItemsTable.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import React from 'react'
|
||||
import { CheckCircle2, MinusCircle } from 'lucide-react'
|
||||
import type { LineItemsResult } from '../api/types'
|
||||
|
||||
interface LineItemsTableProps {
|
||||
lineItems: LineItemsResult
|
||||
}
|
||||
|
||||
export const LineItemsTable: React.FC<LineItemsTableProps> = ({ lineItems }) => {
|
||||
if (!lineItems.items || lineItems.items.length === 0) {
|
||||
return (
|
||||
<div className="text-center py-8 text-warm-text-muted">
|
||||
No line items found in this document
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-warm-divider">
|
||||
<th className="text-left py-3 px-4 font-semibold text-warm-text-muted text-xs uppercase tracking-wide">
|
||||
#
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-semibold text-warm-text-muted text-xs uppercase tracking-wide">
|
||||
Description
|
||||
</th>
|
||||
<th className="text-right py-3 px-4 font-semibold text-warm-text-muted text-xs uppercase tracking-wide">
|
||||
Qty
|
||||
</th>
|
||||
<th className="text-right py-3 px-4 font-semibold text-warm-text-muted text-xs uppercase tracking-wide">
|
||||
Unit Price
|
||||
</th>
|
||||
<th className="text-right py-3 px-4 font-semibold text-warm-text-muted text-xs uppercase tracking-wide">
|
||||
Amount
|
||||
</th>
|
||||
<th className="text-right py-3 px-4 font-semibold text-warm-text-muted text-xs uppercase tracking-wide">
|
||||
VAT %
|
||||
</th>
|
||||
<th className="text-center py-3 px-4 font-semibold text-warm-text-muted text-xs uppercase tracking-wide">
|
||||
Conf.
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{lineItems.items.map((item) => (
|
||||
<tr
|
||||
key={`row-${item.row_index}`}
|
||||
className={`border-b border-warm-divider hover:bg-warm-hover/50 transition-colors ${
|
||||
item.is_deduction ? 'bg-red-50' : ''
|
||||
}`}
|
||||
>
|
||||
<td className="py-3 px-4 text-warm-text-muted font-mono text-xs">
|
||||
{item.row_index}
|
||||
</td>
|
||||
<td className="py-3 px-4 font-medium max-w-xs truncate">
|
||||
<div className="flex items-center gap-2">
|
||||
{item.is_deduction && (
|
||||
<MinusCircle size={14} className="text-red-500 flex-shrink-0" />
|
||||
)}
|
||||
<span className={item.is_deduction ? 'text-red-600' : 'text-warm-text-primary'}>
|
||||
{item.description || '-'}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td className="py-3 px-4 text-right text-warm-text-primary font-mono">
|
||||
{item.quantity || '-'}
|
||||
{item.unit && (
|
||||
<span className="text-warm-text-muted ml-1">{item.unit}</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="py-3 px-4 text-right text-warm-text-primary font-mono">
|
||||
{item.unit_price || '-'}
|
||||
</td>
|
||||
<td className={`py-3 px-4 text-right font-bold font-mono ${
|
||||
item.is_deduction ? 'text-red-600' : 'text-warm-text-primary'
|
||||
}`}>
|
||||
{item.amount || '-'}
|
||||
</td>
|
||||
<td className="py-3 px-4 text-right text-warm-text-secondary font-mono">
|
||||
{item.vat_rate ? `${item.vat_rate}%` : '-'}
|
||||
</td>
|
||||
<td className="py-3 px-4 text-center">
|
||||
<div className="flex items-center justify-center gap-1">
|
||||
<CheckCircle2
|
||||
size={14}
|
||||
className={
|
||||
item.confidence >= 0.8
|
||||
? 'text-green-500'
|
||||
: item.confidence >= 0.5
|
||||
? 'text-yellow-500'
|
||||
: 'text-red-500'
|
||||
}
|
||||
/>
|
||||
<span
|
||||
className={`text-xs font-medium ${
|
||||
item.confidence >= 0.8
|
||||
? 'text-green-600'
|
||||
: item.confidence >= 0.5
|
||||
? 'text-yellow-600'
|
||||
: 'text-red-600'
|
||||
}`}
|
||||
>
|
||||
{(item.confidence * 100).toFixed(0)}%
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{lineItems.total_amount && (
|
||||
<div className="flex justify-end pt-4 border-t border-warm-divider">
|
||||
<div className="text-right">
|
||||
<span className="text-sm text-warm-text-muted mr-4">Total:</span>
|
||||
<span className="text-lg font-bold text-warm-text-primary font-mono">
|
||||
{lineItems.total_amount} SEK
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user