11"use client" ;
22
3- import React from "react" ;
3+ import React , { useState , useEffect } from "react" ;
4+ import { Server } from "soroban-client" ;
45import StickyHeader from "../../../components/StickyHeader" ;
6+ import FractionalPurchaseModal , {
7+ type Invoice ,
8+ } from "../../../components/FractionalPurchaseModal" ;
9+ import { useTokenStore } from "../../../stores/tokenStore" ;
510import { ArrowLeft , ExternalLink , Shield , TrendingUp } from "lucide-react" ;
611import Link from "next/link" ;
7- import { useInvoice } from "@/hooks/useInvoice" ;
812
9- const INVOICE_ID = "INV-00123" ;
13+ // Stellar testnet USDC issuer
14+ const USDC_CODE = "USDC" ;
15+ const USDC_ISSUER = "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5" ;
16+
17+ const server = new Server ( "https://soroban-testnet.stellar.org" , {
18+ allowHttp : true ,
19+ } ) ;
20+
21+ // TODO: Replace with real invoice data from your API / contract query
22+ const INVOICE_DATA : Invoice = {
23+ id : "INV-00123" ,
24+ faceValue : 50000 ,
25+ apy : 8.5 ,
26+ dueDate : "2026-12-15" ,
27+ currency : "USDC" ,
28+ } ;
1029
1130export default function InvoiceDetailPage ( ) {
12- const { invoice, loading, error } = useInvoice ( INVOICE_ID ) ;
31+ const { publicKey, isConnected } = useTokenStore ( ) ;
32+ const [ showBuyModal , setShowBuyModal ] = useState ( false ) ;
33+ const [ usdcBalance , setUsdcBalance ] = useState ( "0" ) ;
34+
35+ // Fetch live USDC balance from Stellar network whenever wallet connects
36+ useEffect ( ( ) => {
37+ if ( ! isConnected || ! publicKey ) {
38+ setUsdcBalance ( "0" ) ;
39+ return ;
40+ }
41+
42+ const fetchBalance = async ( ) => {
43+ try {
44+ const accountResponse = await server . accounts ( ) . accountId ( publicKey ) . call ( ) ;
45+ const usdcEntry = accountResponse . balances . find (
46+ ( b : any ) =>
47+ b . asset_code === USDC_CODE && b . asset_issuer === USDC_ISSUER
48+ ) ;
49+ setUsdcBalance ( usdcEntry ? usdcEntry . balance : "0" ) ;
50+ } catch {
51+ setUsdcBalance ( "0" ) ;
52+ }
53+ } ;
54+
55+ fetchBalance ( ) ;
56+ } , [ isConnected , publicKey ] ) ;
57+
58+ const handleBuyFraction = async (
59+ amountStroops : string ,
60+ invoiceId : string
61+ ) => {
62+ // TODO: Replace with your real Soroban client call, e.g.:
63+ // await sorobanClient.buy_fraction({
64+ // invoice_id: invoiceId,
65+ // amount: BigInt(amountStroops),
66+ // });
67+ console . log ( "buy_fraction called:" , { invoiceId, amountStroops } ) ;
68+ await new Promise ( ( r ) => setTimeout ( r , 1500 ) ) ;
69+ } ;
1370
1471 return (
1572 < div className = "min-h-screen bg-tradeflow-dark text-white font-sans" >
73+ { /* Sticky Header */ }
1674 < StickyHeader
1775 title = "INV-123"
1876 subtitle = "Real World Asset token details and performance metrics"
@@ -25,7 +83,10 @@ export default function InvoiceDetailPage() {
2583 < ArrowLeft size = { 16 } />
2684 Back
2785 </ Link >
28- < button className = "flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors" >
86+ < button
87+ onClick = { ( ) => setShowBuyModal ( true ) }
88+ className = "flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
89+ >
2990 < ExternalLink size = { 16 } />
3091 Trade
3192 </ button >
@@ -35,6 +96,7 @@ export default function InvoiceDetailPage() {
3596
3697 < div className = "px-4 lg:px-8 py-6" >
3798 < div className = "grid grid-cols-1 lg:grid-cols-3 gap-6" >
99+ { /* Left Column */ }
38100 < div className = "lg:col-span-2 space-y-6" >
39101 { /* Invoice Overview */ }
40102 < div className = "bg-slate-800/50 rounded-xl border border-slate-700/50 p-6" >
@@ -75,10 +137,8 @@ export default function InvoiceDetailPage() {
75137 </ p >
76138 </ div >
77139 < div >
78- < p className = "text-slate-400 text-sm mb-1" > Issuer</ p >
79- < p className = "font-mono text-sm truncate text-slate-300" >
80- { invoice ?. issuer ?? "—" }
81- </ p >
140+ < p className = "text-slate-400 text-sm mb-1" > Maturity Date</ p >
141+ < p className = "font-medium" > Dec 15, 2026</ p >
82142 </ div >
83143 < div >
84144 < p className = "text-slate-400 text-sm mb-1" > Status</ p >
@@ -112,7 +172,10 @@ export default function InvoiceDetailPage() {
112172 { date : "2024-01-01" , type : "Payment" , amount : "$2,125" , status : "Completed" } ,
113173 { date : "2023-12-15" , type : "Initial" , amount : "$50,000" , status : "Completed" } ,
114174 ] . map ( ( tx , index ) => (
115- < div key = { index } className = "flex items-center justify-between p-3 bg-slate-700/30 rounded-lg" >
175+ < div
176+ key = { index }
177+ className = "flex items-center justify-between p-3 bg-slate-700/30 rounded-lg"
178+ >
116179 < div >
117180 < p className = "font-medium" > { tx . type } </ p >
118181 < p className = "text-slate-400 text-sm" > { tx . date } </ p >
@@ -135,19 +198,31 @@ export default function InvoiceDetailPage() {
135198 < h2 className = "text-xl font-semibold" > Risk Assessment</ h2 >
136199 </ div >
137200 < div className = "space-y-4" >
138- { [
139- { label : "Credit Score" , value : "A+" , width : "85%" , color : "bg-green-500" } ,
140- { label : "Collateral Ratio" , value : "150%" , width : "75%" , color : "bg-blue-500" } ,
141- { label : "Liquidity Score" , value : "High" , width : "90%" , color : "bg-purple-500" } ,
142- ] . map ( ( item ) => (
143- < div key = { item . label } >
144- < div className = "flex justify-between mb-1" >
145- < span className = "text-sm" > { item . label } </ span >
146- < span className = "text-sm font-medium" > { item . value } </ span >
147- </ div >
148- < div className = "w-full bg-slate-700 h-2 rounded-full" >
149- < div className = { `${ item . color } h-2 rounded-full` } style = { { width : item . width } } />
150- </ div >
201+ < div >
202+ < div className = "flex justify-between mb-1" >
203+ < span className = "text-sm" > Credit Score</ span >
204+ < span className = "text-sm font-medium" > A+</ span >
205+ </ div >
206+ < div className = "w-full bg-slate-700 h-2 rounded-full" >
207+ < div className = "bg-green-500 h-2 rounded-full" style = { { width : "85%" } } />
208+ </ div >
209+ </ div >
210+ < div >
211+ < div className = "flex justify-between mb-1" >
212+ < span className = "text-sm" > Collateral Ratio</ span >
213+ < span className = "text-sm font-medium" > 150%</ span >
214+ </ div >
215+ < div className = "w-full bg-slate-700 h-2 rounded-full" >
216+ < div className = "bg-blue-500 h-2 rounded-full" style = { { width : "75%" } } />
217+ </ div >
218+ </ div >
219+ < div >
220+ < div className = "flex justify-between mb-1" >
221+ < span className = "text-sm" > Liquidity Score</ span >
222+ < span className = "text-sm font-medium" > High</ span >
223+ </ div >
224+ < div className = "w-full bg-slate-700 h-2 rounded-full" >
225+ < div className = "bg-purple-500 h-2 rounded-full" style = { { width : "90%" } } />
151226 </ div >
152227 ))}
153228 </ div >
@@ -156,8 +231,11 @@ export default function InvoiceDetailPage() {
156231 < div className = "bg-slate-800/50 rounded-xl border border-slate-700/50 p-6" >
157232 < h2 className = "text-xl font-semibold mb-4" > Quick Actions</ h2 >
158233 < div className = "space-y-3" >
159- < button className = "w-full px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors" >
160- Buy More Tokens
234+ < button
235+ onClick = { ( ) => setShowBuyModal ( true ) }
236+ className = "w-full px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
237+ >
238+ Buy Fraction
161239 </ button >
162240 < button className = "w-full px-4 py-2 bg-slate-700 hover:bg-slate-600 rounded-lg transition-colors" >
163241 View Documents
@@ -170,6 +248,16 @@ export default function InvoiceDetailPage() {
170248 </ div >
171249 </ div >
172250 </ div >
251+
252+ { /* Fractional Purchase Modal */ }
253+ { showBuyModal && (
254+ < FractionalPurchaseModal
255+ invoice = { INVOICE_DATA }
256+ walletBalance = { usdcBalance }
257+ onClose = { ( ) => setShowBuyModal ( false ) }
258+ onBuyFraction = { handleBuyFraction }
259+ />
260+ ) }
173261 </ div >
174262 );
175263}
0 commit comments