@geenius/tools 0.1.0 → 0.3.0
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 +62 -3
- package/packages/convex/shared/README.md +1 -1
- package/packages/devtools/dist/index.d.ts +204 -0
- package/packages/devtools/dist/index.js +186 -0
- package/packages/devtools/dist/index.js.map +1 -0
- package/packages/devtools/react/README.md +1 -1
- package/packages/devtools/solidjs/README.md +1 -1
- package/packages/devtools/solidjs/dist/index.js +1830 -0
- package/packages/devtools/solidjs/dist/index.js.map +1 -0
- package/packages/env/dist/index.d.ts +151 -0
- package/packages/env/dist/index.js +93 -0
- package/packages/env/dist/index.js.map +1 -0
- package/packages/errors/dist/index.d.ts +177 -0
- package/packages/errors/dist/index.js +187 -0
- package/packages/errors/dist/index.js.map +1 -0
- package/packages/errors/react/README.md +1 -1
- package/packages/errors/solidjs/README.md +1 -1
- package/packages/logger/dist/index.d.ts +171 -0
- package/packages/logger/dist/index.js +216 -0
- package/packages/logger/dist/index.js.map +1 -0
- package/packages/logger/react/README.md +1 -1
- package/packages/logger/solidjs/README.md +1 -1
- package/packages/perf/dist/index.d.ts +168 -0
- package/packages/perf/dist/index.js +265 -0
- package/packages/perf/dist/index.js.map +1 -0
- package/packages/perf/react/README.md +1 -1
- package/packages/perf/solidjs/README.md +1 -1
- package/packages/shared/dist/index.d.ts +253 -0
- package/packages/shared/dist/index.js +278 -0
- package/packages/shared/dist/index.js.map +1 -0
- package/.changeset/config.json +0 -11
- package/.env.example +0 -2
- package/.github/CODEOWNERS +0 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/ci.yml +0 -23
- package/.github/workflows/release.yml +0 -29
- package/.node-version +0 -1
- package/.nvmrc +0 -1
- package/.prettierrc +0 -7
- package/.project/ACCOUNT.yaml +0 -4
- package/.project/IDEAS.yaml +0 -7
- package/.project/PROJECT.yaml +0 -11
- package/.project/ROADMAP.yaml +0 -15
- package/CODE_OF_CONDUCT.md +0 -26
- package/CONTRIBUTING.md +0 -69
- package/SECURITY.md +0 -18
- package/SUPPORT.md +0 -14
- package/packages/convex/shared/package.json +0 -42
- package/packages/convex/shared/src/audit/index.ts +0 -5
- package/packages/convex/shared/src/audit/presets.ts +0 -165
- package/packages/convex/shared/src/audit/schema.ts +0 -85
- package/packages/convex/shared/src/audit/write.ts +0 -102
- package/packages/convex/shared/src/extract.ts +0 -75
- package/packages/convex/shared/src/index.ts +0 -41
- package/packages/convex/shared/src/messages.ts +0 -45
- package/packages/convex/shared/src/security.ts +0 -112
- package/packages/convex/shared/src/throw.ts +0 -184
- package/packages/convex/shared/src/types.ts +0 -57
- package/packages/convex/shared/src/utils.ts +0 -58
- package/packages/convex/shared/tsconfig.json +0 -28
- package/packages/convex/shared/tsup.config.ts +0 -12
- package/packages/devtools/package.json +0 -27
- package/packages/devtools/react/package.json +0 -53
- package/packages/devtools/react/src/components/DesignPreview.tsx +0 -59
- package/packages/devtools/react/src/components/DesignSwitcherDropdown.tsx +0 -99
- package/packages/devtools/react/src/components/DevSidebar.tsx +0 -247
- package/packages/devtools/react/src/components/DevToolbar.tsx +0 -242
- package/packages/devtools/react/src/components/GitHubIssueDialog.tsx +0 -402
- package/packages/devtools/react/src/components/InspectorOverlay.tsx +0 -312
- package/packages/devtools/react/src/components/PageLoadWaterfall.tsx +0 -144
- package/packages/devtools/react/src/components/PerformancePanel.tsx +0 -330
- package/packages/devtools/react/src/context/DevModeContext.tsx +0 -226
- package/packages/devtools/react/src/context/PerformanceContext.tsx +0 -143
- package/packages/devtools/react/src/data/designs.ts +0 -13
- package/packages/devtools/react/src/hooks/useGitHubLabels.ts +0 -47
- package/packages/devtools/react/src/hooks/useVirtualList.ts +0 -124
- package/packages/devtools/react/src/index.ts +0 -77
- package/packages/devtools/react/src/panels/ConvexSpy.tsx +0 -130
- package/packages/devtools/react/src/panels/DatabaseSeeder.tsx +0 -116
- package/packages/devtools/react/src/panels/DevModePhase2.tsx +0 -191
- package/packages/devtools/react/src/panels/DevModePhase3.tsx +0 -234
- package/packages/devtools/react/src/panels/FeatureFlagsToggle.tsx +0 -104
- package/packages/devtools/react/src/panels/QuickRouteJump.tsx +0 -152
- package/packages/devtools/react/src/services/github-service.ts +0 -247
- package/packages/devtools/react/tsconfig.json +0 -31
- package/packages/devtools/react/tsup.config.ts +0 -18
- package/packages/devtools/solidjs/package.json +0 -49
- package/packages/devtools/solidjs/src/components/DesignPreview.tsx +0 -51
- package/packages/devtools/solidjs/src/components/DesignSwitcherDropdown.tsx +0 -95
- package/packages/devtools/solidjs/src/components/DevSidebar.tsx +0 -247
- package/packages/devtools/solidjs/src/components/DevToolbar.tsx +0 -242
- package/packages/devtools/solidjs/src/components/GitHubIssueDialog.tsx +0 -400
- package/packages/devtools/solidjs/src/components/InspectorOverlay.tsx +0 -311
- package/packages/devtools/solidjs/src/components/PageLoadWaterfall.tsx +0 -144
- package/packages/devtools/solidjs/src/components/PerformancePanel.tsx +0 -330
- package/packages/devtools/solidjs/src/context/DevModeContext.tsx +0 -216
- package/packages/devtools/solidjs/src/context/PerformanceContext.tsx +0 -135
- package/packages/devtools/solidjs/src/data/designs.ts +0 -13
- package/packages/devtools/solidjs/src/hooks/createGitHubLabels.ts +0 -47
- package/packages/devtools/solidjs/src/index.ts +0 -64
- package/packages/devtools/solidjs/src/services/github-service.ts +0 -247
- package/packages/devtools/solidjs/tsconfig.json +0 -21
- package/packages/devtools/src/index.ts +0 -377
- package/packages/devtools/tsup.config.ts +0 -12
- package/packages/env/package.json +0 -30
- package/packages/env/src/index.ts +0 -264
- package/packages/env/tsup.config.ts +0 -12
- package/packages/errors/package.json +0 -27
- package/packages/errors/react/package.json +0 -72
- package/packages/errors/react/src/analytics.ts +0 -16
- package/packages/errors/react/src/components/ErrorBoundary.tsx +0 -248
- package/packages/errors/react/src/components/ErrorDisplay.tsx +0 -328
- package/packages/errors/react/src/components/ValidationErrors.tsx +0 -102
- package/packages/errors/react/src/config.ts +0 -199
- package/packages/errors/react/src/constants.ts +0 -74
- package/packages/errors/react/src/hooks/useErrorBoundary.ts +0 -92
- package/packages/errors/react/src/hooks/useErrorHandler.ts +0 -87
- package/packages/errors/react/src/index.ts +0 -96
- package/packages/errors/react/src/types.ts +0 -102
- package/packages/errors/react/src/utils/errorMessages.ts +0 -35
- package/packages/errors/react/src/utils/errorPolicy.ts +0 -139
- package/packages/errors/react/src/utils/extractAppError.ts +0 -174
- package/packages/errors/react/src/utils/formatError.ts +0 -112
- package/packages/errors/react/tsconfig.json +0 -25
- package/packages/errors/react/tsup.config.ts +0 -24
- package/packages/errors/solidjs/package.json +0 -46
- package/packages/errors/solidjs/src/components/ErrorDisplay.tsx +0 -179
- package/packages/errors/solidjs/src/config.ts +0 -98
- package/packages/errors/solidjs/src/hooks/createErrorHandler.ts +0 -107
- package/packages/errors/solidjs/src/index.ts +0 -61
- package/packages/errors/solidjs/src/types.ts +0 -34
- package/packages/errors/solidjs/src/utils/errorPolicy.ts +0 -56
- package/packages/errors/solidjs/src/utils/extractAppError.ts +0 -94
- package/packages/errors/solidjs/src/utils/formatError.ts +0 -33
- package/packages/errors/solidjs/tsconfig.json +0 -26
- package/packages/errors/solidjs/tsup.config.ts +0 -21
- package/packages/errors/src/index.ts +0 -320
- package/packages/errors/tsup.config.ts +0 -12
- package/packages/logger/package.json +0 -27
- package/packages/logger/react/package.json +0 -46
- package/packages/logger/react/src/index.ts +0 -4
- package/packages/logger/react/src/useMetrics.ts +0 -42
- package/packages/logger/react/src/usePerformanceLog.ts +0 -61
- package/packages/logger/react/tsconfig.json +0 -31
- package/packages/logger/react/tsup.config.ts +0 -12
- package/packages/logger/solidjs/package.json +0 -45
- package/packages/logger/solidjs/src/createMetrics.ts +0 -37
- package/packages/logger/solidjs/src/createPerformanceLog.ts +0 -58
- package/packages/logger/solidjs/src/index.ts +0 -4
- package/packages/logger/solidjs/tsconfig.json +0 -32
- package/packages/logger/solidjs/tsup.config.ts +0 -12
- package/packages/logger/src/index.ts +0 -363
- package/packages/logger/tsup.config.ts +0 -12
- package/packages/perf/package.json +0 -27
- package/packages/perf/react/package.json +0 -59
- package/packages/perf/react/src/components/PerformanceDashboard.tsx +0 -257
- package/packages/perf/react/src/hooks/useMonitoredQuery.ts +0 -89
- package/packages/perf/react/src/hooks/usePerformanceMetrics.ts +0 -78
- package/packages/perf/react/src/index.ts +0 -33
- package/packages/perf/react/src/services/PerformanceMonitor.ts +0 -313
- package/packages/perf/react/src/types.ts +0 -77
- package/packages/perf/react/tsconfig.json +0 -25
- package/packages/perf/react/tsup.config.ts +0 -19
- package/packages/perf/solidjs/package.json +0 -41
- package/packages/perf/solidjs/src/components/PerformanceDashboard.tsx +0 -207
- package/packages/perf/solidjs/src/hooks/createPerformanceMetrics.ts +0 -73
- package/packages/perf/solidjs/src/index.ts +0 -31
- package/packages/perf/solidjs/src/services/PerformanceMonitor.ts +0 -134
- package/packages/perf/solidjs/src/types.ts +0 -78
- package/packages/perf/solidjs/tsconfig.json +0 -26
- package/packages/perf/solidjs/tsup.config.ts +0 -14
- package/packages/perf/src/index.ts +0 -410
- package/packages/perf/tsup.config.ts +0 -12
- package/pnpm-workspace.yaml +0 -2
|
@@ -0,0 +1,1830 @@
|
|
|
1
|
+
import { createContext, createSignal, createEffect, createMemo, useContext, onCleanup, onMount } from 'solid-js';
|
|
2
|
+
import { cn } from '@geenius/ui-solid';
|
|
3
|
+
import { Github, AlertCircle, CheckCircle2, ExternalLink, Lightbulb, Bug, Component, Activity, Trash2, X, Clock, Zap, AlertTriangle, Power, Target, PanelRight, RefreshCw, Minimize2, Maximize2 } from 'lucide-solid';
|
|
4
|
+
import { jsx, Fragment, jsxs } from 'solid-js/jsx-runtime';
|
|
5
|
+
import { metricsStore } from '@geenius/tools-logger';
|
|
6
|
+
import { Show, For } from 'solid-js/web';
|
|
7
|
+
|
|
8
|
+
// src/components/DevToolbar.tsx
|
|
9
|
+
var DEV_MODE_STORAGE_KEY = "geenius-dev-mode-state";
|
|
10
|
+
var defaultState = {
|
|
11
|
+
isDevMode: false,
|
|
12
|
+
isSidebarOpen: false,
|
|
13
|
+
isInspectorMode: false,
|
|
14
|
+
issueDialog: {
|
|
15
|
+
isOpen: false,
|
|
16
|
+
type: "bug",
|
|
17
|
+
initialDescription: ""
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var DevModeContext = createContext(void 0);
|
|
21
|
+
function createDevMode() {
|
|
22
|
+
const context = useContext(DevModeContext);
|
|
23
|
+
if (!context) {
|
|
24
|
+
throw new Error("createDevMode must be used within a DevModeProvider");
|
|
25
|
+
}
|
|
26
|
+
return context;
|
|
27
|
+
}
|
|
28
|
+
function createDevModeOptional() {
|
|
29
|
+
return useContext(DevModeContext) ?? null;
|
|
30
|
+
}
|
|
31
|
+
var DevModeProvider = memo(function DevModeProvider2({
|
|
32
|
+
children,
|
|
33
|
+
isAllowed
|
|
34
|
+
}) {
|
|
35
|
+
const resolvedAllowed = isAllowed ?? resolveDevAllowed();
|
|
36
|
+
const [state, setState] = createSignal(() => {
|
|
37
|
+
if (!resolvedAllowed || typeof window === "undefined") return defaultState;
|
|
38
|
+
try {
|
|
39
|
+
const stored = localStorage.getItem(DEV_MODE_STORAGE_KEY);
|
|
40
|
+
if (stored) {
|
|
41
|
+
const parsed = JSON.parse(stored);
|
|
42
|
+
return {
|
|
43
|
+
isDevMode: parsed.isDevMode ?? false,
|
|
44
|
+
isSidebarOpen: false,
|
|
45
|
+
isInspectorMode: false,
|
|
46
|
+
issueDialog: defaultState.issueDialog
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
return defaultState;
|
|
52
|
+
});
|
|
53
|
+
createEffect(() => {
|
|
54
|
+
if (!resolvedAllowed || typeof window === "undefined") return;
|
|
55
|
+
try {
|
|
56
|
+
localStorage.setItem(
|
|
57
|
+
DEV_MODE_STORAGE_KEY,
|
|
58
|
+
JSON.stringify({ isDevMode: state.isDevMode })
|
|
59
|
+
);
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
}, [state.isDevMode, resolvedAllowed]);
|
|
63
|
+
const toggleDevMode = () => {
|
|
64
|
+
setState((prev) => ({
|
|
65
|
+
...prev,
|
|
66
|
+
isDevMode: !prev.isDevMode,
|
|
67
|
+
isSidebarOpen: prev.isDevMode ? false : prev.isSidebarOpen,
|
|
68
|
+
isInspectorMode: prev.isDevMode ? false : prev.isInspectorMode
|
|
69
|
+
}));
|
|
70
|
+
};
|
|
71
|
+
const toggleSidebar = () => {
|
|
72
|
+
setState((prev) => ({ ...prev, isSidebarOpen: !prev.isSidebarOpen }));
|
|
73
|
+
};
|
|
74
|
+
const toggleInspector = () => {
|
|
75
|
+
setState((prev) => ({
|
|
76
|
+
...prev,
|
|
77
|
+
isInspectorMode: !prev.isInspectorMode
|
|
78
|
+
}));
|
|
79
|
+
};
|
|
80
|
+
const setDevMode = (enabled) => {
|
|
81
|
+
setState((prev) => ({
|
|
82
|
+
...prev,
|
|
83
|
+
isDevMode: enabled,
|
|
84
|
+
isSidebarOpen: enabled ? prev.isSidebarOpen : false,
|
|
85
|
+
isInspectorMode: enabled ? prev.isInspectorMode : false
|
|
86
|
+
}));
|
|
87
|
+
};
|
|
88
|
+
const setSidebarOpen = (open) => {
|
|
89
|
+
setState((prev) => ({ ...prev, isSidebarOpen: open }));
|
|
90
|
+
};
|
|
91
|
+
const setInspectorMode = (enabled) => {
|
|
92
|
+
setState((prev) => ({ ...prev, isInspectorMode: enabled }));
|
|
93
|
+
};
|
|
94
|
+
const openIssueDialog = (type, description, componentDetails) => {
|
|
95
|
+
setState((prev) => ({
|
|
96
|
+
...prev,
|
|
97
|
+
issueDialog: {
|
|
98
|
+
isOpen: true,
|
|
99
|
+
type,
|
|
100
|
+
initialDescription: description,
|
|
101
|
+
componentDetails
|
|
102
|
+
}
|
|
103
|
+
}));
|
|
104
|
+
};
|
|
105
|
+
const closeIssueDialog = () => {
|
|
106
|
+
setState((prev) => ({
|
|
107
|
+
...prev,
|
|
108
|
+
issueDialog: { ...prev.issueDialog, isOpen: false }
|
|
109
|
+
}));
|
|
110
|
+
};
|
|
111
|
+
if (!resolvedAllowed) {
|
|
112
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
113
|
+
}
|
|
114
|
+
return /* @__PURE__ */ jsx(
|
|
115
|
+
DevModeContext.Provider,
|
|
116
|
+
{
|
|
117
|
+
value: {
|
|
118
|
+
...state,
|
|
119
|
+
toggleDevMode,
|
|
120
|
+
toggleSidebar,
|
|
121
|
+
toggleInspector,
|
|
122
|
+
setDevMode,
|
|
123
|
+
setSidebarOpen,
|
|
124
|
+
setInspectorMode,
|
|
125
|
+
openIssueDialog,
|
|
126
|
+
closeIssueDialog
|
|
127
|
+
},
|
|
128
|
+
children
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
function createIsDevToolsVisible() {
|
|
133
|
+
const context = createDevModeOptional();
|
|
134
|
+
if (!context) return false;
|
|
135
|
+
return context.isDevMode;
|
|
136
|
+
}
|
|
137
|
+
function createIsDevAllowed(isAllowed) {
|
|
138
|
+
return isAllowed ?? resolveDevAllowed();
|
|
139
|
+
}
|
|
140
|
+
function resolveDevAllowed() {
|
|
141
|
+
try {
|
|
142
|
+
if (import.meta?.env?.VITE_CONVEX_IS_DEV === "true") return true;
|
|
143
|
+
if (import.meta?.env?.DEV) return true;
|
|
144
|
+
} catch {
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
var MAX_METRICS = 100;
|
|
149
|
+
var PerformanceContext = createContext(
|
|
150
|
+
void 0
|
|
151
|
+
);
|
|
152
|
+
function createPerformanceContext() {
|
|
153
|
+
const context = useContext(PerformanceContext);
|
|
154
|
+
if (!context) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
"createPerformanceContext must be used within PerformanceProvider"
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
return context;
|
|
160
|
+
}
|
|
161
|
+
function createPerformanceContextOptional() {
|
|
162
|
+
return useContext(PerformanceContext) ?? null;
|
|
163
|
+
}
|
|
164
|
+
var PerformanceProvider = memo(function PerformanceProvider2({
|
|
165
|
+
children
|
|
166
|
+
}) {
|
|
167
|
+
const [isPerformancePanelOpen, setIsPerformancePanelOpen] = createSignal(false);
|
|
168
|
+
const [metrics, setMetrics] = createSignal([]);
|
|
169
|
+
const [filters, setFilters] = createSignal({
|
|
170
|
+
network: true,
|
|
171
|
+
query: true,
|
|
172
|
+
mutation: true,
|
|
173
|
+
render: true,
|
|
174
|
+
route: true
|
|
175
|
+
});
|
|
176
|
+
createEffect(() => {
|
|
177
|
+
const unsubscribe = metricsStore.subscribe((newMetrics) => {
|
|
178
|
+
setMetrics((prev) => {
|
|
179
|
+
const combined = [...prev, ...newMetrics];
|
|
180
|
+
if (combined.length > MAX_METRICS) {
|
|
181
|
+
return combined.slice(-MAX_METRICS);
|
|
182
|
+
}
|
|
183
|
+
return combined;
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
return () => unsubscribe();
|
|
187
|
+
});
|
|
188
|
+
const stats = () => {
|
|
189
|
+
const filtered = metrics.filter((m) => m.duration !== void 0);
|
|
190
|
+
const total = filtered.length;
|
|
191
|
+
if (total === 0) {
|
|
192
|
+
return {
|
|
193
|
+
totalRequests: 0,
|
|
194
|
+
avgDuration: 0,
|
|
195
|
+
slowRequests: 0,
|
|
196
|
+
fastRequests: 0
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const durations = filtered.map((m) => m.duration);
|
|
200
|
+
const avg = durations.reduce((a, b) => a + b, 0) / total;
|
|
201
|
+
const slow = durations.filter((d) => d > 100).length;
|
|
202
|
+
const fast = durations.filter((d) => d < 50).length;
|
|
203
|
+
return {
|
|
204
|
+
totalRequests: total,
|
|
205
|
+
avgDuration: Math.round(avg * 100) / 100,
|
|
206
|
+
slowRequests: slow,
|
|
207
|
+
fastRequests: fast
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
const togglePerformancePanel = () => {
|
|
211
|
+
setIsPerformancePanelOpen((prev) => !prev);
|
|
212
|
+
};
|
|
213
|
+
const clearMetrics = () => {
|
|
214
|
+
setMetrics([]);
|
|
215
|
+
metricsStore.clear();
|
|
216
|
+
};
|
|
217
|
+
const toggleFilter = (filter) => {
|
|
218
|
+
setFilters((prev) => ({
|
|
219
|
+
...prev,
|
|
220
|
+
[filter]: !prev[filter]
|
|
221
|
+
}));
|
|
222
|
+
};
|
|
223
|
+
return /* @__PURE__ */ jsx(
|
|
224
|
+
PerformanceContext.Provider,
|
|
225
|
+
{
|
|
226
|
+
value: {
|
|
227
|
+
isPerformancePanelOpen,
|
|
228
|
+
metrics,
|
|
229
|
+
filters,
|
|
230
|
+
stats: stats(),
|
|
231
|
+
togglePerformancePanel,
|
|
232
|
+
clearMetrics,
|
|
233
|
+
toggleFilter
|
|
234
|
+
},
|
|
235
|
+
children
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// src/services/github-service.ts
|
|
241
|
+
var _config = null;
|
|
242
|
+
function configureGitHub(config) {
|
|
243
|
+
_config = config;
|
|
244
|
+
}
|
|
245
|
+
function getGitHubConfig() {
|
|
246
|
+
if (_config) return _config;
|
|
247
|
+
let owner = "";
|
|
248
|
+
let repo = "";
|
|
249
|
+
let branch = "main";
|
|
250
|
+
let token = "";
|
|
251
|
+
try {
|
|
252
|
+
owner = import.meta?.env?.VITE_GITHUB_OWNER ?? "";
|
|
253
|
+
repo = import.meta?.env?.VITE_GITHUB_REPO ?? "";
|
|
254
|
+
branch = import.meta?.env?.VITE_GITHUB_BRANCH ?? "main";
|
|
255
|
+
token = import.meta?.env?.VITE_GITHUB_TOKEN ?? "";
|
|
256
|
+
} catch {
|
|
257
|
+
}
|
|
258
|
+
return { owner, repo, branch, token };
|
|
259
|
+
}
|
|
260
|
+
function isGitHubConfigured() {
|
|
261
|
+
const { owner, repo, token } = getGitHubConfig();
|
|
262
|
+
const isPlaceholder = !token || token === "ghp_your_personal_access_token_here";
|
|
263
|
+
return Boolean(owner && repo && token && !isPlaceholder);
|
|
264
|
+
}
|
|
265
|
+
async function createGitHubIssue(issue) {
|
|
266
|
+
const { owner, repo, token } = getGitHubConfig();
|
|
267
|
+
if (!owner || !repo || !token) {
|
|
268
|
+
throw new Error(
|
|
269
|
+
"GitHub configuration is incomplete. Call configureGitHub() or set VITE_GITHUB_* env vars."
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
const response = await fetch(
|
|
273
|
+
`https://api.github.com/repos/${owner}/${repo}/issues`,
|
|
274
|
+
{
|
|
275
|
+
method: "POST",
|
|
276
|
+
headers: {
|
|
277
|
+
Accept: "application/vnd.github+json",
|
|
278
|
+
Authorization: `Bearer ${token}`,
|
|
279
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
280
|
+
"Content-Type": "application/json"
|
|
281
|
+
},
|
|
282
|
+
body: JSON.stringify({
|
|
283
|
+
title: issue.title,
|
|
284
|
+
body: issue.body,
|
|
285
|
+
labels: issue.labels || []
|
|
286
|
+
})
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
if (!response.ok) {
|
|
290
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
291
|
+
throw new Error(
|
|
292
|
+
`Failed to create issue: ${error.message || response.statusText}`
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
return response.json();
|
|
296
|
+
}
|
|
297
|
+
async function getRepositoryLabels() {
|
|
298
|
+
const { owner, repo, token } = getGitHubConfig();
|
|
299
|
+
if (!owner || !repo || !token) return [];
|
|
300
|
+
try {
|
|
301
|
+
const response = await fetch(
|
|
302
|
+
`https://api.github.com/repos/${owner}/${repo}/labels`,
|
|
303
|
+
{
|
|
304
|
+
headers: {
|
|
305
|
+
Accept: "application/vnd.github+json",
|
|
306
|
+
Authorization: `Bearer ${token}`,
|
|
307
|
+
"X-GitHub-Api-Version": "2022-11-28"
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
if (!response.ok) return [];
|
|
312
|
+
return response.json();
|
|
313
|
+
} catch {
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
async function getGitHubIssues(filter = "all", state = "open") {
|
|
318
|
+
const { owner, repo, token } = getGitHubConfig();
|
|
319
|
+
if (!owner || !repo || !token) return [];
|
|
320
|
+
try {
|
|
321
|
+
const params = new URLSearchParams({
|
|
322
|
+
state,
|
|
323
|
+
per_page: "50",
|
|
324
|
+
sort: "updated",
|
|
325
|
+
direction: "desc"
|
|
326
|
+
});
|
|
327
|
+
if (filter !== "all") {
|
|
328
|
+
params.set("labels", filter);
|
|
329
|
+
}
|
|
330
|
+
const response = await fetch(
|
|
331
|
+
`https://api.github.com/repos/${owner}/${repo}/issues?${params.toString()}`,
|
|
332
|
+
{
|
|
333
|
+
headers: {
|
|
334
|
+
Accept: "application/vnd.github+json",
|
|
335
|
+
Authorization: `Bearer ${token}`,
|
|
336
|
+
"X-GitHub-Api-Version": "2022-11-28"
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
);
|
|
340
|
+
if (!response.ok) return [];
|
|
341
|
+
const issues = await response.json();
|
|
342
|
+
return issues.filter((issue) => !("pull_request" in issue));
|
|
343
|
+
} catch {
|
|
344
|
+
return [];
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function generateContextInfo() {
|
|
348
|
+
const lines = [
|
|
349
|
+
"---",
|
|
350
|
+
"### Context",
|
|
351
|
+
"",
|
|
352
|
+
`**Page URL:** ${window.location.href}`,
|
|
353
|
+
`**Timestamp:** ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
354
|
+
`**User Agent:** ${navigator.userAgent}`,
|
|
355
|
+
`**Branch:** ${getGitHubConfig().branch ?? "main"}`
|
|
356
|
+
];
|
|
357
|
+
if (typeof window !== "undefined") {
|
|
358
|
+
lines.push(`**Screen:** ${window.innerWidth}x${window.innerHeight}`);
|
|
359
|
+
}
|
|
360
|
+
return lines.join("\n");
|
|
361
|
+
}
|
|
362
|
+
function getIssueType(issue) {
|
|
363
|
+
const labelNames = issue.labels.map((l) => l.name.toLowerCase());
|
|
364
|
+
if (labelNames.includes("bug")) return "bug";
|
|
365
|
+
if (labelNames.includes("enhancement") || labelNames.includes("feature"))
|
|
366
|
+
return "feature";
|
|
367
|
+
return "other";
|
|
368
|
+
}
|
|
369
|
+
function formatRelativeTime(dateString) {
|
|
370
|
+
const date = new Date(dateString);
|
|
371
|
+
const now = /* @__PURE__ */ new Date();
|
|
372
|
+
const diffMs = now.getTime() - date.getTime();
|
|
373
|
+
const diffMins = Math.floor(diffMs / 6e4);
|
|
374
|
+
const diffHours = Math.floor(diffMs / 36e5);
|
|
375
|
+
const diffDays = Math.floor(diffMs / 864e5);
|
|
376
|
+
if (diffMins < 1) return "just now";
|
|
377
|
+
if (diffMins < 60) return `${diffMins}m ago`;
|
|
378
|
+
if (diffHours < 24) return `${diffHours}h ago`;
|
|
379
|
+
if (diffDays < 7) return `${diffDays}d ago`;
|
|
380
|
+
return date.toLocaleDateString();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// src/hooks/createGitHubLabels.ts
|
|
384
|
+
function createGitHubLabels() {
|
|
385
|
+
const [data, setData] = createSignal(void 0);
|
|
386
|
+
const [isLoading, setIsLoading] = createSignal(false);
|
|
387
|
+
const [error, setError] = createSignal(null);
|
|
388
|
+
const isConfigured = isGitHubConfigured();
|
|
389
|
+
createEffect(() => {
|
|
390
|
+
if (!isConfigured) return;
|
|
391
|
+
let cancelled = false;
|
|
392
|
+
setIsLoading(true);
|
|
393
|
+
getRepositoryLabels().then((labels) => {
|
|
394
|
+
if (!cancelled) {
|
|
395
|
+
setData(labels);
|
|
396
|
+
setIsLoading(false);
|
|
397
|
+
}
|
|
398
|
+
}).catch((err) => {
|
|
399
|
+
if (!cancelled) {
|
|
400
|
+
setError(err);
|
|
401
|
+
setIsLoading(false);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
return () => {
|
|
405
|
+
cancelled = true;
|
|
406
|
+
};
|
|
407
|
+
});
|
|
408
|
+
return { data, isLoading, error, isConfigured };
|
|
409
|
+
}
|
|
410
|
+
var initialFormState = {
|
|
411
|
+
type: "feature",
|
|
412
|
+
title: "",
|
|
413
|
+
description: "",
|
|
414
|
+
selectedLabel: ""
|
|
415
|
+
};
|
|
416
|
+
var GitHubIssueDialog = memo(function GitHubIssueDialog2({
|
|
417
|
+
open,
|
|
418
|
+
onOpenChange,
|
|
419
|
+
initialType = "feature",
|
|
420
|
+
initialDescription = "",
|
|
421
|
+
componentDetails
|
|
422
|
+
}) {
|
|
423
|
+
const [form, setForm] = createSignal({
|
|
424
|
+
...initialFormState,
|
|
425
|
+
type: initialType,
|
|
426
|
+
description: initialDescription
|
|
427
|
+
});
|
|
428
|
+
const [loading, setLoading] = createSignal(false);
|
|
429
|
+
const [success, setSuccess] = createSignal(null);
|
|
430
|
+
const [error, setError] = createSignal(null);
|
|
431
|
+
const { data: labels } = createGitHubLabels();
|
|
432
|
+
const configured = isGitHubConfigured();
|
|
433
|
+
let dialogRef;
|
|
434
|
+
createEffect(() => {
|
|
435
|
+
if (open) {
|
|
436
|
+
setForm({
|
|
437
|
+
...initialFormState,
|
|
438
|
+
type: initialType,
|
|
439
|
+
description: initialDescription
|
|
440
|
+
});
|
|
441
|
+
setError(null);
|
|
442
|
+
setSuccess(null);
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
createEffect(() => {
|
|
446
|
+
if (!open) return;
|
|
447
|
+
const handleKeyDown = (e) => {
|
|
448
|
+
if (e.key === "Escape") onOpenChange(false);
|
|
449
|
+
};
|
|
450
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
451
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
452
|
+
});
|
|
453
|
+
const handleSubmit = async () => {
|
|
454
|
+
if (!form.title.trim()) {
|
|
455
|
+
setError("Please provide a title for the issue.");
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
setLoading(true);
|
|
459
|
+
setError(null);
|
|
460
|
+
try {
|
|
461
|
+
const typePrefix = form.type === "bug" ? "\u{1F41B} Bug Report" : "\u2728 Feature Request";
|
|
462
|
+
let componentSection = "";
|
|
463
|
+
if (componentDetails && componentDetails.length > 0) {
|
|
464
|
+
componentSection = `
|
|
465
|
+
### Components
|
|
466
|
+
${componentDetails.map((detail, index) => {
|
|
467
|
+
let propsBlock = "";
|
|
468
|
+
if (detail.props) {
|
|
469
|
+
try {
|
|
470
|
+
propsBlock = `
|
|
471
|
+
- **Props:**
|
|
472
|
+
\`\`\`json
|
|
473
|
+
${JSON.stringify(detail.props, null, 2)}
|
|
474
|
+
\`\`\``;
|
|
475
|
+
} catch {
|
|
476
|
+
propsBlock = "\n- **Props:** (Complex Object)";
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return `
|
|
480
|
+
**Component ${index + 1}**
|
|
481
|
+
- **Name:** \`${detail.name}\`
|
|
482
|
+
${detail.key ? `- **Key:** \`${detail.key}\`` : ""}
|
|
483
|
+
${detail.file ? `- **File:** \`${detail.file}\`` : ""}
|
|
484
|
+
- **Selector:** \`${detail.selector}\`${propsBlock}
|
|
485
|
+
`;
|
|
486
|
+
}).join("\n")}`;
|
|
487
|
+
}
|
|
488
|
+
const descriptionSection = form.description ? `## Description
|
|
489
|
+
${form.description}` : "";
|
|
490
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
491
|
+
const theme = typeof document !== "undefined" && document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
492
|
+
const viewport = typeof window !== "undefined" ? `${window.innerWidth}x${window.innerHeight}` : "unknown";
|
|
493
|
+
const userAgent = typeof navigator !== "undefined" ? navigator.userAgent : "unknown";
|
|
494
|
+
const url = typeof window !== "undefined" ? window.location.href : "unknown";
|
|
495
|
+
const contextSection = `
|
|
496
|
+
-----
|
|
497
|
+
**Context Information**
|
|
498
|
+
- **URL:** ${url}
|
|
499
|
+
- **Time:** ${timestamp}
|
|
500
|
+
- **Theme:** ${theme}
|
|
501
|
+
- **Viewport:** ${viewport}
|
|
502
|
+
- **User Agent:** ${userAgent}
|
|
503
|
+
`.trim();
|
|
504
|
+
const body = [
|
|
505
|
+
`# ${typePrefix}`,
|
|
506
|
+
"",
|
|
507
|
+
descriptionSection,
|
|
508
|
+
componentSection,
|
|
509
|
+
"",
|
|
510
|
+
contextSection
|
|
511
|
+
].filter(Boolean).join("\n");
|
|
512
|
+
const issueLabels = [];
|
|
513
|
+
if (form.type === "bug") issueLabels.push("bug");
|
|
514
|
+
if (form.type === "feature") issueLabels.push("enhancement");
|
|
515
|
+
if (form.selectedLabel) issueLabels.push(form.selectedLabel);
|
|
516
|
+
const result = await createGitHubIssue({
|
|
517
|
+
title: `[${form.type === "bug" ? "Bug" : "Feature"}] ${form.title}`,
|
|
518
|
+
body,
|
|
519
|
+
labels: issueLabels
|
|
520
|
+
});
|
|
521
|
+
setSuccess(result);
|
|
522
|
+
} catch (err) {
|
|
523
|
+
setError(err instanceof Error ? err.message : "An error occurred");
|
|
524
|
+
} finally {
|
|
525
|
+
setLoading(false);
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
const handleFieldChange = (field, value) => {
|
|
529
|
+
setForm((prev) => ({ ...prev, [field]: value }));
|
|
530
|
+
setError(null);
|
|
531
|
+
};
|
|
532
|
+
if (!open) return null;
|
|
533
|
+
return /* @__PURE__ */ jsxs("div", { class: "fixed inset-0 z-[10000] flex items-center justify-center", "data-dev-tool": "true", children: [
|
|
534
|
+
/* @__PURE__ */ jsx(
|
|
535
|
+
"div",
|
|
536
|
+
{
|
|
537
|
+
class: "absolute inset-0 bg-black/60 backdrop-blur-sm",
|
|
538
|
+
onClick: () => onOpenChange(false)
|
|
539
|
+
}
|
|
540
|
+
),
|
|
541
|
+
/* @__PURE__ */ jsxs(
|
|
542
|
+
"div",
|
|
543
|
+
{
|
|
544
|
+
ref: dialogRef,
|
|
545
|
+
class: cn(
|
|
546
|
+
"relative z-10 w-full max-w-[500px] mx-4",
|
|
547
|
+
"bg-gradient-to-br from-slate-900 to-slate-800",
|
|
548
|
+
"border border-white/10 rounded-2xl shadow-2xl",
|
|
549
|
+
"max-h-[90vh] overflow-y-auto",
|
|
550
|
+
"animate-in fade-in zoom-in-95 duration-200"
|
|
551
|
+
),
|
|
552
|
+
children: [
|
|
553
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2 px-6 py-4 border-b border-white/10", children: [
|
|
554
|
+
/* @__PURE__ */ jsx(Github, { class: "h-5 w-5 text-primary" }),
|
|
555
|
+
/* @__PURE__ */ jsx("h2", { class: "text-lg font-bold text-white", children: "Create GitHub Issue" })
|
|
556
|
+
] }),
|
|
557
|
+
/* @__PURE__ */ jsx("div", { class: "px-6 py-4", children: !configured ? /* @__PURE__ */ jsx("div", { class: "py-6", children: /* @__PURE__ */ jsxs("div", { class: "text-center space-y-3", children: [
|
|
558
|
+
/* @__PURE__ */ jsx("div", { class: "mx-auto w-12 h-12 rounded-full bg-yellow-500/10 flex items-center justify-center", children: /* @__PURE__ */ jsx(AlertCircle, { class: "h-6 w-6 text-yellow-500" }) }),
|
|
559
|
+
/* @__PURE__ */ jsxs("p", { class: "text-sm text-white/60", children: [
|
|
560
|
+
"GitHub integration is not configured. Call",
|
|
561
|
+
" ",
|
|
562
|
+
/* @__PURE__ */ jsx("code", { class: "text-xs bg-white/10 px-1.5 py-0.5 rounded", children: "configureGitHub()" }),
|
|
563
|
+
" ",
|
|
564
|
+
"or set VITE_GITHUB_TOKEN to enable issue creation."
|
|
565
|
+
] })
|
|
566
|
+
] }) }) : success ? /* @__PURE__ */ jsx("div", { class: "py-6", children: /* @__PURE__ */ jsxs("div", { class: "text-center space-y-4", children: [
|
|
567
|
+
/* @__PURE__ */ jsx(CheckCircle2, { class: "mx-auto h-12 w-12 text-green-500" }),
|
|
568
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
569
|
+
/* @__PURE__ */ jsx("p", { class: "font-medium text-white", children: "Issue Created!" }),
|
|
570
|
+
/* @__PURE__ */ jsx("p", { class: "text-sm text-white/60 mt-1", children: success.title })
|
|
571
|
+
] }),
|
|
572
|
+
/* @__PURE__ */ jsxs(
|
|
573
|
+
"a",
|
|
574
|
+
{
|
|
575
|
+
href: success.html_url,
|
|
576
|
+
target: "_blank",
|
|
577
|
+
rel: "noopener noreferrer",
|
|
578
|
+
class: "inline-flex items-center gap-2 px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/80 transition-colors",
|
|
579
|
+
children: [
|
|
580
|
+
/* @__PURE__ */ jsx(ExternalLink, { class: "h-4 w-4" }),
|
|
581
|
+
"View on GitHub"
|
|
582
|
+
]
|
|
583
|
+
}
|
|
584
|
+
)
|
|
585
|
+
] }) }) : /* @__PURE__ */ jsxs("div", { class: "space-y-4 py-2", children: [
|
|
586
|
+
/* @__PURE__ */ jsxs("div", { class: "grid grid-cols-2 gap-2", children: [
|
|
587
|
+
/* @__PURE__ */ jsxs(
|
|
588
|
+
"button",
|
|
589
|
+
{
|
|
590
|
+
type: "button",
|
|
591
|
+
onClick: () => handleFieldChange("type", "feature"),
|
|
592
|
+
class: cn(
|
|
593
|
+
"flex items-center gap-2 p-3 rounded-lg border-2 transition-all",
|
|
594
|
+
form.type === "feature" ? "border-emerald-500 bg-emerald-500/10 text-emerald-400" : "border-white/10 text-white/60 hover:border-white/20"
|
|
595
|
+
),
|
|
596
|
+
children: [
|
|
597
|
+
/* @__PURE__ */ jsx(Lightbulb, { class: "h-4 w-4" }),
|
|
598
|
+
/* @__PURE__ */ jsx("span", { class: "font-medium text-sm", children: "Feature" })
|
|
599
|
+
]
|
|
600
|
+
}
|
|
601
|
+
),
|
|
602
|
+
/* @__PURE__ */ jsxs(
|
|
603
|
+
"button",
|
|
604
|
+
{
|
|
605
|
+
type: "button",
|
|
606
|
+
onClick: () => handleFieldChange("type", "bug"),
|
|
607
|
+
class: cn(
|
|
608
|
+
"flex items-center gap-2 p-3 rounded-lg border-2 transition-all",
|
|
609
|
+
form.type === "bug" ? "border-red-500 bg-red-500/10 text-red-400" : "border-white/10 text-white/60 hover:border-white/20"
|
|
610
|
+
),
|
|
611
|
+
children: [
|
|
612
|
+
/* @__PURE__ */ jsx(Bug, { class: "h-4 w-4" }),
|
|
613
|
+
/* @__PURE__ */ jsx("span", { class: "font-medium text-sm", children: "Bug Report" })
|
|
614
|
+
]
|
|
615
|
+
}
|
|
616
|
+
)
|
|
617
|
+
] }),
|
|
618
|
+
componentDetails && componentDetails.length > 0 && /* @__PURE__ */ jsxs("div", { class: "p-3 rounded-lg bg-white/5 border border-white/10", children: [
|
|
619
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center gap-1.5 text-xs text-white/50 mb-2", children: [
|
|
620
|
+
/* @__PURE__ */ jsx(Component, { class: "h-3 w-3" }),
|
|
621
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
622
|
+
componentDetails.length,
|
|
623
|
+
" component",
|
|
624
|
+
componentDetails.length > 1 ? "s" : "",
|
|
625
|
+
" attached"
|
|
626
|
+
] })
|
|
627
|
+
] }),
|
|
628
|
+
/* @__PURE__ */ jsx("div", { class: "space-y-1", children: componentDetails.map((c, i) => /* @__PURE__ */ jsxs("div", { class: "text-xs font-mono text-white/80", children: [
|
|
629
|
+
c.name,
|
|
630
|
+
c.key && /* @__PURE__ */ jsxs("span", { class: "text-white/40 ml-1", children: [
|
|
631
|
+
"key=",
|
|
632
|
+
c.key
|
|
633
|
+
] })
|
|
634
|
+
] }, i)) })
|
|
635
|
+
] }),
|
|
636
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
637
|
+
/* @__PURE__ */ jsx("label", { class: "block text-xs font-medium text-white/60 mb-1", children: "Title" }),
|
|
638
|
+
/* @__PURE__ */ jsx(
|
|
639
|
+
"input",
|
|
640
|
+
{
|
|
641
|
+
type: "text",
|
|
642
|
+
value: form.title,
|
|
643
|
+
onChange: (e) => handleFieldChange("title", e.target.value),
|
|
644
|
+
placeholder: form.type === "bug" ? "Describe the bug..." : "Feature idea...",
|
|
645
|
+
class: "w-full px-3 py-2 bg-white/5 border border-white/10 rounded-lg text-sm text-white placeholder:text-white/30 focus:outline-none focus:ring-2 focus:ring-primary/50",
|
|
646
|
+
autoFocus: true
|
|
647
|
+
}
|
|
648
|
+
)
|
|
649
|
+
] }),
|
|
650
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
651
|
+
/* @__PURE__ */ jsx("label", { class: "block text-xs font-medium text-white/60 mb-1", children: "Description" }),
|
|
652
|
+
/* @__PURE__ */ jsx(
|
|
653
|
+
"textarea",
|
|
654
|
+
{
|
|
655
|
+
value: form.description,
|
|
656
|
+
onChange: (e) => handleFieldChange("description", e.target.value),
|
|
657
|
+
placeholder: "Provide more details...",
|
|
658
|
+
rows: 4,
|
|
659
|
+
class: "w-full px-3 py-2 bg-white/5 border border-white/10 rounded-lg text-sm text-white placeholder:text-white/30 focus:outline-none focus:ring-2 focus:ring-primary/50 resize-none"
|
|
660
|
+
}
|
|
661
|
+
)
|
|
662
|
+
] }),
|
|
663
|
+
labels && labels.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
664
|
+
/* @__PURE__ */ jsx("label", { class: "block text-xs font-medium text-white/60 mb-1", children: "Label" }),
|
|
665
|
+
/* @__PURE__ */ jsxs(
|
|
666
|
+
"select",
|
|
667
|
+
{
|
|
668
|
+
value: form.selectedLabel,
|
|
669
|
+
onChange: (e) => handleFieldChange("selectedLabel", e.target.value),
|
|
670
|
+
class: "w-full px-3 py-2 bg-white/5 border border-white/10 rounded-lg text-sm text-white focus:outline-none focus:ring-2 focus:ring-primary/50",
|
|
671
|
+
children: [
|
|
672
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "No label" }),
|
|
673
|
+
labels.map((label) => /* @__PURE__ */ jsx("option", { value: label.name, children: label.name }, label.id))
|
|
674
|
+
]
|
|
675
|
+
}
|
|
676
|
+
)
|
|
677
|
+
] }),
|
|
678
|
+
error && /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2 p-3 bg-red-500/10 border border-red-500/20 rounded-lg", children: [
|
|
679
|
+
/* @__PURE__ */ jsx(AlertCircle, { class: "h-4 w-4 text-red-400 flex-shrink-0" }),
|
|
680
|
+
/* @__PURE__ */ jsx("p", { class: "text-xs text-red-300", children: error })
|
|
681
|
+
] }),
|
|
682
|
+
/* @__PURE__ */ jsxs("div", { class: "flex justify-end gap-2 pt-2", children: [
|
|
683
|
+
/* @__PURE__ */ jsx(
|
|
684
|
+
"button",
|
|
685
|
+
{
|
|
686
|
+
onClick: () => onOpenChange(false),
|
|
687
|
+
class: "px-4 py-2 text-sm text-white/60 hover:text-white transition-colors",
|
|
688
|
+
children: "Cancel"
|
|
689
|
+
}
|
|
690
|
+
),
|
|
691
|
+
/* @__PURE__ */ jsx(
|
|
692
|
+
"button",
|
|
693
|
+
{
|
|
694
|
+
onClick: handleSubmit,
|
|
695
|
+
disabled: loading || !form.title.trim(),
|
|
696
|
+
class: cn(
|
|
697
|
+
"px-4 py-2 text-sm font-medium rounded-lg transition-all",
|
|
698
|
+
loading || !form.title.trim() ? "bg-white/10 text-white/30 cursor-not-allowed" : "bg-primary text-white hover:bg-primary/80"
|
|
699
|
+
),
|
|
700
|
+
children: loading ? "Creating..." : "Create Issue"
|
|
701
|
+
}
|
|
702
|
+
)
|
|
703
|
+
] })
|
|
704
|
+
] }) })
|
|
705
|
+
]
|
|
706
|
+
}
|
|
707
|
+
)
|
|
708
|
+
] });
|
|
709
|
+
});
|
|
710
|
+
function getDurationColor(duration) {
|
|
711
|
+
if (duration === void 0) return "text-white/40";
|
|
712
|
+
if (duration > 100) return "text-red-400";
|
|
713
|
+
if (duration > 50) return "text-yellow-400";
|
|
714
|
+
return "text-green-400";
|
|
715
|
+
}
|
|
716
|
+
function getDurationBgColor(duration) {
|
|
717
|
+
if (duration === void 0) return "bg-white/20";
|
|
718
|
+
if (duration > 100) return "bg-red-500";
|
|
719
|
+
if (duration > 50) return "bg-yellow-500";
|
|
720
|
+
return "bg-green-500";
|
|
721
|
+
}
|
|
722
|
+
function getTypeColor(type) {
|
|
723
|
+
switch (type) {
|
|
724
|
+
case "network":
|
|
725
|
+
return "text-blue-400";
|
|
726
|
+
case "query":
|
|
727
|
+
return "text-orange-400";
|
|
728
|
+
case "mutation":
|
|
729
|
+
return "text-red-400";
|
|
730
|
+
case "render":
|
|
731
|
+
return "text-purple-400";
|
|
732
|
+
case "route":
|
|
733
|
+
return "text-green-400";
|
|
734
|
+
case "component":
|
|
735
|
+
return "text-cyan-400";
|
|
736
|
+
case "effect":
|
|
737
|
+
return "text-teal-400";
|
|
738
|
+
default:
|
|
739
|
+
return "text-white/60";
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
function getTypeIcon(type) {
|
|
743
|
+
switch (type) {
|
|
744
|
+
case "network":
|
|
745
|
+
return "\u{1F310}";
|
|
746
|
+
case "query":
|
|
747
|
+
return "\u{1F50D}";
|
|
748
|
+
case "mutation":
|
|
749
|
+
return "\u270F\uFE0F";
|
|
750
|
+
case "render":
|
|
751
|
+
return "\u{1F3A8}";
|
|
752
|
+
case "route":
|
|
753
|
+
return "\u{1F9ED}";
|
|
754
|
+
case "component":
|
|
755
|
+
return "\u{1F4E6}";
|
|
756
|
+
case "effect":
|
|
757
|
+
return "\u26A1";
|
|
758
|
+
default:
|
|
759
|
+
return "\u{1F4DD}";
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
var MiniBar = memo(function MiniBar2({
|
|
763
|
+
height,
|
|
764
|
+
color,
|
|
765
|
+
label
|
|
766
|
+
}) {
|
|
767
|
+
return /* @__PURE__ */ jsx("div", { class: "flex flex-col items-center gap-0.5 flex-1 min-w-0", children: /* @__PURE__ */ jsx("div", { class: "w-full h-12 flex items-end", children: /* @__PURE__ */ jsx(
|
|
768
|
+
"div",
|
|
769
|
+
{
|
|
770
|
+
class: cn("w-full rounded-t-sm transition-all duration-300", color),
|
|
771
|
+
style: { height: `${Math.min(height, 100)}%` },
|
|
772
|
+
title: label
|
|
773
|
+
}
|
|
774
|
+
) }) });
|
|
775
|
+
});
|
|
776
|
+
var MetricRow = memo(function MetricRow2({
|
|
777
|
+
metric
|
|
778
|
+
}) {
|
|
779
|
+
const duration = metric.duration;
|
|
780
|
+
const durationStr = duration ? `${duration.toFixed(1)}ms` : "pending...";
|
|
781
|
+
return /* @__PURE__ */ jsxs(
|
|
782
|
+
"div",
|
|
783
|
+
{
|
|
784
|
+
class: cn(
|
|
785
|
+
"flex items-center gap-3 px-3 py-2 rounded-lg",
|
|
786
|
+
"bg-white/5 hover:bg-white/10 transition-colors"
|
|
787
|
+
),
|
|
788
|
+
children: [
|
|
789
|
+
/* @__PURE__ */ jsx("span", { class: "text-sm", children: getTypeIcon(metric.type) }),
|
|
790
|
+
/* @__PURE__ */ jsx("div", { class: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("div", { class: cn("text-xs font-medium truncate", getTypeColor(metric.type)), children: metric.name }) }),
|
|
791
|
+
/* @__PURE__ */ jsx(
|
|
792
|
+
"div",
|
|
793
|
+
{
|
|
794
|
+
class: cn(
|
|
795
|
+
"text-xs font-mono font-bold",
|
|
796
|
+
getDurationColor(duration)
|
|
797
|
+
),
|
|
798
|
+
children: durationStr
|
|
799
|
+
}
|
|
800
|
+
)
|
|
801
|
+
]
|
|
802
|
+
}
|
|
803
|
+
);
|
|
804
|
+
});
|
|
805
|
+
var StatCard = memo(function StatCard2({
|
|
806
|
+
icon: Icon,
|
|
807
|
+
label,
|
|
808
|
+
value,
|
|
809
|
+
color = "text-white"
|
|
810
|
+
}) {
|
|
811
|
+
return /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2 px-3 py-2 rounded-lg bg-white/5", children: [
|
|
812
|
+
/* @__PURE__ */ jsx(Icon, { class: cn("w-4 h-4", color) }),
|
|
813
|
+
/* @__PURE__ */ jsxs("div", { class: "flex flex-col", children: [
|
|
814
|
+
/* @__PURE__ */ jsx("span", { class: "text-[10px] text-white/50 uppercase", children: label }),
|
|
815
|
+
/* @__PURE__ */ jsx("span", { class: "text-sm font-bold text-white", children: value })
|
|
816
|
+
] })
|
|
817
|
+
] });
|
|
818
|
+
});
|
|
819
|
+
var FilterToggle = memo(function FilterToggle2({
|
|
820
|
+
label,
|
|
821
|
+
active,
|
|
822
|
+
color,
|
|
823
|
+
onClick
|
|
824
|
+
}) {
|
|
825
|
+
return /* @__PURE__ */ jsx(
|
|
826
|
+
"button",
|
|
827
|
+
{
|
|
828
|
+
onClick,
|
|
829
|
+
class: cn(
|
|
830
|
+
"px-2 py-1 rounded text-xs font-medium transition-all",
|
|
831
|
+
active ? `${color} text-white` : "bg-white/10 text-white/50 hover:bg-white/20"
|
|
832
|
+
),
|
|
833
|
+
children: label
|
|
834
|
+
}
|
|
835
|
+
);
|
|
836
|
+
});
|
|
837
|
+
var PerformancePanel = memo(function PerformancePanel2() {
|
|
838
|
+
const {
|
|
839
|
+
isPerformancePanelOpen,
|
|
840
|
+
metrics,
|
|
841
|
+
filters,
|
|
842
|
+
stats,
|
|
843
|
+
togglePerformancePanel,
|
|
844
|
+
clearMetrics,
|
|
845
|
+
toggleFilter
|
|
846
|
+
} = createPerformanceContext();
|
|
847
|
+
let listRef;
|
|
848
|
+
const filteredMetrics = createMemo(() => {
|
|
849
|
+
return metrics.filter((m) => {
|
|
850
|
+
if (m.type === "network" && !filters.network) return false;
|
|
851
|
+
if (m.type === "query" && !filters.query) return false;
|
|
852
|
+
if (m.type === "mutation" && !filters.mutation) return false;
|
|
853
|
+
if (m.type === "render" && !filters.render) return false;
|
|
854
|
+
if (m.type === "route" && !filters.route) return false;
|
|
855
|
+
return true;
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
const chartMetrics = createMemo(() => {
|
|
859
|
+
return filteredMetrics.filter((m) => m.duration !== void 0).slice(-20);
|
|
860
|
+
});
|
|
861
|
+
const maxDuration = createMemo(() => {
|
|
862
|
+
if (chartMetrics.length === 0) return 100;
|
|
863
|
+
const max = Math.max(...chartMetrics.map((m) => m.duration || 0));
|
|
864
|
+
return Math.max(max, 100);
|
|
865
|
+
});
|
|
866
|
+
createEffect(() => {
|
|
867
|
+
}, [filteredMetrics.length]);
|
|
868
|
+
if (!isPerformancePanelOpen) return null;
|
|
869
|
+
return /* @__PURE__ */ jsxs(
|
|
870
|
+
"div",
|
|
871
|
+
{
|
|
872
|
+
"data-dev-tool": "true",
|
|
873
|
+
class: cn(
|
|
874
|
+
"fixed bottom-20 left-1/2 -translate-x-1/2 z-50",
|
|
875
|
+
"w-[440px] max-h-[400px]",
|
|
876
|
+
"rounded-2xl border border-white/10",
|
|
877
|
+
"bg-gradient-to-b from-slate-900/95 via-slate-800/95 to-slate-900/95",
|
|
878
|
+
"backdrop-blur-xl shadow-2xl shadow-black/50",
|
|
879
|
+
"flex flex-col overflow-hidden",
|
|
880
|
+
"animate-in slide-in-from-bottom-4 fade-in duration-300"
|
|
881
|
+
),
|
|
882
|
+
children: [
|
|
883
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center justify-between px-4 py-3 border-b border-white/10", children: [
|
|
884
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
|
|
885
|
+
/* @__PURE__ */ jsx(Activity, { class: "w-4 h-4 text-primary" }),
|
|
886
|
+
/* @__PURE__ */ jsx("span", { class: "text-sm font-bold text-white", children: "Performance" }),
|
|
887
|
+
/* @__PURE__ */ jsxs("span", { class: "text-xs text-white/40", children: [
|
|
888
|
+
"(",
|
|
889
|
+
filteredMetrics.length,
|
|
890
|
+
" events)"
|
|
891
|
+
] })
|
|
892
|
+
] }),
|
|
893
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center gap-1", children: [
|
|
894
|
+
/* @__PURE__ */ jsx(
|
|
895
|
+
"button",
|
|
896
|
+
{
|
|
897
|
+
onClick: clearMetrics,
|
|
898
|
+
class: "p-1.5 text-white/40 hover:text-white hover:bg-white/10 rounded-lg transition-colors",
|
|
899
|
+
title: "Clear metrics",
|
|
900
|
+
children: /* @__PURE__ */ jsx(Trash2, { class: "w-3.5 h-3.5" })
|
|
901
|
+
}
|
|
902
|
+
),
|
|
903
|
+
/* @__PURE__ */ jsx(
|
|
904
|
+
"button",
|
|
905
|
+
{
|
|
906
|
+
onClick: togglePerformancePanel,
|
|
907
|
+
class: "p-1.5 text-white/40 hover:text-white hover:bg-white/10 rounded-lg transition-colors",
|
|
908
|
+
title: "Close panel",
|
|
909
|
+
children: /* @__PURE__ */ jsx(X, { class: "w-4 h-4" })
|
|
910
|
+
}
|
|
911
|
+
)
|
|
912
|
+
] })
|
|
913
|
+
] }),
|
|
914
|
+
/* @__PURE__ */ jsxs("div", { class: "flex gap-2 px-4 py-3 border-b border-white/10 overflow-x-auto", children: [
|
|
915
|
+
/* @__PURE__ */ jsx(
|
|
916
|
+
StatCard,
|
|
917
|
+
{
|
|
918
|
+
icon: Activity,
|
|
919
|
+
label: "Requests",
|
|
920
|
+
value: stats.totalRequests,
|
|
921
|
+
color: "text-blue-400"
|
|
922
|
+
}
|
|
923
|
+
),
|
|
924
|
+
/* @__PURE__ */ jsx(
|
|
925
|
+
StatCard,
|
|
926
|
+
{
|
|
927
|
+
icon: Clock,
|
|
928
|
+
label: "Avg",
|
|
929
|
+
value: `${stats.avgDuration}ms`,
|
|
930
|
+
color: stats.avgDuration > 100 ? "text-red-400" : stats.avgDuration > 50 ? "text-yellow-400" : "text-green-400"
|
|
931
|
+
}
|
|
932
|
+
),
|
|
933
|
+
/* @__PURE__ */ jsx(
|
|
934
|
+
StatCard,
|
|
935
|
+
{
|
|
936
|
+
icon: Zap,
|
|
937
|
+
label: "Fast",
|
|
938
|
+
value: stats.fastRequests,
|
|
939
|
+
color: "text-green-400"
|
|
940
|
+
}
|
|
941
|
+
),
|
|
942
|
+
/* @__PURE__ */ jsx(
|
|
943
|
+
StatCard,
|
|
944
|
+
{
|
|
945
|
+
icon: AlertTriangle,
|
|
946
|
+
label: "Slow",
|
|
947
|
+
value: stats.slowRequests,
|
|
948
|
+
color: stats.slowRequests > 0 ? "text-red-400" : "text-white/50"
|
|
949
|
+
}
|
|
950
|
+
)
|
|
951
|
+
] }),
|
|
952
|
+
chartMetrics.length > 0 && /* @__PURE__ */ jsxs("div", { class: "px-4 py-3 border-b border-white/10", children: [
|
|
953
|
+
/* @__PURE__ */ jsx("div", { class: "flex items-end gap-1 h-16", children: chartMetrics.map((metric) => /* @__PURE__ */ jsx(
|
|
954
|
+
MiniBar,
|
|
955
|
+
{
|
|
956
|
+
height: (metric.duration || 0) / maxDuration * 100,
|
|
957
|
+
color: getDurationBgColor(metric.duration),
|
|
958
|
+
label: `${metric.name}: ${metric.duration?.toFixed(1)}ms`
|
|
959
|
+
},
|
|
960
|
+
metric.id
|
|
961
|
+
)) }),
|
|
962
|
+
/* @__PURE__ */ jsxs("div", { class: "flex justify-between mt-1 text-xs text-white/40", children: [
|
|
963
|
+
/* @__PURE__ */ jsx("span", { children: "Recent requests" }),
|
|
964
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
965
|
+
"0-",
|
|
966
|
+
maxDuration.toFixed(0),
|
|
967
|
+
"ms"
|
|
968
|
+
] })
|
|
969
|
+
] })
|
|
970
|
+
] }),
|
|
971
|
+
/* @__PURE__ */ jsxs("div", { class: "flex gap-1 px-4 py-2 border-b border-white/10", children: [
|
|
972
|
+
/* @__PURE__ */ jsx(FilterToggle, { label: "Network", active: filters.network, color: "bg-blue-500", onClick: () => toggleFilter("network") }),
|
|
973
|
+
/* @__PURE__ */ jsx(FilterToggle, { label: "Query", active: filters.query, color: "bg-orange-500", onClick: () => toggleFilter("query") }),
|
|
974
|
+
/* @__PURE__ */ jsx(FilterToggle, { label: "Mutation", active: filters.mutation, color: "bg-red-500", onClick: () => toggleFilter("mutation") }),
|
|
975
|
+
/* @__PURE__ */ jsx(FilterToggle, { label: "Render", active: filters.render, color: "bg-purple-500", onClick: () => toggleFilter("render") }),
|
|
976
|
+
/* @__PURE__ */ jsx(FilterToggle, { label: "Route", active: filters.route, color: "bg-green-500", onClick: () => toggleFilter("route") })
|
|
977
|
+
] }),
|
|
978
|
+
/* @__PURE__ */ jsx(
|
|
979
|
+
"div",
|
|
980
|
+
{
|
|
981
|
+
ref: listRef,
|
|
982
|
+
class: "flex-1 overflow-y-auto px-3 py-2 space-y-1 min-h-[100px] max-h-[180px]",
|
|
983
|
+
children: filteredMetrics.length === 0 ? /* @__PURE__ */ jsx("div", { class: "flex items-center justify-center py-8 text-sm text-white/30", children: "No metrics recorded yet" }) : filteredMetrics.map((metric) => /* @__PURE__ */ jsx(MetricRow, { metric }, metric.id))
|
|
984
|
+
}
|
|
985
|
+
)
|
|
986
|
+
]
|
|
987
|
+
}
|
|
988
|
+
);
|
|
989
|
+
});
|
|
990
|
+
var ToolbarButton = memo(function ToolbarButton2({
|
|
991
|
+
icon,
|
|
992
|
+
label,
|
|
993
|
+
onClick,
|
|
994
|
+
active = false,
|
|
995
|
+
variant = "default",
|
|
996
|
+
showLabel = true,
|
|
997
|
+
disabled = false
|
|
998
|
+
}) {
|
|
999
|
+
const variantStyles = {
|
|
1000
|
+
default: active ? "bg-white/20 text-white" : "text-white/70 hover:text-white hover:bg-white/10",
|
|
1001
|
+
primary: active ? "bg-primary/30 text-primary-foreground" : "text-white/70 hover:text-primary hover:bg-primary/10",
|
|
1002
|
+
success: "text-white/70 hover:text-emerald-400 hover:bg-emerald-500/10",
|
|
1003
|
+
danger: "text-white/70 hover:text-red-400 hover:bg-red-500/10"
|
|
1004
|
+
};
|
|
1005
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1006
|
+
icon,
|
|
1007
|
+
showLabel && /* @__PURE__ */ jsx("span", { class: "hidden sm:inline text-xs font-medium", children: label })
|
|
1008
|
+
] });
|
|
1009
|
+
const className = cn(
|
|
1010
|
+
"flex items-center gap-2 px-3 py-2 rounded-lg transition-all duration-200",
|
|
1011
|
+
"focus:outline-none focus:ring-2 focus:ring-white/20",
|
|
1012
|
+
disabled ? "opacity-40 cursor-not-allowed text-white" : variantStyles[variant]
|
|
1013
|
+
);
|
|
1014
|
+
return /* @__PURE__ */ jsx(
|
|
1015
|
+
"button",
|
|
1016
|
+
{
|
|
1017
|
+
type: "button",
|
|
1018
|
+
onClick: disabled ? void 0 : onClick,
|
|
1019
|
+
class: cn(className, !disabled && "cursor-pointer"),
|
|
1020
|
+
title: label,
|
|
1021
|
+
disabled,
|
|
1022
|
+
children: content
|
|
1023
|
+
}
|
|
1024
|
+
);
|
|
1025
|
+
});
|
|
1026
|
+
var ExpandableSection = memo(function ExpandableSection2({
|
|
1027
|
+
show,
|
|
1028
|
+
children
|
|
1029
|
+
}) {
|
|
1030
|
+
let contentRef;
|
|
1031
|
+
const [width, setWidth] = createSignal(0);
|
|
1032
|
+
createEffect(() => {
|
|
1033
|
+
});
|
|
1034
|
+
return /* @__PURE__ */ jsx(
|
|
1035
|
+
"div",
|
|
1036
|
+
{
|
|
1037
|
+
class: "overflow-hidden transition-all duration-300 ease-out",
|
|
1038
|
+
style: { width: show ? width : 0, opacity: show ? 1 : 0 },
|
|
1039
|
+
children: /* @__PURE__ */ jsx(
|
|
1040
|
+
"div",
|
|
1041
|
+
{
|
|
1042
|
+
ref: contentRef,
|
|
1043
|
+
class: cn(
|
|
1044
|
+
"flex items-center gap-1 whitespace-nowrap",
|
|
1045
|
+
"transition-transform duration-300 ease-out",
|
|
1046
|
+
show ? "translate-x-0" : "-translate-x-2"
|
|
1047
|
+
),
|
|
1048
|
+
children
|
|
1049
|
+
}
|
|
1050
|
+
)
|
|
1051
|
+
}
|
|
1052
|
+
);
|
|
1053
|
+
});
|
|
1054
|
+
var DevToolbar = memo(function DevToolbar2({
|
|
1055
|
+
isAllowed
|
|
1056
|
+
} = {}) {
|
|
1057
|
+
const isDevAllowed = createIsDevAllowed(isAllowed);
|
|
1058
|
+
const devMode = createDevModeOptional();
|
|
1059
|
+
const performanceContext = createPerformanceContextOptional();
|
|
1060
|
+
const [isReady, setIsReady] = createSignal(false);
|
|
1061
|
+
createEffect(() => {
|
|
1062
|
+
const timer = setTimeout(() => setIsReady(true), 1e3);
|
|
1063
|
+
return () => clearTimeout(timer);
|
|
1064
|
+
});
|
|
1065
|
+
if (!isDevAllowed || !devMode) return null;
|
|
1066
|
+
const {
|
|
1067
|
+
isDevMode,
|
|
1068
|
+
isSidebarOpen,
|
|
1069
|
+
toggleDevMode,
|
|
1070
|
+
toggleSidebar,
|
|
1071
|
+
openIssueDialog,
|
|
1072
|
+
issueDialog,
|
|
1073
|
+
closeIssueDialog
|
|
1074
|
+
} = devMode;
|
|
1075
|
+
const showContent = isDevMode && isReady;
|
|
1076
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1077
|
+
/* @__PURE__ */ jsxs(
|
|
1078
|
+
"div",
|
|
1079
|
+
{
|
|
1080
|
+
"data-dev-tool": "true",
|
|
1081
|
+
class: cn(
|
|
1082
|
+
"fixed bottom-4 left-1/2 -translate-x-1/2 z-50",
|
|
1083
|
+
"flex items-center px-2 py-1",
|
|
1084
|
+
showContent ? "gap-2" : "gap-0",
|
|
1085
|
+
"rounded-2xl border border-white/10",
|
|
1086
|
+
"bg-gradient-to-r from-slate-900/95 via-slate-800/95 to-slate-900/95",
|
|
1087
|
+
"backdrop-blur-xl shadow-2xl shadow-black/50",
|
|
1088
|
+
"transition-all duration-300 ease-out"
|
|
1089
|
+
),
|
|
1090
|
+
children: [
|
|
1091
|
+
/* @__PURE__ */ jsx(
|
|
1092
|
+
ToolbarButton,
|
|
1093
|
+
{
|
|
1094
|
+
icon: /* @__PURE__ */ jsx(Power, { class: "w-4 h-4" }),
|
|
1095
|
+
label: isDevMode ? "Dev Mode On" : "Dev Mode Off",
|
|
1096
|
+
onClick: toggleDevMode,
|
|
1097
|
+
active: isDevMode,
|
|
1098
|
+
variant: isDevMode ? "primary" : "default"
|
|
1099
|
+
}
|
|
1100
|
+
),
|
|
1101
|
+
/* @__PURE__ */ jsxs(ExpandableSection, { show: showContent, children: [
|
|
1102
|
+
/* @__PURE__ */ jsx("div", { class: "shrink-0 w-px h-6 bg-white/20 mx-1 my-2" }),
|
|
1103
|
+
/* @__PURE__ */ jsx(
|
|
1104
|
+
ToolbarButton,
|
|
1105
|
+
{
|
|
1106
|
+
icon: /* @__PURE__ */ jsx(Target, { class: "w-4 h-4" }),
|
|
1107
|
+
label: "Inspector",
|
|
1108
|
+
onClick: devMode.toggleInspector,
|
|
1109
|
+
active: devMode.isInspectorMode,
|
|
1110
|
+
variant: devMode.isInspectorMode ? "primary" : "default"
|
|
1111
|
+
}
|
|
1112
|
+
),
|
|
1113
|
+
performanceContext && /* @__PURE__ */ jsx(
|
|
1114
|
+
ToolbarButton,
|
|
1115
|
+
{
|
|
1116
|
+
icon: /* @__PURE__ */ jsx(Activity, { class: "w-4 h-4" }),
|
|
1117
|
+
label: "Perf",
|
|
1118
|
+
onClick: performanceContext.togglePerformancePanel,
|
|
1119
|
+
active: performanceContext.isPerformancePanelOpen,
|
|
1120
|
+
variant: performanceContext.isPerformancePanelOpen ? "primary" : "default"
|
|
1121
|
+
}
|
|
1122
|
+
),
|
|
1123
|
+
/* @__PURE__ */ jsx("div", { class: "hidden md:block", children: /* @__PURE__ */ jsx(
|
|
1124
|
+
ToolbarButton,
|
|
1125
|
+
{
|
|
1126
|
+
icon: /* @__PURE__ */ jsx(PanelRight, { class: "w-4 h-4" }),
|
|
1127
|
+
label: "Issues",
|
|
1128
|
+
onClick: toggleSidebar,
|
|
1129
|
+
active: isSidebarOpen
|
|
1130
|
+
}
|
|
1131
|
+
) }),
|
|
1132
|
+
/* @__PURE__ */ jsx(
|
|
1133
|
+
ToolbarButton,
|
|
1134
|
+
{
|
|
1135
|
+
icon: /* @__PURE__ */ jsx(Bug, { class: "w-4 h-4" }),
|
|
1136
|
+
label: "Bug",
|
|
1137
|
+
onClick: () => openIssueDialog("bug"),
|
|
1138
|
+
variant: "danger"
|
|
1139
|
+
}
|
|
1140
|
+
),
|
|
1141
|
+
/* @__PURE__ */ jsx(
|
|
1142
|
+
ToolbarButton,
|
|
1143
|
+
{
|
|
1144
|
+
icon: /* @__PURE__ */ jsx(Lightbulb, { class: "w-4 h-4" }),
|
|
1145
|
+
label: "Feature",
|
|
1146
|
+
onClick: () => openIssueDialog("feature"),
|
|
1147
|
+
variant: "success"
|
|
1148
|
+
}
|
|
1149
|
+
)
|
|
1150
|
+
] })
|
|
1151
|
+
]
|
|
1152
|
+
}
|
|
1153
|
+
),
|
|
1154
|
+
performanceContext && /* @__PURE__ */ jsx(PerformancePanel, {}),
|
|
1155
|
+
/* @__PURE__ */ jsx("div", { "data-dev-tool": "true", children: /* @__PURE__ */ jsx(
|
|
1156
|
+
GitHubIssueDialog,
|
|
1157
|
+
{
|
|
1158
|
+
open: issueDialog.isOpen,
|
|
1159
|
+
onOpenChange: (open) => !open && closeIssueDialog(),
|
|
1160
|
+
initialType: issueDialog.type,
|
|
1161
|
+
initialDescription: issueDialog.initialDescription,
|
|
1162
|
+
componentDetails: issueDialog.componentDetails
|
|
1163
|
+
}
|
|
1164
|
+
) })
|
|
1165
|
+
] });
|
|
1166
|
+
});
|
|
1167
|
+
var IssueCard = memo(function IssueCard2({
|
|
1168
|
+
issue,
|
|
1169
|
+
expandedView
|
|
1170
|
+
}) {
|
|
1171
|
+
const issueType = getIssueType(issue);
|
|
1172
|
+
const linkedComponent = createMemo(() => {
|
|
1173
|
+
if (!issue.body) return null;
|
|
1174
|
+
const match = issue.body.match(/\*\*Name:\*\*\s*`([^`]+)`/);
|
|
1175
|
+
return match ? match[1] : null;
|
|
1176
|
+
}, [issue.body]);
|
|
1177
|
+
return /* @__PURE__ */ jsx(
|
|
1178
|
+
"a",
|
|
1179
|
+
{
|
|
1180
|
+
href: issue.html_url,
|
|
1181
|
+
target: "_blank",
|
|
1182
|
+
rel: "noopener noreferrer",
|
|
1183
|
+
class: cn(
|
|
1184
|
+
"block p-3 rounded-lg border transition-all duration-200",
|
|
1185
|
+
"hover:bg-white/5 hover:border-white/20",
|
|
1186
|
+
"border-white/10 bg-white/[0.02]"
|
|
1187
|
+
),
|
|
1188
|
+
children: /* @__PURE__ */ jsxs("div", { class: "flex items-start gap-3", children: [
|
|
1189
|
+
/* @__PURE__ */ jsx(
|
|
1190
|
+
"div",
|
|
1191
|
+
{
|
|
1192
|
+
class: cn(
|
|
1193
|
+
"flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center",
|
|
1194
|
+
issueType === "bug" && "bg-red-500/10 text-red-500",
|
|
1195
|
+
issueType === "feature" && "bg-emerald-500/10 text-emerald-500",
|
|
1196
|
+
issueType === "other" && "bg-blue-500/10 text-blue-500"
|
|
1197
|
+
),
|
|
1198
|
+
children: issueType === "bug" ? /* @__PURE__ */ jsx(Bug, { class: "w-4 h-4" }) : /* @__PURE__ */ jsx(Lightbulb, { class: "w-4 h-4" })
|
|
1199
|
+
}
|
|
1200
|
+
),
|
|
1201
|
+
/* @__PURE__ */ jsxs("div", { class: "flex-1 min-w-0", children: [
|
|
1202
|
+
/* @__PURE__ */ jsx("p", { class: "font-medium text-sm text-white line-clamp-2", children: issue.title }),
|
|
1203
|
+
linkedComponent && /* @__PURE__ */ jsx("span", { class: "inline-flex items-center gap-1 mt-1 text-[10px] px-1.5 py-0.5 bg-white/5 border border-white/10 rounded text-white/60", children: linkedComponent }),
|
|
1204
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center gap-3 mt-2 text-xs text-white/40", children: [
|
|
1205
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1206
|
+
"#",
|
|
1207
|
+
issue.number
|
|
1208
|
+
] }),
|
|
1209
|
+
/* @__PURE__ */ jsxs("span", { class: "flex items-center gap-1", children: [
|
|
1210
|
+
/* @__PURE__ */ jsx(Clock, { class: "w-3 h-3" }),
|
|
1211
|
+
formatRelativeTime(issue.updated_at)
|
|
1212
|
+
] })
|
|
1213
|
+
] }),
|
|
1214
|
+
expandedView && issue.body && /* @__PURE__ */ jsxs("div", { class: "mt-3 text-xs text-white/40 border-l-2 border-white/10 pl-2 line-clamp-6 whitespace-pre-line font-mono bg-white/[0.02] p-2 rounded-sm", children: [
|
|
1215
|
+
issue.body.substring(0, 300),
|
|
1216
|
+
issue.body.length > 300 ? "..." : ""
|
|
1217
|
+
] })
|
|
1218
|
+
] }),
|
|
1219
|
+
/* @__PURE__ */ jsx(ExternalLink, { class: "w-4 h-4 text-white/30 flex-shrink-0" })
|
|
1220
|
+
] })
|
|
1221
|
+
}
|
|
1222
|
+
);
|
|
1223
|
+
});
|
|
1224
|
+
var DevSidebar = memo(function DevSidebar2() {
|
|
1225
|
+
const devMode = createDevModeOptional();
|
|
1226
|
+
const [issues, setIssues] = createSignal([]);
|
|
1227
|
+
const [loading, setLoading] = createSignal(false);
|
|
1228
|
+
const [tab, setTab] = createSignal("bugs");
|
|
1229
|
+
const [isExpanded, setIsExpanded] = createSignal(false);
|
|
1230
|
+
const isSidebarOpen = devMode?.isSidebarOpen ?? false;
|
|
1231
|
+
const setSidebarOpen = devMode?.setSidebarOpen ?? (() => {
|
|
1232
|
+
});
|
|
1233
|
+
createEffect(() => {
|
|
1234
|
+
if (isSidebarOpen && issues.length === 0 && !loading) {
|
|
1235
|
+
fetchIssues();
|
|
1236
|
+
}
|
|
1237
|
+
});
|
|
1238
|
+
const fetchIssues = async () => {
|
|
1239
|
+
setLoading(true);
|
|
1240
|
+
try {
|
|
1241
|
+
const result = await getGitHubIssues("all", "open");
|
|
1242
|
+
setIssues(result);
|
|
1243
|
+
} catch {
|
|
1244
|
+
} finally {
|
|
1245
|
+
setLoading(false);
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
const handleRefresh = () => fetchIssues();
|
|
1249
|
+
const toggleExpand = () => setIsExpanded((prev) => !prev);
|
|
1250
|
+
const { bugs, features } = createMemo(() => {
|
|
1251
|
+
const bugs2 = [];
|
|
1252
|
+
const features2 = [];
|
|
1253
|
+
issues.forEach((issue) => {
|
|
1254
|
+
const type = getIssueType(issue);
|
|
1255
|
+
if (type === "bug") bugs2.push(issue);
|
|
1256
|
+
else features2.push(issue);
|
|
1257
|
+
});
|
|
1258
|
+
return { bugs: bugs2, features: features2 };
|
|
1259
|
+
});
|
|
1260
|
+
const currentIssues = tab === "bugs" ? bugs : features;
|
|
1261
|
+
if (!devMode || !isSidebarOpen) return null;
|
|
1262
|
+
const config = getGitHubConfig();
|
|
1263
|
+
return /* @__PURE__ */ jsxs(
|
|
1264
|
+
"div",
|
|
1265
|
+
{
|
|
1266
|
+
"data-dev-tool": "true",
|
|
1267
|
+
class: cn(
|
|
1268
|
+
"fixed top-0 right-0 h-full z-50",
|
|
1269
|
+
"flex flex-col",
|
|
1270
|
+
"bg-gradient-to-b from-slate-900/98 to-slate-950/98",
|
|
1271
|
+
"backdrop-blur-xl border-l border-white/10",
|
|
1272
|
+
"shadow-2xl shadow-black/50",
|
|
1273
|
+
"transition-all duration-300 ease-in-out",
|
|
1274
|
+
isExpanded ? "w-full sm:max-w-[50vw]" : "w-full sm:max-w-md",
|
|
1275
|
+
"animate-in slide-in-from-right duration-300"
|
|
1276
|
+
),
|
|
1277
|
+
children: [
|
|
1278
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center justify-between px-4 py-3 border-b border-white/10", children: [
|
|
1279
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
|
|
1280
|
+
/* @__PURE__ */ jsx(Bug, { class: "w-4 h-4 text-primary" }),
|
|
1281
|
+
/* @__PURE__ */ jsx("span", { class: "text-sm font-bold text-white", children: "GitHub Issues" }),
|
|
1282
|
+
/* @__PURE__ */ jsxs("span", { class: "text-xs text-white/40", children: [
|
|
1283
|
+
"(",
|
|
1284
|
+
config.owner,
|
|
1285
|
+
"/",
|
|
1286
|
+
config.repo,
|
|
1287
|
+
")"
|
|
1288
|
+
] })
|
|
1289
|
+
] }),
|
|
1290
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center gap-1", children: [
|
|
1291
|
+
/* @__PURE__ */ jsx(
|
|
1292
|
+
"button",
|
|
1293
|
+
{
|
|
1294
|
+
onClick: handleRefresh,
|
|
1295
|
+
disabled: loading,
|
|
1296
|
+
class: cn(
|
|
1297
|
+
"p-1.5 text-white/40 hover:text-white hover:bg-white/10 rounded-lg transition-colors",
|
|
1298
|
+
loading && "animate-spin"
|
|
1299
|
+
),
|
|
1300
|
+
children: /* @__PURE__ */ jsx(RefreshCw, { class: "w-3.5 h-3.5" })
|
|
1301
|
+
}
|
|
1302
|
+
),
|
|
1303
|
+
/* @__PURE__ */ jsx(
|
|
1304
|
+
"button",
|
|
1305
|
+
{
|
|
1306
|
+
onClick: toggleExpand,
|
|
1307
|
+
class: "hidden sm:block p-1.5 text-white/40 hover:text-white hover:bg-white/10 rounded-lg transition-colors",
|
|
1308
|
+
children: isExpanded ? /* @__PURE__ */ jsx(Minimize2, { class: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx(Maximize2, { class: "w-3.5 h-3.5" })
|
|
1309
|
+
}
|
|
1310
|
+
),
|
|
1311
|
+
/* @__PURE__ */ jsx(
|
|
1312
|
+
"button",
|
|
1313
|
+
{
|
|
1314
|
+
onClick: () => setSidebarOpen(false),
|
|
1315
|
+
class: "p-1.5 text-white/40 hover:text-white hover:bg-white/10 rounded-lg transition-colors",
|
|
1316
|
+
children: /* @__PURE__ */ jsx(X, { class: "w-4 h-4" })
|
|
1317
|
+
}
|
|
1318
|
+
)
|
|
1319
|
+
] })
|
|
1320
|
+
] }),
|
|
1321
|
+
/* @__PURE__ */ jsxs("div", { class: "flex border-b border-white/10", children: [
|
|
1322
|
+
/* @__PURE__ */ jsxs(
|
|
1323
|
+
"button",
|
|
1324
|
+
{
|
|
1325
|
+
onClick: () => setTab("bugs"),
|
|
1326
|
+
class: cn(
|
|
1327
|
+
"flex-1 px-4 py-2.5 text-xs font-medium transition-colors",
|
|
1328
|
+
tab === "bugs" ? "text-red-400 border-b-2 border-red-500" : "text-white/40 hover:text-white/70"
|
|
1329
|
+
),
|
|
1330
|
+
children: [
|
|
1331
|
+
"\u{1F41B} Bugs (",
|
|
1332
|
+
bugs.length,
|
|
1333
|
+
")"
|
|
1334
|
+
]
|
|
1335
|
+
}
|
|
1336
|
+
),
|
|
1337
|
+
/* @__PURE__ */ jsxs(
|
|
1338
|
+
"button",
|
|
1339
|
+
{
|
|
1340
|
+
onClick: () => setTab("features"),
|
|
1341
|
+
class: cn(
|
|
1342
|
+
"flex-1 px-4 py-2.5 text-xs font-medium transition-colors",
|
|
1343
|
+
tab === "features" ? "text-emerald-400 border-b-2 border-emerald-500" : "text-white/40 hover:text-white/70"
|
|
1344
|
+
),
|
|
1345
|
+
children: [
|
|
1346
|
+
"\u2728 Features (",
|
|
1347
|
+
features.length,
|
|
1348
|
+
")"
|
|
1349
|
+
]
|
|
1350
|
+
}
|
|
1351
|
+
)
|
|
1352
|
+
] }),
|
|
1353
|
+
/* @__PURE__ */ jsx("div", { class: "flex-1 overflow-y-auto p-3 space-y-2", children: loading ? /* @__PURE__ */ jsx("div", { class: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx("div", { class: "w-6 h-6 border-2 border-white/20 border-t-primary rounded-full animate-spin" }) }) : currentIssues.length === 0 ? /* @__PURE__ */ jsxs("div", { class: "text-center py-12 text-sm text-white/30", children: [
|
|
1354
|
+
"No ",
|
|
1355
|
+
tab === "bugs" ? "bugs" : "features",
|
|
1356
|
+
" found"
|
|
1357
|
+
] }) : currentIssues.map((issue) => /* @__PURE__ */ jsx(IssueCard, { issue, expandedView: isExpanded }, issue.id)) })
|
|
1358
|
+
]
|
|
1359
|
+
}
|
|
1360
|
+
);
|
|
1361
|
+
});
|
|
1362
|
+
function getComponentInfo(element) {
|
|
1363
|
+
let fiberNode = null;
|
|
1364
|
+
const key = Object.keys(element).find((k) => k.startsWith("__reactFiber$"));
|
|
1365
|
+
if (key) {
|
|
1366
|
+
fiberNode = element[key];
|
|
1367
|
+
}
|
|
1368
|
+
if (!fiberNode) return null;
|
|
1369
|
+
const elementKey = fiberNode.key !== null ? String(fiberNode.key) : void 0;
|
|
1370
|
+
let node = fiberNode;
|
|
1371
|
+
while (node) {
|
|
1372
|
+
if (node.tag === 0 || node.tag === 1) {
|
|
1373
|
+
if (node.type && (node.type.displayName || node.type.name)) {
|
|
1374
|
+
return {
|
|
1375
|
+
name: node.type.displayName || node.type.name,
|
|
1376
|
+
file: node._debugSource?.fileName,
|
|
1377
|
+
key: elementKey !== void 0 ? elementKey : node.key !== null ? String(node.key) : void 0
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
node = node.return;
|
|
1382
|
+
}
|
|
1383
|
+
return { name: element.tagName.toLowerCase() };
|
|
1384
|
+
}
|
|
1385
|
+
function InspectorOverlay() {
|
|
1386
|
+
const devMode = createDevModeOptional();
|
|
1387
|
+
const [hoveredRect, setHoveredRect] = createSignal(null);
|
|
1388
|
+
const [selectedComponents, setSelectedComponents] = createSignal([]);
|
|
1389
|
+
const [hoveredComponent, setHoveredComponent] = createSignal(null);
|
|
1390
|
+
const [cursorPos, setCursorPos] = createSignal({ x: 0, y: 0 });
|
|
1391
|
+
let overlayRef;
|
|
1392
|
+
const isInspectorMode = devMode?.isInspectorMode ?? false;
|
|
1393
|
+
const setInspectorMode = devMode?.setInspectorMode ?? (() => {
|
|
1394
|
+
});
|
|
1395
|
+
const openIssueDialog = devMode?.openIssueDialog ?? (() => {
|
|
1396
|
+
});
|
|
1397
|
+
createEffect(() => {
|
|
1398
|
+
if (!isInspectorMode) {
|
|
1399
|
+
setHoveredRect(null);
|
|
1400
|
+
setSelectedComponents([]);
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
const isDevTool = (element) => {
|
|
1404
|
+
if (!element) return false;
|
|
1405
|
+
return !!element.closest('[data-dev-tool="true"]');
|
|
1406
|
+
};
|
|
1407
|
+
const handleMouseMove = (e) => {
|
|
1408
|
+
setCursorPos({ x: e.clientX, y: e.clientY });
|
|
1409
|
+
const elements = document.elementsFromPoint(e.clientX, e.clientY);
|
|
1410
|
+
if (elements.length > 0 && isDevTool(elements[0])) {
|
|
1411
|
+
setHoveredRect(null);
|
|
1412
|
+
setHoveredComponent(null);
|
|
1413
|
+
return;
|
|
1414
|
+
}
|
|
1415
|
+
let target = null;
|
|
1416
|
+
for (const el of elements) {
|
|
1417
|
+
if (!isDevTool(el)) {
|
|
1418
|
+
target = el;
|
|
1419
|
+
break;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
if (target && target !== document.body && target !== document.documentElement) {
|
|
1423
|
+
const rect = target.getBoundingClientRect();
|
|
1424
|
+
setHoveredRect({
|
|
1425
|
+
top: rect.top,
|
|
1426
|
+
left: rect.left,
|
|
1427
|
+
width: rect.width,
|
|
1428
|
+
height: rect.height
|
|
1429
|
+
});
|
|
1430
|
+
setHoveredComponent(getComponentInfo(target));
|
|
1431
|
+
} else {
|
|
1432
|
+
setHoveredRect(null);
|
|
1433
|
+
setHoveredComponent(null);
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
const handleClick = (e) => {
|
|
1437
|
+
const elements = document.elementsFromPoint(e.clientX, e.clientY);
|
|
1438
|
+
if (elements.length > 0 && isDevTool(elements[0])) return;
|
|
1439
|
+
let target = null;
|
|
1440
|
+
for (const el of elements) {
|
|
1441
|
+
if (!isDevTool(el)) {
|
|
1442
|
+
target = el;
|
|
1443
|
+
break;
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
if (target) {
|
|
1447
|
+
e.preventDefault();
|
|
1448
|
+
e.stopPropagation();
|
|
1449
|
+
const info = getComponentInfo(target);
|
|
1450
|
+
const rect = target.getBoundingClientRect();
|
|
1451
|
+
if (info) {
|
|
1452
|
+
setSelectedComponents((prev) => {
|
|
1453
|
+
const existsIndex = prev.findIndex(
|
|
1454
|
+
(p) => p.info.name === info.name && p.info.key === info.key && p.info.file === info.file
|
|
1455
|
+
);
|
|
1456
|
+
if (existsIndex >= 0) {
|
|
1457
|
+
const newSelection = [...prev];
|
|
1458
|
+
newSelection.splice(existsIndex, 1);
|
|
1459
|
+
return newSelection;
|
|
1460
|
+
} else {
|
|
1461
|
+
return [
|
|
1462
|
+
...prev,
|
|
1463
|
+
{
|
|
1464
|
+
rect: {
|
|
1465
|
+
top: rect.top,
|
|
1466
|
+
left: rect.left,
|
|
1467
|
+
width: rect.width,
|
|
1468
|
+
height: rect.height
|
|
1469
|
+
},
|
|
1470
|
+
info
|
|
1471
|
+
}
|
|
1472
|
+
];
|
|
1473
|
+
}
|
|
1474
|
+
});
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
};
|
|
1478
|
+
window.addEventListener("mousemove", handleMouseMove, { capture: true });
|
|
1479
|
+
window.addEventListener("click", handleClick, { capture: true });
|
|
1480
|
+
return () => {
|
|
1481
|
+
window.removeEventListener("mousemove", handleMouseMove, { capture: true });
|
|
1482
|
+
window.removeEventListener("click", handleClick, { capture: true });
|
|
1483
|
+
};
|
|
1484
|
+
});
|
|
1485
|
+
if (!devMode || !isInspectorMode) return null;
|
|
1486
|
+
return (
|
|
1487
|
+
/* Portal: */
|
|
1488
|
+
/* @__PURE__ */ jsxs(
|
|
1489
|
+
"div",
|
|
1490
|
+
{
|
|
1491
|
+
ref: overlayRef,
|
|
1492
|
+
class: "fixed inset-0 z-[9999] pointer-events-none cursor-crosshair",
|
|
1493
|
+
style: { background: "transparent" },
|
|
1494
|
+
"data-dev-tool": "true",
|
|
1495
|
+
children: [
|
|
1496
|
+
/* @__PURE__ */ jsx("div", { class: "hidden md:block fixed top-0 left-0 z-[10000] p-2 text-xs font-mono text-white pointer-events-auto transition-all duration-300", children: /* @__PURE__ */ jsxs(
|
|
1497
|
+
"div",
|
|
1498
|
+
{
|
|
1499
|
+
class: cn(
|
|
1500
|
+
"group flex flex-col gap-1 min-w-[150px] p-2 rounded-lg backdrop-blur-sm transition-all duration-300",
|
|
1501
|
+
"bg-blue-500/10 hover:bg-blue-950/90",
|
|
1502
|
+
"border border-blue-500/30",
|
|
1503
|
+
"text-black hover:text-white"
|
|
1504
|
+
),
|
|
1505
|
+
children: [
|
|
1506
|
+
/* @__PURE__ */ jsxs("div", { class: "flex justify-between items-center opacity-80", children: [
|
|
1507
|
+
/* @__PURE__ */ jsx("span", { class: "font-bold opacity-100 group-hover:text-white/90", children: "INSPECTOR" }),
|
|
1508
|
+
/* @__PURE__ */ jsxs("span", { class: "opacity-70 group-hover:text-white/70", children: [
|
|
1509
|
+
Math.round(cursorPos.x),
|
|
1510
|
+
", ",
|
|
1511
|
+
Math.round(cursorPos.y)
|
|
1512
|
+
] })
|
|
1513
|
+
] }),
|
|
1514
|
+
hoveredComponent && /* @__PURE__ */ jsx("div", { class: "font-bold drop-shadow-sm truncate text-blue-700 group-hover:text-blue-300", children: hoveredComponent.name }),
|
|
1515
|
+
selectedComponents.length > 0 && /* @__PURE__ */ jsxs("div", { class: "truncate text-[10px] opacity-80 text-green-700 group-hover:text-green-300 border-t border-white/10 pt-1 mt-1", children: [
|
|
1516
|
+
selectedComponents.length,
|
|
1517
|
+
" Selected"
|
|
1518
|
+
] })
|
|
1519
|
+
]
|
|
1520
|
+
}
|
|
1521
|
+
) }),
|
|
1522
|
+
hoveredRect && /* @__PURE__ */ jsx(
|
|
1523
|
+
"div",
|
|
1524
|
+
{
|
|
1525
|
+
class: "absolute border-2 border-blue-500 bg-blue-500/10 pointer-events-none transition-all duration-75 ease-out",
|
|
1526
|
+
style: {
|
|
1527
|
+
top: hoveredRect.top,
|
|
1528
|
+
left: hoveredRect.left,
|
|
1529
|
+
width: hoveredRect.width,
|
|
1530
|
+
height: hoveredRect.height
|
|
1531
|
+
},
|
|
1532
|
+
children: /* @__PURE__ */ jsxs("div", { class: "absolute -top-6 left-0 bg-blue-500 text-white text-[10px] px-1.5 py-0.5 rounded-sm whitespace-nowrap", children: [
|
|
1533
|
+
hoveredComponent?.name,
|
|
1534
|
+
" (",
|
|
1535
|
+
Math.round(hoveredRect.width),
|
|
1536
|
+
" x",
|
|
1537
|
+
" ",
|
|
1538
|
+
Math.round(hoveredRect.height),
|
|
1539
|
+
")"
|
|
1540
|
+
] })
|
|
1541
|
+
}
|
|
1542
|
+
),
|
|
1543
|
+
selectedComponents.map((comp, i) => /* @__PURE__ */ jsx(
|
|
1544
|
+
"div",
|
|
1545
|
+
{
|
|
1546
|
+
class: "absolute border-2 border-green-500 bg-green-500/20 pointer-events-none transition-all duration-75 ease-out",
|
|
1547
|
+
style: {
|
|
1548
|
+
top: comp.rect.top,
|
|
1549
|
+
left: comp.rect.left,
|
|
1550
|
+
width: comp.rect.width,
|
|
1551
|
+
height: comp.rect.height
|
|
1552
|
+
},
|
|
1553
|
+
children: /* @__PURE__ */ jsx("div", { class: "absolute -top-6 left-0 bg-green-600 text-white text-[10px] px-1.5 py-0.5 rounded-sm whitespace-nowrap z-[10001]", children: comp.info.name })
|
|
1554
|
+
},
|
|
1555
|
+
i
|
|
1556
|
+
)),
|
|
1557
|
+
selectedComponents.length > 0 && (() => {
|
|
1558
|
+
const lastSelected = selectedComponents[selectedComponents.length - 1];
|
|
1559
|
+
return /* @__PURE__ */ jsxs(
|
|
1560
|
+
"div",
|
|
1561
|
+
{
|
|
1562
|
+
class: "fixed z-[10002] flex items-center gap-1 p-1 bg-slate-900 border border-slate-700 rounded-md shadow-xl animate-in fade-in zoom-in-95 pointer-events-auto",
|
|
1563
|
+
style: {
|
|
1564
|
+
top: Math.max(10, lastSelected.rect.top - 45),
|
|
1565
|
+
left: Math.max(10, lastSelected.rect.left)
|
|
1566
|
+
},
|
|
1567
|
+
children: [
|
|
1568
|
+
/* @__PURE__ */ jsx(
|
|
1569
|
+
"button",
|
|
1570
|
+
{
|
|
1571
|
+
onClick: () => {
|
|
1572
|
+
const allDetails = selectedComponents.map((c) => ({
|
|
1573
|
+
name: c.info.name,
|
|
1574
|
+
file: c.info.file,
|
|
1575
|
+
key: c.info.key,
|
|
1576
|
+
props: c.info.props,
|
|
1577
|
+
selector: "Multi-select"
|
|
1578
|
+
}));
|
|
1579
|
+
openIssueDialog("feature", "", allDetails);
|
|
1580
|
+
setInspectorMode(false);
|
|
1581
|
+
},
|
|
1582
|
+
class: "px-2 py-1 text-xs font-medium text-white hover:bg-white/10 rounded transition-colors",
|
|
1583
|
+
children: "Feature"
|
|
1584
|
+
}
|
|
1585
|
+
),
|
|
1586
|
+
/* @__PURE__ */ jsx("div", { class: "w-px h-3 bg-white/20 mx-0.5" }),
|
|
1587
|
+
/* @__PURE__ */ jsx(
|
|
1588
|
+
"button",
|
|
1589
|
+
{
|
|
1590
|
+
onClick: () => {
|
|
1591
|
+
const allDetails = selectedComponents.map((c) => ({
|
|
1592
|
+
name: c.info.name,
|
|
1593
|
+
file: c.info.file,
|
|
1594
|
+
key: c.info.key,
|
|
1595
|
+
props: c.info.props,
|
|
1596
|
+
selector: "Multi-select"
|
|
1597
|
+
}));
|
|
1598
|
+
openIssueDialog("bug", "", allDetails);
|
|
1599
|
+
setInspectorMode(false);
|
|
1600
|
+
},
|
|
1601
|
+
class: "px-2 py-1 text-xs font-medium text-red-400 hover:bg-red-500/10 rounded transition-colors",
|
|
1602
|
+
children: "Bug"
|
|
1603
|
+
}
|
|
1604
|
+
),
|
|
1605
|
+
/* @__PURE__ */ jsx("div", { class: "w-px h-3 bg-white/20 mx-0.5" }),
|
|
1606
|
+
/* @__PURE__ */ jsx(
|
|
1607
|
+
"button",
|
|
1608
|
+
{
|
|
1609
|
+
onClick: () => setSelectedComponents([]),
|
|
1610
|
+
class: "px-2 py-1 text-xs text-slate-400 hover:text-white hover:bg-white/10 rounded transition-colors",
|
|
1611
|
+
children: "Deselect all"
|
|
1612
|
+
}
|
|
1613
|
+
)
|
|
1614
|
+
]
|
|
1615
|
+
}
|
|
1616
|
+
);
|
|
1617
|
+
})()
|
|
1618
|
+
]
|
|
1619
|
+
}
|
|
1620
|
+
), document.body
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1623
|
+
function DesignPreview(props) {
|
|
1624
|
+
let iframeRef;
|
|
1625
|
+
const applyTheme = () => {
|
|
1626
|
+
try {
|
|
1627
|
+
if (iframeRef?.contentDocument) ;
|
|
1628
|
+
} catch {
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
createEffect(applyTheme);
|
|
1632
|
+
return /* @__PURE__ */ jsxs("div", { class: "relative w-full h-screen", children: [
|
|
1633
|
+
(props.showGrid ?? false) && /* @__PURE__ */ jsx("div", { class: "absolute inset-0 pointer-events-none z-[100] flex justify-between px-4 max-w-[1400px] mx-auto w-full", children: Array.from({ length: 12 }).map((_, i) => /* @__PURE__ */ jsx("div", { class: "h-full w-[calc(100%/12)] border-x border-red-500/20 bg-red-500/5 mx-2" })) }),
|
|
1634
|
+
/* @__PURE__ */ jsx(
|
|
1635
|
+
"iframe",
|
|
1636
|
+
{
|
|
1637
|
+
ref: iframeRef,
|
|
1638
|
+
src: `/designs/design-${props.designNumber}.html`,
|
|
1639
|
+
class: "w-full h-full border-0",
|
|
1640
|
+
title: `Design ${props.designNumber} Preview`,
|
|
1641
|
+
onLoad: applyTheme
|
|
1642
|
+
}
|
|
1643
|
+
)
|
|
1644
|
+
] });
|
|
1645
|
+
}
|
|
1646
|
+
function DesignSwitcherDropdown(props) {
|
|
1647
|
+
const [isOpen, setIsOpen] = createSignal(false);
|
|
1648
|
+
let dropdownRef;
|
|
1649
|
+
const getCurrentDesign = () => {
|
|
1650
|
+
const match = props.currentPath.match(/\/dev\/design\/(\d+)/);
|
|
1651
|
+
return match ? `Design ${match[1]}` : "Current Design";
|
|
1652
|
+
};
|
|
1653
|
+
createEffect(() => {
|
|
1654
|
+
const handleClickOutside = (event) => {
|
|
1655
|
+
};
|
|
1656
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1657
|
+
onCleanup(() => document.removeEventListener("mousedown", handleClickOutside));
|
|
1658
|
+
});
|
|
1659
|
+
const handleDesignChange = (path) => {
|
|
1660
|
+
props.onNavigate(path);
|
|
1661
|
+
setIsOpen(false);
|
|
1662
|
+
};
|
|
1663
|
+
const designs2 = () => [
|
|
1664
|
+
{ label: "Current Design", path: "/" },
|
|
1665
|
+
...Array.from({ length: props.designCount ?? 21 }, (_, i) => ({
|
|
1666
|
+
label: `Design ${i + 1}`,
|
|
1667
|
+
path: `/dev/design/${i + 1}`
|
|
1668
|
+
}))
|
|
1669
|
+
];
|
|
1670
|
+
return /* @__PURE__ */ jsxs("div", { ref: dropdownRef, class: "relative", children: [
|
|
1671
|
+
/* @__PURE__ */ jsxs(
|
|
1672
|
+
"button",
|
|
1673
|
+
{
|
|
1674
|
+
type: "button",
|
|
1675
|
+
onClick: () => setIsOpen(!isOpen()),
|
|
1676
|
+
"aria-label": "Switch Design",
|
|
1677
|
+
class: "flex items-center gap-2 px-3 py-2 rounded-lg text-foreground hover:bg-bg-muted transition-colors text-sm font-medium",
|
|
1678
|
+
children: [
|
|
1679
|
+
/* @__PURE__ */ jsxs("svg", { class: "w-4 h-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": 2, children: [
|
|
1680
|
+
/* @__PURE__ */ jsx("circle", { cx: "13.5", cy: "6.5", r: "0.5" }),
|
|
1681
|
+
/* @__PURE__ */ jsx("circle", { cx: "17.5", cy: "10.5", r: "0.5" }),
|
|
1682
|
+
/* @__PURE__ */ jsx("circle", { cx: "8.5", cy: "7.5", r: "0.5" }),
|
|
1683
|
+
/* @__PURE__ */ jsx("circle", { cx: "6.5", cy: "12", r: "0.5" }),
|
|
1684
|
+
/* @__PURE__ */ jsx("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z" })
|
|
1685
|
+
] }),
|
|
1686
|
+
/* @__PURE__ */ jsx("span", { class: "hidden sm:inline", children: getCurrentDesign() }),
|
|
1687
|
+
/* @__PURE__ */ jsx(
|
|
1688
|
+
"svg",
|
|
1689
|
+
{
|
|
1690
|
+
class: `w-4 h-4 transition-transform duration-200 ${isOpen() ? "rotate-180" : ""}`,
|
|
1691
|
+
fill: "none",
|
|
1692
|
+
stroke: "currentColor",
|
|
1693
|
+
viewBox: "0 0 24 24",
|
|
1694
|
+
children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": 2, d: "M19 9l-7 7-7-7" })
|
|
1695
|
+
}
|
|
1696
|
+
)
|
|
1697
|
+
]
|
|
1698
|
+
}
|
|
1699
|
+
),
|
|
1700
|
+
/* @__PURE__ */ jsx(Show, { when: isOpen(), children: /* @__PURE__ */ jsx("div", { class: "absolute right-0 mt-2 py-2 bg-card border border-border rounded-lg shadow-xl overflow-hidden min-w-[180px] max-h-[400px] overflow-y-auto z-50", children: /* @__PURE__ */ jsx(For, { each: designs2(), children: (design) => /* @__PURE__ */ jsxs(
|
|
1701
|
+
"button",
|
|
1702
|
+
{
|
|
1703
|
+
type: "button",
|
|
1704
|
+
onClick: () => handleDesignChange(design.path),
|
|
1705
|
+
class: `w-full px-4 py-2.5 text-left text-sm transition-colors ${getCurrentDesign() === design.label ? "bg-primary/10 text-primary font-medium" : "hover:bg-bg-muted text-foreground"}`,
|
|
1706
|
+
children: [
|
|
1707
|
+
design.label,
|
|
1708
|
+
/* @__PURE__ */ jsx(Show, { when: getCurrentDesign() === design.label, children: /* @__PURE__ */ jsx("span", { class: "ml-2 text-primary", children: "\u2713" }) })
|
|
1709
|
+
]
|
|
1710
|
+
}
|
|
1711
|
+
) }) }) })
|
|
1712
|
+
] });
|
|
1713
|
+
}
|
|
1714
|
+
function PageLoadWaterfall(props) {
|
|
1715
|
+
let hasLogged = false;
|
|
1716
|
+
onMount(() => {
|
|
1717
|
+
if (hasLogged) return;
|
|
1718
|
+
hasLogged = true;
|
|
1719
|
+
logWaterfall(props.ssrTiming);
|
|
1720
|
+
});
|
|
1721
|
+
return null;
|
|
1722
|
+
}
|
|
1723
|
+
function logWaterfall(ssrTiming) {
|
|
1724
|
+
const clientStart = performance.now();
|
|
1725
|
+
const run = () => {
|
|
1726
|
+
const navEntry = performance.getEntriesByType("navigation")[0];
|
|
1727
|
+
const fcp = performance.getEntriesByType("paint").find((e) => e.name === "first-contentful-paint");
|
|
1728
|
+
console.log("\n");
|
|
1729
|
+
console.log("%c\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557", "color: #4CAF50; font-weight: bold");
|
|
1730
|
+
console.log("%c\u2551 PAGE LOAD PERFORMANCE WATERFALL \u2551", "color: #4CAF50; font-weight: bold");
|
|
1731
|
+
console.log("%c\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D", "color: #4CAF50; font-weight: bold");
|
|
1732
|
+
if (navEntry) {
|
|
1733
|
+
const dns = navEntry.domainLookupEnd - navEntry.domainLookupStart;
|
|
1734
|
+
const tcp = navEntry.connectEnd - navEntry.connectStart;
|
|
1735
|
+
const ttfb = navEntry.responseStart - navEntry.requestStart;
|
|
1736
|
+
const download = navEntry.responseEnd - navEntry.responseStart;
|
|
1737
|
+
const domParsing = navEntry.domInteractive - navEntry.responseEnd;
|
|
1738
|
+
const domComplete = navEntry.domComplete - navEntry.domInteractive;
|
|
1739
|
+
const totalLoad = navEntry.loadEventEnd - navEntry.startTime;
|
|
1740
|
+
console.log("%c\n\u2500\u2500 Network & Browser Timing \u2500\u2500", "color: #FF9800; font-weight: bold");
|
|
1741
|
+
console.table({
|
|
1742
|
+
"DNS Lookup": { ms: Math.round(dns), bar: "\u2588".repeat(Math.max(1, Math.round(dns / 20))) },
|
|
1743
|
+
"TCP Connect": { ms: Math.round(tcp), bar: "\u2588".repeat(Math.max(1, Math.round(tcp / 20))) },
|
|
1744
|
+
"TTFB (Time to First Byte)": { ms: Math.round(ttfb), bar: "\u2588".repeat(Math.max(1, Math.round(ttfb / 20))) },
|
|
1745
|
+
"Response Download": { ms: Math.round(download), bar: "\u2588".repeat(Math.max(1, Math.round(download / 20))) },
|
|
1746
|
+
"DOM Parsing": { ms: Math.round(domParsing), bar: "\u2588".repeat(Math.max(1, Math.round(domParsing / 20))) },
|
|
1747
|
+
"DOM Complete": { ms: Math.round(domComplete), bar: "\u2588".repeat(Math.max(1, Math.round(domComplete / 20))) },
|
|
1748
|
+
"Total Page Load": { ms: Math.round(totalLoad), bar: "\u2588".repeat(Math.max(1, Math.round(totalLoad / 20))) }
|
|
1749
|
+
});
|
|
1750
|
+
console.log(
|
|
1751
|
+
`%c
|
|
1752
|
+
\u26A1 TTFB: ${Math.round(ttfb)}ms \u2014 This includes all SSR processing time`,
|
|
1753
|
+
ttfb > 500 ? "color: #F44336; font-weight: bold; font-size: 14px" : "color: #4CAF50; font-weight: bold; font-size: 14px"
|
|
1754
|
+
);
|
|
1755
|
+
}
|
|
1756
|
+
if (ssrTiming) {
|
|
1757
|
+
console.log("%c\n\u2500\u2500 SSR beforeLoad Breakdown \u2500\u2500", "color: #2196F3; font-weight: bold");
|
|
1758
|
+
const total = ssrTiming.ssrEnd - ssrTiming.ssrStart;
|
|
1759
|
+
const auth = ssrTiming.getAuthEnd ? ssrTiming.getAuthEnd - ssrTiming.getAuthStart : 0;
|
|
1760
|
+
const prefs = ssrTiming.userPrefsEnd ? ssrTiming.userPrefsEnd - ssrTiming.userPrefsStart : 0;
|
|
1761
|
+
const trans = ssrTiming.translationsEnd ? ssrTiming.translationsEnd - ssrTiming.translationsStart : 0;
|
|
1762
|
+
console.table({
|
|
1763
|
+
"getAuth()": { ms: auth, bar: "\u2588".repeat(Math.max(1, Math.round(auth / 20))), note: ssrTiming.isCachedAuth ? "(cached)" : "(server call)" },
|
|
1764
|
+
"User Prefs": { ms: prefs, bar: "\u2588".repeat(Math.max(1, Math.round(prefs / 20))) },
|
|
1765
|
+
"loadTranslations()": { ms: trans, bar: "\u2588".repeat(Math.max(1, Math.round(trans / 20))) },
|
|
1766
|
+
"Total SSR beforeLoad": { ms: total, bar: "\u2588".repeat(Math.max(1, Math.round(total / 20))) }
|
|
1767
|
+
});
|
|
1768
|
+
} else {
|
|
1769
|
+
console.log("%c\n\u2500\u2500 SSR Timing: Not available (client-side navigation) \u2500\u2500", "color: #9E9E9E");
|
|
1770
|
+
}
|
|
1771
|
+
if (fcp) {
|
|
1772
|
+
console.log(
|
|
1773
|
+
`%c
|
|
1774
|
+
\u{1F3A8} First Contentful Paint: ${Math.round(fcp.startTime)}ms`,
|
|
1775
|
+
fcp.startTime > 1500 ? "color: #F44336; font-weight: bold; font-size: 14px" : "color: #4CAF50; font-weight: bold; font-size: 14px"
|
|
1776
|
+
);
|
|
1777
|
+
}
|
|
1778
|
+
console.log(
|
|
1779
|
+
`%c
|
|
1780
|
+
\u{1F9E9} Component mounted at: ${Math.round(clientStart)}ms from page start`,
|
|
1781
|
+
"color: #2c4f7c; font-weight: bold"
|
|
1782
|
+
);
|
|
1783
|
+
const resources = performance.getEntriesByType("resource");
|
|
1784
|
+
const jsResources = resources.filter((r) => r.name.endsWith(".js") || r.name.endsWith(".mjs") || r.name.includes(".js?"));
|
|
1785
|
+
const cssResources = resources.filter((r) => r.name.endsWith(".css") || r.name.includes(".css?"));
|
|
1786
|
+
const fontResources = resources.filter((r) => r.name.includes("fonts.googleapis") || r.name.includes("fonts.gstatic"));
|
|
1787
|
+
const imgResources = resources.filter((r) => r.initiatorType === "img");
|
|
1788
|
+
const totalJsSize = jsResources.reduce((sum, r) => sum + (r.transferSize || 0), 0);
|
|
1789
|
+
const slowestJs = [...jsResources].sort((a, b) => b.duration - a.duration).slice(0, 5);
|
|
1790
|
+
console.log("%c\n\u2500\u2500 Resource Loading \u2500\u2500", "color: #9C27B0; font-weight: bold");
|
|
1791
|
+
console.table({
|
|
1792
|
+
"JS bundles": { count: jsResources.length, totalKB: Math.round(totalJsSize / 1024), slowest_ms: Math.round(slowestJs[0]?.duration ?? 0) },
|
|
1793
|
+
"CSS files": { count: cssResources.length, totalKB: Math.round(cssResources.reduce((s, r) => s + (r.transferSize || 0), 0) / 1024) },
|
|
1794
|
+
"Font resources": { count: fontResources.length, slowest_ms: Math.round([...fontResources].sort((a, b) => b.duration - a.duration)[0]?.duration ?? 0) },
|
|
1795
|
+
"Images": { count: imgResources.length, totalKB: Math.round(imgResources.reduce((s, r) => s + (r.transferSize || 0), 0) / 1024) }
|
|
1796
|
+
});
|
|
1797
|
+
if (slowestJs.length > 0) {
|
|
1798
|
+
console.log("%c\n\u2500\u2500 Top 5 Slowest JS Bundles \u2500\u2500", "color: #E91E63; font-weight: bold");
|
|
1799
|
+
console.table(
|
|
1800
|
+
Object.fromEntries(
|
|
1801
|
+
slowestJs.map((r, i) => [
|
|
1802
|
+
`#${i + 1}`,
|
|
1803
|
+
{
|
|
1804
|
+
file: r.name.split("/").pop()?.split("?")[0] ?? r.name,
|
|
1805
|
+
duration_ms: Math.round(r.duration),
|
|
1806
|
+
size_KB: Math.round((r.transferSize || 0) / 1024)
|
|
1807
|
+
}
|
|
1808
|
+
])
|
|
1809
|
+
)
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
console.log("%c\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550", "color: #4CAF50; font-weight: bold");
|
|
1813
|
+
};
|
|
1814
|
+
if (document.readyState === "complete") {
|
|
1815
|
+
setTimeout(run, 500);
|
|
1816
|
+
} else {
|
|
1817
|
+
window.addEventListener("load", () => setTimeout(run, 500));
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
// src/data/designs.ts
|
|
1822
|
+
var designs = Array.from({ length: 21 }, (_, i) => ({
|
|
1823
|
+
id: String(i + 1),
|
|
1824
|
+
name: `Design ${i + 1}`,
|
|
1825
|
+
path: `/dev/design/${i + 1}`
|
|
1826
|
+
}));
|
|
1827
|
+
|
|
1828
|
+
export { DesignPreview, DesignSwitcherDropdown, DevModeProvider, DevSidebar, DevToolbar, GitHubIssueDialog, InspectorOverlay, PageLoadWaterfall, PerformancePanel, PerformanceProvider, configureGitHub, createDevMode, createDevModeOptional, createGitHubIssue, createGitHubLabels, createIsDevAllowed, createIsDevToolsVisible, createPerformanceContext, createPerformanceContextOptional, designs, formatRelativeTime, generateContextInfo, getGitHubConfig, getGitHubIssues, getIssueType, getRepositoryLabels, isGitHubConfigured, logWaterfall };
|
|
1829
|
+
//# sourceMappingURL=index.js.map
|
|
1830
|
+
//# sourceMappingURL=index.js.map
|