nitrostack 1.0.70 → 1.0.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/studio/app/api/chat/route.ts +33 -15
- package/src/studio/app/auth/callback/page.tsx +6 -6
- package/src/studio/app/chat/page.tsx +1124 -415
- package/src/studio/app/chat/page.tsx.backup +1046 -187
- package/src/studio/app/globals.css +361 -191
- package/src/studio/app/health/page.tsx +72 -76
- package/src/studio/app/layout.tsx +9 -11
- package/src/studio/app/logs/page.tsx +29 -30
- package/src/studio/app/page.tsx +134 -230
- package/src/studio/app/prompts/page.tsx +115 -97
- package/src/studio/app/resources/page.tsx +115 -124
- package/src/studio/app/settings/page.tsx +1080 -125
- package/src/studio/app/tools/page.tsx +343 -0
- package/src/studio/components/EnlargeModal.tsx +76 -65
- package/src/studio/components/LogMessage.tsx +5 -5
- package/src/studio/components/MarkdownRenderer.tsx +4 -4
- package/src/studio/components/Sidebar.tsx +150 -210
- package/src/studio/components/SplashScreen.tsx +109 -0
- package/src/studio/components/ToolCard.tsx +50 -41
- package/src/studio/components/VoiceOrbOverlay.tsx +469 -0
- package/src/studio/components/WidgetRenderer.tsx +8 -3
- package/src/studio/components/tools/ToolsCanvas.tsx +327 -0
- package/src/studio/lib/llm-service.ts +104 -1
- package/src/studio/lib/store.ts +36 -21
- package/src/studio/lib/types.ts +1 -1
- package/src/studio/package-lock.json +3303 -0
- package/src/studio/package.json +3 -1
- package/src/studio/public/NitroStudio Isotype Color.png +0 -0
- package/src/studio/tailwind.config.ts +63 -17
- package/templates/typescript-starter/package-lock.json +4112 -0
- package/templates/typescript-starter/package.json +2 -3
- package/templates/typescript-starter/src/modules/calculator/calculator.tools.ts +100 -5
- package/src/studio/app/auth/page.tsx +0 -560
- package/src/studio/app/ping/page.tsx +0 -209
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
import { useStudioStore } from '@/lib/store';
|
|
5
|
-
import { api } from '@/lib/api';
|
|
6
|
-
import { Wifi, Activity, Clock, TrendingUp, Radio } from 'lucide-react';
|
|
7
|
-
|
|
8
|
-
export default function PingPage() {
|
|
9
|
-
const { pingHistory, addPingResult } = useStudioStore();
|
|
10
|
-
const [pinging, setPinging] = useState(false);
|
|
11
|
-
const [lastLatency, setLastLatency] = useState<number | null>(null);
|
|
12
|
-
|
|
13
|
-
const handlePing = async () => {
|
|
14
|
-
setPinging(true);
|
|
15
|
-
const startTime = Date.now();
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
await api.ping();
|
|
19
|
-
const latency = Date.now() - startTime;
|
|
20
|
-
setLastLatency(latency);
|
|
21
|
-
addPingResult({ time: new Date(), latency });
|
|
22
|
-
} catch (error) {
|
|
23
|
-
console.error('Ping failed:', error);
|
|
24
|
-
} finally {
|
|
25
|
-
setPinging(false);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const averageLatency =
|
|
30
|
-
pingHistory.length > 0
|
|
31
|
-
? Math.round(pingHistory.reduce((sum, p) => sum + p.latency, 0) / pingHistory.length)
|
|
32
|
-
: null;
|
|
33
|
-
|
|
34
|
-
const minLatency =
|
|
35
|
-
pingHistory.length > 0
|
|
36
|
-
? Math.min(...pingHistory.map((p) => p.latency))
|
|
37
|
-
: null;
|
|
38
|
-
|
|
39
|
-
const maxLatency =
|
|
40
|
-
pingHistory.length > 0
|
|
41
|
-
? Math.max(...pingHistory.map((p) => p.latency))
|
|
42
|
-
: null;
|
|
43
|
-
|
|
44
|
-
const getLatencyColor = (latency: number) => {
|
|
45
|
-
if (latency < 100) return 'text-emerald-500';
|
|
46
|
-
if (latency < 500) return 'text-amber-500';
|
|
47
|
-
return 'text-rose-500';
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const getLatencyBg = (latency: number) => {
|
|
51
|
-
if (latency < 100) return 'bg-emerald-500/10 border-emerald-500/20';
|
|
52
|
-
if (latency < 500) return 'bg-amber-500/10 border-amber-500/20';
|
|
53
|
-
return 'bg-rose-500/10 border-rose-500/20';
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const getLatencyDotColor = (latency: number) => {
|
|
57
|
-
if (latency < 100) return 'bg-emerald-500';
|
|
58
|
-
if (latency < 500) return 'bg-amber-500';
|
|
59
|
-
return 'bg-rose-500';
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<div className="fixed inset-0 flex flex-col bg-background" style={{ left: 'var(--sidebar-width, 15rem)' }}>
|
|
64
|
-
{/* Sticky Header */}
|
|
65
|
-
<div className="sticky top-0 z-10 border-b border-border/50 px-6 py-3 flex items-center justify-between bg-card/80 backdrop-blur-md shadow-sm">
|
|
66
|
-
<div className="flex items-center gap-3">
|
|
67
|
-
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-cyan-500 to-blue-500 flex items-center justify-center shadow-md">
|
|
68
|
-
<Wifi className="w-5 h-5 text-white" strokeWidth={2.5} />
|
|
69
|
-
</div>
|
|
70
|
-
<div>
|
|
71
|
-
<h1 className="text-lg font-bold text-foreground">Ping</h1>
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
{/* Content - ONLY this scrolls */}
|
|
77
|
-
<div className="flex-1 overflow-y-auto overflow-x-hidden">
|
|
78
|
-
<div className="max-w-4xl mx-auto px-6 py-6">
|
|
79
|
-
|
|
80
|
-
{/* Main Ping Card */}
|
|
81
|
-
<div className="card card-hover p-8 mb-8 text-center bg-gradient-to-br from-card via-card to-muted/20">
|
|
82
|
-
<button
|
|
83
|
-
onClick={handlePing}
|
|
84
|
-
disabled={pinging}
|
|
85
|
-
className="btn btn-primary btn-lg mx-auto px-12 py-4 text-lg gap-3 shadow-lg hover:shadow-xl transition-all"
|
|
86
|
-
>
|
|
87
|
-
{pinging ? (
|
|
88
|
-
<>
|
|
89
|
-
<Radio className="w-6 h-6 animate-pulse" />
|
|
90
|
-
Pinging...
|
|
91
|
-
</>
|
|
92
|
-
) : (
|
|
93
|
-
<>
|
|
94
|
-
<Wifi className="w-6 h-6" />
|
|
95
|
-
Send Ping
|
|
96
|
-
</>
|
|
97
|
-
)}
|
|
98
|
-
</button>
|
|
99
|
-
|
|
100
|
-
{lastLatency !== null && (
|
|
101
|
-
<div className="mt-8 animate-fade-in">
|
|
102
|
-
<div className={`inline-block px-8 py-4 rounded-2xl border ${getLatencyBg(lastLatency)}`}>
|
|
103
|
-
<div className={`text-6xl font-bold ${getLatencyColor(lastLatency)}`}>
|
|
104
|
-
{lastLatency}ms
|
|
105
|
-
</div>
|
|
106
|
-
<div className="text-muted-foreground mt-2 flex items-center justify-center gap-2">
|
|
107
|
-
<Clock className="w-4 h-4" />
|
|
108
|
-
Last ping latency
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
</div>
|
|
112
|
-
)}
|
|
113
|
-
</div>
|
|
114
|
-
|
|
115
|
-
{/* Statistics Grid */}
|
|
116
|
-
{pingHistory.length > 0 && (
|
|
117
|
-
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
|
118
|
-
{/* Average */}
|
|
119
|
-
<div className="card card-hover p-6">
|
|
120
|
-
<div className="flex items-center gap-3 mb-3">
|
|
121
|
-
<div className="w-10 h-10 rounded-lg bg-blue-500/10 flex items-center justify-center">
|
|
122
|
-
<TrendingUp className="w-5 h-5 text-blue-500" />
|
|
123
|
-
</div>
|
|
124
|
-
<h3 className="font-semibold text-foreground">Average</h3>
|
|
125
|
-
</div>
|
|
126
|
-
<div className="text-3xl font-bold text-foreground">{averageLatency}ms</div>
|
|
127
|
-
<p className="text-sm text-muted-foreground mt-1">{pingHistory.length} total pings</p>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
{/* Min */}
|
|
131
|
-
<div className="card card-hover p-6">
|
|
132
|
-
<div className="flex items-center gap-3 mb-3">
|
|
133
|
-
<div className="w-10 h-10 rounded-lg bg-emerald-500/10 flex items-center justify-center">
|
|
134
|
-
<Activity className="w-5 h-5 text-emerald-500" />
|
|
135
|
-
</div>
|
|
136
|
-
<h3 className="font-semibold text-foreground">Fastest</h3>
|
|
137
|
-
</div>
|
|
138
|
-
<div className="text-3xl font-bold text-emerald-500">{minLatency}ms</div>
|
|
139
|
-
<p className="text-sm text-muted-foreground mt-1">Best response time</p>
|
|
140
|
-
</div>
|
|
141
|
-
|
|
142
|
-
{/* Max */}
|
|
143
|
-
<div className="card card-hover p-6">
|
|
144
|
-
<div className="flex items-center gap-3 mb-3">
|
|
145
|
-
<div className="w-10 h-10 rounded-lg bg-amber-500/10 flex items-center justify-center">
|
|
146
|
-
<Clock className="w-5 h-5 text-amber-500" />
|
|
147
|
-
</div>
|
|
148
|
-
<h3 className="font-semibold text-foreground">Slowest</h3>
|
|
149
|
-
</div>
|
|
150
|
-
<div className="text-3xl font-bold text-amber-500">{maxLatency}ms</div>
|
|
151
|
-
<p className="text-sm text-muted-foreground mt-1">Worst response time</p>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
)}
|
|
155
|
-
|
|
156
|
-
{/* Ping History */}
|
|
157
|
-
{pingHistory.length > 0 && (
|
|
158
|
-
<div>
|
|
159
|
-
<h2 className="text-2xl font-semibold text-foreground mb-6 flex items-center gap-2">
|
|
160
|
-
<Activity className="w-6 h-6 text-primary" />
|
|
161
|
-
Recent Pings
|
|
162
|
-
</h2>
|
|
163
|
-
<div className="space-y-3">
|
|
164
|
-
{pingHistory.slice().reverse().map((ping, idx) => (
|
|
165
|
-
<div
|
|
166
|
-
key={idx}
|
|
167
|
-
className="card card-hover p-5 flex items-center justify-between animate-fade-in"
|
|
168
|
-
>
|
|
169
|
-
<div className="flex items-center gap-3">
|
|
170
|
-
<div className={`w-3 h-3 rounded-full ${getLatencyDotColor(ping.latency)} shadow-lg`} />
|
|
171
|
-
<span className="text-sm text-muted-foreground font-mono">
|
|
172
|
-
{ping.time.toLocaleTimeString()}
|
|
173
|
-
</span>
|
|
174
|
-
</div>
|
|
175
|
-
<div className="flex items-center gap-3">
|
|
176
|
-
<span className={`text-lg font-bold ${getLatencyColor(ping.latency)}`}>
|
|
177
|
-
{ping.latency}ms
|
|
178
|
-
</span>
|
|
179
|
-
<span className={`badge ${
|
|
180
|
-
ping.latency < 100
|
|
181
|
-
? 'badge-success'
|
|
182
|
-
: ping.latency < 500
|
|
183
|
-
? 'badge-warning'
|
|
184
|
-
: 'badge-error'
|
|
185
|
-
}`}>
|
|
186
|
-
{ping.latency < 100 ? 'Excellent' : ping.latency < 500 ? 'Good' : 'Slow'}
|
|
187
|
-
</span>
|
|
188
|
-
</div>
|
|
189
|
-
</div>
|
|
190
|
-
))}
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
)}
|
|
194
|
-
|
|
195
|
-
{/* Empty State */}
|
|
196
|
-
{pingHistory.length === 0 && !pinging && (
|
|
197
|
-
<div className="empty-state">
|
|
198
|
-
<Wifi className="empty-state-icon" />
|
|
199
|
-
<p className="empty-state-title">No ping history yet</p>
|
|
200
|
-
<p className="empty-state-description">
|
|
201
|
-
Click the "Send Ping" button above to test your connection
|
|
202
|
-
</p>
|
|
203
|
-
</div>
|
|
204
|
-
)}
|
|
205
|
-
</div>
|
|
206
|
-
</div>
|
|
207
|
-
</div>
|
|
208
|
-
);
|
|
209
|
-
}
|