@tscircuit/fake-snippets 0.0.95 → 0.0.97
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/api/generated-index.js +8 -0
- package/bun-tests/fake-snippets-api/routes/datasheets/create.test.ts +1 -0
- package/bun-tests/fake-snippets-api/routes/datasheets/process_all_datasheets.test.ts +1 -0
- package/bun-tests/fake-snippets-api/routes/datasheets/run_async_tasks.test.ts +1 -0
- package/bun.lock +36 -32
- package/dist/bundle.js +39 -11
- package/dist/index.d.ts +9 -4
- package/dist/index.js +4 -2
- package/dist/schema.d.ts +14 -6
- package/dist/schema.js +2 -1
- package/fake-snippets-api/lib/db/db-client.ts +1 -0
- package/fake-snippets-api/lib/db/schema.ts +1 -0
- package/fake-snippets-api/routes/api/_fake/datasheets/process_all_datasheets.ts +2 -1
- package/fake-snippets-api/routes/api/package_releases/rebuild.ts +39 -5
- package/package.json +4 -4
- package/src/components/DownloadButtonAndMenu.tsx +4 -4
- package/src/components/ExpandableText.tsx +29 -0
- package/src/components/Header.tsx +11 -0
- package/src/components/Header2.tsx +6 -0
- package/src/components/PackageCard.tsx +16 -35
- package/src/components/PrefetchPageLink.tsx +11 -2
- package/src/components/dialogs/confirm-delete-package-dialog.tsx +19 -6
- package/src/hooks/use-account-balance.ts +2 -1
- package/src/hooks/use-rebuild-package-release-mutation.ts +2 -2
- package/src/pages/datasheet.tsx +36 -15
- package/src/pages/datasheets.tsx +94 -26
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Dialog,
|
|
3
|
+
DialogContent,
|
|
4
|
+
DialogHeader,
|
|
5
|
+
DialogTitle,
|
|
6
|
+
DialogDescription,
|
|
7
|
+
} from "../ui/dialog"
|
|
2
8
|
import { Button } from "../ui/button"
|
|
3
9
|
import { createUseDialog } from "./create-use-dialog"
|
|
4
10
|
import { useDeletePackage } from "@/hooks/use-delete-package"
|
|
@@ -33,13 +39,20 @@ export const ConfirmDeletePackageDialog = ({
|
|
|
33
39
|
|
|
34
40
|
return (
|
|
35
41
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
36
|
-
<DialogContent className="w-[90vw]">
|
|
42
|
+
<DialogContent className="w-[90vw] p-6 rounded-2xl shadow-lg">
|
|
37
43
|
<DialogHeader>
|
|
38
|
-
<DialogTitle
|
|
44
|
+
<DialogTitle className="text-left">
|
|
45
|
+
Confirm Delete Package
|
|
46
|
+
</DialogTitle>
|
|
47
|
+
<DialogDescription className="text-left">
|
|
48
|
+
Are you sure you want to delete the package{" "}
|
|
49
|
+
<span className="font-bold">{packageName}</span>?
|
|
50
|
+
</DialogDescription>
|
|
39
51
|
</DialogHeader>
|
|
40
|
-
<p
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
<p className="text-red-600 font-medium">
|
|
53
|
+
This action cannot be undone.
|
|
54
|
+
</p>
|
|
55
|
+
<div className="flex justify-end gap-4 mt-6">
|
|
43
56
|
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
44
57
|
Cancel
|
|
45
58
|
</Button>
|
|
@@ -17,8 +17,9 @@ export const useAccountBalance = () => {
|
|
|
17
17
|
return data.account_balance
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
refetchInterval: 60000, // Refetch every minute
|
|
20
|
+
// refetchInterval: 60000, // Refetch every minute
|
|
21
21
|
enabled: isLoggedIn,
|
|
22
|
+
refetchOnWindowFocus: false,
|
|
22
23
|
},
|
|
23
24
|
)
|
|
24
25
|
}
|
|
@@ -30,8 +30,8 @@ export const useRebuildPackageReleaseMutation = ({
|
|
|
30
30
|
toast({
|
|
31
31
|
title: "Error",
|
|
32
32
|
description:
|
|
33
|
-
error?.response?.data?.message ||
|
|
34
|
-
error?.data?.message ||
|
|
33
|
+
error?.response?.data?.error?.message ||
|
|
34
|
+
error?.data?.error?.message ||
|
|
35
35
|
"Failed to rebuild package.",
|
|
36
36
|
variant: "destructive",
|
|
37
37
|
})
|
package/src/pages/datasheet.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { useDatasheet } from "@/hooks/use-datasheet"
|
|
|
3
3
|
import { useCreateDatasheet } from "@/hooks/use-create-datasheet"
|
|
4
4
|
import Header from "@/components/Header"
|
|
5
5
|
import Footer from "@/components/Footer"
|
|
6
|
+
import ExpandableText from "@/components/ExpandableText"
|
|
6
7
|
import type { Datasheet } from "fake-snippets-api/lib/db/schema"
|
|
7
8
|
|
|
8
9
|
export const DatasheetPage = () => {
|
|
@@ -20,10 +21,38 @@ export const DatasheetPage = () => {
|
|
|
20
21
|
<Header />
|
|
21
22
|
<main className="container mx-auto flex-1 px-4 py-8">
|
|
22
23
|
<h1 className="text-3xl font-bold mb-6">{chipName} Datasheet</h1>
|
|
24
|
+
<p className="mb-4">
|
|
25
|
+
<a
|
|
26
|
+
href={`https://api.tscircuit.com/datasheets/get?chip_name=${encodeURIComponent(chipName)}`}
|
|
27
|
+
className="text-blue-600 underline"
|
|
28
|
+
>
|
|
29
|
+
Download JSON
|
|
30
|
+
</a>
|
|
31
|
+
</p>
|
|
23
32
|
{datasheetQuery.isLoading ? (
|
|
24
33
|
<p>Loading...</p>
|
|
25
34
|
) : datasheetQuery.data ? (
|
|
26
35
|
<div>
|
|
36
|
+
{!datasheetQuery.data.pin_information &&
|
|
37
|
+
!datasheetQuery.data.datasheet_pdf_urls && (
|
|
38
|
+
<p>Datasheet is processing. Please check back later.</p>
|
|
39
|
+
)}
|
|
40
|
+
|
|
41
|
+
<h2 className="text-xl font-semibold mb-2">PDFs</h2>
|
|
42
|
+
{datasheetQuery.data.datasheet_pdf_urls ? (
|
|
43
|
+
<ul className="list-disc pl-5 mb-6">
|
|
44
|
+
{datasheetQuery.data.datasheet_pdf_urls.map((url) => (
|
|
45
|
+
<li key={url}>
|
|
46
|
+
<a href={url} className="text-blue-600 underline">
|
|
47
|
+
{url}
|
|
48
|
+
</a>
|
|
49
|
+
</li>
|
|
50
|
+
))}
|
|
51
|
+
</ul>
|
|
52
|
+
) : (
|
|
53
|
+
<p>No datasheet PDFs available.</p>
|
|
54
|
+
)}
|
|
55
|
+
|
|
27
56
|
<h2 className="text-xl font-semibold mb-2">Pin Information</h2>
|
|
28
57
|
{datasheetQuery.data.pin_information ? (
|
|
29
58
|
<table className="table-auto border-collapse mb-6">
|
|
@@ -32,6 +61,7 @@ export const DatasheetPage = () => {
|
|
|
32
61
|
<th className="border px-2 py-1">Pin</th>
|
|
33
62
|
<th className="border px-2 py-1">Name</th>
|
|
34
63
|
<th className="border px-2 py-1">Description</th>
|
|
64
|
+
<th className="border px-2 py-1">Capabilities</th>
|
|
35
65
|
</tr>
|
|
36
66
|
</thead>
|
|
37
67
|
<tbody>
|
|
@@ -40,6 +70,12 @@ export const DatasheetPage = () => {
|
|
|
40
70
|
<td className="border px-2 py-1">{pin.pin_number}</td>
|
|
41
71
|
<td className="border px-2 py-1">{pin.name}</td>
|
|
42
72
|
<td className="border px-2 py-1">{pin.description}</td>
|
|
73
|
+
<td className="border px-2 py-1">
|
|
74
|
+
<ExpandableText
|
|
75
|
+
text={pin.capabilities.join(", ")}
|
|
76
|
+
maxChars={30}
|
|
77
|
+
/>
|
|
78
|
+
</td>
|
|
43
79
|
</tr>
|
|
44
80
|
))}
|
|
45
81
|
</tbody>
|
|
@@ -47,21 +83,6 @@ export const DatasheetPage = () => {
|
|
|
47
83
|
) : (
|
|
48
84
|
<p>No pin information available.</p>
|
|
49
85
|
)}
|
|
50
|
-
|
|
51
|
-
<h2 className="text-xl font-semibold mb-2">PDFs</h2>
|
|
52
|
-
{datasheetQuery.data.datasheet_pdf_urls ? (
|
|
53
|
-
<ul className="list-disc pl-5">
|
|
54
|
-
{datasheetQuery.data.datasheet_pdf_urls.map((url) => (
|
|
55
|
-
<li key={url}>
|
|
56
|
-
<a href={url} className="text-blue-600 underline">
|
|
57
|
-
{url}
|
|
58
|
-
</a>
|
|
59
|
-
</li>
|
|
60
|
-
))}
|
|
61
|
-
</ul>
|
|
62
|
-
) : (
|
|
63
|
-
<p>No datasheet PDFs available.</p>
|
|
64
|
-
)}
|
|
65
86
|
</div>
|
|
66
87
|
) : datasheetQuery.error &&
|
|
67
88
|
(datasheetQuery.error as any).status === 404 ? (
|
package/src/pages/datasheets.tsx
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React, { useState } from "react"
|
|
2
2
|
import { useQuery } from "react-query"
|
|
3
3
|
import { useAxios } from "@/hooks/use-axios"
|
|
4
|
+
import { useCreateDatasheet } from "@/hooks/use-create-datasheet"
|
|
4
5
|
import Header from "@/components/Header"
|
|
5
6
|
import Footer from "@/components/Footer"
|
|
6
7
|
import { Input } from "@/components/ui/input"
|
|
7
8
|
import { Search } from "lucide-react"
|
|
8
|
-
import { Link } from "wouter"
|
|
9
|
+
import { Link, useLocation } from "wouter"
|
|
9
10
|
|
|
10
11
|
interface DatasheetSummary {
|
|
11
12
|
datasheet_id: string
|
|
@@ -14,6 +15,10 @@ interface DatasheetSummary {
|
|
|
14
15
|
|
|
15
16
|
export const DatasheetsPage: React.FC = () => {
|
|
16
17
|
const axios = useAxios()
|
|
18
|
+
const [, navigate] = useLocation()
|
|
19
|
+
const createDatasheet = useCreateDatasheet({
|
|
20
|
+
onSuccess: (datasheet) => navigate(`/datasheets/${datasheet.chip_name}`),
|
|
21
|
+
})
|
|
17
22
|
const [searchQuery, setSearchQuery] = useState("")
|
|
18
23
|
|
|
19
24
|
const {
|
|
@@ -29,9 +34,7 @@ export const DatasheetsPage: React.FC = () => {
|
|
|
29
34
|
} else {
|
|
30
35
|
params.append("is_popular", "true")
|
|
31
36
|
}
|
|
32
|
-
const { data } = await axios.get(
|
|
33
|
-
`/api/datasheets/list?${params.toString()}`,
|
|
34
|
-
)
|
|
37
|
+
const { data } = await axios.get(`/datasheets/list?${params.toString()}`)
|
|
35
38
|
return data.datasheets as DatasheetSummary[]
|
|
36
39
|
},
|
|
37
40
|
{ keepPreviousData: true },
|
|
@@ -40,36 +43,101 @@ export const DatasheetsPage: React.FC = () => {
|
|
|
40
43
|
return (
|
|
41
44
|
<div className="min-h-screen flex flex-col">
|
|
42
45
|
<Header />
|
|
43
|
-
<main className="container mx-auto
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<Search className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 h-4 w-4" />
|
|
48
|
-
<Input
|
|
49
|
-
type="search"
|
|
50
|
-
placeholder="Search datasheets..."
|
|
51
|
-
className="pl-10"
|
|
52
|
-
value={searchQuery}
|
|
53
|
-
onChange={(e) => setSearchQuery(e.target.value)}
|
|
54
|
-
aria-label="Search datasheets"
|
|
55
|
-
role="searchbox"
|
|
56
|
-
/>
|
|
46
|
+
<main className="flex-grow container mx-auto px-4 py-8">
|
|
47
|
+
<div className="mb-8 max-w-3xl">
|
|
48
|
+
<div className="flex items-center gap-2 mb-3">
|
|
49
|
+
<h1 className="text-4xl font-bold text-gray-900">Datasheets</h1>
|
|
57
50
|
</div>
|
|
51
|
+
<p className="text-lg text-gray-600 mb-4">
|
|
52
|
+
Explore datasheets for popular electronic components and chips.
|
|
53
|
+
Search to find specific ones.
|
|
54
|
+
</p>
|
|
58
55
|
</div>
|
|
56
|
+
|
|
57
|
+
<div className="mb-6">
|
|
58
|
+
<div className="flex flex-col sm:flex-row gap-4 mb-4">
|
|
59
|
+
<div className="relative flex-grow">
|
|
60
|
+
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" />
|
|
61
|
+
<Input
|
|
62
|
+
type="search"
|
|
63
|
+
placeholder="Search datasheets..."
|
|
64
|
+
className="pl-10"
|
|
65
|
+
value={searchQuery}
|
|
66
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
67
|
+
aria-label="Search datasheets"
|
|
68
|
+
role="searchbox"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
59
74
|
{isLoading ? (
|
|
60
|
-
<
|
|
75
|
+
<div className="text-center py-12 px-4">
|
|
76
|
+
<div className="bg-slate-50 inline-flex rounded-full p-4 mb-4">
|
|
77
|
+
<Search className="w-8 h-8 text-slate-400" />
|
|
78
|
+
</div>
|
|
79
|
+
<h3 className="text-xl font-medium text-slate-900 mb-2">
|
|
80
|
+
Loading Datasheets
|
|
81
|
+
</h3>
|
|
82
|
+
<p className="text-slate-500 max-w-md mx-auto mb-6">
|
|
83
|
+
Please wait while we fetch the datasheets...
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
61
86
|
) : error ? (
|
|
62
|
-
<p
|
|
87
|
+
<div className="bg-red-50 border border-red-200 text-red-700 p-6 rounded-xl shadow-sm max-w-2xl mx-auto">
|
|
88
|
+
<div className="flex items-start">
|
|
89
|
+
<div className="mr-4 bg-red-100 p-2 rounded-full">
|
|
90
|
+
<Search className="w-6 h-6 text-red-600" />
|
|
91
|
+
</div>
|
|
92
|
+
<div>
|
|
93
|
+
<h3 className="text-lg font-semibold mb-2">
|
|
94
|
+
Error Loading Datasheets
|
|
95
|
+
</h3>
|
|
96
|
+
<p className="text-red-600">
|
|
97
|
+
We couldn't load the datasheets. Please try again later.
|
|
98
|
+
</p>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
63
102
|
) : datasheets && datasheets.length > 0 ? (
|
|
64
|
-
<
|
|
103
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
65
104
|
{datasheets.map((ds) => (
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
105
|
+
<Link
|
|
106
|
+
key={ds.datasheet_id}
|
|
107
|
+
href={`/datasheets/${ds.chip_name}`}
|
|
108
|
+
className="block p-4 bg-white rounded-lg shadow hover:shadow-md transition-shadow"
|
|
109
|
+
>
|
|
110
|
+
<h3 className="font-semibold text-gray-900">{ds.chip_name}</h3>
|
|
111
|
+
</Link>
|
|
69
112
|
))}
|
|
70
|
-
</
|
|
113
|
+
</div>
|
|
71
114
|
) : (
|
|
72
|
-
<
|
|
115
|
+
<div className="text-center py-12 px-4">
|
|
116
|
+
<div className="bg-slate-50 inline-flex rounded-full p-4 mb-4">
|
|
117
|
+
<Search className="w-8 h-8 text-slate-400" />
|
|
118
|
+
</div>
|
|
119
|
+
<h3 className="text-xl font-medium text-slate-900 mb-2">
|
|
120
|
+
No Matching Datasheets
|
|
121
|
+
</h3>
|
|
122
|
+
<p className="text-slate-500 max-w-md mx-auto mb-6">
|
|
123
|
+
{searchQuery
|
|
124
|
+
? `No datasheets match your search for "${searchQuery}".`
|
|
125
|
+
: "There are no popular datasheets at the moment."}
|
|
126
|
+
</p>
|
|
127
|
+
{searchQuery && (
|
|
128
|
+
<button
|
|
129
|
+
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded"
|
|
130
|
+
onClick={() =>
|
|
131
|
+
createDatasheet.mutate({ chip_name: searchQuery })
|
|
132
|
+
}
|
|
133
|
+
disabled={createDatasheet.isLoading}
|
|
134
|
+
>
|
|
135
|
+
{createDatasheet.isLoading
|
|
136
|
+
? "Creating..."
|
|
137
|
+
: `Create Datasheet for ${searchQuery}`}
|
|
138
|
+
</button>
|
|
139
|
+
)}
|
|
140
|
+
</div>
|
|
73
141
|
)}
|
|
74
142
|
</main>
|
|
75
143
|
<Footer />
|