Spaces:
Running
Running
feat. integrate posthog
Browse files- package.json +1 -0
- pnpm-lock.yaml +41 -0
- src/app/layout.tsx +9 -6
- src/app/providers.tsx +21 -0
- src/components/preview.tsx +5 -0
- src/components/prompt-input.tsx +6 -0
package.json
CHANGED
|
@@ -49,6 +49,7 @@
|
|
| 49 |
"lucide-react": "^0.454.0",
|
| 50 |
"next": "15.2.4",
|
| 51 |
"next-themes": "^0.4.4",
|
|
|
|
| 52 |
"react": "^19",
|
| 53 |
"react-day-picker": "8.10.1",
|
| 54 |
"react-dom": "^19",
|
|
|
|
| 49 |
"lucide-react": "^0.454.0",
|
| 50 |
"next": "15.2.4",
|
| 51 |
"next-themes": "^0.4.4",
|
| 52 |
+
"posthog-js": "^1.249.2",
|
| 53 |
"react": "^19",
|
| 54 |
"react-day-picker": "8.10.1",
|
| 55 |
"react-dom": "^19",
|
pnpm-lock.yaml
CHANGED
|
@@ -128,6 +128,9 @@ importers:
|
|
| 128 |
next-themes:
|
| 129 |
specifier: ^0.4.4
|
| 130 |
version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
|
|
|
|
|
|
|
|
|
| 131 |
react:
|
| 132 |
specifier: ^19
|
| 133 |
version: 19.1.0
|
|
@@ -1400,6 +1403,9 @@ packages:
|
|
| 1400 |
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
| 1401 |
engines: {node: '>= 6'}
|
| 1402 |
|
|
|
|
|
|
|
|
|
|
| 1403 |
cross-spawn@7.0.6:
|
| 1404 |
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
| 1405 |
engines: {node: '>= 8'}
|
|
@@ -1521,6 +1527,9 @@ packages:
|
|
| 1521 |
fastq@1.19.1:
|
| 1522 |
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
|
| 1523 |
|
|
|
|
|
|
|
|
|
|
| 1524 |
fill-range@7.1.1:
|
| 1525 |
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
| 1526 |
engines: {node: '>=8'}
|
|
@@ -1776,6 +1785,20 @@ packages:
|
|
| 1776 |
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
|
| 1777 |
engines: {node: ^10 || ^12 || >=14}
|
| 1778 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1779 |
prop-types@15.8.1:
|
| 1780 |
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
| 1781 |
|
|
@@ -2049,6 +2072,9 @@ packages:
|
|
| 2049 |
victory-vendor@36.9.2:
|
| 2050 |
resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==}
|
| 2051 |
|
|
|
|
|
|
|
|
|
|
| 2052 |
which@2.0.2:
|
| 2053 |
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
| 2054 |
engines: {node: '>= 8'}
|
|
@@ -3243,6 +3269,8 @@ snapshots:
|
|
| 3243 |
|
| 3244 |
commander@4.1.1: {}
|
| 3245 |
|
|
|
|
|
|
|
| 3246 |
cross-spawn@7.0.6:
|
| 3247 |
dependencies:
|
| 3248 |
path-key: 3.1.1
|
|
@@ -3347,6 +3375,8 @@ snapshots:
|
|
| 3347 |
dependencies:
|
| 3348 |
reusify: 1.1.0
|
| 3349 |
|
|
|
|
|
|
|
| 3350 |
fill-range@7.1.1:
|
| 3351 |
dependencies:
|
| 3352 |
to-regex-range: 5.0.1
|
|
@@ -3565,6 +3595,15 @@ snapshots:
|
|
| 3565 |
picocolors: 1.1.1
|
| 3566 |
source-map-js: 1.2.1
|
| 3567 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3568 |
prop-types@15.8.1:
|
| 3569 |
dependencies:
|
| 3570 |
loose-envify: 1.4.0
|
|
@@ -3878,6 +3917,8 @@ snapshots:
|
|
| 3878 |
d3-time: 3.1.0
|
| 3879 |
d3-timer: 3.0.1
|
| 3880 |
|
|
|
|
|
|
|
| 3881 |
which@2.0.2:
|
| 3882 |
dependencies:
|
| 3883 |
isexe: 2.0.0
|
|
|
|
| 128 |
next-themes:
|
| 129 |
specifier: ^0.4.4
|
| 130 |
version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
| 131 |
+
posthog-js:
|
| 132 |
+
specifier: ^1.249.2
|
| 133 |
+
version: 1.249.2
|
| 134 |
react:
|
| 135 |
specifier: ^19
|
| 136 |
version: 19.1.0
|
|
|
|
| 1403 |
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
| 1404 |
engines: {node: '>= 6'}
|
| 1405 |
|
| 1406 |
+
core-js@3.42.0:
|
| 1407 |
+
resolution: {integrity: sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g==}
|
| 1408 |
+
|
| 1409 |
cross-spawn@7.0.6:
|
| 1410 |
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
| 1411 |
engines: {node: '>= 8'}
|
|
|
|
| 1527 |
fastq@1.19.1:
|
| 1528 |
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
|
| 1529 |
|
| 1530 |
+
fflate@0.4.8:
|
| 1531 |
+
resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==}
|
| 1532 |
+
|
| 1533 |
fill-range@7.1.1:
|
| 1534 |
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
| 1535 |
engines: {node: '>=8'}
|
|
|
|
| 1785 |
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
|
| 1786 |
engines: {node: ^10 || ^12 || >=14}
|
| 1787 |
|
| 1788 |
+
posthog-js@1.249.2:
|
| 1789 |
+
resolution: {integrity: sha512-OMXCO/IfcJBjYTuebVynMbp8Kq329yKEQSCAnkqLmi8W2Bt5bi7S5xxMwDM3Pm7818Uh0C40XMG3rAtYozId6Q==}
|
| 1790 |
+
peerDependencies:
|
| 1791 |
+
'@rrweb/types': 2.0.0-alpha.17
|
| 1792 |
+
rrweb-snapshot: 2.0.0-alpha.17
|
| 1793 |
+
peerDependenciesMeta:
|
| 1794 |
+
'@rrweb/types':
|
| 1795 |
+
optional: true
|
| 1796 |
+
rrweb-snapshot:
|
| 1797 |
+
optional: true
|
| 1798 |
+
|
| 1799 |
+
preact@10.26.8:
|
| 1800 |
+
resolution: {integrity: sha512-1nMfdFjucm5hKvq0IClqZwK4FJkGXhRrQstOQ3P4vp8HxKrJEMFcY6RdBRVTdfQS/UlnX6gfbPuTvaqx/bDoeQ==}
|
| 1801 |
+
|
| 1802 |
prop-types@15.8.1:
|
| 1803 |
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
| 1804 |
|
|
|
|
| 2072 |
victory-vendor@36.9.2:
|
| 2073 |
resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==}
|
| 2074 |
|
| 2075 |
+
web-vitals@4.2.4:
|
| 2076 |
+
resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==}
|
| 2077 |
+
|
| 2078 |
which@2.0.2:
|
| 2079 |
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
| 2080 |
engines: {node: '>= 8'}
|
|
|
|
| 3269 |
|
| 3270 |
commander@4.1.1: {}
|
| 3271 |
|
| 3272 |
+
core-js@3.42.0: {}
|
| 3273 |
+
|
| 3274 |
cross-spawn@7.0.6:
|
| 3275 |
dependencies:
|
| 3276 |
path-key: 3.1.1
|
|
|
|
| 3375 |
dependencies:
|
| 3376 |
reusify: 1.1.0
|
| 3377 |
|
| 3378 |
+
fflate@0.4.8: {}
|
| 3379 |
+
|
| 3380 |
fill-range@7.1.1:
|
| 3381 |
dependencies:
|
| 3382 |
to-regex-range: 5.0.1
|
|
|
|
| 3595 |
picocolors: 1.1.1
|
| 3596 |
source-map-js: 1.2.1
|
| 3597 |
|
| 3598 |
+
posthog-js@1.249.2:
|
| 3599 |
+
dependencies:
|
| 3600 |
+
core-js: 3.42.0
|
| 3601 |
+
fflate: 0.4.8
|
| 3602 |
+
preact: 10.26.8
|
| 3603 |
+
web-vitals: 4.2.4
|
| 3604 |
+
|
| 3605 |
+
preact@10.26.8: {}
|
| 3606 |
+
|
| 3607 |
prop-types@15.8.1:
|
| 3608 |
dependencies:
|
| 3609 |
loose-envify: 1.4.0
|
|
|
|
| 3917 |
d3-time: 3.1.0
|
| 3918 |
d3-timer: 3.0.1
|
| 3919 |
|
| 3920 |
+
web-vitals@4.2.4: {}
|
| 3921 |
+
|
| 3922 |
which@2.0.2:
|
| 3923 |
dependencies:
|
| 3924 |
isexe: 2.0.0
|
src/app/layout.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import { ThemeProvider } from "@/components/theme-provider"
|
|
| 6 |
import { TooltipProvider } from "@/components/ui/tooltip"
|
| 7 |
import { Toaster } from "sonner"
|
| 8 |
import { ModelProvider } from "@/lib/contexts/model-context"
|
|
|
|
| 9 |
|
| 10 |
const inter = Inter({ subsets: ["latin"] })
|
| 11 |
|
|
@@ -22,12 +23,14 @@ export default function RootLayout({
|
|
| 22 |
return (
|
| 23 |
<html lang="en" suppressHydrationWarning>
|
| 24 |
<body className={inter.className} suppressHydrationWarning>
|
| 25 |
-
<
|
| 26 |
-
<
|
| 27 |
-
<
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
|
|
|
|
|
|
| 31 |
</body>
|
| 32 |
</html>
|
| 33 |
)
|
|
|
|
| 6 |
import { TooltipProvider } from "@/components/ui/tooltip"
|
| 7 |
import { Toaster } from "sonner"
|
| 8 |
import { ModelProvider } from "@/lib/contexts/model-context"
|
| 9 |
+
import { PostHogProvider } from './providers'
|
| 10 |
|
| 11 |
const inter = Inter({ subsets: ["latin"] })
|
| 12 |
|
|
|
|
| 23 |
return (
|
| 24 |
<html lang="en" suppressHydrationWarning>
|
| 25 |
<body className={inter.className} suppressHydrationWarning>
|
| 26 |
+
<PostHogProvider>
|
| 27 |
+
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange>
|
| 28 |
+
<ModelProvider>
|
| 29 |
+
<TooltipProvider>{children}</TooltipProvider>
|
| 30 |
+
<Toaster richColors />
|
| 31 |
+
</ModelProvider>
|
| 32 |
+
</ThemeProvider>
|
| 33 |
+
</PostHogProvider>
|
| 34 |
</body>
|
| 35 |
</html>
|
| 36 |
)
|
src/app/providers.tsx
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// app/providers.tsx
|
| 2 |
+
'use client'
|
| 3 |
+
|
| 4 |
+
import posthog from 'posthog-js'
|
| 5 |
+
import { PostHogProvider as PHProvider } from 'posthog-js/react'
|
| 6 |
+
import { useEffect } from 'react'
|
| 7 |
+
|
| 8 |
+
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
| 9 |
+
useEffect(() => {
|
| 10 |
+
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY || '', {
|
| 11 |
+
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
|
| 12 |
+
defaults: '2025-05-24',
|
| 13 |
+
})
|
| 14 |
+
}, [])
|
| 15 |
+
|
| 16 |
+
return (
|
| 17 |
+
<PHProvider client={posthog}>
|
| 18 |
+
{children}
|
| 19 |
+
</PHProvider>
|
| 20 |
+
)
|
| 21 |
+
}
|
src/components/preview.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import { MinimizeIcon, MaximizeIcon, DownloadIcon, RefreshIcon } from "./ui/icon
|
|
| 7 |
import { useModel } from "@/lib/contexts/model-context"
|
| 8 |
import { Loader2 } from "lucide-react"
|
| 9 |
import { cn } from "@/lib/utils"
|
|
|
|
| 10 |
|
| 11 |
interface PreviewProps {
|
| 12 |
initialHtml?: string;
|
|
@@ -132,6 +133,8 @@ export const Preview = forwardRef<PreviewRef, PreviewProps>(function Preview(
|
|
| 132 |
// Only include html in the request if it's not DEFAULT_HTML
|
| 133 |
const isDefaultHtml = initialHtml === DEFAULT_HTML;
|
| 134 |
|
|
|
|
|
|
|
| 135 |
const response = await fetch('/api/generate-code', {
|
| 136 |
method: 'POST',
|
| 137 |
headers: {
|
|
@@ -147,6 +150,7 @@ export const Preview = forwardRef<PreviewRef, PreviewProps>(function Preview(
|
|
| 147 |
});
|
| 148 |
|
| 149 |
if (!response.ok) {
|
|
|
|
| 150 |
// Check specifically for 401 error (authentication required)
|
| 151 |
if (response.status === 401 || response.status === 403) {
|
| 152 |
try {
|
|
@@ -244,6 +248,7 @@ export const Preview = forwardRef<PreviewRef, PreviewProps>(function Preview(
|
|
| 244 |
}
|
| 245 |
} catch (err) {
|
| 246 |
const errorMessage = (err as Error).message || 'An error occurred while generating code';
|
|
|
|
| 247 |
setError(errorMessage);
|
| 248 |
if (onErrorChange) {
|
| 249 |
onErrorChange(errorMessage);
|
|
|
|
| 7 |
import { useModel } from "@/lib/contexts/model-context"
|
| 8 |
import { Loader2 } from "lucide-react"
|
| 9 |
import { cn } from "@/lib/utils"
|
| 10 |
+
import posthog from 'posthog-js'
|
| 11 |
|
| 12 |
interface PreviewProps {
|
| 13 |
initialHtml?: string;
|
|
|
|
| 133 |
// Only include html in the request if it's not DEFAULT_HTML
|
| 134 |
const isDefaultHtml = initialHtml === DEFAULT_HTML;
|
| 135 |
|
| 136 |
+
posthog.capture("Generate code", {"model": selectedModelId});
|
| 137 |
+
|
| 138 |
const response = await fetch('/api/generate-code', {
|
| 139 |
method: 'POST',
|
| 140 |
headers: {
|
|
|
|
| 150 |
});
|
| 151 |
|
| 152 |
if (!response.ok) {
|
| 153 |
+
posthog.capture("Generate code", {"type": "failed", "model": selectedModelId, "status": response.status});
|
| 154 |
// Check specifically for 401 error (authentication required)
|
| 155 |
if (response.status === 401 || response.status === 403) {
|
| 156 |
try {
|
|
|
|
| 248 |
}
|
| 249 |
} catch (err) {
|
| 250 |
const errorMessage = (err as Error).message || 'An error occurred while generating code';
|
| 251 |
+
posthog.capture("Generate code", {"type": "failed", "model": selectedModelId, "error": errorMessage});
|
| 252 |
setError(errorMessage);
|
| 253 |
if (onErrorChange) {
|
| 254 |
onErrorChange(errorMessage);
|
src/components/prompt-input.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/comp
|
|
| 11 |
import { FullscreenToggle } from "./ui/fullscreen-toggle"
|
| 12 |
import { AuthErrorPopup } from "./auth-error-popup"
|
| 13 |
import { getInferenceToken } from "@/lib/auth"
|
|
|
|
| 14 |
|
| 15 |
interface PromptInputProps {
|
| 16 |
onSubmit: (prompt: string, colors: string[]) => Promise<void>;
|
|
@@ -74,6 +75,8 @@ export function PromptInput({
|
|
| 74 |
const isAuthenticated = await checkAuth();
|
| 75 |
if (!isAuthenticated) return;
|
| 76 |
|
|
|
|
|
|
|
| 77 |
// Clear previous errors
|
| 78 |
setImproveError(null);
|
| 79 |
setShowAuthError(false);
|
|
@@ -89,6 +92,8 @@ export function PromptInput({
|
|
| 89 |
})
|
| 90 |
|
| 91 |
if (!response.ok) {
|
|
|
|
|
|
|
| 92 |
// Handle auth error with openLogin flag
|
| 93 |
if (response.status === 401) {
|
| 94 |
const errorData = await response.json();
|
|
@@ -135,6 +140,7 @@ export function PromptInput({
|
|
| 135 |
}
|
| 136 |
}
|
| 137 |
} catch (error) {
|
|
|
|
| 138 |
console.error("Error improving prompt:", error)
|
| 139 |
setImproveError(error instanceof Error ? error.message : "Failed to improve prompt")
|
| 140 |
} finally {
|
|
|
|
| 11 |
import { FullscreenToggle } from "./ui/fullscreen-toggle"
|
| 12 |
import { AuthErrorPopup } from "./auth-error-popup"
|
| 13 |
import { getInferenceToken } from "@/lib/auth"
|
| 14 |
+
import posthog from 'posthog-js'
|
| 15 |
|
| 16 |
interface PromptInputProps {
|
| 17 |
onSubmit: (prompt: string, colors: string[]) => Promise<void>;
|
|
|
|
| 75 |
const isAuthenticated = await checkAuth();
|
| 76 |
if (!isAuthenticated) return;
|
| 77 |
|
| 78 |
+
posthog.capture("Improve prompt", {});
|
| 79 |
+
|
| 80 |
// Clear previous errors
|
| 81 |
setImproveError(null);
|
| 82 |
setShowAuthError(false);
|
|
|
|
| 92 |
})
|
| 93 |
|
| 94 |
if (!response.ok) {
|
| 95 |
+
posthog.capture("Improve prompt", {"type": "failed", "status": response.status});
|
| 96 |
+
|
| 97 |
// Handle auth error with openLogin flag
|
| 98 |
if (response.status === 401) {
|
| 99 |
const errorData = await response.json();
|
|
|
|
| 140 |
}
|
| 141 |
}
|
| 142 |
} catch (error) {
|
| 143 |
+
posthog.capture("Improve prompt", {"type": "failed", "error": error});
|
| 144 |
console.error("Error improving prompt:", error)
|
| 145 |
setImproveError(error instanceof Error ? error.message : "Failed to improve prompt")
|
| 146 |
} finally {
|