@tscircuit/fake-snippets 0.0.101 → 0.0.103

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 (56) hide show
  1. package/api/generated-index.js +23 -1
  2. package/bun.lock +2 -2
  3. package/dist/bundle.js +530 -367
  4. package/dist/index.d.ts +29 -2
  5. package/dist/index.js +18 -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 +6 -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/github/installations/create_new_installation_redirect.ts +75 -0
  12. package/fake-snippets-api/routes/api/github/repos/list_available.ts +91 -0
  13. package/fake-snippets-api/routes/api/packages/update.ts +6 -0
  14. package/package.json +2 -2
  15. package/src/App.tsx +10 -1
  16. package/src/components/CreateReleaseDialog.tsx +124 -0
  17. package/src/components/FileSidebar.tsx +128 -23
  18. package/src/components/PackageBuildsPage/package-build-header.tsx +9 -1
  19. package/src/components/PageSearchComponent.tsx +2 -2
  20. package/src/components/SearchComponent.tsx +2 -2
  21. package/src/components/SuspenseRunFrame.tsx +2 -2
  22. package/src/components/TrendingPackagesCarousel.tsx +2 -2
  23. package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -0
  24. package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +13 -1
  25. package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +17 -0
  26. package/src/components/dialogs/GitHubRepositorySelector.tsx +183 -0
  27. package/src/components/dialogs/create-use-dialog.tsx +8 -2
  28. package/src/components/dialogs/edit-package-details-dialog.tsx +32 -3
  29. package/src/components/dialogs/view-ts-files-dialog.tsx +178 -33
  30. package/src/components/package-port/CodeAndPreview.tsx +4 -1
  31. package/src/components/package-port/CodeEditor.tsx +42 -35
  32. package/src/components/package-port/CodeEditorHeader.tsx +6 -4
  33. package/src/components/package-port/EditorNav.tsx +94 -37
  34. package/src/components/preview/BuildsList.tsx +241 -0
  35. package/src/components/preview/ConnectedPackagesList.tsx +187 -0
  36. package/src/components/preview/ConnectedRepoDashboard.tsx +243 -0
  37. package/src/components/preview/ConnectedRepoOverview.tsx +454 -0
  38. package/src/components/preview/index.tsx +248 -0
  39. package/src/components/ui/tree-view.tsx +23 -6
  40. package/src/hooks/use-axios.ts +2 -2
  41. package/src/hooks/use-create-release-dialog.ts +160 -0
  42. package/src/hooks/use-package-details-form.ts +7 -0
  43. package/src/hooks/use-packages-base-api-url.ts +1 -1
  44. package/src/hooks/use-sign-in.ts +2 -2
  45. package/src/hooks/useFileManagement.ts +22 -2
  46. package/src/index.css +4 -0
  47. package/src/lib/utils/formatTimeAgo.ts +10 -0
  48. package/src/lib/utils/isValidFileName.ts +15 -3
  49. package/src/pages/dashboard.tsx +2 -2
  50. package/src/pages/dev-login.tsx +2 -2
  51. package/src/pages/latest.tsx +2 -2
  52. package/src/pages/preview-build.tsx +380 -0
  53. package/src/pages/search.tsx +2 -2
  54. package/src/pages/trending.tsx +2 -2
  55. package/src/pages/user-profile.tsx +40 -24
  56. package/src/pages/view-connected-repo.tsx +18 -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">Logs</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">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
+ }
@@ -0,0 +1,248 @@
1
+ export { ConnectedRepoOverview } from "./ConnectedRepoOverview"
2
+ export { BuildsList } from "./BuildsList"
3
+ export { ConnectedRepoDashboard } from "./ConnectedRepoDashboard"
4
+
5
+ export const getBuildStatus = (build: PackageBuild) => {
6
+ if (
7
+ build.build_error ||
8
+ build.transpilation_error ||
9
+ build.circuit_json_build_error
10
+ ) {
11
+ return { status: "error", label: "Failed" }
12
+ }
13
+ if (
14
+ build.build_in_progress ||
15
+ build.transpilation_in_progress ||
16
+ build.circuit_json_build_in_progress
17
+ ) {
18
+ return { status: "building", label: "Building" }
19
+ }
20
+ if (build.build_completed_at && build.transpilation_completed_at) {
21
+ return { status: "success", label: "Ready" }
22
+ }
23
+ return { status: "queued", label: "Queued" }
24
+ }
25
+
26
+ export interface PackageBuild {
27
+ package_build_id: string
28
+ package_release_id: string | null
29
+ created_at: string
30
+ transpilation_in_progress: boolean
31
+ transpilation_started_at: string | null
32
+ transpilation_completed_at: string | null
33
+ transpilation_logs: any[]
34
+ transpilation_error: string | null
35
+ circuit_json_build_in_progress: boolean
36
+ circuit_json_build_started_at: string | null
37
+ circuit_json_build_completed_at: string | null
38
+ circuit_json_build_logs: any[]
39
+ circuit_json_build_error: string | null
40
+ build_in_progress: boolean
41
+ build_started_at: string | null
42
+ build_completed_at: string | null
43
+ build_error: string | null
44
+ build_error_last_updated_at: string
45
+ preview_url: string | null
46
+ build_logs: string | null
47
+ branch_name: string | null
48
+ commit_message: string | null
49
+ commit_author: string | null
50
+ }
51
+
52
+ export const MOCK_DEPLOYMENTS: PackageBuild[] = [
53
+ {
54
+ package_build_id: "pb_1a2b3c4d",
55
+ package_release_id: "pr_5e6f7g8h",
56
+ created_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(),
57
+ transpilation_in_progress: false,
58
+ transpilation_started_at: new Date(
59
+ Date.now() - 1000 * 60 * 35,
60
+ ).toISOString(),
61
+ transpilation_completed_at: new Date(
62
+ Date.now() - 1000 * 60 * 32,
63
+ ).toISOString(),
64
+ transpilation_logs: [],
65
+ transpilation_error: null,
66
+ circuit_json_build_in_progress: false,
67
+ circuit_json_build_started_at: new Date(
68
+ Date.now() - 1000 * 60 * 32,
69
+ ).toISOString(),
70
+ circuit_json_build_completed_at: new Date(
71
+ Date.now() - 1000 * 60 * 30,
72
+ ).toISOString(),
73
+ circuit_json_build_logs: [],
74
+ circuit_json_build_error: null,
75
+ build_in_progress: false,
76
+ build_started_at: new Date(Date.now() - 1000 * 60 * 30).toISOString(),
77
+ build_completed_at: new Date(Date.now() - 1000 * 60 * 25).toISOString(),
78
+ build_error: null,
79
+ build_error_last_updated_at: new Date(
80
+ Date.now() - 1000 * 60 * 25,
81
+ ).toISOString(),
82
+ build_logs: null,
83
+ preview_url: "https://preview.tscircuit.com/pb_1a2b3c4d",
84
+ branch_name: "main",
85
+ commit_message: "Add new LED component with improved brightness control",
86
+ commit_author: "john.doe",
87
+ },
88
+ {
89
+ package_build_id: "pb_9i8j7k6l",
90
+ package_release_id: "pr_5m4n3o2p",
91
+ created_at: new Date(Date.now() - 1000 * 60 * 60 * 2).toISOString(),
92
+ transpilation_in_progress: false,
93
+ transpilation_started_at: new Date(
94
+ Date.now() - 1000 * 60 * 60 * 2,
95
+ ).toISOString(),
96
+ transpilation_completed_at: new Date(
97
+ Date.now() - 1000 * 60 * 60 * 2 + 1000 * 60 * 3,
98
+ ).toISOString(),
99
+ transpilation_logs: [],
100
+ transpilation_error: null,
101
+ circuit_json_build_in_progress: true,
102
+ circuit_json_build_started_at: new Date(
103
+ Date.now() - 1000 * 60 * 5,
104
+ ).toISOString(),
105
+ circuit_json_build_completed_at: null,
106
+ circuit_json_build_logs: [],
107
+ circuit_json_build_error: null,
108
+ build_in_progress: false,
109
+ build_started_at: null,
110
+ build_completed_at: null,
111
+ build_error: null,
112
+ build_error_last_updated_at: new Date(
113
+ Date.now() - 1000 * 60 * 60 * 2,
114
+ ).toISOString(),
115
+ build_logs: null,
116
+ preview_url: null,
117
+ branch_name: "feature/resistor-update",
118
+ commit_message: "Update resistor component with new tolerance values",
119
+ commit_author: "jane.smith",
120
+ },
121
+ {
122
+ package_build_id: "pb_1q2w3e4r",
123
+ package_release_id: "pr_5t6y7u8i",
124
+ created_at: new Date(Date.now() - 1000 * 60 * 60 * 6).toISOString(),
125
+ transpilation_in_progress: false,
126
+ transpilation_started_at: new Date(
127
+ Date.now() - 1000 * 60 * 60 * 6,
128
+ ).toISOString(),
129
+ transpilation_completed_at: new Date(
130
+ Date.now() - 1000 * 60 * 60 * 6 + 1000 * 60 * 2,
131
+ ).toISOString(),
132
+ transpilation_logs: [],
133
+ transpilation_error:
134
+ "TypeScript compilation failed: Cannot find module 'missing-dependency'",
135
+ circuit_json_build_in_progress: false,
136
+ circuit_json_build_started_at: null,
137
+ circuit_json_build_completed_at: null,
138
+ circuit_json_build_logs: [],
139
+ circuit_json_build_error: null,
140
+ build_in_progress: false,
141
+ build_started_at: null,
142
+ build_completed_at: null,
143
+ build_error: null,
144
+ build_error_last_updated_at: new Date(
145
+ Date.now() - 1000 * 60 * 60 * 6,
146
+ ).toISOString(),
147
+ build_logs: null,
148
+ preview_url: null,
149
+ branch_name: "hotfix/critical-bug",
150
+ commit_message: "Fix critical issue with capacitor placement",
151
+ commit_author: "alex.wilson",
152
+ },
153
+ {
154
+ package_build_id: "pb_9o8i7u6y",
155
+ package_release_id: "pr_5t4r3e2w",
156
+ created_at: new Date(Date.now() - 1000 * 60 * 60 * 24).toISOString(),
157
+ transpilation_in_progress: false,
158
+ transpilation_started_at: new Date(
159
+ Date.now() - 1000 * 60 * 60 * 24,
160
+ ).toISOString(),
161
+ transpilation_completed_at: new Date(
162
+ Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 4,
163
+ ).toISOString(),
164
+ transpilation_logs: [],
165
+ transpilation_error: null,
166
+ circuit_json_build_in_progress: false,
167
+ circuit_json_build_started_at: new Date(
168
+ Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 4,
169
+ ).toISOString(),
170
+ circuit_json_build_completed_at: new Date(
171
+ Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 8,
172
+ ).toISOString(),
173
+ circuit_json_build_logs: [],
174
+ circuit_json_build_error: null,
175
+ build_in_progress: false,
176
+ build_started_at: new Date(
177
+ Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 8,
178
+ ).toISOString(),
179
+ build_completed_at: new Date(
180
+ Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 12,
181
+ ).toISOString(),
182
+ build_error: null,
183
+ build_error_last_updated_at: new Date(
184
+ Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 12,
185
+ ).toISOString(),
186
+ build_logs: null,
187
+ preview_url: "https://preview.tscircuit.com/pb_9o8i7u6y",
188
+ branch_name: "main",
189
+ commit_message: "Initial project setup with basic components",
190
+ commit_author: "sarah.johnson",
191
+ },
192
+ ]
193
+
194
+ import { Package, PackageRelease } from "fake-snippets-api/lib/db/schema"
195
+ import { Clock, CheckCircle, AlertCircle, Loader2 } from "lucide-react"
196
+ export const StatusIcon = ({ status }: { status: string }) => {
197
+ switch (status) {
198
+ case "success":
199
+ return <CheckCircle className="w-4 h-4 text-green-500" />
200
+ case "error":
201
+ return <AlertCircle className="w-4 h-4 text-red-500" />
202
+ case "building":
203
+ return <Loader2 className="w-4 h-4 text-blue-500 animate-spin" />
204
+ default:
205
+ return <Clock className="w-4 h-4 text-gray-500" />
206
+ }
207
+ }
208
+
209
+ export const getLatestBuildForPackage = (pkg: Package): PackageBuild => {
210
+ return MOCK_DEPLOYMENTS[0]
211
+ }
212
+ export const getLatestBuildFromPackageRelease = (
213
+ pkg: PackageRelease,
214
+ ): PackageBuild => {
215
+ return MOCK_DEPLOYMENTS[0]
216
+ }
217
+ export const getPackageFromBuild = (build: PackageBuild): Package => {
218
+ return {
219
+ ai_description: "placeholder ai description",
220
+ ai_usage_instructions: "placeholder ai usage instructions",
221
+ created_at: "2025-08-06T14:37:05.802Z",
222
+ creator_account_id: "account-1234",
223
+ default_view: "files",
224
+ description: "placeholder ai description",
225
+ github_repo_full_name: "testuser/pcb-designs",
226
+ is_board: false,
227
+ is_footprint: false,
228
+ is_model: false,
229
+ is_package: false,
230
+ is_private: false,
231
+ is_public: true,
232
+ is_snippet: false,
233
+ is_source_from_github: false,
234
+ is_unlisted: false,
235
+ latest_package_release_fs_sha: "md5-425b47ef26be8f0863eca9e63e516dfa",
236
+ latest_package_release_id: "package_release_1754491026466",
237
+ latest_version: "0.0.1",
238
+ license: null,
239
+ name: "testuser/untitled-package-0",
240
+ owner_github_username: "testuser",
241
+ owner_org_id: "org-1234",
242
+ package_id: "package_1754491025802",
243
+ star_count: 0,
244
+ unscoped_name: "untitled-package-0",
245
+ updated_at: "2025-08-06T14:37:25.083Z",
246
+ website: "",
247
+ }
248
+ }