22
33import { useCallback , useState } from "react" ;
44import { AnimatePresence , motion } from "framer-motion" ;
5+ import { useTranslations } from "next-intl" ;
56import Skeleton from "react-loading-skeleton" ;
67import "react-loading-skeleton/dist/skeleton.css" ;
78import {
@@ -33,14 +34,16 @@ const SUPPORTED_ASSETS = [
3334] ;
3435
3536type Step = "SELECT" | "CONNECTING" | "AUTH" | "GENERATING" | "INTERACTIVE" ;
37+ type BusyStep = Exclude < Step , "SELECT" | "INTERACTIVE" > ;
3638
37- const STEP_MESSAGE : Record < Exclude < Step , "SELECT " | "INTERACTIVE" > , string > = {
38- CONNECTING : "Connecting to anchor… " ,
39- AUTH : "Waiting for wallet signature… " ,
40- GENERATING : "Preparing your deposit form… " ,
39+ const STEP_MESSAGE_KEY : Record < BusyStep , "stepConnecting " | "stepAuth" | "stepGenerating" > = {
40+ CONNECTING : "stepConnecting " ,
41+ AUTH : "stepAuth " ,
42+ GENERATING : "stepGenerating " ,
4143} ;
4244
4345export default function FiatOnrampModal ( { isOpen, onClose } : FiatOnrampModalProps ) {
46+ const t = useTranslations ( "fiatOnramp" ) ;
4447 const [ step , setStep ] = useState < Step > ( "SELECT" ) ;
4548 const [ amount , setAmount ] = useState ( "" ) ;
4649 const [ anchorDomain , setAnchorDomain ] = useState ( DEFAULT_ANCHOR ) ;
@@ -96,15 +99,15 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
9699 setInteractiveUrl ( url ) ;
97100 setStep ( "INTERACTIVE" ) ;
98101 } catch ( err ) {
99- const message = err instanceof Error ? err . message : "Deposit failed" ;
102+ const message = err instanceof Error ? err . message : t ( "genericError" ) ;
100103 toast . error ( message ) ;
101104 setError ( message ) ;
102105 setStep ( "SELECT" ) ;
103106 }
104- } , [ anchorDomain , amount , selectedAsset ] ) ;
107+ } , [ anchorDomain , amount , selectedAsset , t ] ) ;
105108
106109 return (
107- < Modal isOpen = { isOpen } onClose = { handleClose } title = "Buy / Deposit Funds" >
110+ < Modal isOpen = { isOpen } onClose = { handleClose } title = { t ( "title" ) } >
108111 < AnimatePresence mode = "wait" >
109112 { step === "SELECT" && (
110113 < motion . div
@@ -115,10 +118,7 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
115118 transition = { { duration : 0.18 } }
116119 className = "flex flex-col gap-6"
117120 >
118- < p className = "text-sm text-slate-400" >
119- Deposit fiat via a Stellar anchor (SEP-0024). Funds arrive as tokens directly
120- in your connected wallet.
121- </ p >
121+ < p className = "text-sm text-slate-400" > { t ( "description" ) } </ p >
122122
123123 { error && (
124124 < div
@@ -131,7 +131,7 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
131131
132132 < div className = "space-y-2" >
133133 < label className = "text-xs font-semibold uppercase tracking-wider text-slate-500" >
134- Select Asset
134+ { t ( "selectAsset" ) }
135135 </ label >
136136 < div className = "grid grid-cols-2 gap-4" >
137137 { SUPPORTED_ASSETS . map ( ( asset ) => (
@@ -158,7 +158,7 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
158158
159159 < div className = "space-y-2" >
160160 < label htmlFor = "onramp-amount" className = "text-xs font-semibold uppercase tracking-wider text-slate-500" >
161- Amount < span className = "normal-case text-slate-600" > (optional) </ span >
161+ { t ( "amountLabel" ) } < span className = "normal-case text-slate-600" > { t ( "amountOptional" ) } </ span >
162162 </ label >
163163 < input
164164 id = "onramp-amount"
@@ -168,13 +168,13 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
168168 onChange = { ( e ) => setAmount ( e . target . value ) }
169169 disabled = { isBusy }
170170 className = "w-full rounded-xl border border-white/10 bg-black/40 px-4 py-3 text-sm text-white focus:outline-none focus:ring-1 focus:ring-mint disabled:cursor-not-allowed disabled:opacity-50"
171- placeholder = { `e.g. 100 ${ selectedAsset . code } ` }
171+ placeholder = { t ( "amountPlaceholder" , { amount : " 100" , asset : selectedAsset . code } ) }
172172 />
173173 </ div >
174174
175175 < div className = "space-y-2" >
176176 < label htmlFor = "onramp-anchor" className = "text-xs font-semibold uppercase tracking-wider text-slate-500" >
177- Anchor Domain
177+ { t ( "anchorDomainLabel" ) }
178178 </ label >
179179 < input
180180 id = "onramp-anchor"
@@ -183,7 +183,7 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
183183 onChange = { ( e ) => setAnchorDomain ( e . target . value ) }
184184 disabled = { isBusy }
185185 className = "w-full rounded-xl border border-white/10 bg-black/40 px-4 py-3 text-sm text-white focus:outline-none focus:ring-1 focus:ring-mint disabled:cursor-not-allowed disabled:opacity-50"
186- placeholder = "e.g. testanchor.stellar.org"
186+ placeholder = { t ( "anchorDomainPlaceholder" ) }
187187 />
188188 </ div >
189189
@@ -196,10 +196,10 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
196196 { isBusy ? (
197197 < >
198198 < Spinner size = "sm" className = "text-black" />
199- { STEP_MESSAGE [ step as Exclude < Step , "SELECT" | "INTERACTIVE" > ] }
199+ { t ( STEP_MESSAGE_KEY [ step as BusyStep ] ) }
200200 </ >
201201 ) : (
202- "Continue to Anchor"
202+ t ( "continueButton" )
203203 ) }
204204 </ button >
205205 </ motion . div >
@@ -222,11 +222,9 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
222222 < Spinner size = "lg" className = "text-mint" />
223223 </ div >
224224 </ div >
225- < h3 className = "text-lg font-bold text-white" > { STEP_MESSAGE [ step ] } </ h3 >
225+ < h3 className = "text-lg font-bold text-white" > { t ( STEP_MESSAGE_KEY [ step as BusyStep ] ) } </ h3 >
226226 < p className = "mt-2 text-sm text-slate-400" >
227- { step === "AUTH"
228- ? `Please sign the challenge transaction in your wallet to securely connect to ${ anchorDomain } .`
229- : "This should only take a moment." }
227+ { step === "AUTH" ? t ( "authHint" , { domain : anchorDomain } ) : t ( "genericHint" ) }
230228 </ p >
231229 </ motion . div >
232230 ) }
@@ -249,7 +247,7 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
249247 ) }
250248 < iframe
251249 src = { interactiveUrl }
252- title = "Anchor deposit form"
250+ title = { t ( "iframeTitle" ) }
253251 className = "h-full w-full"
254252 onLoad = { ( ) => setIframeLoading ( false ) }
255253 />
@@ -258,9 +256,7 @@ export default function FiatOnrampModal({ isOpen, onClose }: FiatOnrampModalProp
258256 </ AnimatePresence >
259257
260258 { step !== "INTERACTIVE" && (
261- < p className = "mt-6 text-center text-xs text-slate-500" >
262- Secured by Stellar Network • SEP-0024 Standard
263- </ p >
259+ < p className = "mt-6 text-center text-xs text-slate-500" > { t ( "footerNote" ) } </ p >
264260 ) }
265261 </ Modal >
266262 ) ;
0 commit comments