@@ -10,6 +10,14 @@ import { SwapBox } from "./swapbox";
1010import { useGetLpInfo } from "./useGetLpInfo" ;
1111import { formatUnits , parseUnits } from "viem" ;
1212import { Button } from "@/components/ui/button" ;
13+ import {
14+ Select ,
15+ SelectContent ,
16+ SelectItem ,
17+ SelectTrigger ,
18+ SelectValue ,
19+ } from "@/components/ui/select" ;
20+ import Image from "next/image" ;
1321
1422export default function SwapPage ( ) {
1523 const pathname = usePathname ( ) ;
@@ -27,6 +35,7 @@ export default function SwapPage() {
2735 const [ buyValue , setBuyValue ] = React . useState ( "" ) ;
2836 const [ sellToken , setSellToken ] = React . useState ( "" ) ;
2937 const [ buyToken , setBuyToken ] = React . useState ( "" ) ;
38+ const [ selectedTokenPair , setSelectedTokenPair ] = React . useState < string > ( "" ) ;
3039 const [ activeBox , setActiveBox ] = React . useState < "sell" | "buy" | undefined > (
3140 "sell"
3241 ) ;
@@ -39,6 +48,40 @@ export default function SwapPage() {
3948 getPoolSize,
4049 } = useGetLpInfo ( ) ;
4150
51+ const tokenPairOptions = useMemo ( ( ) => {
52+ if ( ! assetInfo || ! lpPoolList . length ) return [ ] ;
53+
54+ return lpPoolList . map ( ( [ tokens ] ) => {
55+ const token1 = tokens [ 0 ] ;
56+ const token2 = tokens [ 1 ] ;
57+ const symbol1 = assetInfo [ token1 ] ?. symbol || token1 ;
58+ const symbol2 = assetInfo [ token2 ] ?. symbol || token2 ;
59+ const pairKey = `${ token1 } -${ token2 } ` ;
60+
61+ return {
62+ key : pairKey ,
63+ tokens : [ token1 , token2 ] ,
64+ display : `${ symbol1 } -${ symbol2 } ` ,
65+ symbols : [ symbol1 , symbol2 ] ,
66+ } ;
67+ } ) ;
68+ } , [ lpPoolList , assetInfo ] ) ;
69+
70+ // 当选择 token pair 时,自动设置 sell 和 buy token
71+ useEffect ( ( ) => {
72+ if ( selectedTokenPair && assetInfo ) {
73+ const pair = tokenPairOptions . find (
74+ ( option ) => option . key === selectedTokenPair
75+ ) ;
76+ if ( pair ) {
77+ setSellToken ( pair . tokens [ 0 ] ) ;
78+ setBuyToken ( pair . tokens [ 1 ] ) ;
79+ setSellValue ( "" ) ;
80+ setBuyValue ( "" ) ;
81+ }
82+ }
83+ } , [ selectedTokenPair , tokenPairOptions , assetInfo ] ) ;
84+
4285 const [ sellTokens , buyTokens ] = useMemo ( ( ) => {
4386 if ( ! sellToken && ! buyToken ) return [ lpTokens , lpTokens ] ;
4487 if ( activeBox === "sell" ) {
@@ -156,22 +199,34 @@ export default function SwapPage() {
156199
157200 const handleSellTokenChange = ( token : string ) => {
158201 setSellToken ( token ) ;
159- // if (activeBox === "sell") {
160- // if (buyValue) {
161- // setSellValue("");
162- // setBuyValue("");
163- // }
164- // }
202+ if ( buyToken ) {
203+ const pairKey = `${ token } -${ buyToken } ` ;
204+ const reversePairKey = `${ buyToken } -${ token } ` ;
205+ const existingPair = tokenPairOptions . find (
206+ ( option ) => option . key === pairKey || option . key === reversePairKey
207+ ) ;
208+ if ( existingPair ) {
209+ setSelectedTokenPair ( existingPair . key ) ;
210+ } else {
211+ setSelectedTokenPair ( "" ) ;
212+ }
213+ }
165214 } ;
166215
167216 const handleBuyTokenChange = ( token : string ) => {
168217 setBuyToken ( token ) ;
169- // if (activeBox === "buy") {
170- // if (sellValue) {
171- // setSellValue("");
172- // setBuyValue("");
173- // }
174- // }
218+ if ( sellToken ) {
219+ const pairKey = `${ sellToken } -${ token } ` ;
220+ const reversePairKey = `${ token } -${ sellToken } ` ;
221+ const existingPair = tokenPairOptions . find (
222+ ( option ) => option . key === pairKey || option . key === reversePairKey
223+ ) ;
224+ if ( existingPair ) {
225+ setSelectedTokenPair ( existingPair . key ) ;
226+ } else {
227+ setSelectedTokenPair ( "" ) ;
228+ }
229+ }
175230 } ;
176231
177232 const sellValueRef = useRef ( sellValue ) ;
@@ -267,6 +322,45 @@ export default function SwapPage() {
267322 < div className = "flex-1 px-4" >
268323 < Connect className = "mt-2" />
269324 < div className = "mt-8 flex flex-col gap-4" >
325+ { /* Token Pair Selector */ }
326+ < div >
327+ < div className = "font-bold mb-2" > Select Liquidity Pool</ div >
328+ < Select
329+ value = { selectedTokenPair }
330+ onValueChange = { setSelectedTokenPair }
331+ disabled = { ! assetInfo || ! tokenPairOptions . length }
332+ >
333+ < SelectTrigger className = "w-full h-12! text-md" >
334+ < SelectValue placeholder = "Select a token pair" />
335+ </ SelectTrigger >
336+ < SelectContent >
337+ { tokenPairOptions . map ( ( option ) => (
338+ < SelectItem key = { option . key } value = { option . key } >
339+ < div className = "flex items-center gap-2 select-none" >
340+ < div className = "flex items-center gap-0" >
341+ < Image
342+ className = "w-5 h-5 inline-flex items-center justify-center align-middle"
343+ src = { `https://resources.acala.network/tokens/${ option . symbols [ 0 ] } .png` }
344+ alt = { option . symbols [ 0 ] }
345+ width = { 20 }
346+ height = { 20 }
347+ />
348+ < Image
349+ className = "ml-[-8px] w-5 h-5 inline-flex items-center justify-center align-middle"
350+ src = { `https://resources.acala.network/tokens/${ option . symbols [ 1 ] } .png` }
351+ alt = { option . symbols [ 1 ] }
352+ width = { 20 }
353+ height = { 20 }
354+ />
355+ </ div >
356+ < span className = "font-bold" > { option . display } </ span >
357+ </ div >
358+ </ SelectItem >
359+ ) ) }
360+ </ SelectContent >
361+ </ Select >
362+ </ div >
363+
270364 < div >
271365 < div className = "font-bold" > Sell</ div >
272366 < SwapBox
@@ -335,6 +429,7 @@ export default function SwapPage() {
335429 </ div >
336430 < div >
337431 < Button
432+ size = "lg"
338433 className = "w-full cursor-pointer"
339434 disabled = { ! sellValue || ! buyValue || ! tokenPair }
340435 >
0 commit comments