@tscircuit/fake-snippets 0.0.6 → 0.0.8

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 (45) hide show
  1. package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +2 -5
  2. package/bun-tests/fake-snippets-api/routes/package_files/create.test.ts +375 -0
  3. package/bun-tests/fake-snippets-api/routes/package_files/download.test.ts +248 -0
  4. package/bun-tests/fake-snippets-api/routes/package_files/get.test.ts +220 -0
  5. package/bun-tests/fake-snippets-api/routes/package_files/list.test.ts +204 -0
  6. package/bun-tests/fake-snippets-api/routes/package_releases/get.test.ts +0 -1
  7. package/bun-tests/fake-snippets-api/routes/packages/{list.test.ts → list-1.test.ts} +3 -55
  8. package/bun-tests/fake-snippets-api/routes/packages/list-2.test.ts +59 -0
  9. package/bun-tests/fake-snippets-api/routes/snippets/create.test.ts +34 -1
  10. package/bun.lock +100 -73
  11. package/dist/bundle.js +729 -273
  12. package/fake-snippets-api/lib/db/db-client.ts +58 -50
  13. package/fake-snippets-api/lib/db/schema.ts +15 -6
  14. package/fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor.ts +168 -0
  15. package/fake-snippets-api/lib/package_release/find-package-release-id.ts +122 -0
  16. package/fake-snippets-api/lib/public-mapping/public-map-package.ts +9 -2
  17. package/fake-snippets-api/routes/api/package_files/create.ts +132 -0
  18. package/fake-snippets-api/routes/api/package_files/download.ts +70 -153
  19. package/fake-snippets-api/routes/api/package_files/get.ts +24 -5
  20. package/fake-snippets-api/routes/api/package_files/list.ts +16 -28
  21. package/fake-snippets-api/routes/api/snippets/create.ts +123 -29
  22. package/index.html +12 -1
  23. package/package.json +10 -9
  24. package/playwright-tests/profile-page.spec.ts +59 -0
  25. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-before-delete.png +0 -0
  26. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-delete-dialog.png +0 -0
  27. package/playwright-tests/snapshots/profile-page.spec.ts-profile-page-dropdown-open.png +0 -0
  28. package/scripts/generate-image-sizes.ts +0 -1
  29. package/scripts/generate_bundle_stats.js +22 -6
  30. package/src/components/AiChatInterface.tsx +8 -0
  31. package/src/components/Analytics.tsx +1 -1
  32. package/src/components/CodeAndPreview.tsx +9 -3
  33. package/src/components/CreateNewSnippetWithAiHero.tsx +6 -2
  34. package/src/components/EditorNav.tsx +4 -0
  35. package/src/components/Footer.tsx +1 -1
  36. package/src/components/Header.tsx +7 -10
  37. package/src/components/HeaderLogin.tsx +1 -1
  38. package/src/components/PreviewContent.tsx +4 -1
  39. package/src/components/SnippetList.tsx +71 -0
  40. package/src/lib/templates/blinking-led-board-template.ts +2 -1
  41. package/src/pages/dashboard.tsx +19 -44
  42. package/src/pages/editor.tsx +1 -1
  43. package/src/pages/landing.tsx +8 -16
  44. package/src/pages/quickstart.tsx +9 -9
  45. package/src/pages/user-profile.tsx +50 -3
@@ -65,13 +65,13 @@ export const QuickstartPage = () => {
65
65
  key={snippet.snippet_id}
66
66
  href={`/editor?snippet_id=${snippet.snippet_id}`}
67
67
  >
68
- <Card className="hover:shadow-md transition-shadow rounded-md">
68
+ <Card className="hover:shadow-md transition-shadow rounded-md flex flex-col h-full">
69
69
  <CardHeader className="pb-0 p-4">
70
70
  <CardTitle className="text-md">
71
71
  {snippet.unscoped_name}
72
72
  </CardTitle>
73
73
  </CardHeader>
74
- <CardContent className="p-4 pt-0">
74
+ <CardContent className="p-4 pt-0 mt-auto">
75
75
  <p className="text-sm text-gray-500">
76
76
  Last edited:{" "}
77
77
  {new Date(snippet.updated_at).toLocaleDateString()}
@@ -118,7 +118,7 @@ export const QuickstartPage = () => {
118
118
 
119
119
  <div className="mt-12">
120
120
  <h2 className="text-xl font-semibold mb-4">Import as Snippet</h2>
121
- <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
121
+ <div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4">
122
122
  {[
123
123
  { name: "KiCad Footprint", type: "footprint" },
124
124
  { name: "KiCad Project", type: "board" },
@@ -126,7 +126,7 @@ export const QuickstartPage = () => {
126
126
  ].map((template, index) => (
127
127
  <Card
128
128
  key={index}
129
- className="hover:shadow-md transition-shadow rounded-md opacity-50"
129
+ className="hover:shadow-md transition-shadow rounded-md opacity-50 flex flex-col"
130
130
  >
131
131
  <CardHeader className="p-4 pb-0">
132
132
  <CardTitle className="text-lg flex items-center justify-between">
@@ -134,7 +134,7 @@ export const QuickstartPage = () => {
134
134
  <TypeBadge type={template.type as any} className="ml-2" />
135
135
  </CardTitle>
136
136
  </CardHeader>
137
- <CardContent className="p-4">
137
+ <CardContent className="p-4 mt-auto">
138
138
  <Button
139
139
  className="w-full"
140
140
  onClick={() => {
@@ -146,14 +146,14 @@ export const QuickstartPage = () => {
146
146
  </CardContent>
147
147
  </Card>
148
148
  ))}
149
- <Card className="hover:shadow-md transition-shadow rounded-md">
149
+ <Card className="hover:shadow-md transition-shadow rounded-md flex flex-col">
150
150
  <CardHeader className="p-4 pb-0">
151
151
  <CardTitle className="text-lg flex items-center justify-between">
152
152
  JLCPCB Component
153
153
  <TypeBadge type="package" className="ml-2" />
154
154
  </CardTitle>
155
155
  </CardHeader>
156
- <CardContent className="p-4">
156
+ <CardContent className="p-4 mt-auto">
157
157
  <Button
158
158
  className="w-full"
159
159
  onClick={() => setIsJLCPCBDialogOpen(true)}
@@ -162,14 +162,14 @@ export const QuickstartPage = () => {
162
162
  </Button>
163
163
  </CardContent>
164
164
  </Card>
165
- <Card className="hover:shadow-md transition-shadow rounded-md">
165
+ <Card className="hover:shadow-md transition-shadow rounded-md flex flex-col">
166
166
  <CardHeader className="p-4 pb-0">
167
167
  <CardTitle className="text-lg flex items-center justify-between">
168
168
  Circuit Json
169
169
  <TypeBadge type="module" className="ml-2" />
170
170
  </CardTitle>
171
171
  </CardHeader>
172
- <CardContent className="p-4">
172
+ <CardContent className="p-4 mt-auto">
173
173
  <Button
174
174
  className="w-full"
175
175
  onClick={() => setIsCircuitJsonImportDialogOpen(true)}
@@ -10,6 +10,14 @@ import { Button } from "@/components/ui/button"
10
10
  import { GitHubLogoIcon, StarIcon } from "@radix-ui/react-icons"
11
11
  import { Input } from "@/components/ui/input"
12
12
  import { useGlobalStore } from "@/hooks/use-global-store"
13
+ import { MoreVertical, Trash2 } from "lucide-react"
14
+ import { useConfirmDeleteSnippetDialog } from "@/components/dialogs/confirm-delete-snippet-dialog"
15
+ import {
16
+ DropdownMenu,
17
+ DropdownMenuContent,
18
+ DropdownMenuItem,
19
+ DropdownMenuTrigger,
20
+ } from "@/components/ui/dropdown-menu"
13
21
 
14
22
  export const UserProfilePage = () => {
15
23
  const { username } = useParams()
@@ -17,6 +25,9 @@ export const UserProfilePage = () => {
17
25
  const [searchQuery, setSearchQuery] = useState("")
18
26
  const session = useGlobalStore((s) => s.session)
19
27
  const isCurrentUserProfile = username === session?.github_username
28
+ const { Dialog: DeleteDialog, openDialog: openDeleteDialog } =
29
+ useConfirmDeleteSnippetDialog()
30
+ const [snippetToDelete, setSnippetToDelete] = useState<Snippet | null>(null)
20
31
 
21
32
  const { data: userSnippets, isLoading } = useQuery<Snippet[]>(
22
33
  ["userSnippets", username],
@@ -32,6 +43,12 @@ export const UserProfilePage = () => {
32
43
  snippet.unscoped_name.toLowerCase().includes(searchQuery.toLowerCase()),
33
44
  )
34
45
 
46
+ const handleDeleteClick = (e: React.MouseEvent, snippet: Snippet) => {
47
+ e.preventDefault() // Prevent navigation
48
+ setSnippetToDelete(snippet)
49
+ openDeleteDialog()
50
+ }
51
+
35
52
  return (
36
53
  <div>
37
54
  <Header />
@@ -76,9 +93,33 @@ export const UserProfilePage = () => {
76
93
  <h3 className="text-md font-semibold">
77
94
  {snippet.unscoped_name}
78
95
  </h3>
79
- <div className="flex items-center text-gray-600">
80
- <StarIcon className="w-4 h-4 mr-1" />
81
- <span>{snippet.star_count || 0}</span>
96
+ <div className="flex items-center gap-2">
97
+ <div className="flex items-center text-gray-600">
98
+ <StarIcon className="w-4 h-4 mr-1" />
99
+ <span>{snippet.star_count || 0}</span>
100
+ </div>
101
+ {isCurrentUserProfile && (
102
+ <DropdownMenu>
103
+ <DropdownMenuTrigger asChild>
104
+ <Button
105
+ variant="ghost"
106
+ size="icon"
107
+ className="h-8 w-8"
108
+ >
109
+ <MoreVertical className="h-4 w-4" />
110
+ </Button>
111
+ </DropdownMenuTrigger>
112
+ <DropdownMenuContent>
113
+ <DropdownMenuItem
114
+ className="text-xs text-red-600"
115
+ onClick={(e) => handleDeleteClick(e, snippet)}
116
+ >
117
+ <Trash2 className="mr-2 h-3 w-3" />
118
+ Delete Snippet
119
+ </DropdownMenuItem>
120
+ </DropdownMenuContent>
121
+ </DropdownMenu>
122
+ )}
82
123
  </div>
83
124
  </div>
84
125
  <p className="text-sm text-gray-500">
@@ -91,6 +132,12 @@ export const UserProfilePage = () => {
91
132
  </div>
92
133
  )}
93
134
  </div>
135
+ {snippetToDelete && (
136
+ <DeleteDialog
137
+ snippetId={snippetToDelete.snippet_id}
138
+ snippetName={snippetToDelete.unscoped_name}
139
+ />
140
+ )}
94
141
  <Footer />
95
142
  </div>
96
143
  )