@tscircuit/fake-snippets 0.0.1

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 (396) hide show
  1. package/.github/CODEOWNERS +1 -0
  2. package/.github/workflows/bun-formatcheck.yml +26 -0
  3. package/.github/workflows/bun-test.yml +28 -0
  4. package/.github/workflows/bun-typecheck.yml +26 -0
  5. package/.github/workflows/bundle-size-analysis.yml +79 -0
  6. package/.github/workflows/playwright-test.yml +37 -0
  7. package/.github/workflows/stale.yml +40 -0
  8. package/.github/workflows/update-snapshots.yml +49 -0
  9. package/CONTRIBUTING.md +59 -0
  10. package/LICENSE +21 -0
  11. package/README.md +113 -0
  12. package/biome.json +60 -0
  13. package/bun-tests/fake-snippets-api/fixtures/get-circuit-json.ts +148 -0
  14. package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +96 -0
  15. package/bun-tests/fake-snippets-api/fixtures/start-server.ts +44 -0
  16. package/bun-tests/fake-snippets-api/routes/accounts/get_account_balance.test.ts +18 -0
  17. package/bun-tests/fake-snippets-api/routes/health.test.ts +9 -0
  18. package/bun-tests/fake-snippets-api/routes/order_files/get.test.ts +48 -0
  19. package/bun-tests/fake-snippets-api/routes/order_files/upload.test.ts +77 -0
  20. package/bun-tests/fake-snippets-api/routes/orders/create.test.ts +19 -0
  21. package/bun-tests/fake-snippets-api/routes/orders/get.test.ts +38 -0
  22. package/bun-tests/fake-snippets-api/routes/orders/list.test.ts +30 -0
  23. package/bun-tests/fake-snippets-api/routes/orders/update.test.ts +46 -0
  24. package/bun-tests/fake-snippets-api/routes/snippets/add_star.test.ts +114 -0
  25. package/bun-tests/fake-snippets-api/routes/snippets/create.test.ts +28 -0
  26. package/bun-tests/fake-snippets-api/routes/snippets/delete.test.ts +106 -0
  27. package/bun-tests/fake-snippets-api/routes/snippets/download.test.ts +90 -0
  28. package/bun-tests/fake-snippets-api/routes/snippets/generate_from_jlcpcb.test.ts +25 -0
  29. package/bun-tests/fake-snippets-api/routes/snippets/get_image.test.ts +113 -0
  30. package/bun-tests/fake-snippets-api/routes/snippets/images.test.ts +112 -0
  31. package/bun-tests/fake-snippets-api/routes/snippets/list.test.ts +62 -0
  32. package/bun-tests/fake-snippets-api/routes/snippets/list_newest.test.ts +48 -0
  33. package/bun-tests/fake-snippets-api/routes/snippets/list_trending.test.ts +69 -0
  34. package/bun-tests/fake-snippets-api/routes/snippets/remove_star.test.ts +110 -0
  35. package/bun-tests/fake-snippets-api/routes/snippets/search.test.ts +75 -0
  36. package/bun-tests/fake-snippets-api/routes/snippets/star-count.test.ts +44 -0
  37. package/bun-tests/fake-snippets-api/routes/snippets/update.test.ts +116 -0
  38. package/bun-tests/parts-engine.test.ts +18 -0
  39. package/bun.lockb +0 -0
  40. package/bunfig.toml +2 -0
  41. package/components.json +20 -0
  42. package/dist/assets/editor_example_1-1000w.webp +0 -0
  43. package/dist/assets/editor_example_1-1200w.webp +0 -0
  44. package/dist/assets/editor_example_1-1600w.webp +0 -0
  45. package/dist/assets/editor_example_1-2000w.webp +0 -0
  46. package/dist/assets/editor_example_1-400w.webp +0 -0
  47. package/dist/assets/editor_example_1-600w.webp +0 -0
  48. package/dist/assets/editor_example_1-800w.webp +0 -0
  49. package/dist/assets/editor_example_1_more_square-1000w.webp +0 -0
  50. package/dist/assets/editor_example_1_more_square-1200w.webp +0 -0
  51. package/dist/assets/editor_example_1_more_square-1600w.webp +0 -0
  52. package/dist/assets/editor_example_1_more_square-2000w.webp +0 -0
  53. package/dist/assets/editor_example_1_more_square-400w.webp +0 -0
  54. package/dist/assets/editor_example_1_more_square-600w.webp +0 -0
  55. package/dist/assets/editor_example_1_more_square-800w.webp +0 -0
  56. package/dist/assets/editor_example_2-1000w.webp +0 -0
  57. package/dist/assets/editor_example_2-1200w.webp +0 -0
  58. package/dist/assets/editor_example_2-1600w.webp +0 -0
  59. package/dist/assets/editor_example_2-2000w.webp +0 -0
  60. package/dist/assets/editor_example_2-400w.webp +0 -0
  61. package/dist/assets/editor_example_2-600w.webp +0 -0
  62. package/dist/assets/editor_example_2-800w.webp +0 -0
  63. package/dist/assets/example_schematic-1000w.webp +0 -0
  64. package/dist/assets/example_schematic-1200w.webp +0 -0
  65. package/dist/assets/example_schematic-1600w.webp +0 -0
  66. package/dist/assets/example_schematic-2000w.webp +0 -0
  67. package/dist/assets/example_schematic-400w.webp +0 -0
  68. package/dist/assets/example_schematic-600w.webp +0 -0
  69. package/dist/assets/example_schematic-800w.webp +0 -0
  70. package/dist/bundle.js +3270 -0
  71. package/dist/robots.txt +9 -0
  72. package/dist/sitemap.xml +118 -0
  73. package/docs/CIRCUIT_JSON_SOURCE_COMPONENT_OVERVIEW.md +151 -0
  74. package/fake-snippets-api/README.md +6 -0
  75. package/fake-snippets-api/biome.json +47 -0
  76. package/fake-snippets-api/bun.lockb +0 -0
  77. package/fake-snippets-api/lib/db/autoload-dev-snippets.ts +84 -0
  78. package/fake-snippets-api/lib/db/autoload-snippets.json +24 -0
  79. package/fake-snippets-api/lib/db/db-client.ts +343 -0
  80. package/fake-snippets-api/lib/db/schema.ts +112 -0
  81. package/fake-snippets-api/lib/db/seed.ts +1608 -0
  82. package/fake-snippets-api/lib/middleware/with-ctx-error.ts +26 -0
  83. package/fake-snippets-api/lib/middleware/with-db.ts +15 -0
  84. package/fake-snippets-api/lib/middleware/with-error-handling.ts +24 -0
  85. package/fake-snippets-api/lib/middleware/with-optional-session-auth.ts +34 -0
  86. package/fake-snippets-api/lib/middleware/with-request-logging.ts +54 -0
  87. package/fake-snippets-api/lib/middleware/with-session-auth.ts +39 -0
  88. package/fake-snippets-api/lib/middleware/with-winter-spec.ts +24 -0
  89. package/fake-snippets-api/next-env.d.ts +5 -0
  90. package/fake-snippets-api/routes/api/accounts/get.ts +21 -0
  91. package/fake-snippets-api/routes/api/accounts/get_account_balance.ts +22 -0
  92. package/fake-snippets-api/routes/api/accounts/update.ts +32 -0
  93. package/fake-snippets-api/routes/api/ai/[...anyroute].ts +31 -0
  94. package/fake-snippets-api/routes/api/ai.ts +2 -0
  95. package/fake-snippets-api/routes/api/aistream/[...anyroute].ts +65 -0
  96. package/fake-snippets-api/routes/api/health.ts +9 -0
  97. package/fake-snippets-api/routes/api/internal/sessions/create_without_auth.ts +63 -0
  98. package/fake-snippets-api/routes/api/order_files/get.ts +28 -0
  99. package/fake-snippets-api/routes/api/order_files/upload.ts +43 -0
  100. package/fake-snippets-api/routes/api/orders/create.ts +41 -0
  101. package/fake-snippets-api/routes/api/orders/get.ts +28 -0
  102. package/fake-snippets-api/routes/api/orders/list.ts +15 -0
  103. package/fake-snippets-api/routes/api/orders/update.ts +50 -0
  104. package/fake-snippets-api/routes/api/snippets/add_star.ts +42 -0
  105. package/fake-snippets-api/routes/api/snippets/create.ts +55 -0
  106. package/fake-snippets-api/routes/api/snippets/delete.ts +41 -0
  107. package/fake-snippets-api/routes/api/snippets/download.ts +148 -0
  108. package/fake-snippets-api/routes/api/snippets/generate_from_jlcpcb.ts +55 -0
  109. package/fake-snippets-api/routes/api/snippets/get.ts +50 -0
  110. package/fake-snippets-api/routes/api/snippets/get_image.ts +65 -0
  111. package/fake-snippets-api/routes/api/snippets/images/[author]/[snippet_name]/[typeFormat].ts +74 -0
  112. package/fake-snippets-api/routes/api/snippets/list.ts +28 -0
  113. package/fake-snippets-api/routes/api/snippets/list_newest.ts +13 -0
  114. package/fake-snippets-api/routes/api/snippets/list_trending.ts +21 -0
  115. package/fake-snippets-api/routes/api/snippets/remove_star.ts +42 -0
  116. package/fake-snippets-api/routes/api/snippets/search.ts +18 -0
  117. package/fake-snippets-api/routes/api/snippets/update.ts +86 -0
  118. package/favicon.ico +0 -0
  119. package/index.html +23 -0
  120. package/landing.html +23 -0
  121. package/package.json +164 -0
  122. package/playwright-tests/ai-page.spec.ts +19 -0
  123. package/playwright-tests/cmd-click.spec.ts +43 -0
  124. package/playwright-tests/dashboard-page.spec.ts +10 -0
  125. package/playwright-tests/editor-page.spec.ts +15 -0
  126. package/playwright-tests/files-dialog.spec.ts +19 -0
  127. package/playwright-tests/footprint-dialog/footprint-dialog.spec.ts +27 -0
  128. package/playwright-tests/footprint-dialog/footprint-insertion.spec.ts +38 -0
  129. package/playwright-tests/footprint-dialog/footprint-preview.spec.ts +34 -0
  130. package/playwright-tests/footprint-dialog/footprint-selection.spec.ts +29 -0
  131. package/playwright-tests/handle-manual-edits.spec.ts +55 -0
  132. package/playwright-tests/home-page.spec.ts +10 -0
  133. package/playwright-tests/images.spec.ts +17 -0
  134. package/playwright-tests/manual-edits.spec.ts +89 -0
  135. package/playwright-tests/preview-page.spec.ts +14 -0
  136. package/playwright-tests/quickstart-page.spec.ts +10 -0
  137. package/playwright-tests/search-links.spec.ts +21 -0
  138. package/playwright-tests/search.spec.ts +27 -0
  139. package/playwright-tests/snapshots/ai-page.spec.ts-AI-Page-lg.png +0 -0
  140. package/playwright-tests/snapshots/ai-page.spec.ts-AI-Page-md.png +0 -0
  141. package/playwright-tests/snapshots/ai-page.spec.ts-AI-Page-xs.png +0 -0
  142. package/playwright-tests/snapshots/cmd-click.spec.ts-underlined-imports.png +0 -0
  143. package/playwright-tests/snapshots/dashboard-page.spec.ts-Dashboard-page-lg.png +0 -0
  144. package/playwright-tests/snapshots/dashboard-page.spec.ts-Dashboard-page-md.png +0 -0
  145. package/playwright-tests/snapshots/dashboard-page.spec.ts-Dashboard-page-xs.png +0 -0
  146. package/playwright-tests/snapshots/editor-page.spec.ts-editor-with-snippet.png +0 -0
  147. package/playwright-tests/snapshots/error-fallback.spec.ts-error-fallback-lg.png +0 -0
  148. package/playwright-tests/snapshots/error-fallback.spec.ts-error-fallback-md.png +0 -0
  149. package/playwright-tests/snapshots/error-fallback.spec.ts-error-fallback-xs.png +0 -0
  150. package/playwright-tests/snapshots/files-dialog.spec.ts-view-snippet-files.png +0 -0
  151. package/playwright-tests/snapshots/footprint-dialog/footprint-dialog.spec.ts-footprint-preview-lg.png +0 -0
  152. package/playwright-tests/snapshots/footprint-dialog/footprint-dialog.spec.ts-footprint-preview-md.png +0 -0
  153. package/playwright-tests/snapshots/footprint-dialog/footprint-dialog.spec.ts-footprint-preview-xs.png +0 -0
  154. package/playwright-tests/snapshots/footprint-dialog/footprint-insertion.spec.ts-footprint-insertion-lg.png +0 -0
  155. package/playwright-tests/snapshots/footprint-dialog/footprint-insertion.spec.ts-footprint-insertion-md.png +0 -0
  156. package/playwright-tests/snapshots/footprint-dialog/footprint-insertion.spec.ts-footprint-insertion-xs.png +0 -0
  157. package/playwright-tests/snapshots/footprint-dialog/footprint-preview.spec.ts-footprint-preview-lg.png +0 -0
  158. package/playwright-tests/snapshots/footprint-dialog/footprint-preview.spec.ts-footprint-preview-md.png +0 -0
  159. package/playwright-tests/snapshots/footprint-dialog/footprint-preview.spec.ts-footprint-preview-xs.png +0 -0
  160. package/playwright-tests/snapshots/footprint-dialog/footprint-selection.spec.ts-footprint-preview-lg.png +0 -0
  161. package/playwright-tests/snapshots/footprint-dialog/footprint-selection.spec.ts-footprint-preview-md.png +0 -0
  162. package/playwright-tests/snapshots/footprint-dialog/footprint-selection.spec.ts-footprint-preview-xs.png +0 -0
  163. package/playwright-tests/snapshots/handle-manual-edits.spec.ts-handle-manual-edits.png +0 -0
  164. package/playwright-tests/snapshots/home-page.spec.ts-Home-page-lg.png +0 -0
  165. package/playwright-tests/snapshots/home-page.spec.ts-Home-page-md.png +0 -0
  166. package/playwright-tests/snapshots/home-page.spec.ts-Home-page-xs.png +0 -0
  167. package/playwright-tests/snapshots/images.spec.ts-pcb-image.png +0 -0
  168. package/playwright-tests/snapshots/images.spec.ts-schematic-image.png +0 -0
  169. package/playwright-tests/snapshots/manual-edits.spec.ts-editor-manual-edits.png +0 -0
  170. package/playwright-tests/snapshots/manual-edits.spec.ts-manual-edits-view.png +0 -0
  171. package/playwright-tests/snapshots/preview-page.spec.ts-preview-snippet-pcb.png +0 -0
  172. package/playwright-tests/snapshots/preview-page.spec.ts-preview-snippet-schematic.png +0 -0
  173. package/playwright-tests/snapshots/quickstart-page.spec.ts-Quickstart-Pagelg.png +0 -0
  174. package/playwright-tests/snapshots/quickstart-page.spec.ts-Quickstart-Pagemd.png +0 -0
  175. package/playwright-tests/snapshots/quickstart-page.spec.ts-Quickstart-Pagexs.png +0 -0
  176. package/playwright-tests/snapshots/search-links.spec.ts-search-links.png +0 -0
  177. package/playwright-tests/snapshots/search.spec.ts-search-lg.png +0 -0
  178. package/playwright-tests/snapshots/search.spec.ts-search-md.png +0 -0
  179. package/playwright-tests/snapshots/search.spec.ts-search-xs.png +0 -0
  180. package/playwright-tests/snapshots/star.spec.ts-remove-star-button.png +0 -0
  181. package/playwright-tests/snapshots/star.spec.ts-star-button.png +0 -0
  182. package/playwright-tests/snapshots/update-description.spec.ts-update-description.png +0 -0
  183. package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-after-lg.png +0 -0
  184. package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-after-md.png +0 -0
  185. package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-after-xs.png +0 -0
  186. package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-before-lg.png +0 -0
  187. package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-before-md.png +0 -0
  188. package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-before-xs.png +0 -0
  189. package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-files.png +0 -0
  190. package/playwright-tests/star.spec.ts +40 -0
  191. package/playwright-tests/update-description.spec.ts +18 -0
  192. package/playwright-tests/view-snippet.spec.ts +35 -0
  193. package/playwright-tests/viewports.ts +5 -0
  194. package/playwright.config.ts +27 -0
  195. package/postcss.config.js +6 -0
  196. package/public/robots.txt +9 -0
  197. package/renovate.json +24 -0
  198. package/scripts/generate-image-sizes.ts +58 -0
  199. package/scripts/generate-sitemap.ts +103 -0
  200. package/scripts/generate_bundle_stats.js +192 -0
  201. package/scripts/snapshot.ts +35 -0
  202. package/src/App.tsx +113 -0
  203. package/src/ContextProviders.tsx +9 -0
  204. package/src/assets/originals/editor_example_1.webp +0 -0
  205. package/src/assets/originals/editor_example_1_more_square.webp +0 -0
  206. package/src/assets/originals/editor_example_2.webp +0 -0
  207. package/src/assets/originals/example_schematic.webp +0 -0
  208. package/src/components/AiChatInterface.tsx +221 -0
  209. package/src/components/AiChatMessage.tsx +86 -0
  210. package/src/components/Analytics.tsx +30 -0
  211. package/src/components/BomTable.tsx +69 -0
  212. package/src/components/ChatInput.tsx +53 -0
  213. package/src/components/CircuitToSvgWithMouseControl.tsx +78 -0
  214. package/src/components/CmdKMenu.tsx +301 -0
  215. package/src/components/CodeAndPreview.tsx +258 -0
  216. package/src/components/CodeEditor.tsx +460 -0
  217. package/src/components/CodeEditorHeader.tsx +160 -0
  218. package/src/components/CreateNewSnippetWithAiHero.tsx +77 -0
  219. package/src/components/DownloadButtonAndMenu.tsx +212 -0
  220. package/src/components/EditorNav.tsx +428 -0
  221. package/src/components/ErrorFallback.tsx +25 -0
  222. package/src/components/ErrorTabContent.tsx +122 -0
  223. package/src/components/FAQ.tsx +113 -0
  224. package/src/components/Footer.tsx +134 -0
  225. package/src/components/Footer2.tsx +100 -0
  226. package/src/components/FootprintDialog.tsx +342 -0
  227. package/src/components/Header.tsx +187 -0
  228. package/src/components/Header2.tsx +135 -0
  229. package/src/components/HeaderDropdown.tsx +83 -0
  230. package/src/components/HeaderLogin.tsx +94 -0
  231. package/src/components/JLCPCBImportDialog.tsx +155 -0
  232. package/src/components/LandingHero.tsx +175 -0
  233. package/src/components/LatestSnippets.tsx +39 -0
  234. package/src/components/OptimizedImage.tsx +96 -0
  235. package/src/components/OrderPreviewContent.tsx +61 -0
  236. package/src/components/ParametersEditor.tsx +140 -0
  237. package/src/components/PcbViewerWithContainerHeight.tsx +47 -0
  238. package/src/components/PrefetchPageLink.tsx +45 -0
  239. package/src/components/PreviewContent.tsx +375 -0
  240. package/src/components/PreviewEmptyState.tsx +16 -0
  241. package/src/components/RunButton.tsx +27 -0
  242. package/src/components/SearchComponent.tsx +163 -0
  243. package/src/components/ShippingInformationForm.tsx +423 -0
  244. package/src/components/SnippetLink.tsx +37 -0
  245. package/src/components/StaticPreviewContent.tsx +89 -0
  246. package/src/components/StaticViewSnippetHeader.tsx +70 -0
  247. package/src/components/StaticViewSnippetSidebar.tsx +100 -0
  248. package/src/components/TableViewer/CircuitJsonTableViewer.tsx +316 -0
  249. package/src/components/TableViewer/ClickableText.tsx +21 -0
  250. package/src/components/TableViewer/HeaderCell.tsx +27 -0
  251. package/src/components/TableViewer/Modal.tsx +39 -0
  252. package/src/components/TrendingSnippetCarousel.tsx +77 -0
  253. package/src/components/TypeBadge.tsx +31 -0
  254. package/src/components/ViewSnippetHeader.tsx +144 -0
  255. package/src/components/ViewSnippetSidebar.tsx +162 -0
  256. package/src/components/dialogs/confirm-delete-snippet-dialog.tsx +80 -0
  257. package/src/components/dialogs/create-order-dialog.tsx +146 -0
  258. package/src/components/dialogs/create-use-dialog.tsx +34 -0
  259. package/src/components/dialogs/edit-description-dialog.tsx +96 -0
  260. package/src/components/dialogs/files-dialog.tsx +70 -0
  261. package/src/components/dialogs/import-snippet-dialog.tsx +84 -0
  262. package/src/components/dialogs/rename-snippet-dialog.tsx +81 -0
  263. package/src/components/dialogs/view-ts-files-dialog.tsx +89 -0
  264. package/src/components/ui/accordion.tsx +55 -0
  265. package/src/components/ui/alert-dialog.tsx +139 -0
  266. package/src/components/ui/alert.tsx +59 -0
  267. package/src/components/ui/aspect-ratio.tsx +5 -0
  268. package/src/components/ui/avatar.tsx +48 -0
  269. package/src/components/ui/badge.tsx +36 -0
  270. package/src/components/ui/breadcrumb.tsx +118 -0
  271. package/src/components/ui/button.tsx +58 -0
  272. package/src/components/ui/calendar.tsx +73 -0
  273. package/src/components/ui/card.tsx +76 -0
  274. package/src/components/ui/carousel.tsx +260 -0
  275. package/src/components/ui/chart.tsx +363 -0
  276. package/src/components/ui/checkbox.tsx +28 -0
  277. package/src/components/ui/collapsible.tsx +9 -0
  278. package/src/components/ui/combobox.tsx +178 -0
  279. package/src/components/ui/command.tsx +151 -0
  280. package/src/components/ui/context-menu.tsx +202 -0
  281. package/src/components/ui/dialog.tsx +120 -0
  282. package/src/components/ui/drawer.tsx +116 -0
  283. package/src/components/ui/dropdown-menu.tsx +203 -0
  284. package/src/components/ui/form.tsx +182 -0
  285. package/src/components/ui/hover-card.tsx +27 -0
  286. package/src/components/ui/input-otp.tsx +69 -0
  287. package/src/components/ui/input.tsx +25 -0
  288. package/src/components/ui/label.tsx +24 -0
  289. package/src/components/ui/menubar.tsx +238 -0
  290. package/src/components/ui/navigation-menu.tsx +129 -0
  291. package/src/components/ui/pagination.tsx +121 -0
  292. package/src/components/ui/popover.tsx +31 -0
  293. package/src/components/ui/progress.tsx +26 -0
  294. package/src/components/ui/radio-group.tsx +42 -0
  295. package/src/components/ui/resizable.tsx +43 -0
  296. package/src/components/ui/scroll-area.tsx +46 -0
  297. package/src/components/ui/searchable-select.tsx +94 -0
  298. package/src/components/ui/select.tsx +162 -0
  299. package/src/components/ui/separator.tsx +29 -0
  300. package/src/components/ui/sheet.tsx +141 -0
  301. package/src/components/ui/skeleton.tsx +18 -0
  302. package/src/components/ui/slider.tsx +26 -0
  303. package/src/components/ui/sonner.tsx +30 -0
  304. package/src/components/ui/switch.tsx +27 -0
  305. package/src/components/ui/table.tsx +120 -0
  306. package/src/components/ui/tabs.tsx +53 -0
  307. package/src/components/ui/textarea.tsx +24 -0
  308. package/src/components/ui/toast.tsx +128 -0
  309. package/src/components/ui/toaster.tsx +33 -0
  310. package/src/components/ui/toggle-group.tsx +59 -0
  311. package/src/components/ui/toggle.tsx +43 -0
  312. package/src/components/ui/tooltip.tsx +28 -0
  313. package/src/entry-server.tsx +12 -0
  314. package/src/hooks/use-account-balance.ts +24 -0
  315. package/src/hooks/use-ai-api.ts +35 -0
  316. package/src/hooks/use-axios.ts +20 -0
  317. package/src/hooks/use-code-completion-ai-api.ts +11 -0
  318. package/src/hooks/use-compiled-tsx.ts +37 -0
  319. package/src/hooks/use-copy-to-clipboard.ts +26 -0
  320. package/src/hooks/use-create-snippet-mutation.ts +62 -0
  321. package/src/hooks/use-current-snippet-id.ts +75 -0
  322. package/src/hooks/use-current-snippet.ts +24 -0
  323. package/src/hooks/use-global-store.ts +33 -0
  324. package/src/hooks/use-is-using-fake-api.ts +3 -0
  325. package/src/hooks/use-run-tsx/construct-circuit.tsx +64 -0
  326. package/src/hooks/use-run-tsx/eval-compiled-js.ts +9 -0
  327. package/src/hooks/use-run-tsx/index.tsx +251 -0
  328. package/src/hooks/use-save-snippet.ts +66 -0
  329. package/src/hooks/use-sign-in.ts +22 -0
  330. package/src/hooks/use-snippet-by-name.ts +25 -0
  331. package/src/hooks/use-snippet.ts +23 -0
  332. package/src/hooks/use-snippets-base-api-url.ts +3 -0
  333. package/src/hooks/use-toast.tsx +208 -0
  334. package/src/hooks/use-typecheck.ts +54 -0
  335. package/src/hooks/use-url-params.ts +31 -0
  336. package/src/hooks/use-warn-user-on-page-change.ts +23 -0
  337. package/src/hooks/useForkSnippetMutation.ts +52 -0
  338. package/src/index.css +21 -0
  339. package/src/lib/__tests__/constants.test.ts +66 -0
  340. package/src/lib/base64ToBytes.ts +5 -0
  341. package/src/lib/bytesToBase64.ts +4 -0
  342. package/src/lib/codemirror/basic-setup.ts +51 -0
  343. package/src/lib/constants.ts +12 -0
  344. package/src/lib/decodeUrlHashToText.ts +15 -0
  345. package/src/lib/defaultCodeForBlankCode.tsx +7 -0
  346. package/src/lib/download-fns/createBlobURL.ts +4 -0
  347. package/src/lib/download-fns/download-assembly-svg.ts +12 -0
  348. package/src/lib/download-fns/download-circuit-json-fn.ts +12 -0
  349. package/src/lib/download-fns/download-dsn-file-fn.ts +12 -0
  350. package/src/lib/download-fns/download-fabrication-files.ts +233 -0
  351. package/src/lib/download-fns/download-gltf.ts +49 -0
  352. package/src/lib/download-fns/download-kicad-files.ts +27 -0
  353. package/src/lib/download-fns/download-readable-netlist.ts +12 -0
  354. package/src/lib/download-fns/download-schematic-svg.ts +12 -0
  355. package/src/lib/download-fns/download-simple-route-json.ts +17 -0
  356. package/src/lib/encodeTextToUrlHash.ts +17 -0
  357. package/src/lib/get-snippet-template.ts +26 -0
  358. package/src/lib/handleManualEditsImport.tsx +65 -0
  359. package/src/lib/jlc-parts-engine.ts +69 -0
  360. package/src/lib/templates/blank-3d-model-template.ts +12 -0
  361. package/src/lib/templates/blank-circuit-board-template.ts +24 -0
  362. package/src/lib/templates/blank-footprint-template.ts +29 -0
  363. package/src/lib/templates/blank-package-template.ts +22 -0
  364. package/src/lib/templates/blinking-led-board-template.ts +63 -0
  365. package/src/lib/templates/manual-edits-template.ts +5 -0
  366. package/src/lib/templates/usb-c-led-flashlight-template.ts +22 -0
  367. package/src/lib/utils/checkIfManualEditsImported.ts +6 -0
  368. package/src/lib/utils/getSyntaxError.ts +13 -0
  369. package/src/lib/utils/index.ts +6 -0
  370. package/src/lib/utils/load-prettier.ts +18 -0
  371. package/src/lib/utils/parseFootprintParams.ts +52 -0
  372. package/src/lib/utils/parseJsonOrNull.ts +8 -0
  373. package/src/lib/utils/pcbManualEditEventHandler.ts +156 -0
  374. package/src/main.tsx +10 -0
  375. package/src/pages/ai.tsx +92 -0
  376. package/src/pages/authorize.tsx +54 -0
  377. package/src/pages/dashboard.tsx +165 -0
  378. package/src/pages/dev-login.tsx +68 -0
  379. package/src/pages/editor.tsx +28 -0
  380. package/src/pages/landing.tsx +236 -0
  381. package/src/pages/my-orders.tsx +54 -0
  382. package/src/pages/newest.tsx +16 -0
  383. package/src/pages/preview.tsx +70 -0
  384. package/src/pages/quickstart.tsx +198 -0
  385. package/src/pages/search.tsx +26 -0
  386. package/src/pages/settings.tsx +25 -0
  387. package/src/pages/user-profile.tsx +97 -0
  388. package/src/pages/view-order.tsx +123 -0
  389. package/src/pages/view-snippet.tsx +149 -0
  390. package/src/prettier.ts +9 -0
  391. package/src/vite-env.d.ts +1 -0
  392. package/tailwind.config.js +47 -0
  393. package/tsconfig.json +30 -0
  394. package/vercel.json +50 -0
  395. package/vite.config.ts +146 -0
  396. package/winterspec.config.ts +6 -0
@@ -0,0 +1,28 @@
1
+ import { CodeAndPreview } from "@/components/CodeAndPreview"
2
+ import Footer from "@/components/Footer"
3
+ import Header from "@/components/Header"
4
+ import { useCurrentSnippetId } from "@/hooks/use-current-snippet-id"
5
+ import { useSnippet } from "@/hooks/use-snippet"
6
+
7
+ export const EditorPage = () => {
8
+ const { snippetId } = useCurrentSnippetId()
9
+ const { data: snippet, isLoading, error } = useSnippet(snippetId)
10
+
11
+ return (
12
+ <div>
13
+ <Header />
14
+ {!error && <CodeAndPreview snippet={snippet} />}
15
+ {error && error.status === 404 && (
16
+ <div className="w-full h-[calc(100vh-20rem)] text-xl text-center flex justify-center items-center">
17
+ Snippet not found
18
+ </div>
19
+ )}
20
+ {error && error.status !== 404 && (
21
+ <div className="flex flex-col">
22
+ Something strange happened<div>{error.message}</div>
23
+ </div>
24
+ )}
25
+ <Footer />
26
+ </div>
27
+ )
28
+ }
@@ -0,0 +1,236 @@
1
+ import { Button } from "@/components/ui/button"
2
+ import { Card, CardContent } from "@/components/ui/card"
3
+ import { Badge } from "@/components/ui/badge"
4
+ import { OptimizedImage } from "@/components/OptimizedImage"
5
+ import {
6
+ CircuitBoard,
7
+ Code2,
8
+ Cpu,
9
+ Layers,
10
+ CloudLightningIcon as Lightning,
11
+ Maximize2,
12
+ Zap,
13
+ } from "lucide-react"
14
+ import { Helmet } from "react-helmet"
15
+ import { Header2 } from "@/components/Header2"
16
+ import Footer from "@/components/Footer"
17
+ import { useSignIn } from "@/hooks/use-sign-in"
18
+ import { useGlobalStore } from "@/hooks/use-global-store"
19
+ import { navigate } from "wouter/use-browser-location"
20
+ import { FAQ } from "@/components/FAQ"
21
+ import { TrendingSnippetCarousel } from "@/components/TrendingSnippetCarousel"
22
+ import { PrefetchPageLink } from "@/components/PrefetchPageLink"
23
+
24
+ export function LandingPage() {
25
+ const signIn = useSignIn()
26
+ const isLoggedIn = useGlobalStore((s) => Boolean(s.session))
27
+ return (
28
+ <div className="flex min-h-screen flex-col">
29
+ <Helmet>
30
+ <link rel="preconnect" href="https://img.shields.io" />
31
+ <link rel="dns-prefetch" href="https://img.shields.io" />
32
+
33
+ <link rel="preconnect" href="https://shields.io" />
34
+ <link rel="dns-prefetch" href="https://shields.io" />
35
+
36
+ <link rel="preconnect" href="https://tscircuit.com" />
37
+ <link rel="dns-prefetch" href="https://tscircuit.com" />
38
+
39
+ <link rel="preconnect" href="https://registry-api.tscircuit.com" />
40
+ <link rel="dns-prefetch" href="https://registry-api.tscircuit.com" />
41
+ </Helmet>
42
+ <Header2 />
43
+ <main className="flex-1">
44
+ <section className="w-full py-12 md:py-24 lg:py-32 xl:py-48">
45
+ <div className="container px-4 md:px-6 mx-auto">
46
+ <div className="container mx-auto max-w-7xl">
47
+ <div className="grid gap-6 lg:grid-cols-[1fr_400px] lg:gap-12 xl:grid-cols-[1fr_600px]">
48
+ <div className="flex flex-col justify-center space-y-4">
49
+ <div className="space-y-2">
50
+ <Badge variant="secondary" className="w-fit">
51
+ Open-Source, MIT Licensed
52
+ </Badge>
53
+ <h1 className="text-3xl font-bold tracking-tighter sm:text-5xl xl:text-6xl/none">
54
+ The New Foundation for Electronic Design
55
+ </h1>
56
+ <p className="max-w-[600px] text-muted-foreground md:text-xl">
57
+ Build electronics with code, AI, and drag'n'drop tools.
58
+ <br />
59
+ Render code into schematics, PCBs, 3D, fabrication files,
60
+ and more.
61
+ </p>
62
+ </div>
63
+ <div className="flex flex-col items-center gap-2 min-[400px]:flex-row">
64
+ <Button
65
+ onClick={() => {
66
+ if (!isLoggedIn) {
67
+ signIn()
68
+ } else {
69
+ navigate("/dashboard")
70
+ }
71
+ }}
72
+ size="lg"
73
+ aria-label="Get started with TSCircuit"
74
+ >
75
+ Get Started
76
+ </Button>
77
+ <PrefetchPageLink href="/quickstart">
78
+ <Button
79
+ size="lg"
80
+ variant="outline"
81
+ aria-label="Open online example of TSCircuit"
82
+ >
83
+ Open Online Example
84
+ </Button>
85
+ </PrefetchPageLink>
86
+ <a
87
+ href="https://github.com/tscircuit/tscircuit"
88
+ target="_blank"
89
+ rel="noopener noreferrer"
90
+ >
91
+ <img
92
+ alt="GitHub stars"
93
+ src="https://img.shields.io/github/stars/tscircuit/tscircuit?style=social"
94
+ />
95
+ </a>
96
+ </div>
97
+ <div className="grid grid-cols-2 gap-4 sm:flex items-center w-full text-sm">
98
+ <div className="flex items-center space-x-1">
99
+ <Zap className="h-4 w-4" />
100
+ <span>Lightning Fast Autorouting</span>
101
+ </div>
102
+ <div className="flex items-center space-x-1">
103
+ <Cpu className="h-4 w-4" />
104
+ <span>Designed for AI</span>
105
+ </div>
106
+ <div className="flex items-center space-x-1">
107
+ <Layers className="h-4 w-4" />
108
+ <span>Export &amp; Manufacture</span>
109
+ </div>
110
+ <div className="flex items-center space-x-1 sm:hidden">
111
+ <Code2 className="h-4 w-4" />
112
+ <span>Open Web Standards</span>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ <div className="w-full aspect-video relative">
117
+ <OptimizedImage
118
+ alt="Product preview"
119
+ className="mx-auto overflow-hidden rounded-xl object-cover object-center absolute inset-0 w-full h-full"
120
+ src="/assets/editor_example_1_more_square.webp"
121
+ priority={true}
122
+ />
123
+ </div>
124
+ </div>
125
+ </div>
126
+ </div>
127
+ </section>
128
+ <TrendingSnippetCarousel />
129
+ <section
130
+ className="w-full py-12 md:py-24 lg:py-32 bg-gray-100 dark:bg-gray-800"
131
+ id="features"
132
+ >
133
+ <div className="container px-4 md:px-6 mx-auto">
134
+ <div className="flex flex-col items-center justify-center space-y-4 text-center">
135
+ <div className="space-y-2">
136
+ <h2 className="text-3xl font-bold tracking-tighter md:text-4xl">
137
+ The Modern Toolkit for Electronic Design
138
+ </h2>
139
+ <p className="max-w-[900px] text-muted-foreground md:text-xl">
140
+ Typescript and React equipped with expertly-designed web-first
141
+ electronics libraries
142
+ </p>
143
+ </div>
144
+ </div>
145
+ <div className="mx-auto grid max-w-5xl items-center gap-6 py-12 lg:grid-cols-3">
146
+ <Card className="hover:shadow-lg transition-shadow duration-200 h-full">
147
+ <CardContent className="p-6">
148
+ <Lightning className="h-12 w-12 mb-4" />
149
+ <h3 className="text-xl font-bold">Version Control</h3>
150
+ <p className="text-sm text-muted-foreground">
151
+ Collaborate on Github or wherever you keep source code.
152
+ Utilize industry-standard continuous integration tooling
153
+ </p>
154
+ </CardContent>
155
+ </Card>
156
+ <Card className="hover:shadow-lg transition-shadow duration-200 h-full">
157
+ <CardContent className="p-6">
158
+ <Cpu className="h-12 w-12 mb-4" />
159
+ <h3 className="text-xl font-bold">Robust Autorouting</h3>
160
+ <p className="text-sm text-muted-foreground">
161
+ Near-instant local and cloud autorouters to give you a
162
+ functional circuit board fast
163
+ </p>
164
+ </CardContent>
165
+ </Card>
166
+ <Card className="hover:shadow-lg transition-shadow duration-200 h-full">
167
+ <CardContent className="p-6">
168
+ <Maximize2 className="h-12 w-12 mb-4" />
169
+ <h3 className="text-xl font-bold">
170
+ Export &amp; Manufacture
171
+ </h3>
172
+ <p className="text-sm text-muted-foreground">
173
+ Export to industry-standard formats like Gerber, SPICE
174
+ netlists and more
175
+ </p>
176
+ </CardContent>
177
+ </Card>
178
+ </div>
179
+ </div>
180
+ </section>
181
+ <div className="md:mt-8">
182
+ <OptimizedImage
183
+ alt="Product preview"
184
+ className="mx-auto aspect-video overflow-hidden rounded-xl object-cover object-center"
185
+ src="/assets/editor_example_2.webp"
186
+ height={310}
187
+ width={800}
188
+ />
189
+ </div>
190
+ <FAQ />
191
+ <div className="md:mt-8">
192
+ <OptimizedImage
193
+ alt="Product preview"
194
+ className="mx-auto aspect-video overflow-hidden rounded-xl object-cover object-center"
195
+ src="/assets/example_schematic.webp"
196
+ height={310}
197
+ width={800}
198
+ />
199
+ </div>
200
+ <section className="w-full py-12 md:py-24 lg:py-32 bg-primary" id="cta">
201
+ <div className="container px-4 md:px-6 mx-auto">
202
+ <div className="flex flex-col items-center justify-center space-y-4 text-center text-primary-foreground">
203
+ <div className="space-y-2">
204
+ <h2 className="text-3xl font-bold tracking-tighter md:text-4xl">
205
+ Ready to build electronics with code?
206
+ </h2>
207
+ <p className="max-w-[600px] text-primary-foreground/80 md:text-xl">
208
+ Join hundreds of engineers who are already using tscircuit to
209
+ design complex electronics!
210
+ </p>
211
+ </div>
212
+ <div className="flex flex-col gap-2 min-[400px]:flex-row">
213
+ <Button
214
+ onClick={() => {
215
+ if (!isLoggedIn) {
216
+ signIn()
217
+ } else {
218
+ navigate("/dashboard")
219
+ }
220
+ }}
221
+ size="lg"
222
+ variant="secondary"
223
+ aria-label="Get started with TSCircuit now"
224
+ >
225
+ Get Started
226
+ </Button>
227
+ </div>
228
+ </div>
229
+ </div>
230
+ </section>
231
+ </main>
232
+ <Footer />
233
+ {/* <Footer2 /> */}
234
+ </div>
235
+ )
236
+ }
@@ -0,0 +1,54 @@
1
+ import React from "react"
2
+ import { useQuery } from "react-query"
3
+ import { useAxios } from "@/hooks/use-axios"
4
+ import Header from "@/components/Header"
5
+ import Footer from "@/components/Footer"
6
+ import { Order } from "fake-snippets-api/lib/db/schema"
7
+ import { Link } from "wouter"
8
+ import { Button } from "@/components/ui/button"
9
+
10
+ export const MyOrdersPage = () => {
11
+ const axios = useAxios()
12
+
13
+ const { data: orders, isLoading } = useQuery<Order[]>(
14
+ "userOrders",
15
+ async () => {
16
+ const response = await axios.get("/orders/list")
17
+ return response.data.orders
18
+ },
19
+ )
20
+
21
+ return (
22
+ <div>
23
+ <Header />
24
+ <div className="container mx-auto px-4 py-8">
25
+ <h1 className="text-3xl font-bold mb-6">My Orders</h1>
26
+ {isLoading ? (
27
+ <div>Loading orders...</div>
28
+ ) : (
29
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
30
+ {orders?.map((order) => (
31
+ <div key={order.order_id} className="border p-4 rounded-md">
32
+ <h3 className="text-lg font-semibold">
33
+ Order #{order.order_id}
34
+ </h3>
35
+ <p className="text-sm text-gray-500">
36
+ Created: {new Date(order.created_at).toLocaleString()}
37
+ </p>
38
+ <p className="text-sm text-gray-500">
39
+ Status: {order.is_shipped ? "Shipped" : "Processing"}
40
+ </p>
41
+ <Link href={`/orders/${order.order_id}`}>
42
+ <Button className="mt-2" variant="outline">
43
+ View Details
44
+ </Button>
45
+ </Link>
46
+ </div>
47
+ ))}
48
+ </div>
49
+ )}
50
+ </div>
51
+ <Footer />
52
+ </div>
53
+ )
54
+ }
@@ -0,0 +1,16 @@
1
+ import Header from "@/components/Header"
2
+ import Footer from "@/components/Footer"
3
+ import { LatestSnippets } from "@/components/LatestSnippets"
4
+
5
+ export const NewestPage = () => {
6
+ return (
7
+ <div>
8
+ <Header />
9
+ <div className="container mx-auto px-4 py-8">
10
+ <h1 className="text-3xl font-bold mb-6">Newest Snippets</h1>
11
+ <LatestSnippets />
12
+ </div>
13
+ <Footer />
14
+ </div>
15
+ )
16
+ }
@@ -0,0 +1,70 @@
1
+ import { CircuitToSvgWithMouseControl } from "@/components/CircuitToSvgWithMouseControl"
2
+ import { useSnippet } from "@/hooks/use-snippet"
3
+ import { useUrlParams } from "@/hooks/use-url-params"
4
+ import { CadViewer } from "@tscircuit/3d-viewer"
5
+ import { PCBViewer } from "@tscircuit/pcb-viewer"
6
+ import { Loader2 } from "lucide-react"
7
+
8
+ export const PreviewPage = () => {
9
+ const urlParams = useUrlParams()
10
+ const snippetId = urlParams.snippet_id
11
+ const view = urlParams.view || "pcb"
12
+ const { data: snippet, isLoading, error } = useSnippet(snippetId)
13
+
14
+ if (isLoading) {
15
+ return (
16
+ <div className="w-full h-screen flex items-center justify-center">
17
+ <Loader2 className="w-8 h-8 animate-spin" />
18
+ </div>
19
+ )
20
+ }
21
+
22
+ if (error) {
23
+ return (
24
+ <div className="w-full h-screen flex items-center justify-center text-red-500">
25
+ Error loading snippet: {error.message}
26
+ </div>
27
+ )
28
+ }
29
+
30
+ if (!snippet) {
31
+ return (
32
+ <div className="w-full h-screen flex items-center justify-center text-gray-500">
33
+ Snippet not found
34
+ </div>
35
+ )
36
+ }
37
+
38
+ if (!snippet.circuit_json) {
39
+ return (
40
+ <div className="w-full h-screen flex items-center justify-center text-gray-500">
41
+ No circuit data available
42
+ </div>
43
+ )
44
+ }
45
+
46
+ const validViews = ["pcb", "3d", "schematic"]
47
+ if (!validViews.includes(view)) {
48
+ return (
49
+ <div className="w-full h-screen">
50
+ {view === "pcb" && (
51
+ <PCBViewer soup={snippet.circuit_json} height={window.innerHeight} />
52
+ )}
53
+ </div>
54
+ )
55
+ }
56
+
57
+ return (
58
+ <div className="w-full h-screen">
59
+ {view === "pcb" && (
60
+ <PCBViewer soup={snippet.circuit_json} height={window.innerHeight} />
61
+ )}
62
+ {view === "3d" && <CadViewer soup={snippet.circuit_json as any} />}
63
+ {view === "schematic" && (
64
+ <CircuitToSvgWithMouseControl
65
+ circuitJson={snippet.circuit_json as any}
66
+ />
67
+ )}
68
+ </div>
69
+ )
70
+ }
@@ -0,0 +1,198 @@
1
+ import React, { useState } from "react"
2
+ import { useQuery } from "react-query"
3
+ import { useAxios } from "@/hooks/use-axios"
4
+ import Header from "@/components/Header"
5
+ import Footer from "@/components/Footer"
6
+ import { Snippet } from "fake-snippets-api/lib/db/schema"
7
+ import { Button } from "@/components/ui/button"
8
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
9
+ import { TypeBadge } from "@/components/TypeBadge"
10
+ import { JLCPCBImportDialog } from "@/components/JLCPCBImportDialog"
11
+ import { useNotImplementedToast } from "@/hooks/use-toast"
12
+ import { useGlobalStore } from "@/hooks/use-global-store"
13
+ import { cn } from "@/lib/utils"
14
+ import { PrefetchPageLink } from "@/components/PrefetchPageLink"
15
+
16
+ export const QuickstartPage = () => {
17
+ const axios = useAxios()
18
+ const [isJLCPCBDialogOpen, setIsJLCPCBDialogOpen] = useState(false)
19
+ const toastNotImplemented = useNotImplementedToast()
20
+ const currentUser = useGlobalStore((s) => s.session?.github_username)
21
+ const { data: mySnippets, isLoading } = useQuery<Snippet[]>(
22
+ "userSnippets",
23
+ async () => {
24
+ const response = await axios.get(
25
+ `/snippets/list?owner_name=${currentUser}`,
26
+ )
27
+ return response.data.snippets
28
+ },
29
+ )
30
+
31
+ const blankTemplates = [
32
+ { name: "Blank Circuit Board", type: "board" },
33
+ { name: "Blank Circuit Module", type: "package" },
34
+ { name: "Blank 3D Model", type: "model", disabled: true },
35
+ { name: "Blank Footprint", type: "footprint", disabled: true },
36
+ ]
37
+
38
+ const templates = [
39
+ { name: "Blinking LED Board", type: "board" },
40
+ { name: "USB-C LED Flashlight", type: "board" },
41
+ ]
42
+
43
+ return (
44
+ <div>
45
+ <Header />
46
+ <div className="container mx-auto px-4 py-8">
47
+ <div className="mb-8 hidden md:block">
48
+ <h2 className="text-xl font-semibold mb-4">Recent Snippets</h2>
49
+ {isLoading ? (
50
+ <div>Loading...</div>
51
+ ) : (
52
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
53
+ {mySnippets
54
+ ?.sort(
55
+ (a, b) =>
56
+ new Date(b.created_at).getTime() -
57
+ new Date(a.created_at).getTime(),
58
+ )
59
+ .slice(0, 4)
60
+ .map((snippet) => (
61
+ <PrefetchPageLink
62
+ key={snippet.snippet_id}
63
+ href={`/editor?snippet_id=${snippet.snippet_id}`}
64
+ >
65
+ <Card className="hover:shadow-md transition-shadow rounded-md">
66
+ <CardHeader className="pb-0 p-4">
67
+ <CardTitle className="text-md">
68
+ {snippet.unscoped_name}
69
+ </CardTitle>
70
+ </CardHeader>
71
+ <CardContent className="p-4 pt-0">
72
+ <p className="text-sm text-gray-500">
73
+ Last edited:{" "}
74
+ {new Date(snippet.updated_at).toLocaleDateString()}
75
+ </p>
76
+ </CardContent>
77
+ </Card>
78
+ </PrefetchPageLink>
79
+ ))}
80
+ </div>
81
+ )}
82
+ </div>
83
+
84
+ <div className="mb-8">
85
+ <h2 className="text-xl font-semibold mb-4">Start Blank Snippet</h2>
86
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
87
+ {blankTemplates.map((template, index) => (
88
+ <PrefetchPageLink
89
+ key={index}
90
+ href={
91
+ template.disabled
92
+ ? "#"
93
+ : `/editor?template=${template.name
94
+ .toLowerCase()
95
+ .replace(/ /g, "-")}`
96
+ }
97
+ >
98
+ <Card
99
+ className={cn(
100
+ "hover:shadow-md transition-shadow rounded-md h-full flex flex-col",
101
+ template.disabled && "opacity-50 cursor-not-allowed",
102
+ )}
103
+ >
104
+ <CardHeader className="p-4 flex-grow flex flex-col justify-between">
105
+ <CardTitle className="text-md">{template.name}</CardTitle>
106
+ <div className="mt-2 flex">
107
+ <TypeBadge type={template.type as any} />
108
+ </div>
109
+ </CardHeader>
110
+ </Card>
111
+ </PrefetchPageLink>
112
+ ))}
113
+ </div>
114
+ </div>
115
+
116
+ <div className="mt-12">
117
+ <h2 className="text-xl font-semibold mb-4">Import as Snippet</h2>
118
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
119
+ {[
120
+ { name: "KiCad Footprint", type: "footprint" },
121
+ { name: "KiCad Project", type: "board" },
122
+ { name: "KiCad Module", type: "package" },
123
+ ].map((template, index) => (
124
+ <Card
125
+ key={index}
126
+ className="hover:shadow-md transition-shadow rounded-md opacity-50"
127
+ >
128
+ <CardHeader className="p-4 pb-0">
129
+ <CardTitle className="text-lg flex items-center justify-between">
130
+ {template.name}
131
+ <TypeBadge type={template.type as any} className="ml-2" />
132
+ </CardTitle>
133
+ </CardHeader>
134
+ <CardContent className="p-4">
135
+ <Button
136
+ className="w-full"
137
+ onClick={() => {
138
+ toastNotImplemented("Kicad Imports")
139
+ }}
140
+ >
141
+ Import {template.name}
142
+ </Button>
143
+ </CardContent>
144
+ </Card>
145
+ ))}
146
+ <Card className="hover:shadow-md transition-shadow rounded-md">
147
+ <CardHeader className="p-4 pb-0">
148
+ <CardTitle className="text-lg flex items-center justify-between">
149
+ JLCPCB Component
150
+ <TypeBadge type="package" className="ml-2" />
151
+ </CardTitle>
152
+ </CardHeader>
153
+ <CardContent className="p-4">
154
+ <Button
155
+ className="w-full"
156
+ onClick={() => setIsJLCPCBDialogOpen(true)}
157
+ >
158
+ Import JLCPCB Component
159
+ </Button>
160
+ </CardContent>
161
+ </Card>
162
+ </div>
163
+ </div>
164
+
165
+ <JLCPCBImportDialog
166
+ open={isJLCPCBDialogOpen}
167
+ onOpenChange={setIsJLCPCBDialogOpen}
168
+ />
169
+
170
+ <div>
171
+ <h2 className="text-xl font-semibold mb-4 mt-12">
172
+ Start from a Template
173
+ </h2>
174
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
175
+ {templates.map((template, index) => (
176
+ <PrefetchPageLink
177
+ key={index}
178
+ href={`/editor?template=${template.name
179
+ .toLowerCase()
180
+ .replace(/ /g, "-")}`}
181
+ >
182
+ <Card className="hover:shadow-md transition-shadow rounded-md">
183
+ <CardHeader className="p-4">
184
+ <CardTitle className="text-lg flex items-center justify-between">
185
+ {template.name}
186
+ <TypeBadge type={template.type as any} className="ml-2" />
187
+ </CardTitle>
188
+ </CardHeader>
189
+ </Card>
190
+ </PrefetchPageLink>
191
+ ))}
192
+ </div>
193
+ </div>
194
+ </div>
195
+ <Footer />
196
+ </div>
197
+ )
198
+ }
@@ -0,0 +1,26 @@
1
+ import Header from "@/components/Header"
2
+ import Footer from "@/components/Footer"
3
+
4
+ export const SearchPage = () => {
5
+ return (
6
+ <div>
7
+ <Header />
8
+ <div className="container mx-auto px-4 py-8">
9
+ <h1 className="text-3xl font-bold mb-6">Search Snippets</h1>
10
+ {/* Add search functionality and results display here */}
11
+ <input
12
+ type="text"
13
+ placeholder="Search snippets..."
14
+ className="w-full p-2 border rounded mb-4"
15
+ />
16
+ <div>
17
+ {/* Search results will be displayed here */}
18
+ <p className="text-gray-600">
19
+ No results found. Try a different search term.
20
+ </p>
21
+ </div>
22
+ </div>
23
+ <Footer />
24
+ </div>
25
+ )
26
+ }
@@ -0,0 +1,25 @@
1
+ import Header from "@/components/Header"
2
+ import Footer from "@/components/Footer"
3
+ import ShippingInformationForm from "@/components/ShippingInformationForm"
4
+
5
+ export const SettingsPage = () => {
6
+ return (
7
+ <div>
8
+ <Header />
9
+ <div className="container mx-auto px-4 py-8">
10
+ <h1 className="text-3xl font-bold mb-6">Settings</h1>
11
+ <div className="flex">
12
+ <div className="lg:w-1/2 sm:w-full pr-4">
13
+ <div className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
14
+ <h2 className="text-2xl font-semibold mb-4">
15
+ Shipping Information
16
+ </h2>
17
+ <ShippingInformationForm />
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ <Footer />
23
+ </div>
24
+ )
25
+ }