paginate and sort UTXOs by value (#1031)

This commit is contained in:
kunal yadav 2026-02-08 22:54:29 +05:30 committed by GitHub
parent 1942955e19
commit 7c454482bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 99 additions and 34 deletions

View file

@ -18,6 +18,13 @@ import { buttonVariants } from '@/components/ui/button-variants'
import { Card, CardContent } from '@/components/ui/card'
import { CopyButton } from '@/components/ui/jam/CopyButton'
import { Label } from '@/components/ui/label'
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/pagination'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Spinner } from '@/components/ui/spinner'
import { Switch } from '@/components/ui/switch'
@ -50,6 +57,8 @@ export function CreateFidelityBondDialogSteps({ wizard }: CreateFidelityBondDial
jarsWithUtxos,
selectedUtxos,
availableUtxos,
utxoPage,
setUtxoPage,
toggleUtxoSelection,
selectAllUtxos,
deselectAllUtxos,
@ -233,40 +242,80 @@ export function CreateFidelityBondDialogSteps({ wizard }: CreateFidelityBondDial
</Button>
</div>
<div className="max-h-72 space-y-2 overflow-x-hidden overflow-y-auto pr-1">
{availableUtxos.map((utxo) => {
const isSelected = selectedUtxos.some((u) => u.utxo === utxo.utxo)
<div className="space-y-2">
{(() => {
const perPage = 5
const totalPages = Math.ceil(availableUtxos.length / perPage)
const page = Math.max(0, Math.min(utxoPage, totalPages - 1))
const paged = availableUtxos.slice(page * perPage, (page + 1) * perPage)
return (
<Card
key={utxo.utxo}
className={cn(
'cursor-pointer transition-all duration-200',
isSelected ? 'border-primary bg-primary/5 shadow-sm' : 'hover:bg-muted/30 hover:shadow-sm',
<>
{paged.map((utxo) => {
const isSelected = selectedUtxos.some((u) => u.utxo === utxo.utxo)
return (
<Card
key={utxo.utxo}
className={cn(
'cursor-pointer transition-all duration-200',
isSelected ? 'border-primary bg-primary/5 shadow-sm' : 'hover:bg-muted/30 hover:shadow-sm',
)}
onClick={() => toggleUtxoSelection(utxo)}
>
<CardContent className="flex items-center gap-3 p-3">
<div
className={cn(
'flex h-5 w-5 shrink-0 items-center justify-center rounded border-2 transition-all',
isSelected
? 'border-primary bg-primary text-primary-foreground'
: 'border-muted-foreground/40',
)}
>
{isSelected && <CheckIcon className="h-3.5 w-3.5" />}
</div>
<div className="min-w-0 flex-1 overflow-hidden">
<p className="truncate font-mono text-xs break-all">{utxo.utxo}</p>
<p className="text-muted-foreground mt-0.5 text-xs">
{t('earn.fidelity_bond.select_utxos.utxo_card.confirmations', {
confs: utxo.confirmations,
})}
</p>
</div>
<div className="shrink-0 text-right">
<p className="font-mono text-sm font-semibold whitespace-nowrap">
{formatSats(utxo.value)}
</p>
</div>
</CardContent>
</Card>
)
})}
{totalPages > 1 && (
<Pagination className="pt-2">
<PaginationContent>
<PaginationItem>
<PaginationPrevious
onClick={() => setUtxoPage(Math.max(0, page - 1))}
disabled={page === 0}
/>
</PaginationItem>
<PaginationItem>
<span className="text-muted-foreground px-2 text-sm">
{page + 1} / {totalPages}
</span>
</PaginationItem>
<PaginationItem>
<PaginationNext
onClick={() => setUtxoPage(Math.min(totalPages - 1, page + 1))}
disabled={page >= totalPages - 1}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
)}
onClick={() => toggleUtxoSelection(utxo)}
>
<CardContent className="flex items-center gap-3 p-3">
<div
className={cn(
'flex h-5 w-5 shrink-0 items-center justify-center rounded border-2 transition-all',
isSelected ? 'border-primary bg-primary text-primary-foreground' : 'border-muted-foreground/40',
)}
>
{isSelected && <CheckIcon className="h-3.5 w-3.5" />}
</div>
<div className="min-w-0 flex-1 overflow-hidden">
<p className="truncate font-mono text-xs break-all">{utxo.utxo}</p>
<p className="text-muted-foreground mt-0.5 text-xs">
{t('earn.fidelity_bond.select_utxos.utxo_card.confirmations', { confs: utxo.confirmations })}
</p>
</div>
<div className="shrink-0 text-right">
<p className="font-mono text-sm font-semibold whitespace-nowrap">{formatSats(utxo.value)}</p>
</div>
</CardContent>
</Card>
</>
)
})}
})()}
</div>
{selectedUtxos.length > 0 && (

View file

@ -34,6 +34,7 @@ export function useCreateFidelityBondWizard(
const [selectedJarIndex, setSelectedJarIndex] = useState<JarIndex | undefined>()
const [selectedUtxos, setSelectedUtxos] = useState<Utxo[]>([])
const [frozenUtxos, setFrozenUtxos] = useState<Utxo[]>([])
const [utxoPage, setUtxoPage] = useState(0)
const [confirmationChecked, setConfirmationChecked] = useState(false)
const [txResult, setTxResult] = useState<DirectSendResponse | undefined>()
const [error, setError] = useState<string | undefined>()
@ -77,7 +78,9 @@ export function useCreateFidelityBondWizard(
if (selectedJarIndex === undefined) return []
const jar = walletInfo.jars.find((it) => it.jarIndex === selectedJarIndex)
if (!jar) return []
return jar.utxos.filter((utxo) => !utxo.frozen && !fb.utxo.isFidelityBond(utxo))
return jar.utxos
.filter((utxo) => !utxo.frozen && !fb.utxo.isFidelityBond(utxo))
.toSorted((a, b) => b.value - a.value)
}, [walletInfo.jars, selectedJarIndex])
const utxosToFreeze = useMemo(() => {
@ -143,6 +146,7 @@ export function useCreateFidelityBondWizard(
setSelectedJarIndex(undefined)
setSelectedUtxos([])
setFrozenUtxos([])
setUtxoPage(0)
setConfirmationChecked(false)
setTxResult(undefined)
setError(undefined)
@ -162,16 +166,24 @@ export function useCreateFidelityBondWizard(
setStep('select_date')
break
case 'select_utxos':
setStep('select_jar')
setSelectedUtxos([])
if (jarsWithUtxos.length === 1) {
setSelectedJarIndex(undefined)
setSelectedUtxos([])
setStep('select_date')
} else {
setSelectedUtxos([])
setStep('select_jar')
}
break
case 'freeze_utxos':
setUtxoPage(0)
setStep('select_utxos')
break
case 'review':
if (utxosToFreeze.length > 0) {
setStep('freeze_utxos')
} else {
setUtxoPage(0)
setStep('select_utxos')
}
break
@ -184,12 +196,14 @@ export function useCreateFidelityBondWizard(
case 'select_date':
if (jarsWithUtxos.length === 1) {
setSelectedJarIndex(jarsWithUtxos[0].jarIndex)
setUtxoPage(0)
setStep('select_utxos')
} else {
setStep('select_jar')
}
break
case 'select_jar':
setUtxoPage(0)
setStep('select_utxos')
break
case 'select_utxos':
@ -324,6 +338,8 @@ export function useCreateFidelityBondWizard(
jarsWithUtxos,
selectedUtxos,
availableUtxos,
utxoPage,
setUtxoPage,
toggleUtxoSelection,
selectAllUtxos,
deselectAllUtxos,