@tscircuit/fake-snippets 0.0.67 → 0.0.69
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/bun-tests/fake-snippets-api/routes/packages/update.test.ts +104 -0
- package/bun.lock +26 -83
- package/dist/bundle.js +17 -5
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2 -1
- package/dist/schema.d.ts +8 -0
- package/dist/schema.js +2 -1
- package/fake-snippets-api/lib/db/schema.ts +4 -0
- package/fake-snippets-api/routes/api/packages/create.ts +1 -0
- package/fake-snippets-api/routes/api/packages/update.ts +11 -2
- package/package.json +3 -4
- package/src/App.tsx +0 -4
- package/src/components/CmdKMenu.tsx +19 -19
- package/src/components/FAQ.tsx +3 -1
- package/src/components/FileSidebar.tsx +50 -1
- package/src/components/Header2.tsx +20 -9
- package/src/components/JLCPCBImportDialog.tsx +13 -16
- package/src/components/ViewPackagePage/components/important-files-view.tsx +1 -1
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +1 -0
- package/src/components/ViewPackagePage/components/package-header.tsx +22 -12
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +23 -7
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +1 -0
- package/src/components/dialogs/confirm-delete-package-dialog.tsx +8 -0
- package/src/components/dialogs/edit-package-details-dialog.tsx +177 -139
- package/src/components/package-port/CodeAndPreview.tsx +40 -19
- package/src/components/package-port/CodeEditor.tsx +8 -27
- package/src/components/package-port/EditorNav.tsx +1 -11
- package/src/hooks/use-package-details-form.ts +15 -1
- package/src/hooks/useFileManagement.ts +59 -0
- package/src/index.css +13 -0
- package/src/lib/utils/isValidFileName.ts +5 -0
- package/src/pages/dashboard.tsx +1 -0
- package/src/pages/quickstart.tsx +5 -5
- package/src/pages/search.tsx +1 -1
- package/src/pages/user-profile.tsx +1 -0
- package/src/components/OrderPreviewContent.tsx +0 -61
- package/src/components/ViewSnippetSidebar.tsx +0 -162
- package/src/components/dialogs/create-order-dialog.tsx +0 -146
- package/src/pages/preview.tsx +0 -44
- package/src/pages/view-order.tsx +0 -111
package/dist/index.d.ts
CHANGED
|
@@ -508,6 +508,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
508
508
|
ai_description: z.ZodNullable<z.ZodString>;
|
|
509
509
|
latest_license: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
510
510
|
ai_usage_instructions: z.ZodNullable<z.ZodString>;
|
|
511
|
+
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
511
512
|
}, "strip", z.ZodTypeAny, {
|
|
512
513
|
name: string;
|
|
513
514
|
unscoped_name: string;
|
|
@@ -536,6 +537,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
536
537
|
ai_usage_instructions: string | null;
|
|
537
538
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
538
539
|
latest_license?: string | null | undefined;
|
|
540
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
539
541
|
}, {
|
|
540
542
|
name: string;
|
|
541
543
|
unscoped_name: string;
|
|
@@ -564,6 +566,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
564
566
|
is_source_from_github?: boolean | undefined;
|
|
565
567
|
website?: string | null | undefined;
|
|
566
568
|
latest_license?: string | null | undefined;
|
|
569
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
567
570
|
}>;
|
|
568
571
|
type Package = z.infer<typeof packageSchema>;
|
|
569
572
|
declare const jlcpcbOrderStateSchema: z.ZodObject<{
|
|
@@ -778,6 +781,7 @@ declare const createDatabase: ({ seed }?: {
|
|
|
778
781
|
ai_usage_instructions: string | null;
|
|
779
782
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
780
783
|
latest_license?: string | null | undefined;
|
|
784
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
781
785
|
}[];
|
|
782
786
|
orders: {
|
|
783
787
|
error: z.objectOutputType<{
|
|
@@ -1068,6 +1072,7 @@ declare const createDatabase: ({ seed }?: {
|
|
|
1068
1072
|
ai_usage_instructions: string | null;
|
|
1069
1073
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1070
1074
|
latest_license?: string | null | undefined;
|
|
1075
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
1071
1076
|
}[];
|
|
1072
1077
|
orders: {
|
|
1073
1078
|
error: z.objectOutputType<{
|
package/dist/index.js
CHANGED
|
@@ -187,7 +187,8 @@ var packageSchema = z.object({
|
|
|
187
187
|
star_count: z.number().default(0),
|
|
188
188
|
ai_description: z.string().nullable(),
|
|
189
189
|
latest_license: z.string().nullable().optional(),
|
|
190
|
-
ai_usage_instructions: z.string().nullable()
|
|
190
|
+
ai_usage_instructions: z.string().nullable(),
|
|
191
|
+
default_view: z.enum(["files", "3d", "pcb", "schematic"]).default("files").optional()
|
|
191
192
|
});
|
|
192
193
|
var jlcpcbOrderStateSchema = z.object({
|
|
193
194
|
jlcpcb_order_state_id: z.string(),
|
package/dist/schema.d.ts
CHANGED
|
@@ -633,6 +633,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
633
633
|
ai_description: z.ZodNullable<z.ZodString>;
|
|
634
634
|
latest_license: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
635
635
|
ai_usage_instructions: z.ZodNullable<z.ZodString>;
|
|
636
|
+
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
636
637
|
}, "strip", z.ZodTypeAny, {
|
|
637
638
|
name: string;
|
|
638
639
|
unscoped_name: string;
|
|
@@ -661,6 +662,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
661
662
|
ai_usage_instructions: string | null;
|
|
662
663
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
663
664
|
latest_license?: string | null | undefined;
|
|
665
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
664
666
|
}, {
|
|
665
667
|
name: string;
|
|
666
668
|
unscoped_name: string;
|
|
@@ -689,6 +691,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
689
691
|
is_source_from_github?: boolean | undefined;
|
|
690
692
|
website?: string | null | undefined;
|
|
691
693
|
latest_license?: string | null | undefined;
|
|
694
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
692
695
|
}>;
|
|
693
696
|
type Package = z.infer<typeof packageSchema>;
|
|
694
697
|
declare const jlcpcbOrderStateSchema: z.ZodObject<{
|
|
@@ -1068,6 +1071,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1068
1071
|
ai_description: z.ZodNullable<z.ZodString>;
|
|
1069
1072
|
latest_license: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1070
1073
|
ai_usage_instructions: z.ZodNullable<z.ZodString>;
|
|
1074
|
+
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
1071
1075
|
}, "strip", z.ZodTypeAny, {
|
|
1072
1076
|
name: string;
|
|
1073
1077
|
unscoped_name: string;
|
|
@@ -1096,6 +1100,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1096
1100
|
ai_usage_instructions: string | null;
|
|
1097
1101
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1098
1102
|
latest_license?: string | null | undefined;
|
|
1103
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
1099
1104
|
}, {
|
|
1100
1105
|
name: string;
|
|
1101
1106
|
unscoped_name: string;
|
|
@@ -1124,6 +1129,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1124
1129
|
is_source_from_github?: boolean | undefined;
|
|
1125
1130
|
website?: string | null | undefined;
|
|
1126
1131
|
latest_license?: string | null | undefined;
|
|
1132
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
1127
1133
|
}>, "many">>;
|
|
1128
1134
|
orders: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1129
1135
|
order_id: z.ZodString;
|
|
@@ -1572,6 +1578,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1572
1578
|
ai_usage_instructions: string | null;
|
|
1573
1579
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1574
1580
|
latest_license?: string | null | undefined;
|
|
1581
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
1575
1582
|
}[];
|
|
1576
1583
|
orders: {
|
|
1577
1584
|
error: z.objectOutputType<{
|
|
@@ -1788,6 +1795,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1788
1795
|
is_source_from_github?: boolean | undefined;
|
|
1789
1796
|
website?: string | null | undefined;
|
|
1790
1797
|
latest_license?: string | null | undefined;
|
|
1798
|
+
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
1791
1799
|
}[] | undefined;
|
|
1792
1800
|
orders?: {
|
|
1793
1801
|
error: z.objectInputType<{
|
package/dist/schema.js
CHANGED
|
@@ -182,7 +182,8 @@ var packageSchema = z.object({
|
|
|
182
182
|
star_count: z.number().default(0),
|
|
183
183
|
ai_description: z.string().nullable(),
|
|
184
184
|
latest_license: z.string().nullable().optional(),
|
|
185
|
-
ai_usage_instructions: z.string().nullable()
|
|
185
|
+
ai_usage_instructions: z.string().nullable(),
|
|
186
|
+
default_view: z.enum(["files", "3d", "pcb", "schematic"]).default("files").optional()
|
|
186
187
|
});
|
|
187
188
|
var jlcpcbOrderStateSchema = z.object({
|
|
188
189
|
jlcpcb_order_state_id: z.string(),
|
|
@@ -219,6 +219,10 @@ export const packageSchema = z.object({
|
|
|
219
219
|
ai_description: z.string().nullable(),
|
|
220
220
|
latest_license: z.string().nullable().optional(),
|
|
221
221
|
ai_usage_instructions: z.string().nullable(),
|
|
222
|
+
default_view: z
|
|
223
|
+
.enum(["files", "3d", "pcb", "schematic"])
|
|
224
|
+
.default("files")
|
|
225
|
+
.optional(),
|
|
222
226
|
})
|
|
223
227
|
export type Package = z.infer<typeof packageSchema>
|
|
224
228
|
|
|
@@ -55,6 +55,7 @@ export default withRouteSpec({
|
|
|
55
55
|
is_public: is_private === true ? false : true,
|
|
56
56
|
is_unlisted: is_private === true ? true : (is_unlisted ?? false),
|
|
57
57
|
ai_usage_instructions: "placeholder ai usage instructions",
|
|
58
|
+
default_view: "files",
|
|
58
59
|
})
|
|
59
60
|
|
|
60
61
|
if (!newPackage) {
|
|
@@ -20,6 +20,7 @@ export default withRouteSpec({
|
|
|
20
20
|
website: z.string().optional(),
|
|
21
21
|
is_private: z.boolean().optional(),
|
|
22
22
|
is_unlisted: z.boolean().optional(),
|
|
23
|
+
default_view: z.enum(["files", "3d", "pcb", "schematic"]).optional(),
|
|
23
24
|
})
|
|
24
25
|
.transform((data) => ({
|
|
25
26
|
...data,
|
|
@@ -30,8 +31,15 @@ export default withRouteSpec({
|
|
|
30
31
|
package: packageSchema,
|
|
31
32
|
}),
|
|
32
33
|
})(async (req, ctx) => {
|
|
33
|
-
const {
|
|
34
|
-
|
|
34
|
+
const {
|
|
35
|
+
package_id,
|
|
36
|
+
name,
|
|
37
|
+
description,
|
|
38
|
+
website,
|
|
39
|
+
is_private,
|
|
40
|
+
is_unlisted,
|
|
41
|
+
default_view,
|
|
42
|
+
} = req.jsonBody
|
|
35
43
|
|
|
36
44
|
const packageIndex = ctx.db.packages.findIndex(
|
|
37
45
|
(p) => p.package_id === package_id,
|
|
@@ -77,6 +85,7 @@ export default withRouteSpec({
|
|
|
77
85
|
is_public:
|
|
78
86
|
is_private !== undefined ? !is_private : existingPackage.is_public,
|
|
79
87
|
is_unlisted: is_unlisted ?? existingPackage.is_unlisted,
|
|
88
|
+
default_view: default_view ?? existingPackage.default_view,
|
|
80
89
|
updated_at: new Date().toISOString(),
|
|
81
90
|
})
|
|
82
91
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/fake-snippets",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.69",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -70,13 +70,12 @@
|
|
|
70
70
|
"@radix-ui/react-toggle": "^1.1.0",
|
|
71
71
|
"@radix-ui/react-toggle-group": "^1.1.0",
|
|
72
72
|
"@radix-ui/react-tooltip": "^1.1.2",
|
|
73
|
-
"@tscircuit/3d-viewer": "^0.0.142",
|
|
74
73
|
"@tscircuit/eval": "^0.0.198",
|
|
75
74
|
"@tscircuit/footprinter": "^0.0.124",
|
|
76
75
|
"@tscircuit/layout": "^0.0.29",
|
|
77
76
|
"@tscircuit/math-utils": "^0.0.10",
|
|
78
77
|
"@tscircuit/mm": "^0.0.8",
|
|
79
|
-
"@tscircuit/props": "^0.0.
|
|
78
|
+
"@tscircuit/props": "^0.0.186",
|
|
80
79
|
"@types/file-saver": "^2.0.7",
|
|
81
80
|
"@types/ms": "^0.7.34",
|
|
82
81
|
"@typescript/ata": "^0.9.7",
|
|
@@ -148,7 +147,7 @@
|
|
|
148
147
|
"@tailwindcss/typography": "^0.5.16",
|
|
149
148
|
"@tscircuit/core": "^0.0.384",
|
|
150
149
|
"@tscircuit/prompt-benchmarks": "^0.0.28",
|
|
151
|
-
"@tscircuit/runframe": "^0.0.
|
|
150
|
+
"@tscircuit/runframe": "^0.0.494",
|
|
152
151
|
"@types/babel__standalone": "^7.1.7",
|
|
153
152
|
"@types/bun": "^1.1.10",
|
|
154
153
|
"@types/country-list": "^2.1.4",
|
package/src/App.tsx
CHANGED
|
@@ -61,12 +61,10 @@ const EditorPage = lazyImport(async () => {
|
|
|
61
61
|
const LandingPage = lazyImport(() => import("@/pages/landing"))
|
|
62
62
|
const MyOrdersPage = lazyImport(() => import("@/pages/my-orders"))
|
|
63
63
|
const LatestPage = lazyImport(() => import("@/pages/latest"))
|
|
64
|
-
const PreviewPage = lazyImport(() => import("@/pages/preview"))
|
|
65
64
|
const QuickstartPage = lazyImport(() => import("@/pages/quickstart"))
|
|
66
65
|
const SearchPage = lazyImport(() => import("@/pages/search"))
|
|
67
66
|
const SettingsPage = lazyImport(() => import("@/pages/settings"))
|
|
68
67
|
const UserProfilePage = lazyImport(() => import("@/pages/user-profile"))
|
|
69
|
-
const ViewOrderPage = lazyImport(() => import("@/pages/view-order"))
|
|
70
68
|
const DevLoginPage = lazyImport(() => import("@/pages/dev-login"))
|
|
71
69
|
const BetaPage = lazyImport(() => import("@/pages/beta"))
|
|
72
70
|
const ViewPackagePage = lazyImport(() => import("@/pages/view-package"))
|
|
@@ -123,8 +121,6 @@ function App() {
|
|
|
123
121
|
<Route path="/trending" component={TrendingPage} />
|
|
124
122
|
<Route path="/authorize" component={AuthenticatePage} />
|
|
125
123
|
<Route path="/my-orders" component={MyOrdersPage} />
|
|
126
|
-
<Route path="/orders/:orderId" component={ViewOrderPage} />
|
|
127
|
-
<Route path="/preview" component={PreviewPage} />
|
|
128
124
|
<Route path="/dev-login" component={DevLoginPage} />
|
|
129
125
|
<Route path="/:username" component={UserProfilePage} />
|
|
130
126
|
<Route path="/:author/:packageName" component={ViewPackagePage} />
|
|
@@ -7,7 +7,7 @@ import { Package, Snippet } from "fake-snippets-api/lib/db/schema"
|
|
|
7
7
|
import React from "react"
|
|
8
8
|
import { useQuery } from "react-query"
|
|
9
9
|
|
|
10
|
-
type SnippetType = "board" | "package" | "model" | "footprint"
|
|
10
|
+
type SnippetType = "board" | "package" | "model" | "footprint"
|
|
11
11
|
|
|
12
12
|
interface Template {
|
|
13
13
|
name: string
|
|
@@ -31,13 +31,13 @@ const CmdKMenu = () => {
|
|
|
31
31
|
|
|
32
32
|
// Search results query
|
|
33
33
|
const { data: searchResults = [], isLoading: isSearching } = useQuery(
|
|
34
|
-
["
|
|
34
|
+
["packageSearch", searchQuery],
|
|
35
35
|
async () => {
|
|
36
36
|
if (!searchQuery) return []
|
|
37
|
-
const { data } = await axios.
|
|
38
|
-
|
|
37
|
+
const { data } = await axios.post("/packages/search", {
|
|
38
|
+
query: searchQuery,
|
|
39
39
|
})
|
|
40
|
-
return data.
|
|
40
|
+
return data.packages || []
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
enabled: Boolean(searchQuery),
|
|
@@ -114,7 +114,7 @@ const CmdKMenu = () => {
|
|
|
114
114
|
/>
|
|
115
115
|
</svg>
|
|
116
116
|
<Command.Input
|
|
117
|
-
placeholder="Search
|
|
117
|
+
placeholder="Search packages and commands..."
|
|
118
118
|
value={searchQuery}
|
|
119
119
|
onValueChange={setSearchQuery}
|
|
120
120
|
className="w-full h-12 bg-transparent border-none outline-none text-gray-900 dark:text-gray-100 placeholder-gray-500"
|
|
@@ -133,27 +133,27 @@ const CmdKMenu = () => {
|
|
|
133
133
|
heading="Search Results"
|
|
134
134
|
className="px-2 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400"
|
|
135
135
|
>
|
|
136
|
-
{searchResults.map((
|
|
136
|
+
{searchResults.map((pkg: Package) => (
|
|
137
137
|
<Command.Item
|
|
138
|
-
key={
|
|
139
|
-
value={
|
|
138
|
+
key={pkg.package_id}
|
|
139
|
+
value={pkg.name}
|
|
140
140
|
onSelect={() => {
|
|
141
|
-
window.location.href = `/editor?
|
|
141
|
+
window.location.href = `/editor?package_id=${pkg.package_id}`
|
|
142
142
|
setOpen(false)
|
|
143
143
|
}}
|
|
144
144
|
className="flex items-center justify-between px-2 py-1.5 rounded-sm text-sm hover:bg-gray-100 dark:hover:bg-gray-700 cursor-default aria-selected:bg-gray-100 dark:aria-selected:bg-gray-700"
|
|
145
145
|
>
|
|
146
146
|
<div className="flex flex-col">
|
|
147
147
|
<span className="text-gray-900 dark:text-gray-100">
|
|
148
|
-
{
|
|
148
|
+
{pkg.name}
|
|
149
149
|
</span>
|
|
150
|
-
{
|
|
150
|
+
{pkg.description && (
|
|
151
151
|
<span className="text-sm text-gray-500">
|
|
152
|
-
{
|
|
152
|
+
{pkg.description}
|
|
153
153
|
</span>
|
|
154
154
|
)}
|
|
155
155
|
</div>
|
|
156
|
-
<span className="text-sm text-gray-500">
|
|
156
|
+
<span className="text-sm text-gray-500">package</span>
|
|
157
157
|
</Command.Item>
|
|
158
158
|
))}
|
|
159
159
|
</Command.Group>
|
|
@@ -161,7 +161,7 @@ const CmdKMenu = () => {
|
|
|
161
161
|
|
|
162
162
|
{!searchQuery && recentPackages.length > 0 && (
|
|
163
163
|
<Command.Group
|
|
164
|
-
heading="Recent
|
|
164
|
+
heading="Recent Packages"
|
|
165
165
|
className="px-2 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400"
|
|
166
166
|
>
|
|
167
167
|
{recentPackages.slice(0, 6).map((pkg) => (
|
|
@@ -169,28 +169,28 @@ const CmdKMenu = () => {
|
|
|
169
169
|
key={pkg.package_id}
|
|
170
170
|
value={pkg.unscoped_name}
|
|
171
171
|
onSelect={() => {
|
|
172
|
-
window.location.href = `/editor?
|
|
172
|
+
window.location.href = `/editor?package_id=${pkg.package_id}`
|
|
173
173
|
setOpen(false)
|
|
174
174
|
}}
|
|
175
175
|
className="flex items-center justify-between px-2 py-1.5 rounded-sm text-sm hover:bg-gray-100 dark:hover:bg-gray-700 cursor-default aria-selected:bg-gray-100 dark:aria-selected:bg-gray-700"
|
|
176
176
|
>
|
|
177
177
|
<div className="flex flex-col">
|
|
178
178
|
<span className="text-gray-900 dark:text-gray-100">
|
|
179
|
-
{pkg.
|
|
179
|
+
{pkg.name}
|
|
180
180
|
</span>
|
|
181
181
|
<span className="text-sm text-gray-500">
|
|
182
182
|
Last edited:{" "}
|
|
183
183
|
{new Date(pkg.updated_at).toLocaleDateString()}
|
|
184
184
|
</span>
|
|
185
185
|
</div>
|
|
186
|
-
<span className="text-sm text-gray-500">
|
|
186
|
+
<span className="text-sm text-gray-500">package</span>
|
|
187
187
|
</Command.Item>
|
|
188
188
|
))}
|
|
189
189
|
</Command.Group>
|
|
190
190
|
)}
|
|
191
191
|
|
|
192
192
|
<Command.Group
|
|
193
|
-
heading="Start Blank
|
|
193
|
+
heading="Start Blank Package"
|
|
194
194
|
className="px-2 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400"
|
|
195
195
|
>
|
|
196
196
|
{blankTemplates.map((template) => (
|
package/src/components/FAQ.tsx
CHANGED
|
@@ -176,7 +176,9 @@ export const FAQ = () => (
|
|
|
176
176
|
<Accordion type="single" collapsible>
|
|
177
177
|
{QUESTIONS.map((q, i) => (
|
|
178
178
|
<AccordionItem key={i} value={`item-${i + 1}`}>
|
|
179
|
-
<AccordionTrigger>
|
|
179
|
+
<AccordionTrigger className="text-left">
|
|
180
|
+
{q.question}
|
|
181
|
+
</AccordionTrigger>{" "}
|
|
180
182
|
<AccordionContent>{q.answer}</AccordionContent>
|
|
181
183
|
</AccordionItem>
|
|
182
184
|
))}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React, { useState } from "react"
|
|
2
2
|
import { cn } from "@/lib/utils"
|
|
3
|
-
import { File, Folder, PanelRightOpen } from "lucide-react"
|
|
3
|
+
import { File, Folder, PanelRightOpen, Plus } from "lucide-react"
|
|
4
4
|
import { TreeView, TreeDataItem } from "@/components/ui/tree-view"
|
|
5
5
|
import { isHiddenFile } from "./ViewPackagePage/utils/is-hidden-file"
|
|
6
|
+
import { Input } from "@/components/ui/input"
|
|
7
|
+
import { CreateFileProps } from "./package-port/CodeAndPreview"
|
|
6
8
|
|
|
7
9
|
type FileName = string
|
|
8
10
|
|
|
@@ -12,6 +14,7 @@ interface FileSidebarProps {
|
|
|
12
14
|
onFileSelect: (filename: FileName) => void
|
|
13
15
|
className?: string
|
|
14
16
|
fileSidebarState: ReturnType<typeof useState<boolean>>
|
|
17
|
+
handleCreateFile: (props: CreateFileProps) => void
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
@@ -20,8 +23,13 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
20
23
|
onFileSelect,
|
|
21
24
|
className,
|
|
22
25
|
fileSidebarState,
|
|
26
|
+
handleCreateFile,
|
|
23
27
|
}) => {
|
|
24
28
|
const [sidebarOpen, setSidebarOpen] = fileSidebarState
|
|
29
|
+
const [newFileName, setNewFileName] = useState("")
|
|
30
|
+
const [isCreatingFile, setIsCreatingFile] = useState(false)
|
|
31
|
+
const [errorMessage, setErrorMessage] = useState("")
|
|
32
|
+
|
|
25
33
|
const transformFilesToTreeData = (
|
|
26
34
|
files: Record<FileName, string>,
|
|
27
35
|
): TreeDataItem[] => {
|
|
@@ -82,6 +90,17 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
const treeData = transformFilesToTreeData(files)
|
|
93
|
+
|
|
94
|
+
const handleCreateFileInline = () => {
|
|
95
|
+
handleCreateFile({
|
|
96
|
+
newFileName,
|
|
97
|
+
setErrorMessage,
|
|
98
|
+
onFileSelect,
|
|
99
|
+
setNewFileName,
|
|
100
|
+
setIsCreatingFile,
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
85
104
|
return (
|
|
86
105
|
<div
|
|
87
106
|
className={cn(
|
|
@@ -98,6 +117,36 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
98
117
|
>
|
|
99
118
|
<PanelRightOpen />
|
|
100
119
|
</button>
|
|
120
|
+
<button
|
|
121
|
+
onClick={() => setIsCreatingFile(true)}
|
|
122
|
+
className="absolute top-2 right-2 text-gray-400 hover:text-gray-600"
|
|
123
|
+
aria-label="Create new file"
|
|
124
|
+
>
|
|
125
|
+
<Plus className="w-5 h-5" />
|
|
126
|
+
</button>
|
|
127
|
+
{isCreatingFile && (
|
|
128
|
+
<div className="p-2">
|
|
129
|
+
<Input
|
|
130
|
+
autoFocus
|
|
131
|
+
value={newFileName}
|
|
132
|
+
onChange={(e) => setNewFileName(e.target.value)}
|
|
133
|
+
onBlur={handleCreateFileInline}
|
|
134
|
+
onKeyDown={(e) => {
|
|
135
|
+
if (e.key === "Enter") {
|
|
136
|
+
handleCreateFileInline()
|
|
137
|
+
} else if (e.key === "Escape") {
|
|
138
|
+
setIsCreatingFile(false)
|
|
139
|
+
setNewFileName("")
|
|
140
|
+
setErrorMessage("")
|
|
141
|
+
}
|
|
142
|
+
}}
|
|
143
|
+
placeholder="Enter file name"
|
|
144
|
+
/>
|
|
145
|
+
{errorMessage && (
|
|
146
|
+
<div className="text-red-500 mt-1">{errorMessage}</div>
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
)}
|
|
101
150
|
<TreeView
|
|
102
151
|
data={treeData}
|
|
103
152
|
initialSelectedItemId={currentFile}
|
|
@@ -29,15 +29,26 @@ const SearchButtonComponent = () => {
|
|
|
29
29
|
</Button> */}
|
|
30
30
|
</div>
|
|
31
31
|
) : (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
<>
|
|
33
|
+
<Button
|
|
34
|
+
variant="ghost"
|
|
35
|
+
size="icon"
|
|
36
|
+
onClick={() => setIsExpanded(true)}
|
|
37
|
+
className="h-8 w-8 hidden sm:flex"
|
|
38
|
+
aria-label="Open search"
|
|
39
|
+
>
|
|
40
|
+
<Search className="size-4" />
|
|
41
|
+
</Button>
|
|
42
|
+
<Button
|
|
43
|
+
variant="ghost"
|
|
44
|
+
size="icon"
|
|
45
|
+
onClick={() => (window.location.href = "/search")}
|
|
46
|
+
className="h-8 w-8 flex sm:hidden"
|
|
47
|
+
aria-label="Go to search"
|
|
48
|
+
>
|
|
49
|
+
<Search className="size-4" />
|
|
50
|
+
</Button>
|
|
51
|
+
</>
|
|
41
52
|
)}
|
|
42
53
|
</div>
|
|
43
54
|
)
|
|
@@ -27,9 +27,8 @@ export function JLCPCBImportDialog({
|
|
|
27
27
|
const [partNumber, setPartNumber] = useState("")
|
|
28
28
|
const [isLoading, setIsLoading] = useState(false)
|
|
29
29
|
const [error, setError] = useState<string | null>(null)
|
|
30
|
-
const [
|
|
31
|
-
|
|
32
|
-
>(null)
|
|
30
|
+
const [hasBeenImportedToAccountAlready, setHasBeenImportedToAccountAlready] =
|
|
31
|
+
useState<boolean>(false)
|
|
33
32
|
const axios = useAxios()
|
|
34
33
|
const { toast } = useToast()
|
|
35
34
|
const [, navigate] = useLocation()
|
|
@@ -48,19 +47,17 @@ export function JLCPCBImportDialog({
|
|
|
48
47
|
|
|
49
48
|
setIsLoading(true)
|
|
50
49
|
setError(null)
|
|
51
|
-
|
|
50
|
+
setHasBeenImportedToAccountAlready(false)
|
|
52
51
|
|
|
53
52
|
try {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
53
|
+
const apiUrl = `/snippets/get?owner_name=${session?.github_username}&unscoped_name=${partNumber}`
|
|
54
|
+
|
|
55
|
+
const existingPackageRes = await axios.get(apiUrl, {
|
|
56
|
+
validateStatus: (status) => true,
|
|
57
|
+
})
|
|
60
58
|
|
|
61
59
|
if (existingPackageRes.status !== 404) {
|
|
62
|
-
|
|
63
|
-
setAlreadyImportedPackageId(packageId)
|
|
60
|
+
setHasBeenImportedToAccountAlready(true)
|
|
64
61
|
setIsLoading(false)
|
|
65
62
|
return
|
|
66
63
|
}
|
|
@@ -122,14 +119,14 @@ export function JLCPCBImportDialog({
|
|
|
122
119
|
onChange={(e) => {
|
|
123
120
|
setPartNumber(e.target.value)
|
|
124
121
|
setError(null)
|
|
125
|
-
|
|
122
|
+
setHasBeenImportedToAccountAlready(false)
|
|
126
123
|
}}
|
|
127
124
|
/>
|
|
128
|
-
{error && !
|
|
125
|
+
{error && !hasBeenImportedToAccountAlready && (
|
|
129
126
|
<p className="bg-red-100 p-2 mt-2 pre-wrap">{error}</p>
|
|
130
127
|
)}
|
|
131
128
|
|
|
132
|
-
{error && !
|
|
129
|
+
{error && !hasBeenImportedToAccountAlready && (
|
|
133
130
|
<div className="flex justify-end mt-2">
|
|
134
131
|
<Button
|
|
135
132
|
variant="default"
|
|
@@ -150,7 +147,7 @@ export function JLCPCBImportDialog({
|
|
|
150
147
|
</div>
|
|
151
148
|
)}
|
|
152
149
|
|
|
153
|
-
{
|
|
150
|
+
{hasBeenImportedToAccountAlready && (
|
|
154
151
|
<p className="p-2 mt-2 pre-wrap text-md text-green-600">
|
|
155
152
|
This part number has already been imported to your profile.{" "}
|
|
156
153
|
<PrefetchPageLink
|
|
@@ -65,7 +65,7 @@ export default function ImportantFilesView({
|
|
|
65
65
|
setActiveFilePath(importantFiles[0].file_path)
|
|
66
66
|
setActiveTab("file")
|
|
67
67
|
}
|
|
68
|
-
}, [aiDescription, aiUsageInstructions, hasAiContent])
|
|
68
|
+
}, [aiDescription, aiUsageInstructions, hasAiContent, importantFiles])
|
|
69
69
|
|
|
70
70
|
// Get file name from path
|
|
71
71
|
const getFileName = (path: string) => {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useEffect } from "react"
|
|
2
2
|
import { Link } from "wouter"
|
|
3
|
-
|
|
4
|
-
import { TypeBadge } from "@/components/TypeBadge"
|
|
5
3
|
import { Button } from "@/components/ui/button"
|
|
6
4
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
7
5
|
import {
|
|
@@ -10,7 +8,7 @@ import {
|
|
|
10
8
|
TooltipProvider,
|
|
11
9
|
TooltipTrigger,
|
|
12
10
|
} from "@/components/ui/tooltip"
|
|
13
|
-
import {
|
|
11
|
+
import { Lock, Globe } from "lucide-react"
|
|
14
12
|
import { GitFork, Package, Star } from "lucide-react"
|
|
15
13
|
|
|
16
14
|
import { useForkPackageMutation } from "@/hooks/use-fork-package-mutation"
|
|
@@ -45,6 +43,7 @@ export default function PackageHeader({
|
|
|
45
43
|
const { OrderDialog, isOpen, open, close, stage, setStage } = useOrderDialog({
|
|
46
44
|
onSignIn: signIn,
|
|
47
45
|
isLoggedIn,
|
|
46
|
+
packageReleaseId: packageInfo?.latest_package_release_id ?? "",
|
|
48
47
|
})
|
|
49
48
|
const { data: starData, isLoading: isStarDataLoading } =
|
|
50
49
|
usePackageStarsByName(packageInfo?.name ?? null)
|
|
@@ -105,13 +104,25 @@ export default function PackageHeader({
|
|
|
105
104
|
{packageName}
|
|
106
105
|
</Link>
|
|
107
106
|
</h1>
|
|
108
|
-
{packageInfo?.name &&
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
107
|
+
{packageInfo?.name && (
|
|
108
|
+
<div
|
|
109
|
+
className={`select-none inline-flex items-center px-2 py-1 rounded text-xs font-medium ${
|
|
110
|
+
isPrivate
|
|
111
|
+
? "bg-gray-100 text-gray-700 border border-gray-200"
|
|
112
|
+
: "bg-blue-50 text-blue-700 border border-blue-200"
|
|
113
|
+
}`}
|
|
114
|
+
>
|
|
115
|
+
{isPrivate ? (
|
|
116
|
+
<>
|
|
117
|
+
<Lock className="w-3 h-3 mr-1 flex-shrink-0" />
|
|
118
|
+
<span className="leading-none">Private</span>
|
|
119
|
+
</>
|
|
120
|
+
) : (
|
|
121
|
+
<>
|
|
122
|
+
<Globe className="w-3 h-3 mr-1 flex-shrink-0" />
|
|
123
|
+
<span className="leading-none">Public</span>
|
|
124
|
+
</>
|
|
125
|
+
)}
|
|
115
126
|
</div>
|
|
116
127
|
)}
|
|
117
128
|
</>
|
|
@@ -259,7 +270,6 @@ export default function PackageHeader({
|
|
|
259
270
|
onClose={close}
|
|
260
271
|
stage={stage}
|
|
261
272
|
setStage={setStage}
|
|
262
|
-
packageReleaseId={packageInfo?.latest_package_release_id ?? ""}
|
|
263
273
|
/>
|
|
264
274
|
</header>
|
|
265
275
|
)
|