@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.
- package/.github/CODEOWNERS +1 -0
- package/.github/workflows/bun-formatcheck.yml +26 -0
- package/.github/workflows/bun-test.yml +28 -0
- package/.github/workflows/bun-typecheck.yml +26 -0
- package/.github/workflows/bundle-size-analysis.yml +79 -0
- package/.github/workflows/playwright-test.yml +37 -0
- package/.github/workflows/stale.yml +40 -0
- package/.github/workflows/update-snapshots.yml +49 -0
- package/CONTRIBUTING.md +59 -0
- package/LICENSE +21 -0
- package/README.md +113 -0
- package/biome.json +60 -0
- package/bun-tests/fake-snippets-api/fixtures/get-circuit-json.ts +148 -0
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +96 -0
- package/bun-tests/fake-snippets-api/fixtures/start-server.ts +44 -0
- package/bun-tests/fake-snippets-api/routes/accounts/get_account_balance.test.ts +18 -0
- package/bun-tests/fake-snippets-api/routes/health.test.ts +9 -0
- package/bun-tests/fake-snippets-api/routes/order_files/get.test.ts +48 -0
- package/bun-tests/fake-snippets-api/routes/order_files/upload.test.ts +77 -0
- package/bun-tests/fake-snippets-api/routes/orders/create.test.ts +19 -0
- package/bun-tests/fake-snippets-api/routes/orders/get.test.ts +38 -0
- package/bun-tests/fake-snippets-api/routes/orders/list.test.ts +30 -0
- package/bun-tests/fake-snippets-api/routes/orders/update.test.ts +46 -0
- package/bun-tests/fake-snippets-api/routes/snippets/add_star.test.ts +114 -0
- package/bun-tests/fake-snippets-api/routes/snippets/create.test.ts +28 -0
- package/bun-tests/fake-snippets-api/routes/snippets/delete.test.ts +106 -0
- package/bun-tests/fake-snippets-api/routes/snippets/download.test.ts +90 -0
- package/bun-tests/fake-snippets-api/routes/snippets/generate_from_jlcpcb.test.ts +25 -0
- package/bun-tests/fake-snippets-api/routes/snippets/get_image.test.ts +113 -0
- package/bun-tests/fake-snippets-api/routes/snippets/images.test.ts +112 -0
- package/bun-tests/fake-snippets-api/routes/snippets/list.test.ts +62 -0
- package/bun-tests/fake-snippets-api/routes/snippets/list_newest.test.ts +48 -0
- package/bun-tests/fake-snippets-api/routes/snippets/list_trending.test.ts +69 -0
- package/bun-tests/fake-snippets-api/routes/snippets/remove_star.test.ts +110 -0
- package/bun-tests/fake-snippets-api/routes/snippets/search.test.ts +75 -0
- package/bun-tests/fake-snippets-api/routes/snippets/star-count.test.ts +44 -0
- package/bun-tests/fake-snippets-api/routes/snippets/update.test.ts +116 -0
- package/bun-tests/parts-engine.test.ts +18 -0
- package/bun.lockb +0 -0
- package/bunfig.toml +2 -0
- package/components.json +20 -0
- package/dist/assets/editor_example_1-1000w.webp +0 -0
- package/dist/assets/editor_example_1-1200w.webp +0 -0
- package/dist/assets/editor_example_1-1600w.webp +0 -0
- package/dist/assets/editor_example_1-2000w.webp +0 -0
- package/dist/assets/editor_example_1-400w.webp +0 -0
- package/dist/assets/editor_example_1-600w.webp +0 -0
- package/dist/assets/editor_example_1-800w.webp +0 -0
- package/dist/assets/editor_example_1_more_square-1000w.webp +0 -0
- package/dist/assets/editor_example_1_more_square-1200w.webp +0 -0
- package/dist/assets/editor_example_1_more_square-1600w.webp +0 -0
- package/dist/assets/editor_example_1_more_square-2000w.webp +0 -0
- package/dist/assets/editor_example_1_more_square-400w.webp +0 -0
- package/dist/assets/editor_example_1_more_square-600w.webp +0 -0
- package/dist/assets/editor_example_1_more_square-800w.webp +0 -0
- package/dist/assets/editor_example_2-1000w.webp +0 -0
- package/dist/assets/editor_example_2-1200w.webp +0 -0
- package/dist/assets/editor_example_2-1600w.webp +0 -0
- package/dist/assets/editor_example_2-2000w.webp +0 -0
- package/dist/assets/editor_example_2-400w.webp +0 -0
- package/dist/assets/editor_example_2-600w.webp +0 -0
- package/dist/assets/editor_example_2-800w.webp +0 -0
- package/dist/assets/example_schematic-1000w.webp +0 -0
- package/dist/assets/example_schematic-1200w.webp +0 -0
- package/dist/assets/example_schematic-1600w.webp +0 -0
- package/dist/assets/example_schematic-2000w.webp +0 -0
- package/dist/assets/example_schematic-400w.webp +0 -0
- package/dist/assets/example_schematic-600w.webp +0 -0
- package/dist/assets/example_schematic-800w.webp +0 -0
- package/dist/bundle.js +3270 -0
- package/dist/robots.txt +9 -0
- package/dist/sitemap.xml +118 -0
- package/docs/CIRCUIT_JSON_SOURCE_COMPONENT_OVERVIEW.md +151 -0
- package/fake-snippets-api/README.md +6 -0
- package/fake-snippets-api/biome.json +47 -0
- package/fake-snippets-api/bun.lockb +0 -0
- package/fake-snippets-api/lib/db/autoload-dev-snippets.ts +84 -0
- package/fake-snippets-api/lib/db/autoload-snippets.json +24 -0
- package/fake-snippets-api/lib/db/db-client.ts +343 -0
- package/fake-snippets-api/lib/db/schema.ts +112 -0
- package/fake-snippets-api/lib/db/seed.ts +1608 -0
- package/fake-snippets-api/lib/middleware/with-ctx-error.ts +26 -0
- package/fake-snippets-api/lib/middleware/with-db.ts +15 -0
- package/fake-snippets-api/lib/middleware/with-error-handling.ts +24 -0
- package/fake-snippets-api/lib/middleware/with-optional-session-auth.ts +34 -0
- package/fake-snippets-api/lib/middleware/with-request-logging.ts +54 -0
- package/fake-snippets-api/lib/middleware/with-session-auth.ts +39 -0
- package/fake-snippets-api/lib/middleware/with-winter-spec.ts +24 -0
- package/fake-snippets-api/next-env.d.ts +5 -0
- package/fake-snippets-api/routes/api/accounts/get.ts +21 -0
- package/fake-snippets-api/routes/api/accounts/get_account_balance.ts +22 -0
- package/fake-snippets-api/routes/api/accounts/update.ts +32 -0
- package/fake-snippets-api/routes/api/ai/[...anyroute].ts +31 -0
- package/fake-snippets-api/routes/api/ai.ts +2 -0
- package/fake-snippets-api/routes/api/aistream/[...anyroute].ts +65 -0
- package/fake-snippets-api/routes/api/health.ts +9 -0
- package/fake-snippets-api/routes/api/internal/sessions/create_without_auth.ts +63 -0
- package/fake-snippets-api/routes/api/order_files/get.ts +28 -0
- package/fake-snippets-api/routes/api/order_files/upload.ts +43 -0
- package/fake-snippets-api/routes/api/orders/create.ts +41 -0
- package/fake-snippets-api/routes/api/orders/get.ts +28 -0
- package/fake-snippets-api/routes/api/orders/list.ts +15 -0
- package/fake-snippets-api/routes/api/orders/update.ts +50 -0
- package/fake-snippets-api/routes/api/snippets/add_star.ts +42 -0
- package/fake-snippets-api/routes/api/snippets/create.ts +55 -0
- package/fake-snippets-api/routes/api/snippets/delete.ts +41 -0
- package/fake-snippets-api/routes/api/snippets/download.ts +148 -0
- package/fake-snippets-api/routes/api/snippets/generate_from_jlcpcb.ts +55 -0
- package/fake-snippets-api/routes/api/snippets/get.ts +50 -0
- package/fake-snippets-api/routes/api/snippets/get_image.ts +65 -0
- package/fake-snippets-api/routes/api/snippets/images/[author]/[snippet_name]/[typeFormat].ts +74 -0
- package/fake-snippets-api/routes/api/snippets/list.ts +28 -0
- package/fake-snippets-api/routes/api/snippets/list_newest.ts +13 -0
- package/fake-snippets-api/routes/api/snippets/list_trending.ts +21 -0
- package/fake-snippets-api/routes/api/snippets/remove_star.ts +42 -0
- package/fake-snippets-api/routes/api/snippets/search.ts +18 -0
- package/fake-snippets-api/routes/api/snippets/update.ts +86 -0
- package/favicon.ico +0 -0
- package/index.html +23 -0
- package/landing.html +23 -0
- package/package.json +164 -0
- package/playwright-tests/ai-page.spec.ts +19 -0
- package/playwright-tests/cmd-click.spec.ts +43 -0
- package/playwright-tests/dashboard-page.spec.ts +10 -0
- package/playwright-tests/editor-page.spec.ts +15 -0
- package/playwright-tests/files-dialog.spec.ts +19 -0
- package/playwright-tests/footprint-dialog/footprint-dialog.spec.ts +27 -0
- package/playwright-tests/footprint-dialog/footprint-insertion.spec.ts +38 -0
- package/playwright-tests/footprint-dialog/footprint-preview.spec.ts +34 -0
- package/playwright-tests/footprint-dialog/footprint-selection.spec.ts +29 -0
- package/playwright-tests/handle-manual-edits.spec.ts +55 -0
- package/playwright-tests/home-page.spec.ts +10 -0
- package/playwright-tests/images.spec.ts +17 -0
- package/playwright-tests/manual-edits.spec.ts +89 -0
- package/playwright-tests/preview-page.spec.ts +14 -0
- package/playwright-tests/quickstart-page.spec.ts +10 -0
- package/playwright-tests/search-links.spec.ts +21 -0
- package/playwright-tests/search.spec.ts +27 -0
- package/playwright-tests/snapshots/ai-page.spec.ts-AI-Page-lg.png +0 -0
- package/playwright-tests/snapshots/ai-page.spec.ts-AI-Page-md.png +0 -0
- package/playwright-tests/snapshots/ai-page.spec.ts-AI-Page-xs.png +0 -0
- package/playwright-tests/snapshots/cmd-click.spec.ts-underlined-imports.png +0 -0
- package/playwright-tests/snapshots/dashboard-page.spec.ts-Dashboard-page-lg.png +0 -0
- package/playwright-tests/snapshots/dashboard-page.spec.ts-Dashboard-page-md.png +0 -0
- package/playwright-tests/snapshots/dashboard-page.spec.ts-Dashboard-page-xs.png +0 -0
- package/playwright-tests/snapshots/editor-page.spec.ts-editor-with-snippet.png +0 -0
- package/playwright-tests/snapshots/error-fallback.spec.ts-error-fallback-lg.png +0 -0
- package/playwright-tests/snapshots/error-fallback.spec.ts-error-fallback-md.png +0 -0
- package/playwright-tests/snapshots/error-fallback.spec.ts-error-fallback-xs.png +0 -0
- package/playwright-tests/snapshots/files-dialog.spec.ts-view-snippet-files.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-dialog.spec.ts-footprint-preview-lg.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-dialog.spec.ts-footprint-preview-md.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-dialog.spec.ts-footprint-preview-xs.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-insertion.spec.ts-footprint-insertion-lg.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-insertion.spec.ts-footprint-insertion-md.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-insertion.spec.ts-footprint-insertion-xs.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-preview.spec.ts-footprint-preview-lg.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-preview.spec.ts-footprint-preview-md.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-preview.spec.ts-footprint-preview-xs.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-selection.spec.ts-footprint-preview-lg.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-selection.spec.ts-footprint-preview-md.png +0 -0
- package/playwright-tests/snapshots/footprint-dialog/footprint-selection.spec.ts-footprint-preview-xs.png +0 -0
- package/playwright-tests/snapshots/handle-manual-edits.spec.ts-handle-manual-edits.png +0 -0
- package/playwright-tests/snapshots/home-page.spec.ts-Home-page-lg.png +0 -0
- package/playwright-tests/snapshots/home-page.spec.ts-Home-page-md.png +0 -0
- package/playwright-tests/snapshots/home-page.spec.ts-Home-page-xs.png +0 -0
- package/playwright-tests/snapshots/images.spec.ts-pcb-image.png +0 -0
- package/playwright-tests/snapshots/images.spec.ts-schematic-image.png +0 -0
- package/playwright-tests/snapshots/manual-edits.spec.ts-editor-manual-edits.png +0 -0
- package/playwright-tests/snapshots/manual-edits.spec.ts-manual-edits-view.png +0 -0
- package/playwright-tests/snapshots/preview-page.spec.ts-preview-snippet-pcb.png +0 -0
- package/playwright-tests/snapshots/preview-page.spec.ts-preview-snippet-schematic.png +0 -0
- package/playwright-tests/snapshots/quickstart-page.spec.ts-Quickstart-Pagelg.png +0 -0
- package/playwright-tests/snapshots/quickstart-page.spec.ts-Quickstart-Pagemd.png +0 -0
- package/playwright-tests/snapshots/quickstart-page.spec.ts-Quickstart-Pagexs.png +0 -0
- package/playwright-tests/snapshots/search-links.spec.ts-search-links.png +0 -0
- package/playwright-tests/snapshots/search.spec.ts-search-lg.png +0 -0
- package/playwright-tests/snapshots/search.spec.ts-search-md.png +0 -0
- package/playwright-tests/snapshots/search.spec.ts-search-xs.png +0 -0
- package/playwright-tests/snapshots/star.spec.ts-remove-star-button.png +0 -0
- package/playwright-tests/snapshots/star.spec.ts-star-button.png +0 -0
- package/playwright-tests/snapshots/update-description.spec.ts-update-description.png +0 -0
- package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-after-lg.png +0 -0
- package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-after-md.png +0 -0
- package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-after-xs.png +0 -0
- package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-before-lg.png +0 -0
- package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-before-md.png +0 -0
- package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-before-xs.png +0 -0
- package/playwright-tests/snapshots/view-snippet.spec.ts-view-snippet-files.png +0 -0
- package/playwright-tests/star.spec.ts +40 -0
- package/playwright-tests/update-description.spec.ts +18 -0
- package/playwright-tests/view-snippet.spec.ts +35 -0
- package/playwright-tests/viewports.ts +5 -0
- package/playwright.config.ts +27 -0
- package/postcss.config.js +6 -0
- package/public/robots.txt +9 -0
- package/renovate.json +24 -0
- package/scripts/generate-image-sizes.ts +58 -0
- package/scripts/generate-sitemap.ts +103 -0
- package/scripts/generate_bundle_stats.js +192 -0
- package/scripts/snapshot.ts +35 -0
- package/src/App.tsx +113 -0
- package/src/ContextProviders.tsx +9 -0
- package/src/assets/originals/editor_example_1.webp +0 -0
- package/src/assets/originals/editor_example_1_more_square.webp +0 -0
- package/src/assets/originals/editor_example_2.webp +0 -0
- package/src/assets/originals/example_schematic.webp +0 -0
- package/src/components/AiChatInterface.tsx +221 -0
- package/src/components/AiChatMessage.tsx +86 -0
- package/src/components/Analytics.tsx +30 -0
- package/src/components/BomTable.tsx +69 -0
- package/src/components/ChatInput.tsx +53 -0
- package/src/components/CircuitToSvgWithMouseControl.tsx +78 -0
- package/src/components/CmdKMenu.tsx +301 -0
- package/src/components/CodeAndPreview.tsx +258 -0
- package/src/components/CodeEditor.tsx +460 -0
- package/src/components/CodeEditorHeader.tsx +160 -0
- package/src/components/CreateNewSnippetWithAiHero.tsx +77 -0
- package/src/components/DownloadButtonAndMenu.tsx +212 -0
- package/src/components/EditorNav.tsx +428 -0
- package/src/components/ErrorFallback.tsx +25 -0
- package/src/components/ErrorTabContent.tsx +122 -0
- package/src/components/FAQ.tsx +113 -0
- package/src/components/Footer.tsx +134 -0
- package/src/components/Footer2.tsx +100 -0
- package/src/components/FootprintDialog.tsx +342 -0
- package/src/components/Header.tsx +187 -0
- package/src/components/Header2.tsx +135 -0
- package/src/components/HeaderDropdown.tsx +83 -0
- package/src/components/HeaderLogin.tsx +94 -0
- package/src/components/JLCPCBImportDialog.tsx +155 -0
- package/src/components/LandingHero.tsx +175 -0
- package/src/components/LatestSnippets.tsx +39 -0
- package/src/components/OptimizedImage.tsx +96 -0
- package/src/components/OrderPreviewContent.tsx +61 -0
- package/src/components/ParametersEditor.tsx +140 -0
- package/src/components/PcbViewerWithContainerHeight.tsx +47 -0
- package/src/components/PrefetchPageLink.tsx +45 -0
- package/src/components/PreviewContent.tsx +375 -0
- package/src/components/PreviewEmptyState.tsx +16 -0
- package/src/components/RunButton.tsx +27 -0
- package/src/components/SearchComponent.tsx +163 -0
- package/src/components/ShippingInformationForm.tsx +423 -0
- package/src/components/SnippetLink.tsx +37 -0
- package/src/components/StaticPreviewContent.tsx +89 -0
- package/src/components/StaticViewSnippetHeader.tsx +70 -0
- package/src/components/StaticViewSnippetSidebar.tsx +100 -0
- package/src/components/TableViewer/CircuitJsonTableViewer.tsx +316 -0
- package/src/components/TableViewer/ClickableText.tsx +21 -0
- package/src/components/TableViewer/HeaderCell.tsx +27 -0
- package/src/components/TableViewer/Modal.tsx +39 -0
- package/src/components/TrendingSnippetCarousel.tsx +77 -0
- package/src/components/TypeBadge.tsx +31 -0
- package/src/components/ViewSnippetHeader.tsx +144 -0
- package/src/components/ViewSnippetSidebar.tsx +162 -0
- package/src/components/dialogs/confirm-delete-snippet-dialog.tsx +80 -0
- package/src/components/dialogs/create-order-dialog.tsx +146 -0
- package/src/components/dialogs/create-use-dialog.tsx +34 -0
- package/src/components/dialogs/edit-description-dialog.tsx +96 -0
- package/src/components/dialogs/files-dialog.tsx +70 -0
- package/src/components/dialogs/import-snippet-dialog.tsx +84 -0
- package/src/components/dialogs/rename-snippet-dialog.tsx +81 -0
- package/src/components/dialogs/view-ts-files-dialog.tsx +89 -0
- package/src/components/ui/accordion.tsx +55 -0
- package/src/components/ui/alert-dialog.tsx +139 -0
- package/src/components/ui/alert.tsx +59 -0
- package/src/components/ui/aspect-ratio.tsx +5 -0
- package/src/components/ui/avatar.tsx +48 -0
- package/src/components/ui/badge.tsx +36 -0
- package/src/components/ui/breadcrumb.tsx +118 -0
- package/src/components/ui/button.tsx +58 -0
- package/src/components/ui/calendar.tsx +73 -0
- package/src/components/ui/card.tsx +76 -0
- package/src/components/ui/carousel.tsx +260 -0
- package/src/components/ui/chart.tsx +363 -0
- package/src/components/ui/checkbox.tsx +28 -0
- package/src/components/ui/collapsible.tsx +9 -0
- package/src/components/ui/combobox.tsx +178 -0
- package/src/components/ui/command.tsx +151 -0
- package/src/components/ui/context-menu.tsx +202 -0
- package/src/components/ui/dialog.tsx +120 -0
- package/src/components/ui/drawer.tsx +116 -0
- package/src/components/ui/dropdown-menu.tsx +203 -0
- package/src/components/ui/form.tsx +182 -0
- package/src/components/ui/hover-card.tsx +27 -0
- package/src/components/ui/input-otp.tsx +69 -0
- package/src/components/ui/input.tsx +25 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/menubar.tsx +238 -0
- package/src/components/ui/navigation-menu.tsx +129 -0
- package/src/components/ui/pagination.tsx +121 -0
- package/src/components/ui/popover.tsx +31 -0
- package/src/components/ui/progress.tsx +26 -0
- package/src/components/ui/radio-group.tsx +42 -0
- package/src/components/ui/resizable.tsx +43 -0
- package/src/components/ui/scroll-area.tsx +46 -0
- package/src/components/ui/searchable-select.tsx +94 -0
- package/src/components/ui/select.tsx +162 -0
- package/src/components/ui/separator.tsx +29 -0
- package/src/components/ui/sheet.tsx +141 -0
- package/src/components/ui/skeleton.tsx +18 -0
- package/src/components/ui/slider.tsx +26 -0
- package/src/components/ui/sonner.tsx +30 -0
- package/src/components/ui/switch.tsx +27 -0
- package/src/components/ui/table.tsx +120 -0
- package/src/components/ui/tabs.tsx +53 -0
- package/src/components/ui/textarea.tsx +24 -0
- package/src/components/ui/toast.tsx +128 -0
- package/src/components/ui/toaster.tsx +33 -0
- package/src/components/ui/toggle-group.tsx +59 -0
- package/src/components/ui/toggle.tsx +43 -0
- package/src/components/ui/tooltip.tsx +28 -0
- package/src/entry-server.tsx +12 -0
- package/src/hooks/use-account-balance.ts +24 -0
- package/src/hooks/use-ai-api.ts +35 -0
- package/src/hooks/use-axios.ts +20 -0
- package/src/hooks/use-code-completion-ai-api.ts +11 -0
- package/src/hooks/use-compiled-tsx.ts +37 -0
- package/src/hooks/use-copy-to-clipboard.ts +26 -0
- package/src/hooks/use-create-snippet-mutation.ts +62 -0
- package/src/hooks/use-current-snippet-id.ts +75 -0
- package/src/hooks/use-current-snippet.ts +24 -0
- package/src/hooks/use-global-store.ts +33 -0
- package/src/hooks/use-is-using-fake-api.ts +3 -0
- package/src/hooks/use-run-tsx/construct-circuit.tsx +64 -0
- package/src/hooks/use-run-tsx/eval-compiled-js.ts +9 -0
- package/src/hooks/use-run-tsx/index.tsx +251 -0
- package/src/hooks/use-save-snippet.ts +66 -0
- package/src/hooks/use-sign-in.ts +22 -0
- package/src/hooks/use-snippet-by-name.ts +25 -0
- package/src/hooks/use-snippet.ts +23 -0
- package/src/hooks/use-snippets-base-api-url.ts +3 -0
- package/src/hooks/use-toast.tsx +208 -0
- package/src/hooks/use-typecheck.ts +54 -0
- package/src/hooks/use-url-params.ts +31 -0
- package/src/hooks/use-warn-user-on-page-change.ts +23 -0
- package/src/hooks/useForkSnippetMutation.ts +52 -0
- package/src/index.css +21 -0
- package/src/lib/__tests__/constants.test.ts +66 -0
- package/src/lib/base64ToBytes.ts +5 -0
- package/src/lib/bytesToBase64.ts +4 -0
- package/src/lib/codemirror/basic-setup.ts +51 -0
- package/src/lib/constants.ts +12 -0
- package/src/lib/decodeUrlHashToText.ts +15 -0
- package/src/lib/defaultCodeForBlankCode.tsx +7 -0
- package/src/lib/download-fns/createBlobURL.ts +4 -0
- package/src/lib/download-fns/download-assembly-svg.ts +12 -0
- package/src/lib/download-fns/download-circuit-json-fn.ts +12 -0
- package/src/lib/download-fns/download-dsn-file-fn.ts +12 -0
- package/src/lib/download-fns/download-fabrication-files.ts +233 -0
- package/src/lib/download-fns/download-gltf.ts +49 -0
- package/src/lib/download-fns/download-kicad-files.ts +27 -0
- package/src/lib/download-fns/download-readable-netlist.ts +12 -0
- package/src/lib/download-fns/download-schematic-svg.ts +12 -0
- package/src/lib/download-fns/download-simple-route-json.ts +17 -0
- package/src/lib/encodeTextToUrlHash.ts +17 -0
- package/src/lib/get-snippet-template.ts +26 -0
- package/src/lib/handleManualEditsImport.tsx +65 -0
- package/src/lib/jlc-parts-engine.ts +69 -0
- package/src/lib/templates/blank-3d-model-template.ts +12 -0
- package/src/lib/templates/blank-circuit-board-template.ts +24 -0
- package/src/lib/templates/blank-footprint-template.ts +29 -0
- package/src/lib/templates/blank-package-template.ts +22 -0
- package/src/lib/templates/blinking-led-board-template.ts +63 -0
- package/src/lib/templates/manual-edits-template.ts +5 -0
- package/src/lib/templates/usb-c-led-flashlight-template.ts +22 -0
- package/src/lib/utils/checkIfManualEditsImported.ts +6 -0
- package/src/lib/utils/getSyntaxError.ts +13 -0
- package/src/lib/utils/index.ts +6 -0
- package/src/lib/utils/load-prettier.ts +18 -0
- package/src/lib/utils/parseFootprintParams.ts +52 -0
- package/src/lib/utils/parseJsonOrNull.ts +8 -0
- package/src/lib/utils/pcbManualEditEventHandler.ts +156 -0
- package/src/main.tsx +10 -0
- package/src/pages/ai.tsx +92 -0
- package/src/pages/authorize.tsx +54 -0
- package/src/pages/dashboard.tsx +165 -0
- package/src/pages/dev-login.tsx +68 -0
- package/src/pages/editor.tsx +28 -0
- package/src/pages/landing.tsx +236 -0
- package/src/pages/my-orders.tsx +54 -0
- package/src/pages/newest.tsx +16 -0
- package/src/pages/preview.tsx +70 -0
- package/src/pages/quickstart.tsx +198 -0
- package/src/pages/search.tsx +26 -0
- package/src/pages/settings.tsx +25 -0
- package/src/pages/user-profile.tsx +97 -0
- package/src/pages/view-order.tsx +123 -0
- package/src/pages/view-snippet.tsx +149 -0
- package/src/prettier.ts +9 -0
- package/src/vite-env.d.ts +1 -0
- package/tailwind.config.js +47 -0
- package/tsconfig.json +30 -0
- package/vercel.json +50 -0
- package/vite.config.ts +146 -0
- package/winterspec.config.ts +6 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { GitHubLogoIcon, MagicWandIcon } from "@radix-ui/react-icons"
|
|
2
|
+
import { ClipboardIcon } from "lucide-react"
|
|
3
|
+
import { Button } from "@/components/ui/button"
|
|
4
|
+
import { useAiApi } from "@/hooks/use-ai-api"
|
|
5
|
+
import { useAsyncMemo } from "use-async-memo"
|
|
6
|
+
import { TextBlock } from "@anthropic-ai/sdk/resources/messages.mjs"
|
|
7
|
+
import { encodeTextToUrlHash } from "@/lib/encodeTextToUrlHash"
|
|
8
|
+
|
|
9
|
+
export const ErrorTabContent = ({
|
|
10
|
+
code,
|
|
11
|
+
isStreaming,
|
|
12
|
+
errorMessage,
|
|
13
|
+
}: {
|
|
14
|
+
code?: string
|
|
15
|
+
isStreaming?: boolean
|
|
16
|
+
errorMessage?: string | null
|
|
17
|
+
}) => {
|
|
18
|
+
const anthropic = useAiApi()
|
|
19
|
+
const simplifiedErrorMessage = useAsyncMemo(async () => {
|
|
20
|
+
if (isStreaming) return ""
|
|
21
|
+
if (!code) return ""
|
|
22
|
+
if (!errorMessage) return ""
|
|
23
|
+
// Only simplify for ZodErrors for now
|
|
24
|
+
if (!errorMessage.includes("ZodError")) return ""
|
|
25
|
+
const response = await anthropic.messages.create({
|
|
26
|
+
model: "claude-3-haiku-20240307",
|
|
27
|
+
max_tokens: 1000,
|
|
28
|
+
messages: [
|
|
29
|
+
{
|
|
30
|
+
role: "user",
|
|
31
|
+
content: `
|
|
32
|
+
You are a helpful assistant that simplifies error messages. You only output the rewritten error message.
|
|
33
|
+
|
|
34
|
+
Here is the code:
|
|
35
|
+
${code}
|
|
36
|
+
|
|
37
|
+
Here is the error message:
|
|
38
|
+
${errorMessage}
|
|
39
|
+
`.trim(),
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
})
|
|
43
|
+
return (response.content[0] as TextBlock).text
|
|
44
|
+
}, [code, errorMessage, isStreaming])
|
|
45
|
+
|
|
46
|
+
if (!errorMessage) {
|
|
47
|
+
return (
|
|
48
|
+
<div className="mt-4 bg-green-50 rounded-md border border-green-200">
|
|
49
|
+
<div className="p-4">
|
|
50
|
+
<h3 className="text-lg font-semibold text-green-800 mb-3">
|
|
51
|
+
No Errors 👌
|
|
52
|
+
</h3>
|
|
53
|
+
<p className="text-sm text-green-700">
|
|
54
|
+
Your code is running without any errors.
|
|
55
|
+
</p>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<div className="mt-4 bg-red-50 rounded-md border border-red-200 max-h-[500px] overflow-y-auto">
|
|
64
|
+
<div className="p-4">
|
|
65
|
+
<h3 className="text-lg font-semibold text-red-800 mb-3">Error</h3>
|
|
66
|
+
<p className="text-xs font-semibold font-mono whitespace-pre-wrap text-red-700">
|
|
67
|
+
{simplifiedErrorMessage}
|
|
68
|
+
</p>
|
|
69
|
+
<p className="text-xs font-mono whitespace-pre-wrap text-red-600 mt-2">
|
|
70
|
+
{errorMessage}
|
|
71
|
+
</p>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
<div className="flex gap-2 mt-4 justify-end">
|
|
75
|
+
<Button
|
|
76
|
+
variant="outline"
|
|
77
|
+
onClick={() => {
|
|
78
|
+
if (!errorMessage) return
|
|
79
|
+
navigator.clipboard.writeText(errorMessage)
|
|
80
|
+
alert("Error copied to clipboard!")
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
<ClipboardIcon className="w-4 h-4 mr-2" />
|
|
84
|
+
Copy Error
|
|
85
|
+
</Button>
|
|
86
|
+
<Button
|
|
87
|
+
variant="outline"
|
|
88
|
+
onClick={() => {
|
|
89
|
+
const title = `Error: ${errorMessage
|
|
90
|
+
.replace("Render Error:", "")
|
|
91
|
+
.replace(/\"_errors\":\[\]/g, "")
|
|
92
|
+
.replace(/\{,/g, "{")
|
|
93
|
+
.replace(/"_errors":\[/g, "")
|
|
94
|
+
.replace(/[^a-zA-Z0-9 ]/g, " ")
|
|
95
|
+
.replace(/\s+/g, " ")
|
|
96
|
+
.replace(/ \d+ /g, " ")
|
|
97
|
+
.slice(0, 100)}`
|
|
98
|
+
const url = encodeTextToUrlHash(code ?? "").replace(
|
|
99
|
+
"http://localhost:5173",
|
|
100
|
+
"https://snippets.tscircuit.com",
|
|
101
|
+
)
|
|
102
|
+
let body = `[Snippet code to reproduce](${url})\n\n### Error\n\`\`\`\n${errorMessage.slice(0, 600)}\n\`\`\``
|
|
103
|
+
if (body.length > 4000) {
|
|
104
|
+
body = `\`\`\`tsx\n// Please paste the code here\`\`\`\n\n### Error\n\`\`\`\n${errorMessage.slice(0, 2000)}\n\`\`\``
|
|
105
|
+
}
|
|
106
|
+
window.open(
|
|
107
|
+
`https://github.com/tscircuit/snippets/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`,
|
|
108
|
+
"_blank",
|
|
109
|
+
)
|
|
110
|
+
}}
|
|
111
|
+
>
|
|
112
|
+
<GitHubLogoIcon className="w-4 h-4 mr-2" />
|
|
113
|
+
Report Issue
|
|
114
|
+
</Button>
|
|
115
|
+
<Button variant="outline">
|
|
116
|
+
<MagicWandIcon className="w-4 h-4 mr-2" />
|
|
117
|
+
Fix with AI
|
|
118
|
+
</Button>
|
|
119
|
+
</div>
|
|
120
|
+
</>
|
|
121
|
+
)
|
|
122
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Accordion,
|
|
3
|
+
AccordionContent,
|
|
4
|
+
AccordionItem,
|
|
5
|
+
AccordionTrigger,
|
|
6
|
+
} from "@/components/ui/accordion"
|
|
7
|
+
|
|
8
|
+
const QUESTIONS = [
|
|
9
|
+
{
|
|
10
|
+
question: "Can I use tscircuit commercially?",
|
|
11
|
+
answer:
|
|
12
|
+
"You can use tscircuit for commercial purposes. tscircuit is under the same permissive MIT license as Node.js, React, and thousands of other popular projects you are likely already using! ",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: "Can I import designs from other software?",
|
|
16
|
+
answer:
|
|
17
|
+
"tscircuit has some support for importing designs from other software, but it's not yet fully featured. You should file an issue on our Github if you'd like to see a specific format supported.",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
question: "Can I use tscircuit locally?",
|
|
21
|
+
answer:
|
|
22
|
+
"Yes, you can use tscircuit locally using the tscircuit CLI, but we recommend starting with the web-based application for simplicity.",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
question: "Can tscircuit make schematics? Is it extra effort?",
|
|
26
|
+
answer:
|
|
27
|
+
"tscircuit always renders both a schematic and PCB. Unlike traditional EDA where the schematic capture and PCB layout are separate processes, tscircuit combines them by allowing a user to specify constraints and automations. This means that you can design a schematic and then immediately see a PCB layout or vice versa.",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
question: "What exactly is tscircuit?",
|
|
31
|
+
answer:
|
|
32
|
+
"tscircuit is first and foremost a framework, but it also can be used to refer to the tscircuit platform, the tscircuit company, the tscircuit registry or ecosystem of components and packages for working with tscircuit. When you use tscircuit, you're becoming compatible with a growing ecosystem of web-first electronics technologies.",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
question: "Can I use tscircuit programmatically?",
|
|
36
|
+
answer: (
|
|
37
|
+
<span>
|
|
38
|
+
Yes, use the{" "}
|
|
39
|
+
<a href="https://github.com/tscircuit/core">@tscircuit/core</a> module
|
|
40
|
+
to use classes and/or React and build to various formats. If you'd like
|
|
41
|
+
to dynamically evaluate tscircuit code with automatic import handling,
|
|
42
|
+
you can use{" "}
|
|
43
|
+
<a href="https://github.com/tscircuit/eval-webworker">
|
|
44
|
+
@tscircuit/eval-webworker
|
|
45
|
+
</a>
|
|
46
|
+
. You can use{" "}
|
|
47
|
+
<a href="https://github.com/tscircuit/runframe">@tscircuit/runframe</a>{" "}
|
|
48
|
+
to any view (schematic, PCB etc.) of your compiled Circuit JSON.
|
|
49
|
+
</span>
|
|
50
|
+
),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
question: "How do I display tscircuit circuits on my website?",
|
|
54
|
+
answer: (
|
|
55
|
+
<span>
|
|
56
|
+
You can use our React components to display tscircuit on a webpage. For
|
|
57
|
+
simple cases, you can use{" "}
|
|
58
|
+
<a href="https://github.com/tscircuit/pcb-viewer">
|
|
59
|
+
@tscircuit/pcb-viewer
|
|
60
|
+
</a>
|
|
61
|
+
,{" "}
|
|
62
|
+
<a href="https://github.com/tscircuit/schematic-viewer">
|
|
63
|
+
@tscircuit/schematic-viewer
|
|
64
|
+
</a>
|
|
65
|
+
, or{" "}
|
|
66
|
+
<a href="https://github.com/tscircuit/3d-viewer">
|
|
67
|
+
@tscircuit/3d-viewer
|
|
68
|
+
</a>{" "}
|
|
69
|
+
directly. For more complex use cases,{" "}
|
|
70
|
+
<a href="https://github.com/tscircuit/runframe">@tscircuit/runframe</a>{" "}
|
|
71
|
+
is recommended as it provides a unified interface for all viewers.
|
|
72
|
+
</span>
|
|
73
|
+
),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
question: "What is Circuit JSON?",
|
|
77
|
+
answer: (
|
|
78
|
+
<span>
|
|
79
|
+
<a href="https://github.com/tscircuit/circuit-json">Circuit JSON</a> is
|
|
80
|
+
a JSON format for representing electronic circuits. It is a sort of
|
|
81
|
+
assembly language electronic circuits. All tscircuit designs are
|
|
82
|
+
compiled to Circuit JSON as the intermediary format.
|
|
83
|
+
</span>
|
|
84
|
+
),
|
|
85
|
+
},
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
export const FAQ = () => (
|
|
89
|
+
<section className="w-full py-12 md:py-24 lg:py-32" id="faq">
|
|
90
|
+
<div className="container px-4 md:px-6 mx-auto">
|
|
91
|
+
<div className="flex flex-col items-center justify-center space-y-4 text-center">
|
|
92
|
+
<div className="space-y-2">
|
|
93
|
+
<h2 className="text-3xl font-bold tracking-tighter md:text-4xl">
|
|
94
|
+
Frequently Asked Questions
|
|
95
|
+
</h2>
|
|
96
|
+
<p className="max-w-[900px] text-muted-foreground md:text-xl">
|
|
97
|
+
Got questions? We've got answers.
|
|
98
|
+
</p>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
<div className="mx-auto max-w-3xl space-y-4 py-12">
|
|
102
|
+
<Accordion type="single" collapsible>
|
|
103
|
+
{QUESTIONS.map((q, i) => (
|
|
104
|
+
<AccordionItem key={i} value={`item-${i + 1}`}>
|
|
105
|
+
<AccordionTrigger>{q.question}</AccordionTrigger>
|
|
106
|
+
<AccordionContent>{q.answer}</AccordionContent>
|
|
107
|
+
</AccordionItem>
|
|
108
|
+
))}
|
|
109
|
+
</Accordion>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</section>
|
|
113
|
+
)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
2
|
+
import { CircuitBoard } from "lucide-react"
|
|
3
|
+
import { Link } from "wouter"
|
|
4
|
+
import { PrefetchPageLink } from "./PrefetchPageLink"
|
|
5
|
+
|
|
6
|
+
export default function Footer() {
|
|
7
|
+
const session = useGlobalStore((s) => s.session)
|
|
8
|
+
const isLoggedIn = Boolean(session)
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<footer className="bg-white text-black py-12 border-t mt-8">
|
|
12
|
+
<div className="container mx-auto px-4">
|
|
13
|
+
<div className="space-y-4">
|
|
14
|
+
<div className="flex items-center gap-2">
|
|
15
|
+
<CircuitBoard className="h-6 w-6" />
|
|
16
|
+
<span className="text-lg font-bold">tscircuit</span>
|
|
17
|
+
</div>
|
|
18
|
+
<p className="text-sm text-muted-foreground">
|
|
19
|
+
The New Foundation for Electronic Design
|
|
20
|
+
</p>
|
|
21
|
+
</div>
|
|
22
|
+
<div className="grid grid-cols-2 md:grid-cols-2 lg:grid-cols-4 gap-8 text-sm text-gray-600 mt-8">
|
|
23
|
+
<div className="space-y-4">
|
|
24
|
+
<footer className="flex flex-col space-y-2">
|
|
25
|
+
{[
|
|
26
|
+
{ name: "Home", href: "/" },
|
|
27
|
+
{ name: "Dashboard", href: "/dashboard" },
|
|
28
|
+
{ name: "Editor", href: "/editor" },
|
|
29
|
+
{ name: "Create with AI", href: "/ai" },
|
|
30
|
+
{
|
|
31
|
+
name: "My Profile",
|
|
32
|
+
href: `/${session?.github_username}`,
|
|
33
|
+
hidden: !isLoggedIn,
|
|
34
|
+
},
|
|
35
|
+
{ name: "Settings", href: "/settings" },
|
|
36
|
+
]
|
|
37
|
+
.filter((item) => !item.hidden)
|
|
38
|
+
.map((item) => (
|
|
39
|
+
<PrefetchPageLink
|
|
40
|
+
key={item.name}
|
|
41
|
+
href={item.href}
|
|
42
|
+
className="hover:underline"
|
|
43
|
+
>
|
|
44
|
+
{item.name}
|
|
45
|
+
</PrefetchPageLink>
|
|
46
|
+
))}
|
|
47
|
+
</footer>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div className="space-y-4">
|
|
51
|
+
<h3 className="font-semibold uppercase">Explore</h3>
|
|
52
|
+
<footer className="flex flex-col space-y-2">
|
|
53
|
+
<PrefetchPageLink href="/newest" className="hover:underline">
|
|
54
|
+
Newest Snippets
|
|
55
|
+
</PrefetchPageLink>
|
|
56
|
+
<a href="https://docs.tscircuit.com" className="hover:underline">
|
|
57
|
+
Docs
|
|
58
|
+
</a>
|
|
59
|
+
</footer>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div className="space-y-4">
|
|
63
|
+
<h3 className="font-semibold uppercase">Follow</h3>
|
|
64
|
+
<footer className="flex flex-col space-y-2">
|
|
65
|
+
<a href="https://blog.tscircuit.com" className="hover:underline">
|
|
66
|
+
Blog
|
|
67
|
+
</a>
|
|
68
|
+
<a href="https://x.com/tscircuit" className="hover:underline">
|
|
69
|
+
Twitter
|
|
70
|
+
</a>
|
|
71
|
+
<a href="https://tscircuit.com/join" className="hover:underline">
|
|
72
|
+
Discord
|
|
73
|
+
</a>
|
|
74
|
+
<a
|
|
75
|
+
href="https://github.com/tscircuit/tscircuit"
|
|
76
|
+
className="hover:underline"
|
|
77
|
+
>
|
|
78
|
+
GitHub
|
|
79
|
+
</a>
|
|
80
|
+
<a
|
|
81
|
+
href="https://youtube.com/@seveibar"
|
|
82
|
+
className="hover:underline"
|
|
83
|
+
>
|
|
84
|
+
YouTube
|
|
85
|
+
</a>
|
|
86
|
+
</footer>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div className="space-y-4">
|
|
90
|
+
<h3 className="font-semibold uppercase">Company</h3>
|
|
91
|
+
<nav className="flex flex-col space-y-2">
|
|
92
|
+
<a
|
|
93
|
+
href="https://tscircuit.com/legal/terms-of-service"
|
|
94
|
+
className="hover:underline"
|
|
95
|
+
>
|
|
96
|
+
Terms of Service
|
|
97
|
+
</a>
|
|
98
|
+
<a
|
|
99
|
+
href="https://tscircuit.com/legal/privacy-policy"
|
|
100
|
+
className="hover:underline"
|
|
101
|
+
>
|
|
102
|
+
Privacy Policy
|
|
103
|
+
</a>
|
|
104
|
+
<a
|
|
105
|
+
href="mailto:contact@tscircuit.com"
|
|
106
|
+
className="hover:underline"
|
|
107
|
+
>
|
|
108
|
+
contact@tscircuit.com
|
|
109
|
+
</a>
|
|
110
|
+
<div className="flex-grow" />
|
|
111
|
+
<div className="text-xs text-gray-500">
|
|
112
|
+
we are inspired by{" "}
|
|
113
|
+
<a href="https://val.town" className="underline">
|
|
114
|
+
val.town
|
|
115
|
+
</a>
|
|
116
|
+
,{" "}
|
|
117
|
+
<a href="https://codesandbox.io/" className="underline">
|
|
118
|
+
codesandbox
|
|
119
|
+
</a>{" "}
|
|
120
|
+
and{" "}
|
|
121
|
+
<a href="https://v0.dev" className="underline">
|
|
122
|
+
v0.dev
|
|
123
|
+
</a>
|
|
124
|
+
</div>
|
|
125
|
+
<div className="text-xs text-gray-500">
|
|
126
|
+
© {new Date().getFullYear()} tscircuit Inc.
|
|
127
|
+
</div>
|
|
128
|
+
</nav>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</footer>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Button } from "@/components/ui/button"
|
|
2
|
+
import { Card, CardContent } from "@/components/ui/card"
|
|
3
|
+
import { Badge } from "@/components/ui/badge"
|
|
4
|
+
import {
|
|
5
|
+
Accordion,
|
|
6
|
+
AccordionContent,
|
|
7
|
+
AccordionItem,
|
|
8
|
+
AccordionTrigger,
|
|
9
|
+
} from "@/components/ui/accordion"
|
|
10
|
+
import {
|
|
11
|
+
CircuitBoard,
|
|
12
|
+
Cpu,
|
|
13
|
+
Layers,
|
|
14
|
+
CloudLightningIcon as Lightning,
|
|
15
|
+
Maximize2,
|
|
16
|
+
Zap,
|
|
17
|
+
} from "lucide-react"
|
|
18
|
+
import { Link } from "wouter"
|
|
19
|
+
import { Header2 } from "@/components/Header2"
|
|
20
|
+
|
|
21
|
+
export const Footer2 = () => (
|
|
22
|
+
<footer className="w-full py-6 bg-background">
|
|
23
|
+
<div className="container px-4 md:px-6 mx-auto">
|
|
24
|
+
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-4">
|
|
25
|
+
<div className="space-y-4">
|
|
26
|
+
<div className="flex items-center gap-2">
|
|
27
|
+
<CircuitBoard className="h-6 w-6" />
|
|
28
|
+
<span className="text-lg font-bold">tscircuit</span>
|
|
29
|
+
</div>
|
|
30
|
+
<p className="text-sm text-muted-foreground">
|
|
31
|
+
Transforming electronic design with AI-powered tools.
|
|
32
|
+
</p>
|
|
33
|
+
</div>
|
|
34
|
+
<div className="space-y-4">
|
|
35
|
+
<h4 className="text-sm font-bold">Product</h4>
|
|
36
|
+
<ul className="space-y-2 text-sm">
|
|
37
|
+
<li>
|
|
38
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
39
|
+
Features
|
|
40
|
+
</Link>
|
|
41
|
+
</li>
|
|
42
|
+
<li>
|
|
43
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
44
|
+
Pricing
|
|
45
|
+
</Link>
|
|
46
|
+
</li>
|
|
47
|
+
<li>
|
|
48
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
49
|
+
Tutorials
|
|
50
|
+
</Link>
|
|
51
|
+
</li>
|
|
52
|
+
</ul>
|
|
53
|
+
</div>
|
|
54
|
+
<div className="space-y-4">
|
|
55
|
+
<h4 className="text-sm font-bold">Company</h4>
|
|
56
|
+
<ul className="space-y-2 text-sm">
|
|
57
|
+
<li>
|
|
58
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
59
|
+
About
|
|
60
|
+
</Link>
|
|
61
|
+
</li>
|
|
62
|
+
<li>
|
|
63
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
64
|
+
Blog
|
|
65
|
+
</Link>
|
|
66
|
+
</li>
|
|
67
|
+
<li>
|
|
68
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
69
|
+
Careers
|
|
70
|
+
</Link>
|
|
71
|
+
</li>
|
|
72
|
+
</ul>
|
|
73
|
+
</div>
|
|
74
|
+
<div className="space-y-4">
|
|
75
|
+
<h4 className="text-sm font-bold">Legal</h4>
|
|
76
|
+
<ul className="space-y-2 text-sm">
|
|
77
|
+
<li>
|
|
78
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
79
|
+
Privacy
|
|
80
|
+
</Link>
|
|
81
|
+
</li>
|
|
82
|
+
<li>
|
|
83
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
84
|
+
Terms
|
|
85
|
+
</Link>
|
|
86
|
+
</li>
|
|
87
|
+
<li>
|
|
88
|
+
<Link className="text-muted-foreground hover:underline" href="#">
|
|
89
|
+
Cookie Policy
|
|
90
|
+
</Link>
|
|
91
|
+
</li>
|
|
92
|
+
</ul>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
<div className="mt-8 border-t pt-8 text-center text-sm text-muted-foreground">
|
|
96
|
+
© {new Date().getFullYear()} tscircuit. All rights reserved.
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</footer>
|
|
100
|
+
)
|