JustAPI Bot fix: comprehensive UI, docs, security, and deployment improvements Β· 7/14/2026
381467d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import { useEffect, useState, lazy, Suspense, Component, ReactNode } from "react";
import DashboardStats from "./DashboardStats";
import TrendingDevelopers from "./TrendingDevelopers";
import LiveLogStream from "./LiveLogStream";
import BottomPanel from "./BottomPanel";
import SystemStatus from "./SystemStatus";
import QuickStatsRow from "./QuickStatsRow";
import AlertBanner from "./AlertBanner";
import RecentActivity from "./RecentActivity";
import { GitGraph } from "lucide-react";
// Error boundary for WebGL/Globe issues
class GlobeErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean }> {
constructor(props: { children: ReactNode }) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error: Error) {
console.warn("Globe component error:", error.message);
}
render() {
if (this.state.hasError) {
return (
<div className="w-full h-full flex items-center justify-center">
<div className="text-center text-foreground/50">
<div className="text-6xl mb-4">π</div>
<p className="text-sm">3D Globe unavailable</p>
<p className="text-xs mt-1 opacity-50">WebGL may not be supported</p>
</div>
</div>
);
}
return this.props.children;
}
}
const GlobeViz = lazy(() => import("./GlobeViz").catch(() => ({
default: () => (
<div className="w-full h-full flex items-center justify-center">
<div className="text-center text-foreground/50">
<div className="text-6xl mb-4">π</div>
<p className="text-sm">Globe failed to load</p>
</div>
</div>
)
})));
export default function AdminDashboard() {
const [data, setData] = useState<any>({
totalRepos: 0,
totalUsers: 0,
collaborations: 0,
trendingDevelopers: [],
activityLog: [],
codeStats: {},
reviewStats: {},
languages: [],
quickStats: {}
});
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch("/api/admin/stats");
const json = await res.json();
// Unwrap the data from the API response structure { success: true, data: {...} }
setData(json.data || json);
} catch (e) {
console.error("Failed to fetch admin stats");
}
};
fetchData();
const interval = setInterval(fetchData, 10000);
return () => clearInterval(interval);
}, []);
return (
<div className="relative h-full w-full">
{/* 3D Globe Background */}
<div className="absolute inset-0 z-0 opacity-80 pointer-events-auto">
<GlobeErrorBoundary>
<Suspense fallback={
<div className="w-full h-full flex items-center justify-center">
<div className="text-foreground/30 text-sm">Loading globe...</div>
</div>
}>
<GlobeViz activities={data.activityLog || []} />
</Suspense>
</GlobeErrorBoundary>
</div>
<div className="relative z-10 flex flex-col h-full p-6 pb-8 pointer-events-none">
{/* Top Alert Banner */}
<div className="mb-4 pointer-events-auto shrink-0">
<AlertBanner />
</div>
{/* Quick Stats Row - Top Center */}
<div className="mb-4 pointer-events-auto shrink-0 flex justify-center">
<QuickStatsRow stats={data.quickStats || {}} />
</div>
{/* Main Content Grid */}
<div className="flex-1 grid grid-cols-12 gap-6 min-h-0">
{/* Left Column: Stats & Trending */}
<div className="col-span-3 flex flex-col gap-4 pointer-events-auto overflow-hidden">
{/* Stats Block */}
<div className="glass-panel rounded-xl shrink-0">
<DashboardStats stats={data} />
</div>
{/* Trending Devs Block */}
<div className="glass-panel rounded-xl flex-1 overflow-y-auto custom-scrollbar min-h-0">
<TrendingDevelopers developers={data.trendingDevelopers || []} />
</div>
</div>
{/* Middle Column: Globe Area with System Status */}
<div className="col-span-6 flex flex-col justify-between items-center pointer-events-none py-4">
{/* Top area - Recent Activity floating */}
<div className="pointer-events-auto self-start">
<RecentActivity activities={data.recentActivity || []} />
</div>
{/* Bottom - System Status HUD */}
<div className="pointer-events-auto">
<SystemStatus status={data.systemStatus} />
</div>
</div>
{/* Right Column: Log Stream */}
<div className="col-span-3 flex flex-col gap-4 pointer-events-auto overflow-hidden">
<div className="flex justify-end shrink-0">
<GitGraph className="h-8 w-8 text-foreground opacity-30 hover:opacity-70 transition-opacity cursor-pointer" />
</div>
<div className="glass-panel rounded-xl flex-1 overflow-hidden min-h-0 relative">
<LiveLogStream logs={data.activityLog || []} />
</div>
</div>
</div>
{/* Bottom Section: Carousel Panel */}
<div className="h-48 shrink-0 pointer-events-auto mt-4">
<BottomPanel stats={data} />
</div>
</div>
</div>
);
}