@tscircuit/fake-snippets 0.0.100 → 0.0.102

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.
Files changed (61) hide show
  1. package/api/generated-index.js +23 -1
  2. package/bun.lock +2 -2
  3. package/dist/bundle.js +620 -412
  4. package/dist/index.d.ts +33 -4
  5. package/dist/index.js +43 -1
  6. package/dist/schema.d.ts +94 -1
  7. package/dist/schema.js +17 -1
  8. package/fake-snippets-api/lib/db/db-client.ts +38 -1
  9. package/fake-snippets-api/lib/db/schema.ts +15 -0
  10. package/fake-snippets-api/lib/public-mapping/public-map-package.ts +2 -0
  11. package/fake-snippets-api/routes/api/accounts/search.ts +20 -0
  12. package/fake-snippets-api/routes/api/github/installations/create_new_installation_redirect.ts +75 -0
  13. package/fake-snippets-api/routes/api/github/repos/list_available.ts +91 -0
  14. package/fake-snippets-api/routes/api/packages/update.ts +4 -0
  15. package/package.json +2 -2
  16. package/src/App.tsx +10 -1
  17. package/src/components/CmdKMenu.tsx +154 -19
  18. package/src/components/CreateReleaseDialog.tsx +124 -0
  19. package/src/components/FileSidebar.tsx +128 -23
  20. package/src/components/Header2.tsx +106 -25
  21. package/src/components/PackageBuildsPage/package-build-header.tsx +28 -16
  22. package/src/components/PageSearchComponent.tsx +2 -2
  23. package/src/components/SearchComponent.tsx +2 -2
  24. package/src/components/SuspenseRunFrame.tsx +2 -2
  25. package/src/components/TrendingPackagesCarousel.tsx +2 -2
  26. package/src/components/ViewPackagePage/components/important-files-view.tsx +18 -13
  27. package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -0
  28. package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +1 -0
  29. package/src/components/dialogs/GitHubRepositorySelector.tsx +123 -0
  30. package/src/components/dialogs/create-use-dialog.tsx +8 -2
  31. package/src/components/dialogs/edit-package-details-dialog.tsx +22 -3
  32. package/src/components/dialogs/view-ts-files-dialog.tsx +178 -33
  33. package/src/components/package-port/CodeAndPreview.tsx +4 -1
  34. package/src/components/package-port/CodeEditor.tsx +42 -35
  35. package/src/components/package-port/CodeEditorHeader.tsx +26 -20
  36. package/src/components/package-port/EditorNav.tsx +94 -37
  37. package/src/components/preview/BuildsList.tsx +238 -0
  38. package/src/components/preview/ConnectedRepoDashboard.tsx +258 -0
  39. package/src/components/preview/ConnectedRepoOverview.tsx +454 -0
  40. package/src/components/preview/ConnectedRepoSettings.tsx +343 -0
  41. package/src/components/preview/ConnectedReposCards.tsx +191 -0
  42. package/src/components/preview/index.tsx +207 -0
  43. package/src/components/ui/tree-view.tsx +23 -6
  44. package/src/hooks/use-axios.ts +2 -2
  45. package/src/hooks/use-create-release-dialog.ts +160 -0
  46. package/src/hooks/use-package-details-form.ts +7 -0
  47. package/src/hooks/use-packages-base-api-url.ts +1 -1
  48. package/src/hooks/use-sign-in.ts +2 -2
  49. package/src/hooks/useFileManagement.ts +22 -2
  50. package/src/index.css +4 -0
  51. package/src/lib/utils/formatTimeAgo.ts +10 -0
  52. package/src/lib/utils/isValidFileName.ts +15 -3
  53. package/src/pages/dashboard.tsx +2 -2
  54. package/src/pages/dev-login.tsx +2 -2
  55. package/src/pages/landing.tsx +1 -1
  56. package/src/pages/latest.tsx +2 -2
  57. package/src/pages/preview-build.tsx +380 -0
  58. package/src/pages/search.tsx +2 -2
  59. package/src/pages/trending.tsx +2 -2
  60. package/src/pages/user-profile.tsx +32 -24
  61. package/src/pages/view-connected-repo.tsx +24 -0
@@ -0,0 +1,454 @@
1
+ import { useState } from "react"
2
+ import { Badge } from "@/components/ui/badge"
3
+ import { Button } from "@/components/ui/button"
4
+ import {
5
+ Clock,
6
+ GitBranch,
7
+ CheckCircle,
8
+ AlertCircle,
9
+ Loader2,
10
+ ExternalLink,
11
+ ChevronRight,
12
+ User,
13
+ Hash,
14
+ } from "lucide-react"
15
+ import {
16
+ Collapsible,
17
+ CollapsibleContent,
18
+ CollapsibleTrigger,
19
+ } from "@/components/ui/collapsible"
20
+ import { getBuildStatus, PackageBuild, StatusIcon } from "."
21
+ import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
22
+
23
+ interface ConnectedRepoOverviewProps {
24
+ build: PackageBuild
25
+ }
26
+
27
+ export const ConnectedRepoOverview = ({
28
+ build,
29
+ }: ConnectedRepoOverviewProps) => {
30
+ const { status, label } = getBuildStatus(build)
31
+ const [openSections, setOpenSections] = useState({
32
+ transpilation: false,
33
+ circuitJson: false,
34
+ finalBuild: false,
35
+ })
36
+
37
+ const copyToClipboard = (text: string) => {
38
+ navigator.clipboard.writeText(text)
39
+ }
40
+
41
+ const buildDuration =
42
+ build.build_started_at && build.build_completed_at
43
+ ? Math.floor(
44
+ (new Date(build.build_completed_at).getTime() -
45
+ new Date(build.build_started_at).getTime()) /
46
+ 1000,
47
+ )
48
+ : null
49
+
50
+ const toggleSection = (section: keyof typeof openSections) => {
51
+ setOpenSections((prev) => ({ ...prev, [section]: !prev[section] }))
52
+ }
53
+
54
+ const getStepStatus = (
55
+ error: string | null,
56
+ completed: string | null,
57
+ inProgress: boolean,
58
+ ) => {
59
+ if (error) return "error"
60
+ if (completed) return "success"
61
+ if (inProgress) return "building"
62
+ return "queued"
63
+ }
64
+
65
+ const getStepDuration = (
66
+ started: string | null,
67
+ completed: string | null,
68
+ ) => {
69
+ if (started && completed) {
70
+ const duration = Math.floor(
71
+ (new Date(completed).getTime() - new Date(started).getTime()) / 1000,
72
+ )
73
+ return `${duration}s`
74
+ }
75
+ return null
76
+ }
77
+
78
+ return (
79
+ <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6 focus:outline-none">
80
+ <div className="bg-white border border-gray-200 rounded-lg">
81
+ <div className="px-6 py-6 border-b border-gray-200">
82
+ <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
83
+ <div className="flex items-center gap-4">
84
+ <StatusIcon status={status} />
85
+ <div className="flex-1">
86
+ <div className="flex flex-col sm:flex-row sm:items-center sm:gap-3">
87
+ <h1 className="text-xl sm:text-2xl font-semibold text-gray-900">
88
+ Deployment {label}
89
+ </h1>
90
+ </div>
91
+ <p className="text-sm text-gray-600 mt-1">
92
+ Created {formatTimeAgo(build.created_at)}
93
+ </p>
94
+ </div>
95
+ </div>
96
+ <div className="flex items-center gap-3 flex-shrink-0">
97
+ {build.preview_url && (
98
+ <Button
99
+ size="sm"
100
+ className="flex items-center gap-2 min-w-[80px] h-9"
101
+ onClick={() => window.open(build.preview_url!, "_blank")}
102
+ >
103
+ <ExternalLink className="w-3 h-3" />
104
+ Preview Deployment
105
+ </Button>
106
+ )}
107
+ </div>
108
+ </div>
109
+ </div>
110
+
111
+ <div className="px-6 py-4">
112
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
113
+ <div className="flex items-center gap-3 group">
114
+ <Hash className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
115
+ <div>
116
+ <p className="text-xs text-gray-500 uppercase tracking-wide">
117
+ Build ID
118
+ </p>
119
+ <div className="flex items-center gap-2">
120
+ <button
121
+ onClick={() => copyToClipboard(build.package_build_id)}
122
+ className="group-hover:text-blue-500 rounded transition-colors"
123
+ >
124
+ {build.package_build_id}
125
+ </button>
126
+ </div>
127
+ </div>
128
+ </div>
129
+
130
+ <div className="flex items-center gap-3 group">
131
+ <GitBranch className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
132
+ <div>
133
+ <p className="text-xs text-gray-500 uppercase tracking-wide">
134
+ Branch
135
+ </p>
136
+ <a
137
+ href={`https://github.com/tscircuit/tscircuit/tree/${build.branch_name || "main"}`}
138
+ target="_blank"
139
+ rel="noopener noreferrer"
140
+ className="inline-block"
141
+ >
142
+ <Badge
143
+ variant="outline"
144
+ className="text-xs mt-1 hover:bg-gray-100 cursor-pointer transition-colors"
145
+ >
146
+ {build.branch_name || "main"}
147
+ </Badge>
148
+ </a>
149
+ </div>
150
+ </div>
151
+
152
+ <div className="flex items-center gap-3 group">
153
+ <User className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
154
+ <div>
155
+ <p className="text-xs text-gray-500 uppercase tracking-wide">
156
+ Author
157
+ </p>
158
+ <a
159
+ href={`https://github.com/${build.commit_author}`}
160
+ target="_blank"
161
+ rel="noopener noreferrer"
162
+ className="text-sm font-medium hover:text-blue-500 transition-colors"
163
+ >
164
+ {build.commit_author || "Unknown"}
165
+ </a>
166
+ </div>
167
+ </div>
168
+
169
+ {buildDuration && (
170
+ <div className="flex items-center gap-3 group">
171
+ <Clock className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
172
+ <div>
173
+ <p className="text-xs text-gray-500 uppercase tracking-wide">
174
+ Duration
175
+ </p>
176
+ <p
177
+ className="text-sm font-medium hover:text-blue-500 transition-colors cursor-help"
178
+ title={`Build started at ${build.build_started_at}`}
179
+ >
180
+ {buildDuration}s
181
+ </p>
182
+ </div>
183
+ </div>
184
+ )}
185
+ </div>
186
+
187
+ {build.commit_message && (
188
+ <div className="mt-6 p-4 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors group">
189
+ <p className="text-xs text-gray-500 uppercase tracking-wide mb-2">
190
+ Commit Message
191
+ </p>
192
+ <p className="text-sm text-gray-900 group-hover:text-gray-700 transition-colors">
193
+ {build.commit_message}
194
+ </p>
195
+ </div>
196
+ )}
197
+ </div>
198
+ </div>
199
+
200
+ <div className="space-y-3">
201
+ <h2 className="text-lg font-semibold text-gray-900">Build Steps</h2>
202
+
203
+ <Collapsible
204
+ open={openSections.transpilation}
205
+ onOpenChange={() => toggleSection("transpilation")}
206
+ >
207
+ <CollapsibleTrigger asChild>
208
+ <div className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-50">
209
+ <div className="flex items-center gap-3">
210
+ <ChevronRight
211
+ className={`w-4 h-4 transition-transform ${openSections.transpilation ? "rotate-90" : ""}`}
212
+ />
213
+ {build.transpilation_error ? (
214
+ <AlertCircle className="w-5 h-5 text-red-500" />
215
+ ) : build.transpilation_completed_at ? (
216
+ <CheckCircle className="w-5 h-5 text-green-500" />
217
+ ) : build.transpilation_in_progress ? (
218
+ <Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
219
+ ) : (
220
+ <Clock className="w-5 h-5 text-gray-400" />
221
+ )}
222
+ <span className="font-medium">Transpilation</span>
223
+ </div>
224
+ <div className="flex items-center gap-2">
225
+ {getStepDuration(
226
+ build.transpilation_started_at,
227
+ build.transpilation_completed_at,
228
+ ) && (
229
+ <span className="text-sm text-gray-600">
230
+ {getStepDuration(
231
+ build.transpilation_started_at,
232
+ build.transpilation_completed_at,
233
+ )}
234
+ </span>
235
+ )}
236
+ <Badge
237
+ variant={
238
+ getStepStatus(
239
+ build.transpilation_error,
240
+ build.transpilation_completed_at,
241
+ build.transpilation_in_progress,
242
+ ) === "success"
243
+ ? "default"
244
+ : getStepStatus(
245
+ build.transpilation_error,
246
+ build.transpilation_completed_at,
247
+ build.transpilation_in_progress,
248
+ ) === "error"
249
+ ? "destructive"
250
+ : "secondary"
251
+ }
252
+ className="text-xs"
253
+ >
254
+ {build.transpilation_error
255
+ ? "Failed"
256
+ : build.transpilation_completed_at
257
+ ? "Completed"
258
+ : build.transpilation_in_progress
259
+ ? "Running"
260
+ : "Queued"}
261
+ </Badge>
262
+ </div>
263
+ </div>
264
+ </CollapsibleTrigger>
265
+ <CollapsibleContent>
266
+ <div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
267
+ <div className="font-mono text-xs space-y-1">
268
+ {build.transpilation_error ? (
269
+ <div className="text-red-600 whitespace-pre-wrap">
270
+ {build.transpilation_error}
271
+ </div>
272
+ ) : build.transpilation_logs &&
273
+ build.transpilation_logs.length > 0 ? (
274
+ build.transpilation_logs.map((log: any, i: number) => (
275
+ <div key={i} className="text-gray-600 whitespace-pre-wrap">
276
+ {log.msg || log.message || JSON.stringify(log)}
277
+ </div>
278
+ ))
279
+ ) : (
280
+ <div className="text-gray-500">No logs available</div>
281
+ )}
282
+ </div>
283
+ </div>
284
+ </CollapsibleContent>
285
+ </Collapsible>
286
+
287
+ <Collapsible
288
+ open={openSections.circuitJson}
289
+ onOpenChange={() => toggleSection("circuitJson")}
290
+ >
291
+ <CollapsibleTrigger asChild>
292
+ <div className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-50">
293
+ <div className="flex items-center gap-3">
294
+ <ChevronRight
295
+ className={`w-4 h-4 transition-transform ${openSections.circuitJson ? "rotate-90" : ""}`}
296
+ />
297
+ {build.circuit_json_build_error ? (
298
+ <AlertCircle className="w-5 h-5 text-red-500" />
299
+ ) : build.circuit_json_build_completed_at ? (
300
+ <CheckCircle className="w-5 h-5 text-green-500" />
301
+ ) : build.circuit_json_build_in_progress ? (
302
+ <Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
303
+ ) : (
304
+ <Clock className="w-5 h-5 text-gray-400" />
305
+ )}
306
+ <span className="font-medium">Circuit JSON Build</span>
307
+ </div>
308
+ <div className="flex items-center gap-2">
309
+ {getStepDuration(
310
+ build.circuit_json_build_started_at,
311
+ build.circuit_json_build_completed_at,
312
+ ) && (
313
+ <span className="text-sm text-gray-600">
314
+ {getStepDuration(
315
+ build.circuit_json_build_started_at,
316
+ build.circuit_json_build_completed_at,
317
+ )}
318
+ </span>
319
+ )}
320
+ <Badge
321
+ variant={
322
+ getStepStatus(
323
+ build.circuit_json_build_error,
324
+ build.circuit_json_build_completed_at,
325
+ build.circuit_json_build_in_progress,
326
+ ) === "success"
327
+ ? "default"
328
+ : getStepStatus(
329
+ build.circuit_json_build_error,
330
+ build.circuit_json_build_completed_at,
331
+ build.circuit_json_build_in_progress,
332
+ ) === "error"
333
+ ? "destructive"
334
+ : "secondary"
335
+ }
336
+ className="text-xs"
337
+ >
338
+ {build.circuit_json_build_error
339
+ ? "Failed"
340
+ : build.circuit_json_build_completed_at
341
+ ? "Completed"
342
+ : build.circuit_json_build_in_progress
343
+ ? "Running"
344
+ : "Queued"}
345
+ </Badge>
346
+ </div>
347
+ </div>
348
+ </CollapsibleTrigger>
349
+ <CollapsibleContent>
350
+ <div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
351
+ <div className="font-mono text-xs space-y-1">
352
+ {build.circuit_json_build_error ? (
353
+ <div className="text-red-600 whitespace-pre-wrap">
354
+ {build.circuit_json_build_error}
355
+ </div>
356
+ ) : build.circuit_json_build_logs &&
357
+ build.circuit_json_build_logs.length > 0 ? (
358
+ build.circuit_json_build_logs.map((log: any, i: number) => (
359
+ <div key={i} className="text-gray-600 whitespace-pre-wrap">
360
+ {log.msg || log.message || JSON.stringify(log)}
361
+ </div>
362
+ ))
363
+ ) : (
364
+ <div className="text-gray-500">No logs available</div>
365
+ )}
366
+ </div>
367
+ </div>
368
+ </CollapsibleContent>
369
+ </Collapsible>
370
+
371
+ <Collapsible
372
+ open={openSections.finalBuild}
373
+ onOpenChange={() => toggleSection("finalBuild")}
374
+ >
375
+ <CollapsibleTrigger asChild>
376
+ <div className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-50">
377
+ <div className="flex items-center gap-3">
378
+ <ChevronRight
379
+ className={`w-4 h-4 transition-transform ${openSections.finalBuild ? "rotate-90" : ""}`}
380
+ />
381
+ {build.build_error ? (
382
+ <AlertCircle className="w-5 h-5 text-red-500" />
383
+ ) : build.build_completed_at ? (
384
+ <CheckCircle className="w-5 h-5 text-green-500" />
385
+ ) : build.build_in_progress ? (
386
+ <Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
387
+ ) : (
388
+ <Clock className="w-5 h-5 text-gray-400" />
389
+ )}
390
+ <span className="font-medium">Final Build</span>
391
+ </div>
392
+ <div className="flex items-center gap-2">
393
+ {getStepDuration(
394
+ build.build_started_at,
395
+ build.build_completed_at,
396
+ ) && (
397
+ <span className="text-sm text-gray-600">
398
+ {getStepDuration(
399
+ build.build_started_at,
400
+ build.build_completed_at,
401
+ )}
402
+ </span>
403
+ )}
404
+ <Badge
405
+ variant={
406
+ getStepStatus(
407
+ build.build_error,
408
+ build.build_completed_at,
409
+ build.build_in_progress,
410
+ ) === "success"
411
+ ? "default"
412
+ : getStepStatus(
413
+ build.build_error,
414
+ build.build_completed_at,
415
+ build.build_in_progress,
416
+ ) === "error"
417
+ ? "destructive"
418
+ : "secondary"
419
+ }
420
+ className="text-xs"
421
+ >
422
+ {build.build_error
423
+ ? "Failed"
424
+ : build.build_completed_at
425
+ ? "Completed"
426
+ : build.build_in_progress
427
+ ? "Running"
428
+ : "Queued"}
429
+ </Badge>
430
+ </div>
431
+ </div>
432
+ </CollapsibleTrigger>
433
+ <CollapsibleContent>
434
+ <div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
435
+ <div className="font-mono text-xs space-y-1">
436
+ {build.build_error ? (
437
+ <div className="text-red-600 whitespace-pre-wrap">
438
+ {build.build_error}
439
+ </div>
440
+ ) : build.build_logs ? (
441
+ <div className="text-gray-600 whitespace-pre-wrap">
442
+ {build.build_logs}
443
+ </div>
444
+ ) : (
445
+ <div className="text-gray-500">No logs available</div>
446
+ )}
447
+ </div>
448
+ </div>
449
+ </CollapsibleContent>
450
+ </Collapsible>
451
+ </div>
452
+ </div>
453
+ )
454
+ }