22
33import type React from "react" ;
44
5- import { useState , useCallback , useRef } from "react" ;
5+ import { useState , useCallback , useRef , useEffect } from "react" ;
66import { Button } from "@/components/ui/button" ;
77import { Input } from "@/components/ui/input" ;
88import { Wallet } from "lucide-react" ;
@@ -15,26 +15,37 @@ interface TokenBuyInputProps {
1515 contractPrincipal : string ;
1616 disabled ?: boolean ;
1717 onSend : ( ) => void ;
18+ initialAmount ?: string ;
19+ onAmountChange ?: ( amount : string ) => void ;
1820}
1921
2022export function TokenBuyInput ( {
2123 tokenName,
2224 contractPrincipal,
2325 disabled = false ,
2426 onSend,
27+ initialAmount = "" ,
28+ onAmountChange,
2529} : TokenBuyInputProps ) {
26- const [ amount , setAmount ] = useState ( "" ) ;
30+ const [ amount , setAmount ] = useState ( initialAmount ) ;
2731 const inputRef = useRef < HTMLInputElement > ( null ) ;
2832 const containerRef = useRef < HTMLDivElement > ( null ) ;
2933 const { sendMessage, activeThreadId } = useChatStore ( ) ;
3034 const { accessToken } = useSessionStore ( ) ;
3135
36+ useEffect ( ( ) => {
37+ // Update amount when initialAmount prop changes
38+ if ( initialAmount ) {
39+ setAmount ( initialAmount ) ;
40+ }
41+ } , [ initialAmount ] ) ;
42+
3243 const handleSubmit = useCallback (
3344 async ( e : React . FormEvent ) => {
3445 e . preventDefault ( ) ;
3546 if ( ! amount . trim ( ) || ! accessToken || ! activeThreadId ) return ;
3647
37- const message = `Buy ${ amount } satoshis of ${ tokenName } .\nToken DEX: ${ contractPrincipal } ` ;
48+ const message = `Buy ${ tokenName } tokens worth ${ amount } satoshis .\nToken DEX: ${ contractPrincipal } ` ;
3849
3950 try {
4051 await sendMessage ( activeThreadId , message ) ;
@@ -55,11 +66,19 @@ export function TokenBuyInput({
5566 ]
5667 ) ;
5768
58- const handleChange = useCallback ( ( e : React . ChangeEvent < HTMLInputElement > ) => {
59- // Only allow numbers and decimal points
60- const value = e . target . value . replace ( / [ ^ \d . ] / g, "" ) ;
61- setAmount ( value ) ;
62- } , [ ] ) ;
69+ const handleChange = useCallback (
70+ ( e : React . ChangeEvent < HTMLInputElement > ) => {
71+ // Only allow numbers and decimal points
72+ const value = e . target . value . replace ( / [ ^ \d . ] / g, "" ) ;
73+ setAmount ( value ) ;
74+
75+ // Notify parent component about the amount change
76+ if ( onAmountChange ) {
77+ onAmountChange ( value ) ;
78+ }
79+ } ,
80+ [ onAmountChange ]
81+ ) ;
6382
6483 const handleFocus = ( ) => {
6584 // Mobile scroll fix
@@ -70,34 +89,60 @@ export function TokenBuyInput({
7089
7190 if ( ! accessToken ) return null ;
7291
92+ // Convert satoshis to BTC for display
93+ const satoshiToBTC = ( satoshis : string ) => {
94+ if ( ! satoshis || isNaN ( Number ( satoshis ) ) ) return "0.00000000" ;
95+ return ( Number ( satoshis ) / 100000000 ) . toFixed ( 8 ) ;
96+ } ;
97+
98+ const btcValue = satoshiToBTC ( amount ) ;
99+
73100 return (
74- < div ref = { containerRef } className = "w-full backdrop-blur" >
75- < div className = "mx-auto max-w-5xl px-2 md:px-4 py-2 w-full" >
76- < form onSubmit = { handleSubmit } className = "flex gap-2 w-full" >
77- < div className = "flex flex-1 gap-2 items-end w-full" >
101+ < div
102+ ref = { containerRef }
103+ className = "w-full backdrop-blur bg-background/95 border-t border-border"
104+ >
105+ < div className = "mx-auto max-w-5xl px-2 md:px-4 py-3 w-full" >
106+ < form onSubmit = { handleSubmit } className = "flex flex-col gap-2 w-full" >
107+ < div className = "text-md text-muted-foreground text-right px-1 text-orange-500" >
108+ { amount ? `${ btcValue } BTC` : "0 BTC" }
109+ </ div >
110+ < div className = "flex flex-1 gap-2 items-center w-full" >
78111 < div className = "relative flex-1 min-w-0" >
79- < Input
80- ref = { inputRef }
81- type = "text"
82- value = { amount }
83- onChange = { handleChange }
84- onClick = { handleFocus }
85- onFocus = { handleFocus }
86- placeholder = { `Enter amount of ${ tokenName } to buy...` }
87- disabled = { disabled }
88- className = { cn (
89- "h-11" ,
90- "py-2.5 px-4 border border-muted" ,
91- "text-base placeholder:text-muted-foreground" ,
92- "rounded-xl md:rounded-2xl" ,
93- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" ,
94- "transition-all duration-200"
95- ) }
96- />
112+ < div className = "flex items-center relative" >
113+ < Input
114+ ref = { inputRef }
115+ type = "text"
116+ value = { amount }
117+ onChange = { handleChange }
118+ onClick = { handleFocus }
119+ onFocus = { handleFocus }
120+ placeholder = { `Enter satoshi amount to spend on ${ tokenName } ...` }
121+ disabled = { disabled }
122+ className = { cn (
123+ "h-11 pr-16" ,
124+ "py-2.5 px-4 border border-muted" ,
125+ "text-base placeholder:text-muted-foreground" ,
126+ "rounded-xl md:rounded-2xl" ,
127+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" ,
128+ "transition-all duration-200"
129+ ) }
130+ />
131+ < div className = "absolute right-3 flex items-center gap-1 pointer-events-none" >
132+ < span className = "text-sm font-medium text-muted-foreground text-orange-500" >
133+ sats
134+ </ span >
135+ </ div >
136+ </ div >
97137 </ div >
98- < Button type = "submit" disabled = { disabled || ! amount . trim ( ) } >
138+ < Button
139+ type = "submit"
140+ variant = "primary"
141+ disabled = { disabled || ! amount . trim ( ) }
142+ className = "h-11 px-4"
143+ >
99144 Buy
100- < Wallet className = "h-4 w-4" />
145+ < Wallet className = "h-4 w-4 ml-2 " />
101146 </ Button >
102147 </ div >
103148 </ form >
0 commit comments