Skip to content

Commit aaf7a0f

Browse files
authored
Merge pull request #39 from DevanshuNEU/feature/repo-detail-dark-theme
feat(frontend): Repo Detail Pages Dark Theme (#35)
2 parents 6e94d2d + f6f0f71 commit aaf7a0f

5 files changed

Lines changed: 202 additions & 198 deletions

File tree

frontend/src/components/DependencyGraph.tsx

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export function DependencyGraph({ repoId, apiUrl, apiKey }: DependencyGraphProps
100100

101101
const data = await response.json()
102102

103-
// Convert to React Flow format
104103
const flowNodes: Node[] = data.nodes.map((node: any) => {
105104
const fileName = node.label || node.id.split('/').pop()
106105
const fullPath = node.id
@@ -145,10 +144,10 @@ export function DependencyGraph({ repoId, apiUrl, apiKey }: DependencyGraphProps
145144
source: edge.source,
146145
target: edge.target,
147146
animated: false,
148-
style: { stroke: '#94a3b8', strokeWidth: 1.5 },
147+
style: { stroke: '#4b5563', strokeWidth: 1.5 },
149148
markerEnd: {
150149
type: MarkerType.ArrowClosed,
151-
color: '#94a3b8',
150+
color: '#4b5563',
152151
},
153152
}))
154153

@@ -172,7 +171,6 @@ export function DependencyGraph({ repoId, apiUrl, apiKey }: DependencyGraphProps
172171
const handleNodeClick = useCallback((event: any, node: Node) => {
173172
setHighlightedNode(node.id)
174173

175-
// Highlight connected nodes
176174
const connectedNodeIds = new Set<string>()
177175
connectedNodeIds.add(node.id)
178176

@@ -232,67 +230,67 @@ export function DependencyGraph({ repoId, apiUrl, apiKey }: DependencyGraphProps
232230

233231
if (loading) {
234232
return (
235-
<div className="card p-12 text-center">
236-
<div className="w-16 h-16 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin mx-auto mb-4" />
237-
<p className="text-gray-600">Building dependency graph...</p>
233+
<div className="p-12 text-center">
234+
<div className="w-16 h-16 border-4 border-blue-500/20 border-t-blue-500 rounded-full animate-spin mx-auto mb-4" />
235+
<p className="text-gray-400">Building dependency graph...</p>
238236
</div>
239237
)
240238
}
241239

242240
return (
243-
<div className="space-y-6">
244-
{/* Metrics + Controls */}
241+
<div className="p-6 space-y-6">
242+
{/* Metrics */}
245243
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
246-
<div className="card p-5">
247-
<div className="text-sm text-gray-600 mb-1">Total Files</div>
248-
<div className="text-3xl font-bold text-gray-900">{allNodes.length}</div>
244+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
245+
<div className="text-sm text-gray-400 mb-1">Total Files</div>
246+
<div className="text-3xl font-bold text-white">{allNodes.length}</div>
249247
</div>
250-
<div className="card p-5">
251-
<div className="text-sm text-gray-600 mb-1">Dependencies</div>
252-
<div className="text-3xl font-bold text-blue-600">{edges.length}</div>
248+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
249+
<div className="text-sm text-gray-400 mb-1">Dependencies</div>
250+
<div className="text-3xl font-bold text-blue-400">{edges.length}</div>
253251
</div>
254-
<div className="card p-5">
255-
<div className="text-sm text-gray-600 mb-1">Avg per File</div>
256-
<div className="text-3xl font-bold text-gray-900">
252+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
253+
<div className="text-sm text-gray-400 mb-1">Avg per File</div>
254+
<div className="text-3xl font-bold text-white">
257255
{metrics?.avg_dependencies?.toFixed(1) || 0}
258256
</div>
259257
</div>
260-
<div className="card p-5">
261-
<div className="text-sm text-gray-600 mb-1">Showing</div>
262-
<div className="text-3xl font-bold text-green-600">{nodes.length}</div>
258+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
259+
<div className="text-sm text-gray-400 mb-1">Showing</div>
260+
<div className="text-3xl font-bold text-green-400">{nodes.length}</div>
263261
</div>
264262
</div>
265263

266264
{/* Filter Controls */}
267-
<div className="card p-5">
265+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
268266
<div className="flex flex-wrap items-center gap-4">
269267
<label className="flex items-center gap-2 cursor-pointer">
270268
<input
271269
type="checkbox"
272270
checked={filterCritical}
273271
onChange={(e) => setFilterCritical(e.target.checked)}
274-
className="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
272+
className="w-4 h-4 bg-white/5 border-white/10 rounded focus:ring-2 focus:ring-blue-500"
275273
/>
276-
<span className="text-sm text-gray-700">Show only critical files (≥3 deps)</span>
274+
<span className="text-sm text-gray-300">Show only critical files (≥3 deps)</span>
277275
</label>
278276

279277
<div className="flex items-center gap-2">
280-
<label className="text-sm text-gray-700">Min dependencies:</label>
278+
<label className="text-sm text-gray-300">Min dependencies:</label>
281279
<input
282280
type="range"
283281
min="0"
284282
max="10"
285283
value={minDeps}
286284
onChange={(e) => setMinDeps(Number(e.target.value))}
287-
className="w-32"
285+
className="w-32 accent-blue-500"
288286
/>
289-
<span className="text-sm font-mono text-gray-900">{minDeps}</span>
287+
<span className="text-sm font-mono text-white">{minDeps}</span>
290288
</div>
291289

292290
{highlightedNode && (
293291
<button
294292
onClick={resetHighlight}
295-
className="text-sm px-3 py-1.5 bg-red-50 text-red-600 rounded hover:bg-red-100 border border-red-200"
293+
className="text-sm px-3 py-1.5 bg-red-500/10 text-red-400 rounded-lg hover:bg-red-500/20 border border-red-500/20 transition-colors"
296294
>
297295
Clear highlight
298296
</button>
@@ -302,15 +300,15 @@ export function DependencyGraph({ repoId, apiUrl, apiKey }: DependencyGraphProps
302300

303301
{/* Most Critical Files */}
304302
{metrics?.most_critical_files && metrics.most_critical_files.length > 0 && (
305-
<div className="card p-5">
306-
<h3 className="text-sm font-semibold mb-3 text-gray-900">Most Critical Files</h3>
303+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
304+
<h3 className="text-sm font-semibold mb-3 text-white">Most Critical Files</h3>
307305
<div className="space-y-2">
308306
{metrics.most_critical_files.slice(0, 5).map((item: any, idx: number) => (
309307
<div key={idx} className="flex items-center justify-between text-sm">
310-
<span className="font-mono text-gray-700 truncate flex-1">
308+
<span className="font-mono text-gray-300 truncate flex-1">
311309
{item.file.split('/').slice(-2).join('/')}
312310
</span>
313-
<span className="badge-danger ml-2">
311+
<span className="ml-2 px-2 py-0.5 text-xs bg-red-500/10 text-red-400 border border-red-500/20 rounded">
314312
{item.dependents} dependents
315313
</span>
316314
</div>
@@ -320,7 +318,7 @@ export function DependencyGraph({ repoId, apiUrl, apiKey }: DependencyGraphProps
320318
)}
321319

322320
{/* Graph Visualization */}
323-
<div className="card p-0 overflow-hidden" style={{ height: '700px' }}>
321+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl overflow-hidden" style={{ height: '700px' }}>
324322
<ReactFlow
325323
nodes={nodes}
326324
edges={edges}
@@ -333,39 +331,41 @@ export function DependencyGraph({ repoId, apiUrl, apiKey }: DependencyGraphProps
333331
minZoom={0.1}
334332
maxZoom={2}
335333
>
336-
<Background />
337-
<Controls />
334+
<Background color="#1f1f23" gap={16} />
335+
<Controls className="!bg-[#111113] !border-white/10 !rounded-lg [&>button]:!bg-[#111113] [&>button]:!border-white/10 [&>button]:!text-gray-400 [&>button:hover]:!bg-white/10" />
338336
<MiniMap
339337
nodeColor={(node) => {
340338
const style = node.style as any
341339
return style?.background || '#6b7280'
342340
}}
343-
maskColor="rgba(0, 0, 0, 0.1)"
341+
maskColor="rgba(0, 0, 0, 0.5)"
342+
className="!bg-[#111113] !border-white/10"
344343
/>
345344
</ReactFlow>
346345
</div>
347346

348-
<div className="card p-5">
349-
<h3 className="text-sm font-semibold mb-3 text-gray-900">Graph Legend</h3>
347+
{/* Legend */}
348+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
349+
<h3 className="text-sm font-semibold mb-3 text-white">Graph Legend</h3>
350350
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-xs">
351351
<div className="flex items-center gap-2">
352352
<div className="w-4 h-4 rounded" style={{ background: '#3776ab' }} />
353-
<span className="text-gray-600">Python</span>
353+
<span className="text-gray-400">Python</span>
354354
</div>
355355
<div className="flex items-center gap-2">
356356
<div className="w-4 h-4 rounded" style={{ background: '#3178c6' }} />
357-
<span className="text-gray-600">TypeScript</span>
357+
<span className="text-gray-400">TypeScript</span>
358358
</div>
359359
<div className="flex items-center gap-2">
360360
<div className="w-4 h-4 rounded" style={{ background: '#f7df1e' }} />
361-
<span className="text-gray-600">JavaScript</span>
361+
<span className="text-gray-400">JavaScript</span>
362362
</div>
363363
<div className="flex items-center gap-2">
364-
<div className="w-1 h-4 bg-blue-600" />
365-
<span className="text-gray-600">Dependency</span>
364+
<div className="w-1 h-4 bg-blue-500" />
365+
<span className="text-gray-400">Dependency</span>
366366
</div>
367367
</div>
368-
<div className="mt-3 pt-3 border-t border-gray-200 text-xs text-gray-600">
368+
<div className="mt-3 pt-3 border-t border-white/5 text-xs text-gray-500">
369369
💡 Click any node to highlight its dependencies • Drag to pan • Scroll to zoom
370370
</div>
371371
</div>

frontend/src/components/ImpactAnalyzer.tsx

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -60,47 +60,47 @@ export function ImpactAnalyzer({ repoId, apiUrl, apiKey }: ImpactAnalyzerProps)
6060

6161
const getRiskColor = (risk: string) => {
6262
switch (risk) {
63-
case 'high': return 'text-red-600 bg-red-50 border-red-200'
64-
case 'medium': return 'text-amber-600 bg-amber-50 border-amber-200'
65-
case 'low': return 'text-green-600 bg-green-50 border-green-200'
66-
default: return 'text-gray-600 bg-gray-50 border-gray-200'
63+
case 'high': return 'text-red-400 bg-red-500/10 border-red-500/20'
64+
case 'medium': return 'text-yellow-400 bg-yellow-500/10 border-yellow-500/20'
65+
case 'low': return 'text-green-400 bg-green-500/10 border-green-500/20'
66+
default: return 'text-gray-400 bg-white/5 border-white/10'
6767
}
6868
}
6969

7070
return (
71-
<div className="space-y-6">
71+
<div className="p-6 space-y-6">
7272
{/* Input Form */}
73-
<div className="card p-6">
74-
<h3 className="text-base font-semibold mb-4 text-gray-900">Analyze Change Impact</h3>
73+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
74+
<h3 className="text-base font-semibold mb-4 text-white">Analyze Change Impact</h3>
7575
<form onSubmit={analyzeImpact} className="space-y-4">
7676
<div>
77-
<label className="block text-sm font-medium mb-2 text-gray-700">
77+
<label className="block text-sm font-medium mb-2 text-gray-300">
7878
File Path (relative to repository root)
7979
</label>
8080
<input
8181
type="text"
8282
value={filePath}
8383
onChange={(e) => setFilePath(e.target.value)}
8484
placeholder="e.g., src/auth/middleware.py or components/Button.tsx"
85-
className="input"
85+
className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-xl text-white placeholder:text-gray-500 focus:outline-none focus:border-blue-500/50 focus:ring-1 focus:ring-blue-500/20 transition-all"
8686
disabled={loading}
8787
/>
88-
<p className="mt-1.5 text-xs text-gray-500">
88+
<p className="mt-2 text-xs text-gray-500">
8989
Enter the path of the file you want to modify to see its impact
9090
</p>
9191
</div>
9292

9393
<button
9494
type="submit"
95-
className="btn-primary"
95+
className="px-4 py-2.5 bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white font-medium rounded-lg transition-all disabled:opacity-50"
9696
disabled={loading}
9797
>
9898
{loading ? 'Analyzing...' : 'Analyze Impact'}
9999
</button>
100100
</form>
101101

102102
{error && (
103-
<div className="mt-4 p-4 bg-red-50 border border-red-200 rounded-md text-sm text-red-700">
103+
<div className="mt-4 p-4 bg-red-500/10 border border-red-500/20 rounded-lg text-sm text-red-400">
104104
{error}
105105
</div>
106106
)}
@@ -110,46 +110,46 @@ export function ImpactAnalyzer({ repoId, apiUrl, apiKey }: ImpactAnalyzerProps)
110110
{result && (
111111
<div className="space-y-6">
112112
{/* Risk Assessment */}
113-
<div className={`card p-6 border-2 ${getRiskColor(result.risk_level)}`}>
113+
<div className={`bg-[#0a0a0c] rounded-xl p-5 border-2 ${getRiskColor(result.risk_level)}`}>
114114
<div className="flex items-center justify-between mb-3">
115-
<h3 className="text-lg font-semibold">Risk Assessment</h3>
116-
<span className={`px-4 py-1.5 rounded-md font-semibold uppercase text-sm border ${getRiskColor(result.risk_level)}`}>
115+
<h3 className="text-lg font-semibold text-white">Risk Assessment</h3>
116+
<span className={`px-4 py-1.5 rounded-lg font-semibold uppercase text-sm border ${getRiskColor(result.risk_level)}`}>
117117
{result.risk_level} Risk
118118
</span>
119119
</div>
120-
<p className="text-sm font-mono text-gray-700 mb-4">
120+
<p className="text-sm font-mono text-gray-300 mb-4">
121121
{result.file}
122122
</p>
123-
<p className="text-sm text-gray-600">
123+
<p className="text-sm text-gray-400">
124124
{result.impact_summary}
125125
</p>
126126
</div>
127127

128128
{/* Impact Overview */}
129129
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
130-
<div className="card p-5">
131-
<div className="text-sm text-gray-600 mb-1">Direct Dependencies</div>
132-
<div className="text-3xl font-bold text-blue-600">
130+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
131+
<div className="text-sm text-gray-400 mb-1">Direct Dependencies</div>
132+
<div className="text-3xl font-bold text-blue-400">
133133
{result.dependency_count}
134134
</div>
135135
<div className="text-xs text-gray-500 mt-1">
136136
Files this imports
137137
</div>
138138
</div>
139139

140-
<div className="card p-5">
141-
<div className="text-sm text-gray-600 mb-1">Total Impact</div>
142-
<div className="text-3xl font-bold text-amber-600">
140+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
141+
<div className="text-sm text-gray-400 mb-1">Total Impact</div>
142+
<div className="text-3xl font-bold text-yellow-400">
143143
{result.dependent_count}
144144
</div>
145145
<div className="text-xs text-gray-500 mt-1">
146146
Files affected by changes
147147
</div>
148148
</div>
149149

150-
<div className="card p-5">
151-
<div className="text-sm text-gray-600 mb-1">Test Files</div>
152-
<div className="text-3xl font-bold text-green-600">
150+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
151+
<div className="text-sm text-gray-400 mb-1">Test Files</div>
152+
<div className="text-3xl font-bold text-green-400">
153153
{result.test_files?.length || 0}
154154
</div>
155155
<div className="text-xs text-gray-500 mt-1">
@@ -160,16 +160,16 @@ export function ImpactAnalyzer({ repoId, apiUrl, apiKey }: ImpactAnalyzerProps)
160160

161161
{/* Dependencies (What This File Needs) */}
162162
{result.direct_dependencies && result.direct_dependencies.length > 0 && (
163-
<div className="card p-6">
164-
<h3 className="text-base font-semibold mb-4 text-gray-900">
163+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
164+
<h3 className="text-base font-semibold mb-4 text-white">
165165
Dependencies ({result.direct_dependencies.length})
166166
</h3>
167-
<p className="text-sm text-gray-600 mb-3">
167+
<p className="text-sm text-gray-400 mb-3">
168168
Files this file imports (upstream)
169169
</p>
170170
<div className="space-y-1.5">
171171
{result.direct_dependencies.map((dep, idx) => (
172-
<div key={idx} className="text-sm font-mono text-gray-700 bg-blue-50 px-3 py-2 rounded">
172+
<div key={idx} className="text-sm font-mono text-gray-300 bg-blue-500/10 border border-blue-500/20 px-3 py-2 rounded-lg">
173173
{dep}
174174
</div>
175175
))}
@@ -179,16 +179,16 @@ export function ImpactAnalyzer({ repoId, apiUrl, apiKey }: ImpactAnalyzerProps)
179179

180180
{/* Dependents (What Breaks If Changed) */}
181181
{result.all_dependents && result.all_dependents.length > 0 && (
182-
<div className="card p-6">
183-
<h3 className="text-base font-semibold mb-4 text-gray-900">
182+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
183+
<h3 className="text-base font-semibold mb-4 text-white">
184184
Affected Files ({result.all_dependents.length})
185185
</h3>
186-
<p className="text-sm text-gray-600 mb-3">
186+
<p className="text-sm text-gray-400 mb-3">
187187
Files that would be impacted by changes to this file (downstream)
188188
</p>
189189
<div className="space-y-1.5 max-h-96 overflow-y-auto">
190190
{result.all_dependents.map((dep, idx) => (
191-
<div key={idx} className="text-sm font-mono text-gray-700 bg-amber-50 px-3 py-2 rounded">
191+
<div key={idx} className="text-sm font-mono text-gray-300 bg-yellow-500/10 border border-yellow-500/20 px-3 py-2 rounded-lg">
192192
{dep}
193193
</div>
194194
))}
@@ -198,16 +198,16 @@ export function ImpactAnalyzer({ repoId, apiUrl, apiKey }: ImpactAnalyzerProps)
198198

199199
{/* Test Files */}
200200
{result.test_files && result.test_files.length > 0 && (
201-
<div className="card p-6">
202-
<h3 className="text-base font-semibold mb-4 text-gray-900">
201+
<div className="bg-[#0a0a0c] border border-white/5 rounded-xl p-5">
202+
<h3 className="text-base font-semibold mb-4 text-white">
203203
Related Tests ({result.test_files.length})
204204
</h3>
205-
<p className="text-sm text-gray-600 mb-3">
205+
<p className="text-sm text-gray-400 mb-3">
206206
Test files that may need updates
207207
</p>
208208
<div className="space-y-1.5">
209209
{result.test_files.map((test, idx) => (
210-
<div key={idx} className="text-sm font-mono text-gray-700 bg-green-50 px-3 py-2 rounded">
210+
<div key={idx} className="text-sm font-mono text-gray-300 bg-green-500/10 border border-green-500/20 px-3 py-2 rounded-lg">
211211
{test}
212212
</div>
213213
))}

0 commit comments

Comments
 (0)