@@ -5,8 +5,12 @@ import { useRouter } from "next/navigation";
55import { splitClient , payWithNonce } from "@/lib/stellar" ;
66import { getFreighterPublicKey } from "@/lib/freighter" ;
77import { formatAmount , parseAmount , truncateAddress } from "@stellar-split/sdk" ;
8- import type { Invoice , Payment } from "@stellar-split/sdk" ;
9- import PaymentProgress from "@/components/PaymentProgress" ;
8+ import { useInvoiceCustomization } from "@/lib/customization" ;
9+ import type { Locale } from "@/lib/i18n" ;
10+ import PaymentSuggestions from "@/components/PaymentSuggestions" ;
11+ import FundingProgress from "@/components/FundingProgress" ;
12+ import StatusBadge from "@/components/StatusBadge" ;
13+ import { InvoiceDetailSkeleton } from "@/components/Skeleton" ;
1014import PayModal from "@/components/PayModal" ;
1115import PaymentMethodSelector from "@/components/PaymentMethodSelector" ;
1216import CountdownTimer from "@/components/CountdownTimer" ;
@@ -127,29 +131,14 @@ export default function InvoiceDetailPage({ params }: Props) {
127131
128132 if ( error && ! invoice ) {
129133 return (
130- < main className = "max-w-2xl mx-auto px-4 sm:px-6 py-20 text-center" >
131- < div className = "bg-red-950/40 border border-red-800 rounded-xl p-6" >
132- < p className = "text-red-400 text-lg mb-2" > Failed to load invoice</ p >
133- < p className = "text-red-300/70 text-sm" > { error } </ p >
134- < button
135- type = "button"
136- onClick = { ( ) => { setLoading ( true ) ; setError ( null ) ; load ( ) ; } }
137- className = "mt-4 px-4 py-2 rounded-lg bg-red-700 hover:bg-red-600 text-sm font-medium transition-colors"
138- >
139- Retry
140- </ button >
141- </ div >
134+ < main className = "max-w-xl mx-auto w-full px-4 sm:px-6 py-20 overflow-x-hidden" >
135+ < InvoiceDetailSkeleton />
142136 </ main >
143137 ) ;
144138 }
145139
146140 if ( ! invoice ) return null ;
147141
148- const isCreator = publicKey === invoice . creator ;
149- const status = statusConfig [ invoice . status ] ?? statusConfig . Pending ;
150- const remaining = total - invoice . funded ;
151- const percentFunded = total > 0n ? Number ( ( invoice . funded * 100n ) / total ) : 0 ;
152-
153142 return (
154143 < main className = "max-w-2xl mx-auto px-4 sm:px-6 py-16" >
155144 { /* Header */ }
@@ -165,7 +154,14 @@ export default function InvoiceDetailPage({ params }: Props) {
165154 < span > { status . label } </ span >
166155 </ span >
167156 </ div >
168- < div className = "flex items-center gap-2" >
157+
158+ < div className = "mb-6" >
159+ < FlowDiagram invoice = { invoice } />
160+ </ div >
161+
162+ < CloneLineageTree invoiceId = { id } />
163+ < StatusBadge status = { invoice . status as any } size = "md" />
164+ < div className = "ml-auto flex items-center gap-2 print:hidden flex-wrap justify-end" >
169165 < CopyLinkButton url = { `${ typeof window !== "undefined" ? window . location . origin : "" } /verify/${ id } ` } />
170166 { isCreator && invoice . status === "Pending" && (
171167 < >
@@ -217,22 +213,20 @@ export default function InvoiceDetailPage({ params }: Props) {
217213 </ div >
218214
219215 { /* Progress */ }
220- < section className = "mb-8" >
221- < div className = "flex items-center justify-between mb-2" >
222- < h2 className = "text-lg font-semibold text-white" > Funding Progress</ h2 >
223- < span className = "text-sm text-gray-400" > { percentFunded } %</ span >
224- </ div >
225- < PaymentProgress funded = { invoice . funded } total = { total } />
226- < div className = "flex justify-between mt-2" >
227- < p className = "text-sm text-gray-400" >
228- < span className = "text-indigo-300 font-medium" > { formatAmount ( invoice . funded ) } USDC</ span >
229- { " / " }
230- { formatAmount ( total ) } USDC
216+ < section aria-labelledby = "progress-heading" className = "mb-8" >
217+ < h2 id = "progress-heading" className = "sr-only" > Payment Progress</ h2 >
218+ < FundingProgress funded = { invoice . funded } total = { total } token = { invoice . token || "USDC" } />
219+ { channelState ?. opened && (
220+ < p className = "text-sm text-indigo-300 mt-1" >
221+ · Channel balance: { formatAmount ( channelState . balance ) } USDC
231222 </ p >
232- { remaining > 0n && (
233- < p className = "text-sm text-gray-500" > { formatAmount ( remaining ) } USDC remaining</ p >
234- ) }
235- </ div >
223+ ) }
224+ { invoice . deadline > 0 && (
225+ < div className = "flex items-center gap-2 mt-3" >
226+ < span className = "text-sm text-gray-400" > Time remaining:</ span >
227+ < CountdownTimer deadline = { invoice . deadline } />
228+ </ div >
229+ ) }
236230 </ section >
237231
238232 { /* QR */ }
0 commit comments