@tscircuit/fake-snippets 0.0.28 → 0.0.30

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 (48) hide show
  1. package/bun-tests/fake-snippets-api/routes/packages/add_star.test.ts +161 -0
  2. package/bun-tests/fake-snippets-api/routes/packages/get.test.ts +1 -1
  3. package/bun-tests/fake-snippets-api/routes/packages/remove_star.test.ts +158 -0
  4. package/bun.lock +43 -30
  5. package/dist/bundle.js +279 -145
  6. package/fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor.ts +9 -4
  7. package/fake-snippets-api/routes/api/package_files/list.ts +1 -1
  8. package/fake-snippets-api/routes/api/packages/add_star.ts +82 -0
  9. package/fake-snippets-api/routes/api/packages/get.ts +12 -2
  10. package/fake-snippets-api/routes/api/packages/remove_star.ts +70 -0
  11. package/fake-snippets-api/utils/normalizeProjectFilePath.ts +60 -0
  12. package/package.json +4 -3
  13. package/src/App.tsx +5 -1
  14. package/src/components/DownloadButtonAndMenu.tsx +21 -11
  15. package/src/components/OrderPreviewContent.tsx +1 -1
  16. package/src/components/PreviewContent.tsx +1 -1
  17. package/src/components/ViewPackagePage/components/file-explorer.tsx +26 -77
  18. package/src/components/ViewPackagePage/components/main-content-header.tsx +32 -39
  19. package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +44 -6
  20. package/src/components/ViewPackagePage/components/package-header.tsx +54 -21
  21. package/src/components/ViewPackagePage/components/repo-page-content.tsx +76 -69
  22. package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +25 -19
  23. package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +13 -9
  24. package/src/components/ViewPackagePage/components/sidebar.tsx +2 -2
  25. package/src/components/ViewPackagePage/components/tab-views/3d-view.tsx +25 -4
  26. package/src/components/ViewPackagePage/components/tab-views/bom-view.tsx +25 -4
  27. package/src/components/ViewPackagePage/components/tab-views/files-view.tsx +135 -33
  28. package/src/components/ViewPackagePage/components/tab-views/pcb-view.tsx +31 -4
  29. package/src/components/ViewPackagePage/components/tab-views/schematic-view.tsx +31 -4
  30. package/src/components/ViewPackagePage/hooks/use-current-package-circuit-json.ts +46 -0
  31. package/src/components/ViewPackagePage/utils/is-within-directory.ts +32 -0
  32. package/src/hooks/use-current-package-id.ts +3 -0
  33. package/src/hooks/use-current-package-info.ts +8 -0
  34. package/src/hooks/use-current-snippet-id.ts +7 -4
  35. package/src/hooks/use-fork-package-mutation.ts +1 -4
  36. package/src/hooks/use-package-files.ts +6 -2
  37. package/src/hooks/use-package-release.ts +1 -1
  38. package/src/hooks/use-package-stars.ts +86 -0
  39. package/src/lib/utils/timeAgo.ts +9 -0
  40. package/src/pages/user-profile.tsx +17 -11
  41. package/src/pages/view-package.tsx +14 -15
  42. package/public/placeholder-logo.png +0 -0
  43. package/public/placeholder-logo.svg +0 -1
  44. package/public/placeholder-user.jpg +0 -0
  45. package/public/placeholder.jpg +0 -0
  46. package/public/placeholder.svg +0 -1
  47. package/src/components/ViewPackagePage/components/repo-tab-header.tsx +0 -12
  48. package/src/components/ViewPackagePage/simulate-page.tsx +0 -120
@@ -0,0 +1,86 @@
1
+ import { useMutation, useQuery, useQueryClient } from "react-query"
2
+ import { useAxios } from "./use-axios"
3
+
4
+ type PackageStarQuery = { package_id: string } | { name: string }
5
+
6
+ interface PackageStarResponse {
7
+ is_starred: boolean
8
+ star_count: number
9
+ }
10
+
11
+ export const usePackageStars = (query: PackageStarQuery | null) => {
12
+ const axios = useAxios()
13
+
14
+ return useQuery<PackageStarResponse, Error & { status: number }>(
15
+ ["packageStars", query],
16
+ async () => {
17
+ if (!query) {
18
+ throw new Error("Query is required")
19
+ }
20
+
21
+ const { data } = await axios.get("/packages/get", {
22
+ params: query,
23
+ })
24
+
25
+ return {
26
+ is_starred: data.package.is_starred ?? false,
27
+ star_count: data.package.star_count ?? 0,
28
+ }
29
+ },
30
+ {
31
+ retry: false,
32
+ enabled: Boolean(query),
33
+ },
34
+ )
35
+ }
36
+
37
+ export const usePackageStarMutation = (query: PackageStarQuery) => {
38
+ const axios = useAxios()
39
+ const queryClient = useQueryClient()
40
+
41
+ const addStar = useMutation(
42
+ async () => {
43
+ const { data } = await axios.post("/packages/add_star", query)
44
+ return data
45
+ },
46
+ {
47
+ onSuccess: () => {
48
+ queryClient.invalidateQueries(["packageStars", query])
49
+ },
50
+ },
51
+ )
52
+
53
+ const removeStar = useMutation(
54
+ async () => {
55
+ const { data } = await axios.post("/packages/remove_star", query)
56
+ return data
57
+ },
58
+ {
59
+ onSuccess: () => {
60
+ queryClient.invalidateQueries(["packageStars", query])
61
+ },
62
+ },
63
+ )
64
+
65
+ return {
66
+ addStar,
67
+ removeStar,
68
+ }
69
+ }
70
+
71
+ // Convenience hooks for common use cases
72
+ export const usePackageStarsById = (packageId: string | null) => {
73
+ return usePackageStars(packageId ? { package_id: packageId } : null)
74
+ }
75
+
76
+ export const usePackageStarsByName = (packageName: string | null) => {
77
+ return usePackageStars(packageName ? { name: packageName } : null)
78
+ }
79
+
80
+ export const usePackageStarMutationById = (packageId: string) => {
81
+ return usePackageStarMutation({ package_id: packageId })
82
+ }
83
+
84
+ export const usePackageStarMutationByName = (packageName: string) => {
85
+ return usePackageStarMutation({ name: packageName })
86
+ }
@@ -0,0 +1,9 @@
1
+ import TimeAgo from "javascript-time-ago"
2
+ import en from "javascript-time-ago/locale/en"
3
+
4
+ TimeAgo.addDefaultLocale(en)
5
+
6
+ export const timeAgo = (date: Date) => {
7
+ const timeAgo = new TimeAgo("en-US")
8
+ return timeAgo.format(date)
9
+ }
@@ -12,6 +12,7 @@ import { Input } from "@/components/ui/input"
12
12
  import { useGlobalStore } from "@/hooks/use-global-store"
13
13
  import { GlobeIcon, MoreVertical, PencilIcon, Trash2 } from "lucide-react"
14
14
  import { useConfirmDeleteSnippetDialog } from "@/components/dialogs/confirm-delete-snippet-dialog"
15
+ import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"
15
16
  import {
16
17
  DropdownMenu,
17
18
  DropdownMenuContent,
@@ -22,10 +23,7 @@ import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
22
23
  import { OptimizedImage } from "@/components/OptimizedImage"
23
24
  import { useSnippetsBaseApiUrl } from "@/hooks/use-snippets-base-api-url"
24
25
  import { SnippetTypeIcon } from "@/components/SnippetTypeIcon"
25
- import TimeAgo from "javascript-time-ago"
26
- import en from "javascript-time-ago/locale/en"
27
-
28
- TimeAgo.addDefaultLocale(en)
26
+ import { timeAgo } from "@/lib/utils/timeAgo"
29
27
 
30
28
  export const UserProfilePage = () => {
31
29
  const { username } = useParams()
@@ -60,7 +58,6 @@ export const UserProfilePage = () => {
60
58
  )
61
59
 
62
60
  const baseUrl = useSnippetsBaseApiUrl()
63
- const timeAgo = new TimeAgo("en-US")
64
61
 
65
62
  const snippetsToShow =
66
63
  activeTab === "starred" ? starredSnippets : userSnippets
@@ -84,9 +81,20 @@ export const UserProfilePage = () => {
84
81
  <div>
85
82
  <Header />
86
83
  <div className="container mx-auto px-4 py-8">
87
- <h1 className="text-3xl font-bold mb-6">
88
- {isCurrentUserProfile ? "My Profile" : `${username}'s Profile`}
89
- </h1>
84
+ <div className="flex items-center gap-4 mb-6">
85
+ <Avatar className="h-16 w-16">
86
+ <AvatarImage src={`https://github.com/${username}.png`} />
87
+ <AvatarFallback>{username?.[0]?.toUpperCase()}</AvatarFallback>
88
+ </Avatar>
89
+ <div>
90
+ <h1 className="text-3xl font-bold">
91
+ {isCurrentUserProfile ? "My Profile" : `${username}'s Profile`}
92
+ </h1>
93
+ <div className="text-gray-600 mt-1">
94
+ {userSnippets?.length || 0} packages
95
+ </div>
96
+ </div>
97
+ </div>
90
98
  <div className="mb-6">
91
99
  <a
92
100
  href={`https://github.com/${username}`}
@@ -208,9 +216,7 @@ export const UserProfilePage = () => {
208
216
  )}
209
217
  <div className="flex items-center text-xs gap-1 text-gray-500">
210
218
  <PencilIcon height={12} width={12} />
211
- <span>
212
- {timeAgo.format(new Date(snippet.updated_at))}
213
- </span>
219
+ <span>{timeAgo(new Date(snippet.updated_at))}</span>
214
220
  </div>
215
221
  </div>
216
222
  </div>
@@ -1,23 +1,18 @@
1
1
  import RepoPageContent from "@/components/ViewPackagePage/components/repo-page-content"
2
- import SimulatePage from "@/components/ViewPackagePage/simulate-page"
2
+ import { useCurrentPackageInfo } from "@/hooks/use-current-package-info"
3
3
  import { usePackageByName } from "@/hooks/use-package-by-package-name"
4
4
  import { usePackageFiles } from "@/hooks/use-package-files"
5
5
  import { usePackageRelease } from "@/hooks/use-package-release"
6
- import { useLocation } from "wouter"
6
+ import { useLocation, useParams } from "wouter"
7
7
 
8
8
  export const ViewPackagePage = () => {
9
- // Get the current path and extract author/packageName
10
- const [location] = useLocation()
11
- const pathParts = location.split("/")
12
- const author = pathParts[2]
13
- const urlPackageName = pathParts[3]
14
- const fullPackageName = `${author}/${urlPackageName}`
15
-
16
- const { data: packageInfo } = usePackageByName(fullPackageName)
9
+ const { packageInfo } = useCurrentPackageInfo()
10
+ const { author, packageName } = useParams()
11
+ const [, setLocation] = useLocation()
17
12
 
18
13
  const { data: packageRelease } = usePackageRelease({
19
14
  is_latest: true,
20
- package_name: fullPackageName,
15
+ package_name: `${author}/${packageName}`,
21
16
  })
22
17
 
23
18
  const { data: packageFiles } = usePackageFiles(
@@ -29,10 +24,14 @@ export const ViewPackagePage = () => {
29
24
  packageFiles={packageFiles as any}
30
25
  packageInfo={packageInfo as any}
31
26
  importantFilePaths={["README.md", "LICENSE", "package.json"]}
32
- onFileClicked={() => {}}
33
- onDirectoryClicked={() => {}}
34
- onExportClicked={() => {}}
35
- onEditClicked={() => {}}
27
+ onFileClicked={(file) => {
28
+ setLocation(
29
+ `/editor?package_id=${packageInfo?.package_id}&file_path=${file.file_path}`,
30
+ )
31
+ }}
32
+ onEditClicked={() => {
33
+ setLocation(`/editor?package_id=${packageInfo?.package_id}`)
34
+ }}
36
35
  />
37
36
  )
38
37
  }
Binary file
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="215" height="48" fill="none"><path fill="#000" d="M57.588 9.6h6L73.828 38h-5.2l-2.36-6.88h-11.36L52.548 38h-5.2l10.24-28.4Zm7.16 17.16-4.16-12.16-4.16 12.16h8.32Zm23.694-2.24c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.486-7.72.12 3.4c.534-1.227 1.307-2.173 2.32-2.84 1.04-.693 2.267-1.04 3.68-1.04 1.494 0 2.76.387 3.8 1.16 1.067.747 1.827 1.813 2.28 3.2.507-1.44 1.294-2.52 2.36-3.24 1.094-.747 2.414-1.12 3.96-1.12 1.414 0 2.64.307 3.68.92s1.84 1.52 2.4 2.72c.56 1.2.84 2.667.84 4.4V38h-4.96V25.92c0-1.813-.293-3.187-.88-4.12-.56-.96-1.413-1.44-2.56-1.44-.906 0-1.68.213-2.32.64-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.84-.48 3.04V38h-4.56V25.92c0-1.2-.133-2.213-.4-3.04-.24-.827-.626-1.453-1.16-1.88-.506-.427-1.133-.64-1.88-.64-.906 0-1.68.227-2.32.68-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.827-.48 3V38h-4.96V16.8h4.48Zm26.723 10.6c0-2.24.427-4.187 1.28-5.84.854-1.68 2.067-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.84 0 3.494.413 4.96 1.24 1.467.827 2.64 2.08 3.52 3.76.88 1.653 1.347 3.693 1.4 6.12v1.32h-15.08c.107 1.813.614 3.227 1.52 4.24.907.987 2.134 1.48 3.68 1.48.987 0 1.88-.253 2.68-.76a4.803 4.803 0 0 0 1.84-2.2l5.08.36c-.64 2.027-1.84 3.64-3.6 4.84-1.733 1.173-3.733 1.76-6 1.76-2.08 0-3.906-.453-5.48-1.36-1.573-.907-2.786-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84Zm15.16-2.04c-.213-1.733-.76-3.013-1.64-3.84-.853-.827-1.893-1.24-3.12-1.24-1.44 0-2.6.453-3.48 1.36-.88.88-1.44 2.12-1.68 3.72h9.92ZM163.139 9.6V38h-5.04V9.6h5.04Zm8.322 7.2.24 5.88-.64-.36c.32-2.053 1.094-3.56 2.32-4.52 1.254-.987 2.787-1.48 4.6-1.48 2.32 0 4.107.733 5.36 2.2 1.254 1.44 1.88 3.387 1.88 5.84V38h-4.96V25.92c0-1.253-.12-2.28-.36-3.08-.24-.8-.64-1.413-1.2-1.84-.533-.427-1.253-.64-2.16-.64-1.44 0-2.573.48-3.4 1.44-.8.933-1.2 2.307-1.2 4.12V38h-4.96V16.8h4.48Zm30.003 7.72c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.443 8.16V38h-5.6v-5.32h5.6Z"/><path fill="#171717" fill-rule="evenodd" d="m7.839 40.783 16.03-28.054L20 6 0 40.783h7.839Zm8.214 0H40L27.99 19.894l-4.02 7.032 3.976 6.914H20.02l-3.967 6.943Z" clip-rule="evenodd"/></svg>
Binary file
Binary file
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>
@@ -1,12 +0,0 @@
1
- interface RepoTabHeaderProps {
2
- activeTab: string
3
- setActiveTab: (tab: string) => void
4
- }
5
-
6
- export default function RepoTabHeader({
7
- activeTab,
8
- setActiveTab,
9
- }: RepoTabHeaderProps) {
10
- // This component is being handled by a different team
11
- return null
12
- }
@@ -1,120 +0,0 @@
1
- "use client"
2
-
3
- import { useState, useEffect } from "react"
4
- import RepoPageContent from "./components/repo-page-content"
5
-
6
- // Sample data for simulation
7
- const samplePackageFiles = [
8
- {
9
- package_file_id: "1",
10
- package_release_id: "1",
11
- file_path: "README.md",
12
- content_text:
13
- "# @tscircuit/keyboard-default60\n\nA Default 60 keyboard created with tscircuit\n\n## Features\n\n- Full mechanical keyboard PCB design\n- Compatible with standard 60% cases\n- USB-C connector\n- Supports QMK firmware",
14
- created_at: "2023-04-15T12:00:00Z",
15
- },
16
- {
17
- package_file_id: "2",
18
- package_release_id: "1",
19
- file_path: "LICENSE",
20
- content_text:
21
- 'MIT License\n\nCopyright (c) 2023 tscircuit\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions...',
22
- created_at: "2023-04-15T12:00:00Z",
23
- },
24
- {
25
- package_file_id: "3",
26
- package_release_id: "1",
27
- file_path: "lib/index.tsx",
28
- content_text:
29
- "import React from 'react'\nimport { PCB, Resistor, Capacitor, LED } from '@tscircuit/react'\n\nexport const KeyboardDefault60 = () => {\n return (\n <PCB name=\"keyboard-default60\">\n {/* Main controller */}\n <Microcontroller x={50} y={50} name=\"MCU1\" />\n \n {/* Key matrix */}\n <KeyMatrix x={100} y={100} rows={5} cols={14} />\n \n {/* Power circuit */}\n <PowerCircuit x={20} y={20} />\n </PCB>\n )\n}",
30
- created_at: "2023-04-15T12:00:00Z",
31
- },
32
- {
33
- package_file_id: "4",
34
- package_release_id: "1",
35
- file_path: "lib/components/KeyMatrix.tsx",
36
- content_text:
37
- "import React from 'react'\nimport { Switch, Diode } from '@tscircuit/react'\n\ninterface KeyMatrixProps {\n x: number\n y: number\n rows: number\n cols: number\n}\n\nexport const KeyMatrix = ({ x, y, rows, cols }: KeyMatrixProps) => {\n const keys = []\n \n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n keys.push(\n <Switch\n key={`key-${row}-${col}`}\n x={x + col * 19.05}\n y={y + row * 19.05}\n name={`SW${row * cols + col + 1}`}\n />\n )\n \n keys.push(\n <Diode\n key={`diode-${row}-${col}`}\n x={x + col * 19.05 + 5}\n y={y + row * 19.05 + 5}\n name={`D${row * cols + col + 1}`}\n />\n )\n }\n }\n \n return <>{keys}</>\n}",
38
- created_at: "2023-04-15T12:00:00Z",
39
- },
40
- {
41
- package_file_id: "5",
42
- package_release_id: "1",
43
- file_path: "lib/components/PowerCircuit.tsx",
44
- content_text:
45
- 'import React from \'react\'\nimport { Capacitor, Resistor, Regulator } from \'@tscircuit/react\'\n\ninterface PowerCircuitProps {\n x: number\n y: number\n}\n\nexport const PowerCircuit = ({ x, y }: PowerCircuitProps) => {\n return (\n <>\n <Regulator\n x={x}\n y={y}\n name="U1"\n value="AP2112K-3.3"\n />\n <Capacitor\n x={x - 10}\n y={y}\n name="C1"\n value="10uF"\n />\n <Capacitor\n x={x + 10}\n y={y}\n name="C2"\n value="10uF"\n />\n <Resistor\n x={x}\n y={y + 10}\n name="R1"\n value="10k"\n />\n </>\n )\n}',
46
- created_at: "2023-04-15T12:00:00Z",
47
- },
48
- {
49
- package_file_id: "6",
50
- package_release_id: "1",
51
- file_path: "package.json",
52
- content_text:
53
- '{\n "name": "@tscircuit/keyboard-default60",\n "version": "0.0.361",\n "description": "A Default 60 keyboard created with tscircuit",\n "main": "dist/index.js",\n "types": "dist/index.d.ts",\n "scripts": {\n "build": "tsc",\n "test": "jest"\n },\n "dependencies": {\n "@tscircuit/react": "^0.1.0",\n "react": "^18.2.0"\n },\n "devDependencies": {\n "typescript": "^5.0.0",\n "jest": "^29.0.0"\n },\n "license": "MIT"\n}',
54
- created_at: "2023-04-15T12:00:00Z",
55
- },
56
- {
57
- package_file_id: "7",
58
- package_release_id: "1",
59
- file_path: "tsconfig.json",
60
- content_text:
61
- '{\n "compilerOptions": {\n "target": "es2020",\n "module": "esnext",\n "moduleResolution": "node",\n "declaration": true,\n "outDir": "./dist",\n "strict": true,\n "esModuleInterop": true,\n "skipLibCheck": true,\n "forceConsistentCasingInFileNames": true,\n "jsx": "react"\n },\n "include": ["lib/**/*"],\n "exclude": ["node_modules", "**/*.test.ts"]\n}',
62
- created_at: "2023-04-15T12:00:00Z",
63
- },
64
- ]
65
-
66
- const samplePackageInfo = {
67
- name: "@tscircuit/keyboard-default60",
68
- unscoped_name: "keyboard-default60",
69
- owner_github_username: "tscircuit",
70
- star_count: "16",
71
- description: "A Default 60 keyboard created with tscircuit",
72
- ai_description:
73
- "This package contains the PCB design for a standard 60% mechanical keyboard layout, created using the tscircuit library. It includes the schematic, PCB layout, and 3D model.",
74
- }
75
-
76
- export default function SimulatePage() {
77
- const [packageFiles, setPackageFiles] = useState<any>(null)
78
- const [packageInfo, setPackageInfo] = useState<any>(null)
79
- const [loading, setLoading] = useState(true)
80
-
81
- useEffect(() => {
82
- // Simulate loading data after 1 second
83
- const timer = setTimeout(() => {
84
- setPackageFiles(samplePackageFiles)
85
- setPackageInfo(samplePackageInfo)
86
- setLoading(false)
87
- }, 1000)
88
-
89
- return () => clearTimeout(timer)
90
- }, [])
91
-
92
- // Event handlers with window.alert for testing
93
- const handleFileClicked = (file: any) => {
94
- window.alert(`File clicked: ${file.name}`)
95
- }
96
-
97
- const handleDirectoryClicked = (directory: any) => {
98
- window.alert(`Directory clicked: ${directory.name}`)
99
- }
100
-
101
- const handleExportClicked = (exportType: string) => {
102
- window.alert(`Export clicked: ${exportType}`)
103
- }
104
-
105
- const handleEditClicked = () => {
106
- window.alert("Edit button clicked")
107
- }
108
-
109
- return (
110
- <RepoPageContent
111
- packageFiles={packageFiles}
112
- packageInfo={packageInfo}
113
- importantFilePaths={["README.md", "LICENSE", "package.json"]}
114
- onFileClicked={handleFileClicked}
115
- onDirectoryClicked={handleDirectoryClicked}
116
- onExportClicked={handleExportClicked}
117
- onEditClicked={handleEditClicked}
118
- />
119
- )
120
- }