@@ -30,9 +30,21 @@ function DeployPanel(): JSX.Element {
3030 const [ isDetailsOpen , setIsDetailsOpen ] = useState ( true ) ;
3131 const [ isPublishOpen , setIsPublishOpen ] = useState ( true ) ;
3232 const [ isEnsOpen , setIsEnsOpen ] = useState ( true ) ;
33+ const [ ensError , setEnsError ] = useState ( '' ) ;
3334
3435 const logoInputRef = useRef < HTMLInputElement > ( null ) ;
3536
37+ const validateEnsName = ( name : string ) => {
38+ const regex = / ^ [ a - z 0 - 9 - ] + $ / ;
39+
40+ if ( ! name ) return '' ;
41+ if ( name . length < 3 ) return 'Name must be at least 3 characters.' ;
42+ if ( ! regex . test ( name ) ) return 'Only lowercase letters, numbers, and hyphens are allowed.' ;
43+ if ( name . startsWith ( '-' ) || name . endsWith ( '-' ) ) return 'Name cannot start or end with a hyphen.' ;
44+
45+ return '' ;
46+ } ;
47+
3648 const handleRemoveLogo = ( ) => {
3749 dispatch ( { type : 'SET_INSTANCE' , payload : { logo : null } } ) ;
3850 if ( logoInputRef . current ) {
@@ -159,6 +171,12 @@ function DeployPanel(): JSX.Element {
159171
160172 const label = ensName . trim ( ) . toLowerCase ( ) ;
161173
174+ const validationError = validateEnsName ( label ) ;
175+ if ( validationError ) {
176+ setEnsError ( validationError ) ;
177+ return ;
178+ }
179+
162180 if ( ! label || ! deployResult . cid ) {
163181 setEnsResult ( { ...ensResult , error : 'ENS label or IPFS CID is missing.' } ) ;
164182 setIsEnsLoading ( false ) ;
@@ -269,9 +287,9 @@ function DeployPanel(): JSX.Element {
269287 </ Card . Header >
270288 < Collapse in = { isPublishOpen } >
271289 < Card . Body >
272- < Alert variant = "info" className = "small" >
290+ < Alert variant = "info" >
273291 < i className = "fas fa-info-circle me-2" > </ i >
274- Deploy your DApp to IPFS using Remix's centralized gateway. No personal IPFS keys required.
292+ Deploy your DApp to IPFS using Remix's gateway. No personal IPFS keys required.
275293 </ Alert >
276294
277295 < Button
@@ -288,13 +306,12 @@ function DeployPanel(): JSX.Element {
288306 </ Button >
289307
290308 { deployResult . cid && (
291- < Alert variant = "success" className = "mt-3 small " style = { { wordBreak : 'break-all' } } >
309+ < Alert variant = "success" className = "mt-3" style = { { wordBreak : 'break-all' } } >
292310 < div className = "fw-bold" > Deployed Successfully!</ div >
293311 < div > < strong > CID:</ strong > { deployResult . cid } </ div >
294- < hr className = "my-2" />
295- < a href = { deployResult . gatewayUrl } target = "_blank" rel = "noopener noreferrer" >
296- View DApp
297- </ a >
312+ < div className = "mt-1" >
313+ < strong > Domain:</ strong > < a href = { deployResult . gatewayUrl } target = "_blank" rel = "noopener noreferrer" > View DApp</ a >
314+ </ div >
298315 </ Alert >
299316 ) }
300317 { deployResult . error && (
@@ -319,12 +336,11 @@ function DeployPanel(): JSX.Element {
319336 </ Card . Header >
320337 < Collapse in = { isEnsOpen } >
321338 < Card . Body >
322- < Alert variant = "info" className = "small" >
339+ < Alert variant = "info" >
323340 < i className = "fas fa-gas-pump me-2" > </ i >
324341 Register a < strong > .remixdapp.eth</ strong > subdomain on Arbitrum.
325342 Remix covers the gas fees!
326343 </ Alert >
327-
328344 < Form . Group className = "mb-2" >
329345 < Form . Label className = "text-uppercase mb-0" > Subdomain Label</ Form . Label >
330346 < div className = "input-group" >
@@ -333,15 +349,28 @@ function DeployPanel(): JSX.Element {
333349 placeholder = "myapp"
334350 value = { ensName }
335351 onChange = { ( e ) => {
336- setEnsName ( e . target . value )
337- if ( ensResult . success ) setEnsResult ( { ...ensResult , success : '' , txHash : '' , domain : '' } )
352+ const val = e . target . value . toLowerCase ( ) ;
353+ setEnsName ( val ) ;
354+ const errorMsg = validateEnsName ( val ) ;
355+ setEnsError ( errorMsg ) ;
356+ if ( ensResult . success || ensResult . error ) {
357+ setEnsResult ( { success : '' , error : '' , txHash : '' , domain : '' } ) ;
358+ }
338359 } }
360+ isInvalid = { ! ! ensError }
339361 />
340362 < span className = "input-group-text" > .remixdapp.eth</ span >
341363 </ div >
342- { ! ensResult . success && (
343- < Form . Text className = "text-muted" >
344- Preview: < strong > https://{ ensName || 'myapp' } .remixdapp.eth.limo</ strong >
364+ { ensError && (
365+ < Form . Text className = "text-danger" >
366+ < i className = "fas fa-exclamation-circle me-1" > </ i >
367+ { ensError }
368+ </ Form . Text >
369+ ) }
370+ { ! ensError && ensName && ! ensResult . success && (
371+ < Form . Text className = "text-success" >
372+ < i className = "fas fa-check-circle me-1" > </ i >
373+ Valid name format
345374 </ Form . Text >
346375 ) }
347376 </ Form . Group >
@@ -350,7 +379,7 @@ function DeployPanel(): JSX.Element {
350379 variant = "secondary"
351380 className = "w-100"
352381 onClick = { handleEnsLink }
353- disabled = { isEnsLoading || ! ensName }
382+ disabled = { isEnsLoading || ! ensName || ! ! ensError }
354383 >
355384 { isEnsLoading ? (
356385 < > < i className = "fas fa-spinner fa-spin me-1" > </ i > Registering...</ >
@@ -360,8 +389,7 @@ function DeployPanel(): JSX.Element {
360389 </ Button >
361390
362391 { ensResult . success && (
363- < Alert variant = "success" className = "mt-3 small" >
364- < div className = "fw-bold mb-1" > Success!</ div >
392+ < Alert variant = "success" className = "mt-3" >
365393 < div > { ensResult . success } </ div >
366394 < div className = "mt-1" >
367395 < strong > Domain:</ strong > < a href = { `https://${ ensResult . domain } .limo` } target = "_blank" rel = "noreferrer" > { ensResult . domain } </ a >
@@ -380,14 +408,14 @@ function DeployPanel(): JSX.Element {
380408 < div className = "mt-3" >
381409 < Button
382410 size = "sm"
383- variant = "outline- secondary"
411+ variant = "secondary"
384412 onClick = { ( ) => { resetInstance ( ) ; handleRemoveLogo ( ) ; } }
385413 >
386414 < FormattedMessage id = "quickDapp.resetFunctions" />
387415 </ Button >
388416 < Button
389417 size = "sm"
390- variant = "outline- danger"
418+ variant = "danger"
391419 className = "ms-3"
392420 onClick = { ( ) => { emptyInstance ( ) ; } }
393421 >
0 commit comments