1- import { useState , useCallback } from 'react'
1+ import { useState , useCallback , type ReactNode } from 'react'
22import type { BioAccount } from '@aspect-aspect/bio-sdk'
33import { Button } from '@/components/ui/button'
44import { Card , CardHeader , CardTitle , CardDescription , CardContent } from '@/components/ui/card'
@@ -108,114 +108,135 @@ export default function App() {
108108 } , [ ] )
109109
110110 return (
111- < div className = "min-h-screen flex items-center justify-center p-5 bg-background" >
112- < Card className = "w-full max-w-sm" >
113- < CardHeader className = "text-center" >
114- < CardTitle className = "text-xl" > 一键传送</ CardTitle >
115- < CardDescription > 将资产从一个钱包转移到另一个钱包</ CardDescription >
116- </ CardHeader >
117-
118- < CardContent className = "space-y-4" >
119- { error && (
120- < div className = "bg-destructive/10 text-destructive p-3 rounded-lg text-sm" >
121- { error }
122- </ div >
123- ) }
111+ < div className = "relative min-h-screen overflow-hidden bg-background" >
112+ < AuroraBackdrop />
113+ < div className = "relative flex min-h-screen items-center justify-center p-5" >
114+ < div className = "w-full max-w-sm" >
115+ < GradientFrame >
116+ < Card className = "border-0 bg-background/80 shadow-2xl backdrop-blur-xl" >
117+ < CardHeader className = "text-center" >
118+ < CardTitle className = "text-xl" > 一键传送</ CardTitle >
119+ < CardDescription > 将资产从一个钱包转移到另一个钱包</ CardDescription >
120+ </ CardHeader >
124121
125- { step === 'connect' && (
126- < div className = "flex flex-col items-center gap-4" >
127- < div className = "size-16 rounded-full bg-primary/10 flex items-center justify-center" >
128- < svg className = "size-8 text-primary" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
129- < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M13 10V3L4 14h7v7l9-11h-7z" />
130- </ svg >
131- </ div >
132- < p className = "text-muted-foreground text-center text-sm" >
133- 连接钱包以开始传送
134- </ p >
135- < Button
136- className = "w-full h-11"
137- onClick = { handleConnect }
138- disabled = { loading }
139- >
140- { loading ? '连接中...' : '连接钱包' }
141- </ Button >
142- </ div >
143- ) }
122+ < CardContent className = "space-y-4" >
123+ { error && (
124+ < div className = "bg-destructive/10 text-destructive rounded-lg p-3 text-sm" >
125+ { error }
126+ </ div >
127+ ) }
144128
145- { step === 'select-source' && (
146- < div className = "flex flex-col items-center gap-4" >
147- < StepIndicator current = { 1 } total = { 3 } />
148- < p className = "text-muted-foreground text-center text-sm" >
149- 选择源地址(资产转出方)
150- </ p >
151- < Button
152- className = "w-full h-11"
153- onClick = { handleSelectSource }
154- disabled = { loading }
155- >
156- { loading ? '选择中...' : '选择源地址' }
157- </ Button >
158- </ div >
159- ) }
129+ < div
130+ key = { step }
131+ className = "animate-in fade-in slide-in-from-bottom-2 duration-300"
132+ >
133+ { step === 'connect' && (
134+ < div className = "flex flex-col items-center gap-4" >
135+ < div className = "relative" >
136+ < div className = "absolute -inset-3 rounded-full bg-primary/20 blur-xl" />
137+ < div className = "relative flex size-16 items-center justify-center rounded-full bg-primary/10" >
138+ < svg className = "size-8 text-primary" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
139+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M13 10V3L4 14h7v7l9-11h-7z" />
140+ </ svg >
141+ </ div >
142+ </ div >
143+ < p className = "text-muted-foreground text-center text-sm" >
144+ 连接钱包以开始传送
145+ </ p >
146+ < Button
147+ className = "h-11 w-full"
148+ onClick = { handleConnect }
149+ disabled = { loading }
150+ >
151+ { loading ? '连接中...' : '连接钱包' }
152+ </ Button >
153+ </ div >
154+ ) }
160155
161- { step === 'select-target' && (
162- < div className = "flex flex-col gap-4" >
163- < StepIndicator current = { 2 } total = { 3 } />
164- < AddressCard label = "源地址" address = { sourceAccount ?. address } />
165- < p className = "text-muted-foreground text-center text-sm" >
166- 选择目标地址(资产接收方)
167- </ p >
168- < Button
169- className = "w-full h-11"
170- onClick = { handleSelectTarget }
171- disabled = { loading }
172- >
173- { loading ? '选择中...' : '选择目标地址' }
174- </ Button >
175- </ div >
176- ) }
156+ { step === 'select-source' && (
157+ < div className = "flex flex-col items-center gap-4" >
158+ < StepIndicator current = { 1 } total = { 3 } />
159+ < p className = "text-muted-foreground text-center text-sm" >
160+ 选择源地址(资产转出方)
161+ </ p >
162+ < Button
163+ className = "h-11 w-full"
164+ onClick = { handleSelectSource }
165+ disabled = { loading }
166+ >
167+ { loading ? '选择中...' : '选择源地址' }
168+ </ Button >
169+ </ div >
170+ ) }
177171
178- { step === 'confirm' && (
179- < div className = "flex flex-col gap-4" >
180- < StepIndicator current = { 3 } total = { 3 } />
181- < AddressCard label = "从" address = { sourceAccount ?. address } />
182- < div className = "flex justify-center" >
183- < div className = "size-8 rounded-full bg-primary/10 flex items-center justify-center" >
184- < svg className = "size-4 text-primary" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
185- < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M19 14l-7 7m0 0l-7-7m7 7V3" />
186- </ svg >
187- </ div >
188- </ div >
189- < AddressCard label = "到" address = { targetAccount ?. address } />
190- < Button
191- className = "w-full h-11"
192- onClick = { handleConfirm }
193- disabled = { loading }
194- >
195- { loading ? '签名中...' : '确认传送' }
196- </ Button >
197- </ div >
198- ) }
172+ { step === 'select-target' && (
173+ < div className = "flex flex-col gap-4" >
174+ < StepIndicator current = { 2 } total = { 3 } />
175+ < AddressCard label = "源地址" address = { sourceAccount ?. address } />
176+ < p className = "text-muted-foreground text-center text-sm" >
177+ 选择目标地址(资产接收方)
178+ </ p >
179+ < Button
180+ className = "h-11 w-full"
181+ onClick = { handleSelectTarget }
182+ disabled = { loading }
183+ >
184+ { loading ? '选择中...' : '选择目标地址' }
185+ </ Button >
186+ </ div >
187+ ) }
199188
200- { step === 'success' && (
201- < div className = "flex flex-col items-center gap-4 py-4" >
202- < div className = "size-16 rounded-full bg-success/10 flex items-center justify-center" >
203- < svg className = "size-8 text-success" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
204- < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M5 13l4 4L19 7" />
205- </ svg >
206- </ div >
207- < p className = "font-medium" > 传送请求已提交!</ p >
208- < Button
209- variant = "secondary"
210- className = "w-full h-11"
211- onClick = { handleReset }
212- >
213- 再次传送
214- </ Button >
215- </ div >
216- ) }
217- </ CardContent >
218- </ Card >
189+ { step === 'confirm' && (
190+ < div className = "flex flex-col gap-4" >
191+ < StepIndicator current = { 3 } total = { 3 } />
192+ < AddressCard label = "从" address = { sourceAccount ?. address } />
193+ < div className = "flex justify-center" >
194+ < div className = "relative" >
195+ < div className = "absolute -inset-2 rounded-full bg-primary/20 blur-lg" />
196+ < div className = "relative flex size-8 items-center justify-center rounded-full bg-primary/10" >
197+ < svg className = "size-4 text-primary" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
198+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M19 14l-7 7m0 0l-7-7m7 7V3" />
199+ </ svg >
200+ </ div >
201+ </ div >
202+ </ div >
203+ < AddressCard label = "到" address = { targetAccount ?. address } />
204+ < Button
205+ className = "h-11 w-full"
206+ onClick = { handleConfirm }
207+ disabled = { loading }
208+ >
209+ { loading ? '签名中...' : '确认传送' }
210+ </ Button >
211+ </ div >
212+ ) }
213+
214+ { step === 'success' && (
215+ < div className = "flex flex-col items-center gap-4 py-4" >
216+ < div className = "relative" >
217+ < div className = "absolute -inset-4 rounded-full bg-success/25 blur-xl" />
218+ < div className = "relative flex size-16 items-center justify-center rounded-full bg-success/10" >
219+ < svg className = "size-8 text-success" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
220+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M5 13l4 4L19 7" />
221+ </ svg >
222+ </ div >
223+ </ div >
224+ < p className = "font-medium" > 传送请求已提交!</ p >
225+ < Button
226+ variant = "secondary"
227+ className = "h-11 w-full"
228+ onClick = { handleReset }
229+ >
230+ 再次传送
231+ </ Button >
232+ </ div >
233+ ) }
234+ </ div >
235+ </ CardContent >
236+ </ Card >
237+ </ GradientFrame >
238+ </ div >
239+ </ div >
219240 </ div >
220241 )
221242}
@@ -238,9 +259,30 @@ function StepIndicator({ current, total }: { current: number; total: number }) {
238259
239260function AddressCard ( { label, address } : { label : string ; address ?: string } ) {
240261 return (
241- < div className = "bg-muted/50 rounded-lg p-3" >
262+ < div className = "bg-muted/50 rounded-lg p-3 ring-1 ring-border/30 " >
242263 < div className = "text-xs text-muted-foreground mb-1" > { label } </ div >
243264 < div className = "font-mono text-xs break-all" > { address } </ div >
244265 </ div >
245266 )
246267}
268+
269+ function GradientFrame ( { children } : { children : ReactNode } ) {
270+ return (
271+ < div className = "relative rounded-2xl p-[1px]" >
272+ < div className = "absolute inset-0 rounded-2xl bg-[conic-gradient(from_180deg_at_50%_50%,color-mix(in_srgb,var(--color-primary)_35%,transparent),transparent,rgba(168,85,247,0.25),transparent,rgba(34,211,238,0.25),transparent)]" />
273+ < div className = "relative rounded-2xl" > { children } </ div >
274+ </ div >
275+ )
276+ }
277+
278+ function AuroraBackdrop ( ) {
279+ return (
280+ < div className = "pointer-events-none absolute inset-0 overflow-hidden" >
281+ < div className = "absolute -top-24 left-1/2 h-72 w-72 -translate-x-1/2 rounded-full bg-primary/20 blur-3xl" />
282+ < div className = "absolute -bottom-28 right-[-6rem] h-80 w-80 rounded-full bg-fuchsia-500/20 blur-3xl" />
283+ < div className = "absolute top-1/3 left-[-7rem] h-80 w-80 rounded-full bg-cyan-500/18 blur-3xl" />
284+ < div className = "absolute inset-0 bg-[radial-gradient(circle_at_50%_0%,rgba(255,255,255,0.06),transparent_55%)]" />
285+ < div className = "absolute inset-0 bg-[linear-gradient(to_right,rgba(255,255,255,0.04)_1px,transparent_1px),linear-gradient(to_bottom,rgba(255,255,255,0.04)_1px,transparent_1px)] bg-[size:24px_24px] opacity-40 [mask-image:radial-gradient(ellipse_at_center,black_50%,transparent_75%)]" />
286+ </ div >
287+ )
288+ }
0 commit comments