@tscircuit/fake-snippets 0.0.109 → 0.0.110
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/.github/workflows/bun-formatcheck.yml +2 -2
- package/.github/workflows/bun-pver-release.yml +3 -3
- package/.github/workflows/bun-test.yml +1 -1
- package/.github/workflows/bun-typecheck.yml +2 -2
- package/.github/workflows/update-snapshots.yml +1 -1
- package/README.md +4 -0
- package/api/generated-index.js +37 -3
- package/biome.json +2 -1
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +31 -3
- package/bun-tests/fake-snippets-api/fixtures/preload.ts +18 -0
- package/bun-tests/fake-snippets-api/routes/orgs/add_member.test.ts +26 -0
- package/bun-tests/fake-snippets-api/routes/orgs/create.test.ts +37 -0
- package/bun-tests/fake-snippets-api/routes/orgs/get.test.ts +52 -0
- package/bun-tests/fake-snippets-api/routes/orgs/list.test.ts +17 -0
- package/bun-tests/fake-snippets-api/routes/orgs/list_members.test.ts +23 -0
- package/bun-tests/fake-snippets-api/routes/orgs/remove_member.test.ts +81 -0
- package/bun-tests/fake-snippets-api/routes/orgs/update.test.ts +99 -0
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +1 -1
- package/bun-tests/fake-snippets-api/routes/package_files/create.test.ts +15 -13
- package/bun-tests/fake-snippets-api/routes/package_files/create_or_update.test.ts +26 -24
- package/bun-tests/fake-snippets-api/routes/package_files/delete.test.ts +9 -9
- package/bun-tests/fake-snippets-api/routes/package_files/download.test.ts +4 -4
- package/bun-tests/fake-snippets-api/routes/package_files/get.test.ts +38 -28
- package/bun-tests/fake-snippets-api/routes/package_files/list.test.ts +23 -15
- package/bun-tests/fake-snippets-api/routes/package_releases/create.test.ts +33 -0
- package/bun-tests/fake-snippets-api/routes/package_releases/get.test.ts +4 -4
- package/bun-tests/fake-snippets-api/routes/package_releases/get_image_generation_fields.test.ts +38 -0
- package/bun-tests/fake-snippets-api/routes/packages/create.test.ts +19 -0
- package/bun-tests/fake-snippets-api/routes/packages/fork.test.ts +3 -4
- package/bun-tests/fake-snippets-api/routes/packages/get.test.ts +30 -0
- package/bun-tests/fake-snippets-api/routes/packages/images.test.ts +4 -2
- package/bun-tests/fake-snippets-api/routes/packages/list-1.test.ts +34 -0
- package/bun.lock +349 -453
- package/bunfig.toml +2 -1
- package/dist/bundle.js +1253 -624
- package/dist/index.d.ts +291 -4
- package/dist/index.js +323 -23
- package/dist/schema.d.ts +274 -1
- package/dist/schema.js +52 -1
- package/fake-snippets-api/lib/db/autoload-dev-packages.ts +31 -20
- package/fake-snippets-api/lib/db/db-client.ts +214 -3
- package/fake-snippets-api/lib/db/schema.ts +61 -0
- package/fake-snippets-api/lib/db/seed.ts +100 -0
- package/fake-snippets-api/lib/middleware/with-session-auth.ts +1 -1
- package/fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor.ts +2 -2
- package/fake-snippets-api/lib/public-mapping/public-map-org.ts +32 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +10 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +17 -0
- package/fake-snippets-api/routes/api/orgs/add_member.ts +52 -0
- package/fake-snippets-api/routes/api/orgs/create.ts +46 -0
- package/fake-snippets-api/routes/api/orgs/get.ts +39 -0
- package/fake-snippets-api/routes/api/orgs/list.ts +31 -0
- package/fake-snippets-api/routes/api/orgs/list_members.ts +67 -0
- package/fake-snippets-api/routes/api/orgs/remove_member.ts +46 -0
- package/fake-snippets-api/routes/api/orgs/update.ts +93 -0
- package/fake-snippets-api/routes/api/package_files/get.ts +3 -6
- package/fake-snippets-api/routes/api/package_files/list.ts +7 -4
- package/fake-snippets-api/routes/api/packages/create.ts +54 -10
- package/fake-snippets-api/routes/api/packages/get.ts +23 -0
- package/fake-snippets-api/routes/api/packages/images/[owner_github_username]/[unscoped_name]/[view_format].ts +13 -11
- package/fake-snippets-api/routes/api/packages/list.ts +29 -2
- package/fake-snippets-api/routes/api/packages/update_ai_description.ts +37 -0
- package/package.json +24 -20
- package/renovate.json +1 -1
- package/scripts/generate-sitemap.ts +1 -1
- package/src/App.tsx +29 -8
- package/src/ContextProviders.tsx +25 -2
- package/src/components/CircuitJsonImportDialog.tsx +1 -1
- package/src/components/CmdKMenu.tsx +281 -247
- package/src/components/DownloadButtonAndMenu.tsx +3 -4
- package/src/components/FileSidebar.tsx +11 -17
- package/src/components/Footer.tsx +8 -9
- package/src/components/Header.tsx +19 -32
- package/src/components/Header2.tsx +16 -32
- package/src/components/HeaderDropdown.tsx +13 -8
- package/src/components/HeaderLogin.tsx +43 -15
- package/src/components/NotFound.tsx +5 -5
- package/src/components/PackageBreadcrumb.tsx +6 -12
- package/src/components/PackageSearchResults.tsx +1 -1
- package/src/components/PrefetchPageLink.tsx +7 -1
- package/src/components/ProfileRouter.tsx +32 -0
- package/src/components/SearchComponent.tsx +12 -8
- package/src/components/UserCard.tsx +80 -0
- package/src/components/ViewPackagePage/components/build-status.tsx +1 -1
- package/src/components/ViewPackagePage/components/important-files-view.tsx +105 -34
- package/src/components/ViewPackagePage/components/main-content-header.tsx +10 -6
- package/src/components/ViewPackagePage/components/main-content-view-selector.tsx +1 -1
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +54 -19
- package/src/components/ViewPackagePage/components/package-header.tsx +25 -33
- package/src/components/ViewPackagePage/components/preview-image-squares.tsx +11 -18
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +12 -5
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +16 -10
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +11 -11
- package/src/components/ViewPackagePage/components/tab-views/pcb-view.tsx +1 -2
- package/src/components/ViewPackagePage/components/tab-views/schematic-view.tsx +2 -1
- package/src/components/dialogs/GitHubRepositorySelector.tsx +56 -49
- package/src/components/dialogs/edit-package-details-dialog.tsx +5 -6
- package/src/components/dialogs/import-component-dialog.tsx +16 -9
- package/src/components/dialogs/import-package-dialog.tsx +3 -2
- package/src/components/dialogs/new-package-save-prompt-dialog.tsx +190 -0
- package/src/components/organization/OrganizationCard.tsx +204 -0
- package/src/components/organization/OrganizationCardSkeleton.tsx +55 -0
- package/src/components/organization/OrganizationHeader.tsx +154 -0
- package/src/components/organization/OrganizationMembers.tsx +146 -0
- package/src/components/package-port/CodeAndPreview.tsx +15 -12
- package/src/components/package-port/CodeEditor.tsx +4 -30
- package/src/components/package-port/CodeEditorHeader.tsx +123 -61
- package/src/components/package-port/EditorNav.tsx +32 -49
- package/src/components/preview/ConnectedPackagesList.tsx +8 -8
- package/src/components/preview/ConnectedRepoOverview.tsx +102 -2
- package/src/components/preview/PackageReleasesDashboard.tsx +23 -11
- package/src/components/ui/tree-view.tsx +6 -3
- package/src/hooks/use-add-org-member-mutation.ts +51 -0
- package/src/hooks/use-create-org-mutation.ts +38 -0
- package/src/hooks/use-create-package-mutation.ts +3 -0
- package/src/hooks/use-current-package-release.ts +4 -3
- package/src/hooks/use-download-zip.ts +2 -2
- package/src/hooks/use-global-store.ts +6 -4
- package/src/hooks/use-jlcpcb-component-import.tsx +164 -0
- package/src/hooks/use-list-org-members.ts +27 -0
- package/src/hooks/use-list-user-orgs.ts +25 -0
- package/src/hooks/use-org-by-github-handle.ts +26 -0
- package/src/hooks/use-org.ts +24 -0
- package/src/hooks/use-organization.ts +42 -0
- package/src/hooks/use-package-as-snippet.ts +4 -2
- package/src/hooks/use-package-builds.ts +6 -2
- package/src/hooks/use-package-files.ts +5 -3
- package/src/hooks/use-package-release-by-id-or-version.ts +29 -20
- package/src/hooks/use-package-release-images.ts +105 -0
- package/src/hooks/use-package-release.ts +2 -2
- package/src/hooks/use-package-stars.ts +80 -4
- package/src/hooks/use-preview-images.ts +6 -3
- package/src/hooks/use-remove-org-member-mutation.ts +32 -0
- package/src/hooks/use-update-ai-description-mutation.ts +42 -0
- package/src/hooks/use-update-org-mutation.ts +41 -0
- package/src/hooks/use-warn-user-on-page-change.ts +71 -4
- package/src/hooks/useFileManagement.ts +51 -22
- package/src/hooks/useOptimizedPackageFilesLoader.ts +11 -24
- package/src/hooks/usePackageFilesLoader.ts +2 -2
- package/src/hooks/useUpdatePackageFilesMutation.ts +13 -1
- package/src/lib/download-fns/download-gltf-from-circuit-json.ts +1 -1
- package/src/lib/download-fns/download-kicad-files.ts +12 -11
- package/src/lib/normalize-svg-for-tile.ts +50 -0
- package/src/lib/posthog.ts +11 -9
- package/src/lib/react-query-api-failure-tracking.ts +148 -0
- package/src/lib/sentry.ts +14 -0
- package/src/lib/templates/blank-circuit-board-template.ts +0 -4
- package/src/lib/ts-lib-cache.ts +122 -7
- package/src/lib/utils/checkIfManualEditsImported.ts +4 -4
- package/src/lib/utils/findTargetFile.ts +45 -10
- package/src/lib/utils/isComponentExported.ts +2 -1
- package/src/main.tsx +2 -1
- package/src/pages/create-organization.tsx +168 -0
- package/src/pages/dashboard.tsx +38 -6
- package/src/pages/datasheet.tsx +1 -1
- package/src/pages/datasheets.tsx +3 -3
- package/src/pages/editor.tsx +4 -6
- package/src/pages/landing.tsx +6 -6
- package/src/pages/latest.tsx +3 -0
- package/src/pages/organization-profile.tsx +199 -0
- package/src/pages/organization-settings.tsx +566 -0
- package/src/pages/package-editor.tsx +21 -21
- package/src/pages/preview-release.tsx +75 -145
- package/src/pages/quickstart.tsx +159 -123
- package/src/pages/release-detail.tsx +119 -31
- package/src/pages/search.tsx +192 -57
- package/src/pages/settings-redirect.tsx +44 -0
- package/src/pages/trending.tsx +29 -20
- package/src/pages/user-profile.tsx +58 -7
- package/src/pages/view-package.tsx +7 -13
- package/vite.config.ts +9 -0
- package/fake-snippets-api/routes/api/autocomplete/create_autocomplete.ts +0 -133
- package/src/components/JLCPCBImportDialog.tsx +0 -280
- package/src/components/PackageBuildsPage/LogContent.tsx +0 -72
- package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +0 -113
- package/src/components/PackageBuildsPage/build-preview-content.tsx +0 -56
- package/src/components/PackageBuildsPage/collapsible-section.tsx +0 -63
- package/src/components/PackageBuildsPage/package-build-details-panel.tsx +0 -166
- package/src/components/PackageBuildsPage/package-build-header.tsx +0 -79
- package/src/components/PageSearchComponent.tsx +0 -148
- package/src/pages/package-builds.tsx +0 -33
package/src/pages/quickstart.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useQuery } from "react-query"
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react"
|
|
2
|
+
import { useQuery, useQueryClient } from "react-query"
|
|
3
3
|
import { useAxios } from "@/hooks/use-axios"
|
|
4
4
|
import Header from "@/components/Header"
|
|
5
5
|
import Footer from "@/components/Footer"
|
|
@@ -7,35 +7,64 @@ import { Package } from "fake-snippets-api/lib/db/schema"
|
|
|
7
7
|
import { Button } from "@/components/ui/button"
|
|
8
8
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|
9
9
|
import { TypeBadge } from "@/components/TypeBadge"
|
|
10
|
-
import { JLCPCBImportDialog } from "@/components/JLCPCBImportDialog"
|
|
11
10
|
import { CircuitJsonImportDialog } from "@/components/CircuitJsonImportDialog"
|
|
12
|
-
import { useNotImplementedToast } from "@/hooks/use-toast"
|
|
13
11
|
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
12
|
+
import { useImportComponentDialog } from "@/components/dialogs/import-component-dialog"
|
|
13
|
+
import { useJlcpcbComponentImport } from "@/hooks/use-jlcpcb-component-import"
|
|
14
|
+
import { JlcpcbComponentTsxLoadedPayload } from "@tscircuit/runframe/runner"
|
|
14
15
|
import { cn } from "@/lib/utils"
|
|
15
|
-
import {
|
|
16
|
+
import { Link } from "wouter"
|
|
17
|
+
import { Loader2 } from "lucide-react"
|
|
16
18
|
|
|
17
19
|
export const QuickstartPage = () => {
|
|
18
20
|
const axios = useAxios()
|
|
19
|
-
const
|
|
21
|
+
const queryClient = useQueryClient()
|
|
20
22
|
const [isCircuitJsonImportDialogOpen, setIsCircuitJsonImportDialogOpen] =
|
|
21
23
|
useState(false)
|
|
22
|
-
const
|
|
23
|
-
const currentUser =
|
|
24
|
+
const session = useGlobalStore((s) => s.session)
|
|
25
|
+
const currentUser = session?.github_username
|
|
26
|
+
const isLoggedIn = Boolean(currentUser)
|
|
27
|
+
const { Dialog: ImportComponentDialog, openDialog: openImportDialog } =
|
|
28
|
+
useImportComponentDialog()
|
|
29
|
+
const { importComponent: importJlcpcbComponent } = useJlcpcbComponentImport()
|
|
30
|
+
const jlcpcbProxyRequestHeaders = useMemo(
|
|
31
|
+
() =>
|
|
32
|
+
session?.token
|
|
33
|
+
? {
|
|
34
|
+
Authorization: `Bearer ${session.token}`,
|
|
35
|
+
}
|
|
36
|
+
: undefined,
|
|
37
|
+
[session?.token],
|
|
38
|
+
)
|
|
39
|
+
const handleJlcpcbComponentSelected = useCallback(
|
|
40
|
+
async (payload: JlcpcbComponentTsxLoadedPayload) => {
|
|
41
|
+
await importJlcpcbComponent(payload)
|
|
42
|
+
},
|
|
43
|
+
[importJlcpcbComponent],
|
|
44
|
+
)
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
queryClient.removeQueries("userPackages")
|
|
47
|
+
}, [queryClient])
|
|
24
48
|
const { data: myPackages, isLoading } = useQuery<Package[]>(
|
|
25
|
-
"userPackages",
|
|
49
|
+
["userPackages", currentUser],
|
|
26
50
|
async () => {
|
|
27
51
|
const response = await axios.post(`/packages/list`, {
|
|
28
52
|
owner_github_username: currentUser,
|
|
29
53
|
})
|
|
30
54
|
return response.data.packages
|
|
31
55
|
},
|
|
56
|
+
{
|
|
57
|
+
enabled: isLoggedIn,
|
|
58
|
+
},
|
|
32
59
|
)
|
|
33
60
|
|
|
34
|
-
const blankTemplates
|
|
61
|
+
const blankTemplates: Array<{
|
|
62
|
+
name: string
|
|
63
|
+
type: string
|
|
64
|
+
disabled?: boolean
|
|
65
|
+
}> = [
|
|
35
66
|
{ name: "Blank Circuit Board", type: "board" },
|
|
36
67
|
{ name: "Blank Circuit Module", type: "package" },
|
|
37
|
-
{ name: "Blank 3D Model", type: "model", disabled: true },
|
|
38
|
-
{ name: "Blank Footprint", type: "footprint", disabled: true },
|
|
39
68
|
]
|
|
40
69
|
|
|
41
70
|
const templates = [
|
|
@@ -44,51 +73,63 @@ export const QuickstartPage = () => {
|
|
|
44
73
|
]
|
|
45
74
|
|
|
46
75
|
return (
|
|
47
|
-
<div>
|
|
76
|
+
<div className="min-h-screen">
|
|
48
77
|
<Header />
|
|
49
|
-
<div className="container mx-auto px-
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
{myPackages
|
|
57
|
-
?.sort(
|
|
58
|
-
(a, b) =>
|
|
59
|
-
new Date(b.created_at).getTime() -
|
|
60
|
-
new Date(a.created_at).getTime(),
|
|
61
|
-
)
|
|
62
|
-
.slice(0, 4)
|
|
63
|
-
.map((pkg) => (
|
|
64
|
-
<PrefetchPageLink
|
|
65
|
-
key={pkg.package_id}
|
|
66
|
-
href={`/editor?package_id=${pkg.package_id}`}
|
|
67
|
-
>
|
|
68
|
-
<Card className="hover:shadow-md transition-shadow rounded-md flex flex-col h-full">
|
|
69
|
-
<CardHeader className="pb-0 p-4">
|
|
70
|
-
<CardTitle className="text-md">
|
|
71
|
-
{pkg.unscoped_name}
|
|
72
|
-
</CardTitle>
|
|
73
|
-
</CardHeader>
|
|
74
|
-
<CardContent className="p-4 pt-0 mt-auto">
|
|
75
|
-
<p className="text-sm text-gray-500">
|
|
76
|
-
Last edited:{" "}
|
|
77
|
-
{new Date(pkg.updated_at).toLocaleDateString()}
|
|
78
|
-
</p>
|
|
79
|
-
</CardContent>
|
|
80
|
-
</Card>
|
|
81
|
-
</PrefetchPageLink>
|
|
82
|
-
))}
|
|
78
|
+
<div className="container mx-auto px-6 py-12">
|
|
79
|
+
{isLoggedIn && (
|
|
80
|
+
<div className="mb-16 hidden md:block">
|
|
81
|
+
<div className="mb-8">
|
|
82
|
+
<h2 className="text-2xl font-semibold text-slate-900">
|
|
83
|
+
Recent Packages
|
|
84
|
+
</h2>
|
|
83
85
|
</div>
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
{isLoading ? (
|
|
87
|
+
<div className="flex items-center justify-center py-12">
|
|
88
|
+
<Loader2 className="w-10 h-10 animate-spin text-blue-500 mb-4" />
|
|
89
|
+
</div>
|
|
90
|
+
) : (
|
|
91
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
92
|
+
{myPackages
|
|
93
|
+
?.sort(
|
|
94
|
+
(a, b) =>
|
|
95
|
+
new Date(b.created_at).getTime() -
|
|
96
|
+
new Date(a.created_at).getTime(),
|
|
97
|
+
)
|
|
98
|
+
.slice(0, 4)
|
|
99
|
+
.map((pkg) => (
|
|
100
|
+
<Link
|
|
101
|
+
key={pkg.package_id}
|
|
102
|
+
href={`/editor?package_id=${pkg.package_id}`}
|
|
103
|
+
>
|
|
104
|
+
<Card className="hover:shadow-md border bg-white shadow-sm transition-shadow flex flex-col h-full rounded-md">
|
|
105
|
+
<CardHeader>
|
|
106
|
+
<CardTitle className="text-lg font-semibold text-slate-900">
|
|
107
|
+
{pkg.unscoped_name}
|
|
108
|
+
</CardTitle>
|
|
109
|
+
</CardHeader>
|
|
110
|
+
<CardContent className="-mt-4">
|
|
111
|
+
<p className="text-sm text-slate-500">
|
|
112
|
+
Last edited{" "}
|
|
113
|
+
{new Date(pkg.updated_at).toLocaleDateString()}
|
|
114
|
+
</p>
|
|
115
|
+
</CardContent>
|
|
116
|
+
</Card>
|
|
117
|
+
</Link>
|
|
118
|
+
))}
|
|
119
|
+
</div>
|
|
120
|
+
)}
|
|
121
|
+
</div>
|
|
122
|
+
)}
|
|
86
123
|
|
|
87
|
-
<div className="mb-
|
|
88
|
-
<
|
|
89
|
-
|
|
124
|
+
<div className="mb-16">
|
|
125
|
+
<div className="mb-8">
|
|
126
|
+
<h2 className="text-2xl font-semibold text-slate-900">
|
|
127
|
+
Start Blank
|
|
128
|
+
</h2>
|
|
129
|
+
</div>
|
|
130
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
90
131
|
{blankTemplates.map((template, index) => (
|
|
91
|
-
<
|
|
132
|
+
<Link
|
|
92
133
|
key={index}
|
|
93
134
|
href={
|
|
94
135
|
template.disabled
|
|
@@ -100,90 +141,81 @@ export const QuickstartPage = () => {
|
|
|
100
141
|
>
|
|
101
142
|
<Card
|
|
102
143
|
className={cn(
|
|
103
|
-
"hover:shadow-md transition-shadow
|
|
144
|
+
"hover:shadow-md border bg-white transition-shadow h-full flex flex-col rounded-md",
|
|
104
145
|
template.disabled && "opacity-50 cursor-not-allowed",
|
|
105
146
|
)}
|
|
106
147
|
>
|
|
107
|
-
<CardHeader className="p-
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
|
|
148
|
+
<CardHeader className="p-6 flex-grow flex flex-col justify-between">
|
|
149
|
+
<div>
|
|
150
|
+
<CardTitle className="text-lg font-semibold text-slate-900 mb-3">
|
|
151
|
+
{template.name}
|
|
152
|
+
</CardTitle>
|
|
153
|
+
<div className="flex justify-between items-center">
|
|
154
|
+
<TypeBadge type={template.type as any} />
|
|
155
|
+
</div>
|
|
111
156
|
</div>
|
|
112
157
|
</CardHeader>
|
|
113
158
|
</Card>
|
|
114
|
-
</
|
|
159
|
+
</Link>
|
|
115
160
|
))}
|
|
116
161
|
</div>
|
|
117
162
|
</div>
|
|
118
163
|
|
|
119
|
-
<div className="
|
|
120
|
-
<
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
<CardHeader className="p-4 pb-0">
|
|
132
|
-
<CardTitle className="text-lg flex items-center justify-between">
|
|
133
|
-
{template.name}
|
|
134
|
-
<TypeBadge type={template.type as any} className="ml-2" />
|
|
164
|
+
<div className="mb-16">
|
|
165
|
+
<div className="mb-8">
|
|
166
|
+
<h2 className="text-2xl font-semibold text-slate-900">
|
|
167
|
+
Import Components
|
|
168
|
+
</h2>
|
|
169
|
+
</div>
|
|
170
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
171
|
+
<Card className="hover:shadow-md border bg-white transition-shadow flex flex-col rounded-md">
|
|
172
|
+
<CardHeader className="p-6 pb-4">
|
|
173
|
+
<div className="flex items-center justify-between mb-2">
|
|
174
|
+
<CardTitle className="text-lg font-semibold text-slate-900">
|
|
175
|
+
JLCPCB Component
|
|
135
176
|
</CardTitle>
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
toastNotImplemented("Kicad Imports")
|
|
142
|
-
}}
|
|
143
|
-
>
|
|
144
|
-
Import {template.name}
|
|
145
|
-
</Button>
|
|
146
|
-
</CardContent>
|
|
147
|
-
</Card>
|
|
148
|
-
))} */}
|
|
149
|
-
<Card className="hover:shadow-md transition-shadow rounded-md flex flex-col">
|
|
150
|
-
<CardHeader className="p-4 pb-0">
|
|
151
|
-
<CardTitle className="text-lg flex items-center justify-between">
|
|
152
|
-
JLCPCB Component
|
|
153
|
-
<TypeBadge type="package" className="ml-2" />
|
|
154
|
-
</CardTitle>
|
|
177
|
+
<TypeBadge type="package" />
|
|
178
|
+
</div>
|
|
179
|
+
<p className="text-sm text-slate-500">
|
|
180
|
+
Import components from JLCPCB library
|
|
181
|
+
</p>
|
|
155
182
|
</CardHeader>
|
|
156
|
-
<CardContent className="p-
|
|
183
|
+
<CardContent className="p-6 pt-0 mt-auto">
|
|
157
184
|
<Button
|
|
158
|
-
className="w-full"
|
|
159
|
-
onClick={() =>
|
|
185
|
+
className="w-full text-white"
|
|
186
|
+
onClick={() => openImportDialog()}
|
|
160
187
|
>
|
|
161
|
-
Import JLCPCB
|
|
188
|
+
Import JLCPCB
|
|
162
189
|
</Button>
|
|
163
190
|
</CardContent>
|
|
164
191
|
</Card>
|
|
165
|
-
<Card className="hover:shadow-md transition-shadow
|
|
166
|
-
<CardHeader className="p-
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
192
|
+
<Card className="hover:shadow-md border bg-white transition-shadow flex flex-col rounded-md">
|
|
193
|
+
<CardHeader className="p-6 pb-4">
|
|
194
|
+
<div className="flex items-center justify-between mb-2">
|
|
195
|
+
<CardTitle className="text-lg font-semibold text-slate-900">
|
|
196
|
+
Circuit JSON
|
|
197
|
+
</CardTitle>
|
|
198
|
+
<TypeBadge type="package" />
|
|
199
|
+
</div>
|
|
200
|
+
<p className="text-sm text-slate-500">
|
|
201
|
+
Import from Circuit JSON format
|
|
202
|
+
</p>
|
|
171
203
|
</CardHeader>
|
|
172
|
-
<CardContent className="p-
|
|
204
|
+
<CardContent className="p-6 pt-0 mt-auto">
|
|
173
205
|
<Button
|
|
174
|
-
className="w-full"
|
|
206
|
+
className="w-full text-white"
|
|
175
207
|
onClick={() => setIsCircuitJsonImportDialogOpen(true)}
|
|
176
208
|
>
|
|
177
|
-
Import
|
|
209
|
+
Import JSON
|
|
178
210
|
</Button>
|
|
179
211
|
</CardContent>
|
|
180
212
|
</Card>
|
|
181
213
|
</div>
|
|
182
214
|
</div>
|
|
183
215
|
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
216
|
+
<ImportComponentDialog
|
|
217
|
+
onJlcpcbComponentTsxLoaded={handleJlcpcbComponentSelected}
|
|
218
|
+
jlcpcbProxyRequestHeaders={jlcpcbProxyRequestHeaders}
|
|
187
219
|
/>
|
|
188
220
|
|
|
189
221
|
<CircuitJsonImportDialog
|
|
@@ -191,27 +223,31 @@ export const QuickstartPage = () => {
|
|
|
191
223
|
onOpenChange={setIsCircuitJsonImportDialogOpen}
|
|
192
224
|
/>
|
|
193
225
|
|
|
194
|
-
<div>
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
226
|
+
<div className="mb-16">
|
|
227
|
+
<div className="mb-8">
|
|
228
|
+
<h2 className="text-2xl font-semibold text-slate-900">
|
|
229
|
+
Popular Templates
|
|
230
|
+
</h2>
|
|
231
|
+
</div>
|
|
232
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
199
233
|
{templates.map((template, index) => (
|
|
200
|
-
<
|
|
234
|
+
<Link
|
|
201
235
|
key={index}
|
|
202
236
|
href={`/editor?template=${template.name
|
|
203
237
|
.toLowerCase()
|
|
204
238
|
.replace(/ /g, "-")}`}
|
|
205
239
|
>
|
|
206
|
-
<Card className="hover:shadow-md transition-shadow rounded-md">
|
|
207
|
-
<CardHeader className="p-
|
|
208
|
-
<
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
240
|
+
<Card className="hover:shadow-md border bg-white transition-shadow rounded-md">
|
|
241
|
+
<CardHeader className="p-6">
|
|
242
|
+
<div className="flex items-center justify-between ">
|
|
243
|
+
<CardTitle className="text-lg font-semibold text-slate-900">
|
|
244
|
+
{template.name}
|
|
245
|
+
</CardTitle>
|
|
246
|
+
<TypeBadge type={template.type as any} />
|
|
247
|
+
</div>
|
|
212
248
|
</CardHeader>
|
|
213
249
|
</Card>
|
|
214
|
-
</
|
|
250
|
+
</Link>
|
|
215
251
|
))}
|
|
216
252
|
</div>
|
|
217
253
|
</div>
|
|
@@ -6,10 +6,14 @@ import { usePackageBuild } from "@/hooks/use-package-builds"
|
|
|
6
6
|
import { ConnectedRepoOverview } from "@/components/preview/ConnectedRepoOverview"
|
|
7
7
|
import Header from "@/components/Header"
|
|
8
8
|
import { Badge } from "@/components/ui/badge"
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { Button } from "@/components/ui/button"
|
|
10
|
+
import { Calendar, GitBranch, RefreshCw } from "lucide-react"
|
|
11
11
|
import { formatTimeAgo } from "@/lib/utils/formatTimeAgo"
|
|
12
12
|
import { PackageBreadcrumb } from "@/components/PackageBreadcrumb"
|
|
13
|
+
import { usePackageReleaseImages } from "@/hooks/use-package-release-images"
|
|
14
|
+
import { Skeleton } from "@/components/ui/skeleton"
|
|
15
|
+
import { useRebuildPackageReleaseMutation } from "@/hooks/use-rebuild-package-release-mutation"
|
|
16
|
+
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
13
17
|
|
|
14
18
|
export default function ReleaseDetailPage() {
|
|
15
19
|
const params = useParams<{
|
|
@@ -24,8 +28,6 @@ export default function ReleaseDetailPage() {
|
|
|
24
28
|
? `${params.author}/${params.packageName}`
|
|
25
29
|
: null
|
|
26
30
|
|
|
27
|
-
const [copied, setCopied] = useState(false)
|
|
28
|
-
|
|
29
31
|
const {
|
|
30
32
|
data: pkg,
|
|
31
33
|
isLoading: isLoadingPackage,
|
|
@@ -39,16 +41,58 @@ export default function ReleaseDetailPage() {
|
|
|
39
41
|
data: packageRelease,
|
|
40
42
|
isLoading: isLoadingRelease,
|
|
41
43
|
error: releaseError,
|
|
42
|
-
} = usePackageReleaseByIdOrVersion(releaseIdOrVersion, packageName
|
|
44
|
+
} = usePackageReleaseByIdOrVersion(releaseIdOrVersion, packageName, {
|
|
45
|
+
include_logs: true,
|
|
46
|
+
})
|
|
43
47
|
|
|
44
48
|
const {
|
|
45
49
|
data: latestBuild,
|
|
46
50
|
isLoading: isLoadingBuild,
|
|
47
51
|
error: buildError,
|
|
48
|
-
} = usePackageBuild(packageRelease?.latest_package_build_id ?? null
|
|
52
|
+
} = usePackageBuild(packageRelease?.latest_package_build_id ?? null, {
|
|
53
|
+
include_logs: true,
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const { availableViews } = usePackageReleaseImages({
|
|
57
|
+
packageReleaseId: packageRelease?.package_release_id,
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const session = useGlobalStore((s) => s.session)
|
|
61
|
+
const { mutate: rebuildPackage, isLoading: isRebuildLoading } =
|
|
62
|
+
useRebuildPackageReleaseMutation()
|
|
49
63
|
|
|
50
64
|
if (isLoadingPackage || isLoadingRelease) {
|
|
51
|
-
return
|
|
65
|
+
return (
|
|
66
|
+
<>
|
|
67
|
+
<Header />
|
|
68
|
+
<div className="min-h-screen bg-white">
|
|
69
|
+
{/* Page Header Skeleton */}
|
|
70
|
+
<div className="bg-gray-50 border-b py-6">
|
|
71
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
72
|
+
<Skeleton className="h-6 w-64 mb-4" />
|
|
73
|
+
<div className="flex items-center gap-4">
|
|
74
|
+
<Skeleton className="h-4 w-20" />
|
|
75
|
+
<Skeleton className="h-4 w-32" />
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
{/* Images Skeleton */}
|
|
81
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
|
82
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
83
|
+
{[1, 2, 3].map((i) => (
|
|
84
|
+
<Skeleton key={i} className="h-48 rounded-lg" />
|
|
85
|
+
))}
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
{/* Main Content Skeleton */}
|
|
90
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
|
91
|
+
<Skeleton className="h-64 w-full" />
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</>
|
|
95
|
+
)
|
|
52
96
|
}
|
|
53
97
|
|
|
54
98
|
if (packageError?.status === 404 || !pkg) {
|
|
@@ -65,7 +109,7 @@ export default function ReleaseDetailPage() {
|
|
|
65
109
|
<div className="min-h-screen bg-white">
|
|
66
110
|
{/* Page Header */}
|
|
67
111
|
<div className="bg-gray-50 border-b py-6">
|
|
68
|
-
<div className="max-w-7xl
|
|
112
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
69
113
|
{/* Breadcrumb */}
|
|
70
114
|
<PackageBreadcrumb
|
|
71
115
|
author={pkg.owner_github_username || ""}
|
|
@@ -78,35 +122,79 @@ export default function ReleaseDetailPage() {
|
|
|
78
122
|
/>
|
|
79
123
|
|
|
80
124
|
{/* Header Content */}
|
|
81
|
-
<div className="flex flex-
|
|
82
|
-
<div className="flex-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
Created {formatTimeAgo(packageRelease.created_at)}
|
|
102
|
-
</span>
|
|
103
|
-
</div>
|
|
125
|
+
<div className="flex flex-wrap items-center justify-between gap-3 mt-4">
|
|
126
|
+
<div className="flex flex-wrap items-center gap-4 text-sm text-gray-600">
|
|
127
|
+
{packageRelease.is_pr_preview && (
|
|
128
|
+
<a
|
|
129
|
+
href={`https://github.com/${pkg.github_repo_full_name}/pull/${packageRelease.github_pr_number}`}
|
|
130
|
+
target="_blank"
|
|
131
|
+
rel="noopener noreferrer"
|
|
132
|
+
className="flex items-center gap-1 hover:text-gray-800 transition-colors"
|
|
133
|
+
>
|
|
134
|
+
<GitBranch className="w-4 h-4" />
|
|
135
|
+
<Badge variant="outline" className="text-xs">
|
|
136
|
+
PR #{packageRelease.github_pr_number}
|
|
137
|
+
</Badge>
|
|
138
|
+
</a>
|
|
139
|
+
)}
|
|
140
|
+
<div className="flex items-center gap-1">
|
|
141
|
+
<Calendar className="w-4 h-4" />
|
|
142
|
+
<span>
|
|
143
|
+
Created {formatTimeAgo(packageRelease.created_at)}
|
|
144
|
+
</span>
|
|
104
145
|
</div>
|
|
105
146
|
</div>
|
|
147
|
+
|
|
148
|
+
{/* Rebuild Button */}
|
|
149
|
+
{session?.github_username === pkg.owner_github_username && (
|
|
150
|
+
<Button
|
|
151
|
+
variant="outline"
|
|
152
|
+
size="sm"
|
|
153
|
+
className="border-gray-300 bg-white hover:bg-gray-50 flex-shrink-0"
|
|
154
|
+
disabled={isRebuildLoading || !packageRelease}
|
|
155
|
+
onClick={() =>
|
|
156
|
+
packageRelease &&
|
|
157
|
+
rebuildPackage({
|
|
158
|
+
package_release_id: packageRelease.package_release_id,
|
|
159
|
+
})
|
|
160
|
+
}
|
|
161
|
+
>
|
|
162
|
+
<RefreshCw
|
|
163
|
+
className={`w-4 h-4 mr-2 ${isRebuildLoading ? "animate-spin" : ""}`}
|
|
164
|
+
/>
|
|
165
|
+
{isRebuildLoading ? "Rebuilding..." : "Rebuild"}
|
|
166
|
+
</Button>
|
|
167
|
+
)}
|
|
106
168
|
</div>
|
|
107
169
|
</div>
|
|
108
170
|
</div>
|
|
109
171
|
|
|
172
|
+
{/* Images Section - Always show with skeletons while loading */}
|
|
173
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
|
174
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
175
|
+
{availableViews.length > 0
|
|
176
|
+
? availableViews.map((view) => (
|
|
177
|
+
<div
|
|
178
|
+
key={view.id}
|
|
179
|
+
className="flex items-center justify-center border rounded-lg bg-gray-50 overflow-hidden h-48"
|
|
180
|
+
>
|
|
181
|
+
{view.isLoading ? (
|
|
182
|
+
<Skeleton className="w-full h-full" />
|
|
183
|
+
) : (
|
|
184
|
+
<img
|
|
185
|
+
src={view.imageUrl}
|
|
186
|
+
alt={`${view.label} preview`}
|
|
187
|
+
className={`w-full h-full object-contain ${view.label.toLowerCase() == "pcb" ? "bg-black" : view.label.toLowerCase() == "schematic" ? "bg-[#F5F1ED]" : "bg-gray-100"}`}
|
|
188
|
+
/>
|
|
189
|
+
)}
|
|
190
|
+
</div>
|
|
191
|
+
))
|
|
192
|
+
: [1, 2, 3].map((i) => (
|
|
193
|
+
<Skeleton key={i} className="h-48 rounded-lg" />
|
|
194
|
+
))}
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
|
|
110
198
|
{/* Main Content */}
|
|
111
199
|
<ConnectedRepoOverview
|
|
112
200
|
packageBuild={latestBuild ?? null}
|