@@ -5,6 +5,9 @@ import dynamic from 'next/dynamic';
55
66const ThreatGlobe = dynamic ( ( ) => import ( './ThreatGlobe' ) , { ssr : false } ) ;
77
8+ // Fix #1: Use environment variable for API URL instead of hardcoded localhost
9+ const API_URL = process . env . NEXT_PUBLIC_API_URL || 'http://localhost:8000' ;
10+
811interface Log {
912 id : number ;
1013 timestamp : string ;
@@ -23,7 +26,7 @@ const Dashboard: React.FC = () => {
2326 useEffect ( ( ) => {
2427 const fetchLogs = async ( ) => {
2528 try {
26- const response = await fetch ( 'http://localhost:8000/ logs/' ) ;
29+ const response = await fetch ( ` ${ API_URL } / logs/` ) ;
2730 const data : Log [ ] = await response . json ( ) ;
2831 setLogs ( data ) ;
2932 const threats = data . filter ( l => l . event_type !== 'Normal' ) . length ;
@@ -46,76 +49,87 @@ const Dashboard: React.FC = () => {
4649
4750 return (
4851 < div className = "min-h-screen bg-gradient-to-br from-gray-900 via-gray-800 to-gray-700 text-white font-sans p-6 backdrop-blur-sm" >
49- { /* Glass‑ morphism container */ }
52+ { /* Glass- morphism container */ }
5053 < div className = "bg-white/5 rounded-xl border border-white/10 shadow-xl p-6 backdrop-blur-sm" >
5154 { /* Header */ }
5255 < header className = "mb-8 flex justify-between items-center" >
5356 < h1 className = "text-3xl font-bold flex items-center gap-2" >
54- < Shield className = "text-blue-400" /> AI Security Monitor
57+ < Shield className = "text-cyan-400" />
58+ AI Security Monitor
5559 </ h1 >
56- < div className = "flex gap-4" >
57- < div className = "bg-white/10 p-4 rounded-lg flex items-center gap-3" >
58- < Activity className = "text-green-400" />
59- < div >
60- < p className = "text-gray-300 text-sm" > Total Traffic</ p >
61- < p className = "text-2xl font-bold" > { stats . total } </ p >
62- </ div >
60+ < div className = "flex gap-6" >
61+ < div className = "text-center" >
62+ < p className = "text-xs text-gray-400" > Total Traffic</ p >
63+ < p className = "text-2xl font-bold text-cyan-400" > { stats . total } </ p >
64+ </ div >
65+ < div className = "text-center" >
66+ < p className = "text-xs text-gray-400" > Threats Detected</ p >
67+ < p className = "text-2xl font-bold text-red-400" > { stats . threats } </ p >
6368 </ div >
64- < div className = "bg-white/10 p-4 rounded-lg flex items-center gap-3" >
65- < AlertCircle className = "text-red-400" />
66- < div >
67- < p className = "text-gray-300 text-sm" > Threats Detected</ p >
68- < p className = "text-2xl font-bold" > { stats . threats } </ p >
69- </ div >
69+ < div className = "text-center" >
70+ < p className = "text-xs text-gray-400" > Active Anomalies</ p >
71+ < p className = "text-2xl font-bold text-yellow-400" > { stats . active_anomalies } </ p >
7072 </ div >
7173 </ div >
7274 </ header >
7375
7476 { /* Main Grid */ }
75- < div className = "grid grid-cols-1 lg:grid-cols-2 gap-6" >
77+ < div className = "grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6 " >
7678 { /* 3D Threat Globe */ }
77- < div className = "bg-white/5 rounded-xl border border-white/10 shadow-xl p-4 backdrop-blur-sm" >
78- < h2 className = "text-xl font-semibold mb-2 text-gray-200" > Global Threat Landscape</ h2 >
79+ < div className = "bg-white/5 rounded-xl border border-white/10 p-4" >
80+ < h2 className = "text-lg font-semibold mb-3 flex items-center gap-2" >
81+ < Activity className = "text-cyan-400" size = { 18 } />
82+ Global Threat Landscape
83+ </ h2 >
7984 < ThreatGlobe />
8085 </ div >
86+
8187 { /* Network Traffic Chart */ }
82- < div className = "bg-white/5 rounded-xl border border-white/10 shadow-xl p-4 backdrop-blur-sm" >
83- < h2 className = "text-xl font-semibold mb-4 text-gray-200" > Network Traffic (Bytes)</ h2 >
84- < div className = "h-64" >
85- < ResponsiveContainer width = "100%" height = "100%" >
86- < LineChart data = { chartData } >
87- < CartesianGrid strokeDasharray = "3 3" stroke = "#374151" />
88- < XAxis dataKey = "time" stroke = "#9CA3AF" />
89- < YAxis stroke = "#9CA3AF" />
90- < Tooltip contentStyle = { { backgroundColor : '#1F2937' , border : 'none' } } />
91- < Line type = "monotone" dataKey = "bytes" stroke = "#3B82F6" strokeWidth = { 2 } dot = { false } />
92- </ LineChart >
93- </ ResponsiveContainer >
94- </ div >
88+ < div className = "bg-white/5 rounded-xl border border-white/10 p-4" >
89+ < h2 className = "text-lg font-semibold mb-3" > Network Traffic (Bytes)</ h2 >
90+ < ResponsiveContainer width = "100%" height = { 250 } >
91+ < LineChart data = { chartData } >
92+ < CartesianGrid strokeDasharray = "3 3" stroke = "rgba(255,255,255,0.1)" />
93+ < XAxis dataKey = "time" tick = { { fontSize : 10 , fill : '#9ca3af' } } />
94+ < YAxis tick = { { fontSize : 10 , fill : '#9ca3af' } } />
95+ < Tooltip
96+ contentStyle = { { backgroundColor : '#1f2937' , border : '1px solid rgba(255,255,255,0.1)' } }
97+ />
98+ < Line type = "monotone" dataKey = "bytes" stroke = "#22d3ee" strokeWidth = { 2 } dot = { false } />
99+ < Line type = "monotone" dataKey = "threat" stroke = "#f87171" strokeWidth = { 2 } dot = { false } />
100+ </ LineChart >
101+ </ ResponsiveContainer >
95102 </ div >
96103 </ div >
97104
98105 { /* Recent Alerts */ }
99- < div className = "mt-8 bg-gray-800 p-6 rounded-lg shadow-lg overflow-hidden" >
100- < h2 className = "text-xl font-semibold mb-4 text-gray-200" > Recent Alerts</ h2 >
101- < div className = "overflow-y-auto h-64" >
102- < table className = "w-full text-left" >
106+ < div className = "bg-white/5 rounded-xl border border-white/10 p-4" >
107+ < h2 className = "text-lg font-semibold mb-3 flex items-center gap-2" >
108+ < AlertCircle className = "text-red-400" size = { 18 } />
109+ Recent Alerts
110+ </ h2 >
111+ < div className = "overflow-x-auto" >
112+ < table className = "w-full text-sm" >
103113 < thead >
104- < tr className = "text-gray-400 border-b border-gray-700 " >
105- < th className = "pb-2" > Time</ th >
106- < th className = "pb-2" > Event</ th >
107- < th className = "pb-2" > Source IP</ th >
108- < th className = "pb-2" > Status</ th >
114+ < tr className = "text-gray-400 border-b border-white/10 " >
115+ < th className = "text-left pb-2" > Time</ th >
116+ < th className = "text-left pb-2" > Event</ th >
117+ < th className = "text-left pb-2" > Source IP</ th >
118+ < th className = "text-left pb-2" > Status</ th >
109119 </ tr >
110120 </ thead >
111121 < tbody >
112122 { logs . slice ( 0 , 10 ) . map ( log => (
113- < tr key = { log . id } className = "border-b border-gray-700/50 hover:bg-gray-700/30 " >
114- < td className = "py-2 text-sm text-gray-300 " > { new Date ( log . timestamp ) . toLocaleTimeString ( ) } </ td >
115- < td className = "py-2 text-sm font-medium " > { log . event_type } </ td >
116- < td className = "py-2 text-sm text-gray-300 " > { log . source_ip } </ td >
123+ < tr key = { log . id } className = "border-b border-white/5 hover:bg-white/5 " >
124+ < td className = "py-2" > { new Date ( log . timestamp ) . toLocaleTimeString ( ) } </ td >
125+ < td className = "py-2" > { log . event_type } </ td >
126+ < td className = "py-2" > { log . source_ip } </ td >
117127 < td className = "py-2" >
118- < span className = { `px-2 py-1 rounded text-xs ${ log . event_type === 'Normal' ? 'bg-green-900 text-green-300' : 'bg-red-900 text-red-300' } ` } >
128+ < span className = { `px-2 py-1 rounded text-xs font-medium ${
129+ log . event_type === 'Normal'
130+ ? 'bg-green-500/20 text-green-400'
131+ : 'bg-red-500/20 text-red-400'
132+ } `} >
119133 { log . event_type === 'Normal' ? 'Safe' : 'Critical' }
120134 </ span >
121135 </ td >
0 commit comments