Skip to content
This repository was archived by the owner on Mar 16, 2026. It is now read-only.

Commit 5d83df5

Browse files
authored
Merge pull request #263 from aibtcdev/staging
2025/03/13 Release LIVE
2 parents dee39dc + 7012bf3 commit 5d83df5

9 files changed

Lines changed: 684 additions & 235 deletions

File tree

src/components/daos/dao-buy-input.tsx

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import type React from "react";
44

5-
import { useState, useCallback, useRef } from "react";
5+
import { useState, useCallback, useRef, useEffect } from "react";
66
import { Button } from "@/components/ui/button";
77
import { Input } from "@/components/ui/input";
88
import { 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

2022
export 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

Comments
 (0)