@tscircuit/fake-snippets 0.0.83 → 0.0.84
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/README.md +5 -2
- package/bun-tests/fake-snippets-api/routes/ai_reviews/create.test.ts +12 -0
- package/bun-tests/fake-snippets-api/routes/ai_reviews/get.test.ts +16 -0
- package/bun-tests/fake-snippets-api/routes/ai_reviews/list.test.ts +14 -0
- package/bun-tests/fake-snippets-api/routes/ai_reviews/process_review.test.ts +16 -0
- package/bun.lock +26 -37
- package/dist/bundle.js +557 -422
- package/dist/index.d.ts +62 -10
- package/dist/index.js +45 -1
- package/dist/schema.d.ts +82 -13
- package/dist/schema.js +12 -1
- package/fake-snippets-api/lib/db/db-client.ts +40 -0
- package/fake-snippets-api/lib/db/schema.ts +12 -0
- package/fake-snippets-api/routes/api/_fake/ai_reviews/process_review.ts +31 -0
- package/fake-snippets-api/routes/api/ai_reviews/create.ts +22 -0
- package/fake-snippets-api/routes/api/ai_reviews/get.ts +24 -0
- package/fake-snippets-api/routes/api/ai_reviews/list.ts +14 -0
- package/package.json +4 -3
- package/src/ContextProviders.tsx +1 -1
- package/src/components/Header2.tsx +8 -18
- package/src/components/SearchComponent.tsx +46 -8
- package/src/components/ViewSnippetHeader.tsx +9 -6
- package/src/components/dialogs/edit-package-details-dialog.tsx +5 -10
- package/src/hooks/use-fork-package-mutation.ts +4 -3
- package/src/hooks/use-sign-in.ts +10 -8
- package/src/hooks/useFileManagement.ts +74 -12
- package/src/hooks/useForkPackageMutation.ts +2 -1
- package/src/hooks/useForkSnippetMutation.ts +2 -1
- package/src/pages/authorize.tsx +164 -8
package/src/pages/authorize.tsx
CHANGED
|
@@ -6,6 +6,33 @@ import { useEffect, useState } from "react"
|
|
|
6
6
|
import * as jose from "jose"
|
|
7
7
|
import Footer from "@/components/Footer"
|
|
8
8
|
import { useLocation } from "wouter"
|
|
9
|
+
import { useIsUsingFakeApi } from "@/hooks/use-is-using-fake-api"
|
|
10
|
+
import { CheckCircle, AlertCircle, Loader2 } from "lucide-react"
|
|
11
|
+
|
|
12
|
+
const handleRedirect = (
|
|
13
|
+
redirect: string | null,
|
|
14
|
+
fallbackLocation: () => void,
|
|
15
|
+
) => {
|
|
16
|
+
if (redirect) {
|
|
17
|
+
try {
|
|
18
|
+
const decodedRedirect = decodeURIComponent(redirect)
|
|
19
|
+
|
|
20
|
+
if (decodedRedirect.startsWith("/")) {
|
|
21
|
+
window.location.href = decodedRedirect
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const redirectUrl = new URL(decodedRedirect)
|
|
26
|
+
if (redirectUrl.origin === window.location.origin) {
|
|
27
|
+
window.location.href = redirectUrl.href
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.warn("Invalid redirect URL:", redirect)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
fallbackLocation()
|
|
35
|
+
}
|
|
9
36
|
|
|
10
37
|
const AuthenticatePageInnerContent = () => {
|
|
11
38
|
const [location, setLocation] = useLocation()
|
|
@@ -13,32 +40,161 @@ const AuthenticatePageInnerContent = () => {
|
|
|
13
40
|
const [message, setMessage] = useState("logging you in...")
|
|
14
41
|
const searchParams = new URLSearchParams(window.location.search.split("?")[1])
|
|
15
42
|
const session_token = searchParams.get("session_token")
|
|
43
|
+
const redirect = searchParams.get("redirect")
|
|
44
|
+
const isUsingFakeApi = useIsUsingFakeApi()
|
|
45
|
+
|
|
46
|
+
const isError = message.includes("error") || message.includes("couldn't")
|
|
47
|
+
const isSuccess =
|
|
48
|
+
message.includes("success") || message.includes("redirecting")
|
|
49
|
+
|
|
16
50
|
useEffect(() => {
|
|
17
51
|
async function login() {
|
|
52
|
+
if (isUsingFakeApi) {
|
|
53
|
+
setSession({
|
|
54
|
+
account_id: "account-1234",
|
|
55
|
+
github_username: "testuser",
|
|
56
|
+
token: "1234",
|
|
57
|
+
session_id: "session-1234",
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
handleRedirect(redirect, () => setLocation("/"))
|
|
61
|
+
return
|
|
62
|
+
}
|
|
18
63
|
if (!session_token) {
|
|
19
|
-
setMessage("couldn't log in - no token")
|
|
64
|
+
setMessage("couldn't log in - no token provided")
|
|
20
65
|
return
|
|
21
66
|
}
|
|
22
|
-
|
|
23
67
|
if (session_token) {
|
|
24
68
|
const decodedToken = jose.decodeJwt(session_token)
|
|
25
69
|
setSession({
|
|
26
70
|
...(decodedToken as any),
|
|
27
71
|
token: session_token,
|
|
28
72
|
})
|
|
29
|
-
|
|
73
|
+
setMessage("success! redirecting you now...")
|
|
74
|
+
setTimeout(() => {
|
|
75
|
+
handleRedirect(redirect, () => setLocation("/"))
|
|
76
|
+
}, 1000)
|
|
30
77
|
return
|
|
31
78
|
}
|
|
32
79
|
}
|
|
33
80
|
login().catch((e) => {
|
|
34
|
-
setMessage(`error logging you in
|
|
81
|
+
setMessage(`error logging you in: ${e.message || e.toString()}`)
|
|
35
82
|
})
|
|
36
|
-
}, [session_token])
|
|
83
|
+
}, [session_token, redirect])
|
|
37
84
|
|
|
38
85
|
return (
|
|
39
|
-
<div className="bg-white
|
|
40
|
-
<div
|
|
41
|
-
|
|
86
|
+
<div className="min-h-screen bg-white flex items-center justify-center px-4">
|
|
87
|
+
<div className="w-full max-w-md">
|
|
88
|
+
<div className="bg-gray-50/20 rounded-2xl shadow-xl border border-gray-200 p-8">
|
|
89
|
+
<div className="text-center">
|
|
90
|
+
<div className="mb-6">
|
|
91
|
+
{isError ? (
|
|
92
|
+
<div className="mx-auto w-16 h-16 bg-red-100 rounded-full flex items-center justify-center">
|
|
93
|
+
<AlertCircle className="h-8 w-8 text-red-500" />
|
|
94
|
+
</div>
|
|
95
|
+
) : isSuccess ? (
|
|
96
|
+
<div className="mx-auto w-16 h-16 bg-green-100 rounded-full flex items-center justify-center">
|
|
97
|
+
<CheckCircle className="h-8 w-8 text-green-500" />
|
|
98
|
+
</div>
|
|
99
|
+
) : (
|
|
100
|
+
<div className="mx-auto w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center">
|
|
101
|
+
<Loader2 className="h-8 w-8 text-blue-500 animate-spin" />
|
|
102
|
+
</div>
|
|
103
|
+
)}
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
{/* Title */}
|
|
107
|
+
<h1 className="text-2xl font-semibold text-gray-900 mb-3">
|
|
108
|
+
{isError
|
|
109
|
+
? "Authentication Failed"
|
|
110
|
+
: isSuccess
|
|
111
|
+
? "Success!"
|
|
112
|
+
: "Signing You In"}
|
|
113
|
+
</h1>
|
|
114
|
+
|
|
115
|
+
{/* Message */}
|
|
116
|
+
<div className="text-gray-600">
|
|
117
|
+
{isError ? (
|
|
118
|
+
<div className="bg-red-50 border border-red-200 rounded-lg p-4 text-left">
|
|
119
|
+
<p className="text-red-800 font-medium mb-2">
|
|
120
|
+
Authentication Error
|
|
121
|
+
</p>
|
|
122
|
+
<p className="text-red-700 text-sm break-words">{message}</p>
|
|
123
|
+
<div className="mt-4 pt-3 border-t border-red-200">
|
|
124
|
+
<p className="text-red-600 text-xs">
|
|
125
|
+
Please try signing in again or contact support if the
|
|
126
|
+
problem persists.
|
|
127
|
+
</p>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
) : isSuccess ? (
|
|
131
|
+
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
|
|
132
|
+
<p className="text-green-800 font-medium">
|
|
133
|
+
Authentication successful!
|
|
134
|
+
</p>
|
|
135
|
+
<p className="text-green-700 text-sm mt-1">
|
|
136
|
+
Redirecting you now...
|
|
137
|
+
</p>
|
|
138
|
+
</div>
|
|
139
|
+
) : (
|
|
140
|
+
<div>
|
|
141
|
+
<p className="text-gray-600 mb-4">
|
|
142
|
+
Please wait while we authenticate your account and redirect
|
|
143
|
+
you to your destination.
|
|
144
|
+
</p>
|
|
145
|
+
<div className="flex items-center justify-center text-sm text-gray-500">
|
|
146
|
+
<div className="flex space-x-1">
|
|
147
|
+
<div className="w-1 h-1 bg-gray-400 rounded-full animate-bounce"></div>
|
|
148
|
+
<div
|
|
149
|
+
className="w-1 h-1 bg-gray-400 rounded-full animate-bounce"
|
|
150
|
+
style={{ animationDelay: "0.1s" }}
|
|
151
|
+
></div>
|
|
152
|
+
<div
|
|
153
|
+
className="w-1 h-1 bg-gray-400 rounded-full animate-bounce"
|
|
154
|
+
style={{ animationDelay: "0.2s" }}
|
|
155
|
+
></div>
|
|
156
|
+
</div>
|
|
157
|
+
<span className="ml-2">Processing</span>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
)}
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
{/* Footer info */}
|
|
166
|
+
<div className="text-center mt-6 text-xs text-gray-500">
|
|
167
|
+
If you encounter any issues, please report them on our{" "}
|
|
168
|
+
<a
|
|
169
|
+
href="https://github.com/tscircuit/tscircuit/issues"
|
|
170
|
+
className="text-blue-500 underline"
|
|
171
|
+
>
|
|
172
|
+
GitHub Issues page
|
|
173
|
+
</a>
|
|
174
|
+
.
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
<style
|
|
179
|
+
dangerouslySetInnerHTML={{
|
|
180
|
+
__html: `
|
|
181
|
+
@keyframes pulse-loading {
|
|
182
|
+
0% {
|
|
183
|
+
width: 0%;
|
|
184
|
+
}
|
|
185
|
+
50% {
|
|
186
|
+
width: 60%;
|
|
187
|
+
}
|
|
188
|
+
100% {
|
|
189
|
+
width: 100%;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
.animate-pulse-loading {
|
|
193
|
+
animation: pulse-loading 2s ease-in-out infinite;
|
|
194
|
+
}
|
|
195
|
+
`,
|
|
196
|
+
}}
|
|
197
|
+
/>
|
|
42
198
|
</div>
|
|
43
199
|
)
|
|
44
200
|
}
|