@@ -3,7 +3,7 @@ import { useParams, useNavigate } from "react-router-dom";
33import axios from "axios" ;
44import { useAuth } from "../context/AuthContext" ;
55import toast from "react-hot-toast" ;
6- import { Trash2 , AlertTriangle , Save , CheckCircle } from "lucide-react" ;
6+ import { Trash2 , AlertTriangle , Save , CheckCircle , Copy , Server } from "lucide-react" ;
77import { API_URL } from "../config" ;
88import ConfirmationModal from "./ConfirmationModal" ;
99
@@ -308,11 +308,31 @@ function DatabaseConfigForm({ project, projectId, token }) {
308308 const isConfigured = project ?. resources ?. db ?. isExternal || false ;
309309 const [ showForm , setShowForm ] = useState ( ! isConfigured ) ;
310310
311+ const [ serverIp , setServerIp ] = useState ( null ) ;
312+
311313 useEffect ( ( ) => {
312314 const configured = project ?. resources ?. db ?. isExternal || false ;
313315 setShowForm ( ! configured ) ;
316+
317+ // Fetch Server IP
318+ const fetchIp = async ( ) => {
319+ try {
320+ const res = await axios . get ( `${ API_URL } /api/server-ip` ) ;
321+ setServerIp ( res . data . ip ) ;
322+ } catch ( e ) {
323+ console . error ( "Failed to fetch server IP" ) ;
324+ }
325+ } ;
326+ fetchIp ( ) ;
314327 } , [ project ] ) ;
315328
329+ const copyIp = ( ) => {
330+ if ( serverIp ) {
331+ navigator . clipboard . writeText ( serverIp ) ;
332+ toast . success ( "Server IP copied!" ) ;
333+ }
334+ } ;
335+
316336 const handleUpdate = async ( ) => {
317337 if ( ! dbUri ) return toast . error ( "Database URI is required" ) ;
318338
@@ -329,7 +349,20 @@ function DatabaseConfigForm({ project, projectId, token }) {
329349 // Typically we'd reload project data here, but for now we rely on user refresh or optimistic ui if needed
330350 // Ideally notify parent to refresh project, but basic flow:
331351 } catch ( err ) {
332- toast . error ( err . response ?. data ?. error || "Failed to update DB config" ) ;
352+ const errorMsg = err . response ?. data ?. error || "Failed to update DB config" ;
353+
354+ if ( errorMsg . includes ( "whitelist Server IP" ) ) {
355+ toast . error (
356+ < div >
357+ < b > Access Denied!</ b >
358+ < br />
359+ { errorMsg }
360+ </ div > ,
361+ { duration : 6000 }
362+ ) ;
363+ } else {
364+ toast . error ( errorMsg ) ;
365+ }
333366 } finally {
334367 setLoading ( false ) ;
335368 }
@@ -439,26 +472,45 @@ function DatabaseConfigForm({ project, projectId, token }) {
439472 < div
440473 style = { {
441474 display : "flex" ,
442- justifyContent : "flex-end " ,
443- gap : "12px " ,
475+ justifyContent : "space-between " ,
476+ alignItems : "center " ,
444477 marginTop : "1rem" ,
478+ paddingTop : "1rem" ,
479+ borderTop : "1px solid var(--color-border)" ,
445480 } }
446481 >
447- { isConfigured && (
482+ < div style = { { display : 'flex' , alignItems : 'center' , gap : '8px' , fontSize : '0.85rem' , color : 'var(--color-text-muted)' } } >
483+ < Server size = { 14 } />
484+ < span > Server Public IP: < code style = { { background : 'rgba(255,255,255,0.1)' , padding : '2px 6px' , borderRadius : '4px' } } > { serverIp || "Loading..." } </ code > </ span >
485+ { serverIp && (
486+ < button
487+ onClick = { copyIp }
488+ className = "btn-icon"
489+ title = "Copy IP"
490+ style = { { border : 'none' , background : 'transparent' , cursor : 'pointer' , color : 'var(--color-primary)' , padding : 0 , marginLeft : '5px' } }
491+ >
492+ < Copy size = { 14 } />
493+ </ button >
494+ ) }
495+ </ div >
496+
497+ < div style = { { display : 'flex' , gap : '12px' } } >
498+ { isConfigured && (
499+ < button
500+ className = "btn btn-ghost"
501+ onClick = { ( ) => setShowForm ( false ) }
502+ >
503+ Cancel
504+ </ button >
505+ ) }
448506 < button
449- className = "btn btn-ghost"
450- onClick = { ( ) => setShowForm ( false ) }
507+ onClick = { handleUpdate }
508+ className = "btn btn-primary"
509+ disabled = { loading }
451510 >
452- Cancel
511+ { loading ? "Saving..." : "Connect Database" }
453512 </ button >
454- ) }
455- < button
456- onClick = { handleUpdate }
457- className = "btn btn-primary"
458- disabled = { loading }
459- >
460- { loading ? "Saving..." : "Connect Database" }
461- </ button >
513+ </ div >
462514 </ div >
463515 </ div >
464516 ) }
0 commit comments