@tscircuit/fake-snippets 0.0.107 → 0.0.109

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 (80) hide show
  1. package/api/generated-index.js +82 -22
  2. package/biome.json +7 -1
  3. package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +0 -15
  4. package/bun-tests/fake-snippets-api/routes/package_builds/list.test.ts +0 -12
  5. package/bun.lock +62 -19
  6. package/dist/bundle.js +25 -24
  7. package/dist/index.d.ts +26 -15
  8. package/dist/index.js +19 -18
  9. package/dist/schema.d.ts +32 -24
  10. package/dist/schema.js +7 -6
  11. package/fake-snippets-api/lib/db/db-client.ts +10 -1
  12. package/fake-snippets-api/lib/db/schema.ts +4 -3
  13. package/fake-snippets-api/lib/db/seed.ts +6 -9
  14. package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +0 -3
  15. package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +3 -0
  16. package/package.json +7 -8
  17. package/src/App.tsx +12 -11
  18. package/src/components/DownloadButtonAndMenu.tsx +133 -35
  19. package/src/components/FileSidebar.tsx +45 -193
  20. package/src/components/Footer.tsx +0 -1
  21. package/src/components/HeaderLogin.tsx +1 -1
  22. package/src/components/HiddenFilesDropdown.tsx +0 -2
  23. package/src/components/PackageBreadcrumb.tsx +1 -1
  24. package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +0 -2
  25. package/src/components/PackageBuildsPage/build-preview-content.tsx +34 -5
  26. package/src/components/PackageCard.tsx +0 -1
  27. package/src/components/ViewPackagePage/components/ShikiCodeViewer.tsx +20 -11
  28. package/src/components/ViewPackagePage/components/important-files-view.tsx +75 -59
  29. package/src/components/ViewPackagePage/components/main-content-header.tsx +4 -4
  30. package/src/components/ViewPackagePage/components/main-content-view-selector.tsx +0 -1
  31. package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -2
  32. package/src/components/ViewPackagePage/components/package-header.tsx +14 -17
  33. package/src/components/ViewPackagePage/components/preview-image-squares.tsx +0 -1
  34. package/src/components/ViewPackagePage/components/repo-page-content.tsx +21 -20
  35. package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +18 -2
  36. package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +1 -1
  37. package/src/components/ViewPackagePage/components/sidebar.tsx +0 -2
  38. package/src/components/ViewPackagePage/components/tab-views/files-view.tsx +18 -17
  39. package/src/components/ViewPackagePage/components/theme-toggle.tsx +0 -2
  40. package/src/components/ViewPackagePage/hooks/use-toast.tsx +0 -1
  41. package/src/components/package-port/CodeAndPreview.tsx +23 -40
  42. package/src/components/package-port/CodeEditor.tsx +24 -1
  43. package/src/components/package-port/CodeEditorHeader.tsx +5 -2
  44. package/src/components/preview/BuildsList.tsx +20 -9
  45. package/src/components/preview/ConnectedPackagesList.tsx +73 -60
  46. package/src/components/preview/ConnectedRepoOverview.tsx +160 -154
  47. package/src/components/preview/PackageReleasesDashboard.tsx +41 -30
  48. package/src/components/preview/index.tsx +16 -153
  49. package/src/hooks/use-current-package-id.ts +5 -30
  50. package/src/hooks/use-current-package-info.ts +29 -5
  51. package/src/hooks/use-global-store.ts +1 -1
  52. package/src/hooks/useFileManagement.ts +153 -34
  53. package/src/hooks/useOptimizedPackageFilesLoader.ts +149 -0
  54. package/src/hooks/useUpdatePackageFilesMutation.ts +2 -0
  55. package/src/index.css +24 -0
  56. package/src/lib/download-fns/download-circuit-png.ts +11 -3
  57. package/src/lib/download-fns/download-gltf-from-circuit-json.ts +44 -0
  58. package/src/lib/utils/isComponentExported.ts +9 -0
  59. package/src/lib/utils/transformFilesToTreeData.tsx +195 -0
  60. package/src/pages/404.tsx +3 -5
  61. package/src/pages/authorize.tsx +0 -2
  62. package/src/pages/landing.tsx +0 -1
  63. package/src/pages/preview-release.tsx +279 -0
  64. package/src/pages/release-builds.tsx +0 -8
  65. package/src/pages/release-detail.tsx +17 -15
  66. package/src/pages/releases.tsx +5 -1
  67. package/src/pages/view-package.tsx +14 -13
  68. package/src/components/Footer2.tsx +0 -100
  69. package/src/components/ShippingInformationForm.tsx +0 -423
  70. package/src/components/StaticViewSnippetHeader.tsx +0 -70
  71. package/src/components/ViewPackagePage/components/file-explorer.tsx +0 -67
  72. package/src/components/ViewPackagePage/components/readme-view.tsx +0 -58
  73. package/src/components/ViewPackagePage/components/repo-header-button.tsx +0 -36
  74. package/src/components/ViewPackagePage/components/repo-header.tsx +0 -4
  75. package/src/components/ViewPackagePage/components/sidebar-contributors-section.tsx +0 -31
  76. package/src/components/ViewSnippetHeader.tsx +0 -181
  77. package/src/components/ui/input-otp.tsx +0 -69
  78. package/src/hooks/use-snippets-base-api-url.ts +0 -3
  79. package/src/pages/preview-build.tsx +0 -380
  80. package/src/pages/settings.tsx +0 -25
@@ -27,34 +27,109 @@ import {
27
27
  } from "fake-snippets-api/lib/db/schema"
28
28
 
29
29
  export const ConnectedRepoOverview = ({
30
- build,
30
+ packageBuild,
31
31
  pkg,
32
+ isLoadingBuild,
32
33
  packageRelease,
33
34
  }: {
34
- build: PackageBuild
35
+ packageBuild?: PackageBuild | null
36
+ isLoadingBuild: boolean
35
37
  pkg: Package
36
38
  packageRelease: PackageRelease
37
39
  }) => {
38
- const { status, label } = getBuildStatus(build)
40
+ const { status, label } = getBuildStatus(packageBuild ?? null)
39
41
  const [openSections, setOpenSections] = useState({
40
42
  transpilation: false,
41
43
  circuitJson: false,
42
- finalBuild: false,
43
44
  })
44
45
 
46
+ // Gracefully handle when there is no build yet
47
+ if (isLoadingBuild) {
48
+ return (
49
+ <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6 space-y-6 focus:outline-none">
50
+ <div className="bg-white border border-gray-200 rounded-lg">
51
+ <div className="px-6 py-6 border-b border-gray-200">
52
+ <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
53
+ <div className="flex items-center gap-4">
54
+ <div className="w-6 h-6 rounded-full bg-gray-200 animate-pulse" />
55
+ <div className="flex-1 space-y-2">
56
+ <div className="h-7 w-32 bg-gray-200 rounded animate-pulse" />
57
+ <div className="h-4 w-24 bg-gray-200 rounded animate-pulse" />
58
+ </div>
59
+ </div>
60
+ <div className="w-24 h-9 bg-gray-200 rounded animate-pulse" />
61
+ </div>
62
+ </div>
63
+ <div className="px-6 py-4">
64
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
65
+ {Array(4)
66
+ .fill(0)
67
+ .map((_, i) => (
68
+ <div key={i} className="flex items-center gap-3">
69
+ <div className="w-4 h-4 rounded bg-gray-200 animate-pulse" />
70
+ <div className="space-y-2">
71
+ <div className="h-4 w-20 bg-gray-200 rounded animate-pulse" />
72
+ <div className="h-5 w-24 bg-gray-200 rounded animate-pulse" />
73
+ </div>
74
+ </div>
75
+ ))}
76
+ </div>
77
+ <div className="mt-6 p-4 bg-gray-50 rounded-lg">
78
+ <div className="h-4 w-32 bg-gray-200 rounded animate-pulse mb-2" />
79
+ <div className="h-5 w-full bg-gray-200 rounded animate-pulse" />
80
+ </div>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ )
85
+ }
86
+
87
+ if (!packageBuild) {
88
+ return (
89
+ <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
90
+ <div className="bg-white border border-gray-200 rounded-lg p-6 text-center">
91
+ <p className="text-sm text-gray-600">
92
+ No build information available.
93
+ </p>
94
+ </div>
95
+ </div>
96
+ )
97
+ }
98
+
45
99
  const copyToClipboard = (text: string) => {
46
100
  navigator.clipboard.writeText(text)
47
101
  }
48
102
 
49
- const buildDuration =
50
- build.build_started_at && build.build_completed_at
103
+ const buildDuration = (() => {
104
+ const transpilationDuration = packageBuild?.transpilation_started_at
105
+ ? Math.floor(
106
+ (new Date(
107
+ packageBuild.transpilation_completed_at || new Date(),
108
+ ).getTime() -
109
+ new Date(packageBuild.transpilation_started_at).getTime()) /
110
+ 1000,
111
+ )
112
+ : 0
113
+
114
+ const circuitJsonDuration = packageBuild?.circuit_json_build_started_at
51
115
  ? Math.floor(
52
- (new Date(build.build_completed_at).getTime() -
53
- new Date(build.build_started_at).getTime()) /
116
+ (new Date(
117
+ packageBuild.circuit_json_build_completed_at || new Date(),
118
+ ).getTime() -
119
+ new Date(packageBuild.circuit_json_build_started_at).getTime()) /
54
120
  1000,
55
121
  )
56
- : null
122
+ : 0
57
123
 
124
+ if (
125
+ !packageBuild?.transpilation_started_at &&
126
+ !packageBuild?.circuit_json_build_started_at
127
+ ) {
128
+ return null
129
+ }
130
+
131
+ return transpilationDuration + circuitJsonDuration
132
+ })()
58
133
  const toggleSection = (section: keyof typeof openSections) => {
59
134
  setOpenSections((prev) => ({ ...prev, [section]: !prev[section] }))
60
135
  }
@@ -97,18 +172,23 @@ export const ConnectedRepoOverview = ({
97
172
  </h1>
98
173
  </div>
99
174
  <p className="text-sm text-gray-600 mt-1">
100
- <time dateTime={build.created_at}>
101
- Built {formatTimeAgo(build.created_at)}
175
+ <time dateTime={packageBuild.created_at}>
176
+ Built {formatTimeAgo(packageBuild.created_at)}
102
177
  </time>
103
178
  </p>
104
179
  </div>
105
180
  </div>
106
181
  <div className="flex items-center gap-3 flex-shrink-0">
107
- {build.preview_url && (
182
+ {status !== "error" && (
108
183
  <Button
109
184
  size="sm"
110
185
  className="flex items-center gap-2 min-w-[80px] h-9"
111
- onClick={() => window.open(build.preview_url!, "_blank")}
186
+ onClick={() =>
187
+ window.open(
188
+ `/${pkg.name}/releases/${packageBuild.package_release_id}/preview`,
189
+ "_blank",
190
+ )
191
+ }
112
192
  >
113
193
  <ExternalLink className="w-3 h-3" />
114
194
  Preview
@@ -118,7 +198,7 @@ export const ConnectedRepoOverview = ({
118
198
  </div>
119
199
  </div>
120
200
 
121
- <div className="px-6 py-4">
201
+ <div className="px-6 py-4 select-none">
122
202
  <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
123
203
  <div className="flex items-center gap-3 group">
124
204
  <Hash className="w-4 h-4 text-gray-500 group-hover:text-blue-500 transition-colors" />
@@ -128,10 +208,12 @@ export const ConnectedRepoOverview = ({
128
208
  </p>
129
209
  <div className="flex items-center gap-2">
130
210
  <button
131
- onClick={() => copyToClipboard(build.package_build_id)}
132
- className="group-hover:text-blue-500 rounded text-left transition-colors"
211
+ onClick={() =>
212
+ copyToClipboard(packageBuild.package_build_id)
213
+ }
214
+ className="group-hover:text-blue-500 text-xs rounded text-left transition-colors"
133
215
  >
134
- {build.package_build_id}
216
+ {packageBuild.package_build_id}
135
217
  </button>
136
218
  </div>
137
219
  </div>
@@ -150,8 +232,8 @@ export const ConnectedRepoOverview = ({
150
232
  <a
151
233
  href={
152
234
  packageRelease?.is_pr_preview
153
- ? `https://github.com/${pkg.github_repo_full_name}/pull/${packageRelease.github_pr_number}`
154
- : `https://github.com/${pkg.github_repo_full_name}/tree/${build.branch_name || "main"}`
235
+ ? `https://github.com/${pkg.github_repo_full_name}/pull/${packageRelease?.github_pr_number}`
236
+ : `https://github.com/${pkg.github_repo_full_name}/tree/${packageRelease?.branch_name || "main"}`
155
237
  }
156
238
  target="_blank"
157
239
  rel="noopener noreferrer"
@@ -163,7 +245,7 @@ export const ConnectedRepoOverview = ({
163
245
  >
164
246
  {packageRelease?.is_pr_preview
165
247
  ? `#${packageRelease.github_pr_number}`
166
- : build?.branch_name || "main"}
248
+ : packageRelease?.branch_name || "main"}
167
249
  </Badge>
168
250
  </a>
169
251
  </div>
@@ -176,12 +258,12 @@ export const ConnectedRepoOverview = ({
176
258
  Author
177
259
  </p>
178
260
  <a
179
- href={`https://github.com/${build.commit_author}`}
261
+ href={`https://github.com/${pkg.owner_github_username}`}
180
262
  target="_blank"
181
263
  rel="noopener noreferrer"
182
264
  className="text-sm font-medium hover:text-blue-500 transition-colors"
183
265
  >
184
- {build.commit_author || "Unknown"}
266
+ {pkg.owner_github_username || "Unknown"}
185
267
  </a>
186
268
  </div>
187
269
  </div>
@@ -194,21 +276,21 @@ export const ConnectedRepoOverview = ({
194
276
  </p>
195
277
  <p
196
278
  className="text-sm font-medium hover:text-blue-500 transition-colors cursor-help"
197
- title={`Build started at ${build.build_started_at}`}
279
+ title={`Build started at ${packageBuild.build_started_at}`}
198
280
  >
199
- {buildDuration}s
281
+ {buildDuration || 0}s
200
282
  </p>
201
283
  </div>
202
284
  </div>
203
285
  </div>
204
286
 
205
- {build.commit_message && (
287
+ {packageRelease?.commit_message && (
206
288
  <div className="mt-6 p-4 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors group">
207
289
  <p className="text-xs text-gray-500 uppercase tracking-wide mb-2">
208
290
  Commit Message
209
291
  </p>
210
292
  <p className="text-sm text-gray-900 group-hover:text-gray-700 transition-colors">
211
- {build.commit_message}
293
+ {packageRelease?.commit_message}
212
294
  </p>
213
295
  </div>
214
296
  )}
@@ -221,7 +303,7 @@ export const ConnectedRepoOverview = ({
221
303
  Latest Build Logs
222
304
  </h2>
223
305
  <a
224
- href={`/${pkg.name.split("/")[0]}/${pkg.name.split("/")[1]}/release/${packageRelease.package_release_id}/builds`}
306
+ href={`/${pkg.name.split("/")[0]}/${pkg.name.split("/")[1]}/releases/${packageRelease.package_release_id}/builds`}
225
307
  className="text-sm text-blue-600 hover:text-blue-800 transition-colors"
226
308
  >
227
309
  (previous builds)
@@ -238,11 +320,11 @@ export const ConnectedRepoOverview = ({
238
320
  <ChevronRight
239
321
  className={`w-4 h-4 transition-transform ${openSections.transpilation ? "rotate-90" : ""}`}
240
322
  />
241
- {build.transpilation_error ? (
323
+ {packageBuild.transpilation_error ? (
242
324
  <AlertCircle className="w-5 h-5 text-red-500" />
243
- ) : build.transpilation_completed_at ? (
325
+ ) : packageBuild.transpilation_completed_at ? (
244
326
  <CheckCircle className="w-5 h-5 text-green-500" />
245
- ) : build.transpilation_in_progress ? (
327
+ ) : packageBuild.transpilation_in_progress ? (
246
328
  <Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
247
329
  ) : (
248
330
  <Clock className="w-5 h-5 text-gray-400" />
@@ -251,39 +333,39 @@ export const ConnectedRepoOverview = ({
251
333
  </div>
252
334
  <div className="flex items-center gap-2">
253
335
  {getStepDuration(
254
- build.transpilation_started_at,
255
- build.transpilation_completed_at,
336
+ packageBuild.transpilation_started_at,
337
+ packageBuild.transpilation_completed_at,
256
338
  ) && (
257
339
  <span className="text-sm text-gray-600">
258
340
  {getStepDuration(
259
- build.transpilation_started_at,
260
- build.transpilation_completed_at,
341
+ packageBuild.transpilation_started_at,
342
+ packageBuild.transpilation_completed_at,
261
343
  )}
262
344
  </span>
263
345
  )}
264
346
  <Badge
265
347
  variant={
266
348
  getStepStatus(
267
- build.transpilation_error,
268
- build.transpilation_completed_at,
269
- build.transpilation_in_progress,
349
+ packageBuild.transpilation_error,
350
+ packageBuild.transpilation_completed_at,
351
+ packageBuild.transpilation_in_progress,
270
352
  ) === "success"
271
353
  ? "default"
272
354
  : getStepStatus(
273
- build.transpilation_error,
274
- build.transpilation_completed_at,
275
- build.transpilation_in_progress,
355
+ packageBuild.transpilation_error,
356
+ packageBuild.transpilation_completed_at,
357
+ packageBuild.transpilation_in_progress,
276
358
  ) === "error"
277
359
  ? "destructive"
278
360
  : "secondary"
279
361
  }
280
362
  className="text-xs"
281
363
  >
282
- {build.transpilation_error
364
+ {packageBuild.transpilation_error
283
365
  ? "Failed"
284
- : build.transpilation_completed_at
366
+ : packageBuild.transpilation_completed_at
285
367
  ? "Completed"
286
- : build.transpilation_in_progress
368
+ : packageBuild.transpilation_in_progress
287
369
  ? "Running"
288
370
  : "Queued"}
289
371
  </Badge>
@@ -293,13 +375,13 @@ export const ConnectedRepoOverview = ({
293
375
  <CollapsibleContent>
294
376
  <div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
295
377
  <div className="font-mono text-xs space-y-1">
296
- {build.transpilation_error ? (
378
+ {packageBuild.transpilation_error ? (
297
379
  <div className="text-red-600 whitespace-pre-wrap">
298
- {build.transpilation_error}
380
+ {packageBuild.transpilation_error}
299
381
  </div>
300
- ) : build.transpilation_logs &&
301
- build.transpilation_logs.length > 0 ? (
302
- build.transpilation_logs.map((log: any, i: number) => (
382
+ ) : packageBuild.transpilation_logs &&
383
+ packageBuild.transpilation_logs.length > 0 ? (
384
+ packageBuild.transpilation_logs.map((log: any, i: number) => (
303
385
  <div key={i} className="text-gray-600 whitespace-pre-wrap">
304
386
  {log.msg || log.message || JSON.stringify(log)}
305
387
  </div>
@@ -322,11 +404,11 @@ export const ConnectedRepoOverview = ({
322
404
  <ChevronRight
323
405
  className={`w-4 h-4 transition-transform ${openSections.circuitJson ? "rotate-90" : ""}`}
324
406
  />
325
- {build.circuit_json_build_error ? (
407
+ {packageBuild.circuit_json_build_error ? (
326
408
  <AlertCircle className="w-5 h-5 text-red-500" />
327
- ) : build.circuit_json_build_completed_at ? (
409
+ ) : packageBuild.circuit_json_build_completed_at ? (
328
410
  <CheckCircle className="w-5 h-5 text-green-500" />
329
- ) : build.circuit_json_build_in_progress ? (
411
+ ) : packageBuild.circuit_json_build_in_progress ? (
330
412
  <Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
331
413
  ) : (
332
414
  <Clock className="w-5 h-5 text-gray-400" />
@@ -335,123 +417,39 @@ export const ConnectedRepoOverview = ({
335
417
  </div>
336
418
  <div className="flex items-center gap-2">
337
419
  {getStepDuration(
338
- build.circuit_json_build_started_at,
339
- build.circuit_json_build_completed_at,
340
- ) && (
341
- <span className="text-sm text-gray-600">
342
- {getStepDuration(
343
- build.circuit_json_build_started_at,
344
- build.circuit_json_build_completed_at,
345
- )}
346
- </span>
347
- )}
348
- <Badge
349
- variant={
350
- getStepStatus(
351
- build.circuit_json_build_error,
352
- build.circuit_json_build_completed_at,
353
- build.circuit_json_build_in_progress,
354
- ) === "success"
355
- ? "default"
356
- : getStepStatus(
357
- build.circuit_json_build_error,
358
- build.circuit_json_build_completed_at,
359
- build.circuit_json_build_in_progress,
360
- ) === "error"
361
- ? "destructive"
362
- : "secondary"
363
- }
364
- className="text-xs"
365
- >
366
- {build.circuit_json_build_error
367
- ? "Failed"
368
- : build.circuit_json_build_completed_at
369
- ? "Completed"
370
- : build.circuit_json_build_in_progress
371
- ? "Running"
372
- : "Queued"}
373
- </Badge>
374
- </div>
375
- </div>
376
- </CollapsibleTrigger>
377
- <CollapsibleContent>
378
- <div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
379
- <div className="font-mono text-xs space-y-1">
380
- {build.circuit_json_build_error ? (
381
- <div className="text-red-600 whitespace-pre-wrap">
382
- {build.circuit_json_build_error}
383
- </div>
384
- ) : build.circuit_json_build_logs &&
385
- build.circuit_json_build_logs.length > 0 ? (
386
- build.circuit_json_build_logs.map((log: any, i: number) => (
387
- <div key={i} className="text-gray-600 whitespace-pre-wrap">
388
- {log.msg || log.message || JSON.stringify(log)}
389
- </div>
390
- ))
391
- ) : (
392
- <div className="text-gray-500">No logs available</div>
393
- )}
394
- </div>
395
- </div>
396
- </CollapsibleContent>
397
- </Collapsible>
398
-
399
- <Collapsible
400
- open={openSections.finalBuild}
401
- onOpenChange={() => toggleSection("finalBuild")}
402
- >
403
- <CollapsibleTrigger asChild>
404
- <div className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-50">
405
- <div className="flex items-center gap-3">
406
- <ChevronRight
407
- className={`w-4 h-4 transition-transform ${openSections.finalBuild ? "rotate-90" : ""}`}
408
- />
409
- {build.build_error ? (
410
- <AlertCircle className="w-5 h-5 text-red-500" />
411
- ) : build.build_completed_at ? (
412
- <CheckCircle className="w-5 h-5 text-green-500" />
413
- ) : build.build_in_progress ? (
414
- <Loader2 className="w-5 h-5 text-blue-500 animate-spin" />
415
- ) : (
416
- <Clock className="w-5 h-5 text-gray-400" />
417
- )}
418
- <span className="font-medium">Build</span>
419
- </div>
420
- <div className="flex items-center gap-2">
421
- {getStepDuration(
422
- build.build_started_at,
423
- build.build_completed_at,
420
+ packageBuild.circuit_json_build_started_at,
421
+ packageBuild.circuit_json_build_completed_at,
424
422
  ) && (
425
423
  <span className="text-sm text-gray-600">
426
424
  {getStepDuration(
427
- build.build_started_at,
428
- build.build_completed_at,
425
+ packageBuild.circuit_json_build_started_at,
426
+ packageBuild.circuit_json_build_completed_at,
429
427
  )}
430
428
  </span>
431
429
  )}
432
430
  <Badge
433
431
  variant={
434
432
  getStepStatus(
435
- build.build_error,
436
- build.build_completed_at,
437
- build.build_in_progress,
433
+ packageBuild.circuit_json_build_error,
434
+ packageBuild.circuit_json_build_completed_at,
435
+ packageBuild.circuit_json_build_in_progress,
438
436
  ) === "success"
439
437
  ? "default"
440
438
  : getStepStatus(
441
- build.build_error,
442
- build.build_completed_at,
443
- build.build_in_progress,
439
+ packageBuild.circuit_json_build_error,
440
+ packageBuild.circuit_json_build_completed_at,
441
+ packageBuild.circuit_json_build_in_progress,
444
442
  ) === "error"
445
443
  ? "destructive"
446
444
  : "secondary"
447
445
  }
448
446
  className="text-xs"
449
447
  >
450
- {build.build_error
448
+ {packageBuild.circuit_json_build_error
451
449
  ? "Failed"
452
- : build.build_completed_at
450
+ : packageBuild.circuit_json_build_completed_at
453
451
  ? "Completed"
454
- : build.build_in_progress
452
+ : packageBuild.circuit_json_build_in_progress
455
453
  ? "Running"
456
454
  : "Queued"}
457
455
  </Badge>
@@ -461,14 +459,22 @@ export const ConnectedRepoOverview = ({
461
459
  <CollapsibleContent>
462
460
  <div className="bg-white border-x border-b border-gray-200 rounded-b-lg p-4">
463
461
  <div className="font-mono text-xs space-y-1">
464
- {build.build_error ? (
462
+ {packageBuild.circuit_json_build_error ? (
465
463
  <div className="text-red-600 whitespace-pre-wrap">
466
- {build.build_error}
467
- </div>
468
- ) : build.build_logs ? (
469
- <div className="text-gray-600 whitespace-pre-wrap">
470
- {build.build_logs}
464
+ {packageBuild.circuit_json_build_error}
471
465
  </div>
466
+ ) : packageBuild.circuit_json_build_logs &&
467
+ packageBuild.circuit_json_build_logs.length > 0 ? (
468
+ packageBuild.circuit_json_build_logs.map(
469
+ (log: any, i: number) => (
470
+ <div
471
+ key={i}
472
+ className="text-gray-600 whitespace-pre-wrap"
473
+ >
474
+ {log.msg || log.message || JSON.stringify(log)}
475
+ </div>
476
+ ),
477
+ )
472
478
  ) : (
473
479
  <div className="text-gray-500">No logs available</div>
474
480
  )}
@@ -15,12 +15,18 @@ import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
15
15
  import { getBuildStatus } from "."
16
16
  import { PrefetchPageLink } from "../PrefetchPageLink"
17
17
  import { PackageBreadcrumb } from "../PackageBreadcrumb"
18
- import { Package, PackageBuild } from "fake-snippets-api/lib/db/schema"
18
+ import {
19
+ Package,
20
+ PackageBuild,
21
+ PackageRelease,
22
+ } from "fake-snippets-api/lib/db/schema"
19
23
 
20
24
  export const PackageReleasesDashboard = ({
25
+ latestRelease,
21
26
  latestBuild,
22
27
  pkg,
23
28
  }: {
29
+ latestRelease: PackageRelease
24
30
  latestBuild: PackageBuild | null
25
31
  pkg: Package
26
32
  }) => {
@@ -85,17 +91,18 @@ export const PackageReleasesDashboard = ({
85
91
  </div>
86
92
  <div className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4 mt-2 text-sm text-gray-600">
87
93
  <div
88
- className="flex cursor-pointer items-center gap-1"
94
+ className={`flex items-center gap-1 ${pkg.github_repo_full_name ? "cursor-pointer" : ""}`}
89
95
  onClick={() =>
96
+ pkg.github_repo_full_name &&
90
97
  window?.open(
91
- `https://github.com/${pkg.github_repo_full_name}/tree/${latestBuild?.branch_name || "main"}`,
98
+ `https://github.com/${pkg.github_repo_full_name}/tree/${latestRelease?.branch_name || "main"}`,
92
99
  "_blank",
93
100
  )
94
101
  }
95
102
  >
96
103
  <GitBranch className="w-4 h-4 flex-shrink-0" />
97
104
  <span className="truncate">
98
- {latestBuild?.branch_name || "main"}
105
+ {latestRelease?.branch_name || "main"}
99
106
  </span>
100
107
  </div>
101
108
  <div className="flex items-center gap-1">
@@ -115,29 +122,31 @@ export const PackageReleasesDashboard = ({
115
122
  </div>
116
123
 
117
124
  <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-2">
118
- <Button
119
- variant="outline"
120
- size="sm"
121
- className="flex items-center gap-2 justify-center min-w-[120px] h-9"
122
- onClick={() =>
123
- window.open(
124
- `https://github.com/${pkg.github_repo_full_name}`,
125
- "_blank",
126
- )
127
- }
128
- >
129
- <GitHubLogoIcon className="w-4 h-4" />
130
- <span className="hidden sm:inline">Repository</span>
131
- <span className="sm:hidden">Repository</span>
132
- </Button>
133
- {latestBuild?.preview_url && (
125
+ {pkg.github_repo_full_name && (
126
+ <Button
127
+ variant="outline"
128
+ size="sm"
129
+ className="flex items-center gap-2 justify-center min-w-[120px] h-9"
130
+ onClick={() =>
131
+ window.open(
132
+ `https://github.com/${pkg.github_repo_full_name}`,
133
+ "_blank",
134
+ )
135
+ }
136
+ >
137
+ <GitHubLogoIcon className="w-4 h-4" />
138
+ <span className="hidden sm:inline">Repository</span>
139
+ <span className="sm:hidden">Repository</span>
140
+ </Button>
141
+ )}
142
+ {latestBuild && (
134
143
  <Button
135
144
  variant="outline"
136
145
  size="sm"
137
146
  className="flex items-center gap-2 justify-center min-w-[120px] h-9"
138
147
  onClick={() =>
139
148
  window.open(
140
- `/build/${latestBuild?.package_build_id}/preview`,
149
+ `/${pkg.name}/releases/${latestBuild?.package_release_id}/preview`,
141
150
  "_blank",
142
151
  )
143
152
  }
@@ -158,15 +167,17 @@ export const PackageReleasesDashboard = ({
158
167
  </Button>
159
168
  </DropdownMenuTrigger>
160
169
  <DropdownMenuContent align="end">
161
- <DropdownMenuItem asChild>
162
- <a
163
- href={`https://github.com/${pkg.github_repo_full_name}`}
164
- target="_blank"
165
- rel="noopener noreferrer"
166
- >
167
- View Source
168
- </a>
169
- </DropdownMenuItem>
170
+ {pkg.github_repo_full_name && (
171
+ <DropdownMenuItem asChild>
172
+ <a
173
+ href={`https://github.com/${pkg.github_repo_full_name}`}
174
+ target="_blank"
175
+ rel="noopener noreferrer"
176
+ >
177
+ View Source
178
+ </a>
179
+ </DropdownMenuItem>
180
+ )}
170
181
  <DropdownMenuItem asChild>
171
182
  <a href="#" download>
172
183
  Download Build