diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..8230b97
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,52 @@
+# Since the ".env" file is gitignored, you can use the ".env.example" file to
+# build a new ".env" file when you clone the repo. Keep this file up-to-date
+# when you add new variables to `.env`.
+
+# This file will be committed to version control, so make sure not to have any
+# secrets in it. If you are cloning this repo, create a copy of this file named
+# ".env" and populate it with your secrets.
+
+# When adding additional environment variables, the schema in "/src/env.mjs"
+# should be updated accordingly.
+
+ORIGIN=""
+
+# Prisma DB
+# https://www.prisma.io/docs/reference/database-reference/connection-urls#env
+DATABASE_URL=""
+
+# Google API
+GOOGLE_CLIENT_ID=""
+GOOGLE_CLIENT_SECRET=""
+
+# Dall E API
+DALLE_API_KEY=""
+USE_MOCK_DALLE="true"
+
+# Stable Diffusion API
+STABLE_DIFFUSION_API_KEY=""
+STABLE_DIFFUSION_API_ENDPOINT=""
+
+# AWS/S3 API
+ACCESS_KEY_ID_AWS=""
+SECRET_ACCESS_KEY_AWS=""
+REGION_AWS="us-east-2"
+S3_BUCKET_URL_AWS=""
+S3_BUCKET_THUMBNAIL_URL_AWS=""
+S3_BUCKET_NAME_AWS=""
+
+# Stripe API
+STRIPE_PUBLISHABLE_KEY=""
+STRIPE_SECRET_KEY=""
+STRIPE_CREDITS_PRICE_ID=""
+STRIPE_WEB_HOOK_SECRET=""
+
+# Honeypot
+HONEYPOT_SECRET="SOME_SECRET_HONEYPOT"
+
+# CSRF
+SESSION_SECRET="SOME_SECRET_SESSION"
+
+# Clerk
+CLERK_PUBLISHABLE_KEY=""
+CLERK_SECRET_KEY=""
\ No newline at end of file
diff --git a/app/components/NavigationSidebar.tsx b/app/components/NavigationSidebar.tsx
index 9a6870b..0aece79 100644
--- a/app/components/NavigationSidebar.tsx
+++ b/app/components/NavigationSidebar.tsx
@@ -2,14 +2,6 @@ import React from "react";
import PixelStudioIcon from "components/PixelStudioIcon";
import { Link } from "@remix-run/react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
import {
Search,
Layers,
@@ -19,7 +11,44 @@ import {
LogOut,
CreditCard,
} from "lucide-react";
-// import { useLoggedInUser } from "~/hooks";
+import {
+ SignedIn,
+ SignedOut,
+ SignInButton,
+ SignUpButton,
+ UserButton,
+ useUser,
+} from "@clerk/remix";
+
+const NAV_LINKS = [
+ {
+ title: "Explore",
+ icon: ,
+ href: "/explore",
+ },
+ {
+ title: "Collections",
+ icon: ,
+ href: "/collections",
+ },
+ {
+ title: "Create",
+ icon: ,
+ href: "/create",
+ },
+ {
+ title: "Profile",
+ icon: ,
+ // href: `/profile/${userData?.username || ""}`,
+ href: `/profile/`,
+ },
+ // ! TODO: Hide for now, get barebones out first
+ // {
+ // title: "Manage",
+ // icon: ,
+ // href: "/manage",
+ // },
+];
const NavButton = ({
title,
@@ -37,58 +66,22 @@ const NavButton = ({
{...props}
>
{icon}
- {/* */}
{title}
);
const NavigationSidebar = () => {
+ const { user } = useUser();
+ console.log(user);
+
const [credits, setCredits] = React.useState(31);
// const userData = React.useContext(UserContext);
// const userData = useLoggedInUser();
// const isLoggedIn = Boolean(userData?.id);
- const userData = {
- name: "John Doe",
- username: "johndoe",
- };
- const NAV_LINKS = [
- {
- title: "Explore",
- icon: ,
- href: "/explore",
- },
- {
- title: "Collections",
- icon: ,
- href: "/collections",
- },
- {
- title: "Create",
- icon: ,
- href: "/create",
- },
- {
- title: "Profile",
- icon: ,
- // href: `/profile/${userData?.username || ""}`,
- href: `/profile/`,
- },
- // ! TODO: Hide for now, get barebones out first
- // {
- // title: "Manage",
- // icon: ,
- // href: "/manage",
- // },
- ];
-
- // const navLinksToRender = isLoggedIn ? NAV_LINKS : [];
- const navLinksToRender = NAV_LINKS;
return (
<>
- {/*
>
diff --git a/app/root.tsx b/app/root.tsx
index a2e1714..444c3ec 100644
--- a/app/root.tsx
+++ b/app/root.tsx
@@ -11,7 +11,11 @@ import {
useLocation,
useRouteError,
} from "@remix-run/react";
-import { LoaderFunctionArgs } from "@remix-run/node";
+import {
+ LoaderFunction,
+ LoaderFunctionArgs,
+ MetaFunction,
+} from "@remix-run/node";
import { Toaster, toast as showToast } from "sonner";
import { prisma } from "services/prisma.server";
import NavigationSidebar from "components/NavigationSidebar";
@@ -22,59 +26,76 @@ import { AuthenticityTokenProvider } from "remix-utils/csrf/react";
import { HoneypotProvider } from "remix-utils/honeypot/react";
import { honeypot } from "utils/honeypot.server";
import { getToast, type Toast } from "utils/toast.server";
+import { rootAuthLoader } from "@clerk/remix/ssr.server";
+import { ClerkApp } from "@clerk/remix";
import "./tailwind.css";
import "./globals.css";
-export async function loader({ request }: LoaderFunctionArgs) {
- const [csrfToken, csrfCookieHeader] = await csrf.commitToken(request);
- const honeyProps = honeypot.getInputProps();
- const users = (await prisma.user.findMany()) || [];
+export const meta: MetaFunction = () => [
+ {
+ charset: "utf-8",
+ title: "Pixel Studio AI",
+ viewport: "width=device-width,initial-scale=1",
+ property: "og:title",
+ content: "Pixel Studio AI",
+ },
+];
- const { toast, headers: toastHeaders } = await getToast(request);
+// export async function loader({ request }: LoaderFunctionArgs) {
+export const loader: LoaderFunction = (args) => {
+ return rootAuthLoader(args, async ({ request }) => {
+ const [csrfToken, csrfCookieHeader] = await csrf.commitToken(request);
+ const honeyProps = honeypot.getInputProps();
+ const users = (await prisma.user.findMany()) || [];
- return json(
- {
- // username: os.userInfo().username,
- // theme: getTheme(request),
- users: users.length,
- toast,
- ENV: getEnv(),
- csrfToken,
- honeyProps,
- },
- {
- headers: combineHeaders(
- csrfCookieHeader ? { "set-cookie": csrfCookieHeader } : null,
- toastHeaders
- ),
- }
- );
-}
+ const { toast, headers: toastHeaders } = await getToast(request);
+
+ return json(
+ {
+ // username: os.userInfo().username,
+ // theme: getTheme(request),
+ users: users.length,
+ toast,
+ ENV: getEnv(),
+ csrfToken,
+ honeyProps,
+ },
+ {
+ headers: combineHeaders(
+ csrfCookieHeader ? { "set-cookie": csrfCookieHeader } : null,
+ toastHeaders
+ ),
+ }
+ );
+ });
+};
function Document({
children,
- env,
-}: {
+}: // env,
+{
children: React.ReactNode;
- env?: Record;
+ // env?: Record;
}) {
return (
-
-
+
{/* */}
{children}
-
+ /> */}
@@ -85,26 +106,31 @@ function Document({
export function Layout({ children }: { children: React.ReactNode }) {
const data = useLoaderData();
- console.log(data);
- const location = useLocation();
- const isHome = location.pathname === "/";
+ // console.log(data);
+ // const location = useLocation();
+ // const isHome = location.pathname === "/";
return (
<>
-
- {!isHome && } {children}
+
+ {children}
{data && data.toast ? : null}
>
);
}
-export default function App() {
+function App() {
const data = useLoaderData();
+ const location = useLocation();
+ const isHome = location.pathname === "/";
return (
- ;
+ {!isHome && }
+
);
@@ -125,3 +151,5 @@ export const ErrorBoundary = () => {
captureRemixErrorBoundaryError(error);
return Something went wrong
;
};
+
+export default ClerkApp(App);
diff --git a/package-lock.json b/package-lock.json
index 8525d0e..7169ba9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7,6 +7,7 @@
"name": "pixel-studio",
"hasInstallScript": true,
"dependencies": {
+ "@clerk/remix": "^4.2.20",
"@conform-to/react": "^1.1.5",
"@conform-to/zod": "^1.1.5",
"@paralleldrive/cuid2": "^2.2.2",
@@ -605,6 +606,135 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@clerk/backend": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@clerk/backend/-/backend-1.9.0.tgz",
+ "integrity": "sha512-yT/WvH4qesWhG6OdllhUMLs0uMrMkTQMURCoC6dX3RZ0BzUMmgf0z6nD3o3zvFEXpWwInfh+vsXCgbIQ7QjBfg==",
+ "dependencies": {
+ "@clerk/shared": "2.6.0",
+ "@clerk/types": "4.17.0",
+ "cookie": "0.5.0",
+ "snakecase-keys": "5.4.4",
+ "tslib": "2.4.1"
+ },
+ "engines": {
+ "node": ">=18.17.0"
+ }
+ },
+ "node_modules/@clerk/backend/node_modules/cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@clerk/backend/node_modules/tslib": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
+ },
+ "node_modules/@clerk/clerk-react": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@clerk/clerk-react/-/clerk-react-5.5.0.tgz",
+ "integrity": "sha512-0M/YJTXYJFbkNns8f5HbcZ6C+KEyPATjeTSy6rFVzYus8YYPGYj1CsjYRfEZLjuwzVObDv2SRadVXQJJWnbvRg==",
+ "dependencies": {
+ "@clerk/shared": "2.6.0",
+ "@clerk/types": "4.17.0",
+ "tslib": "2.4.1"
+ },
+ "engines": {
+ "node": ">=18.17.0"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-beta",
+ "react-dom": ">=18 || >=19.0.0-beta"
+ }
+ },
+ "node_modules/@clerk/clerk-react/node_modules/tslib": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
+ },
+ "node_modules/@clerk/remix": {
+ "version": "4.2.20",
+ "resolved": "https://registry.npmjs.org/@clerk/remix/-/remix-4.2.20.tgz",
+ "integrity": "sha512-moAV+VoYpOEBFTGrOA1IKdMFV7bbe4daP6Gj675024o8++7STxuU56Mo0/FSzpOSYPcmIn4LCnruKOzc04+D4g==",
+ "dependencies": {
+ "@clerk/backend": "1.9.0",
+ "@clerk/clerk-react": "5.5.0",
+ "@clerk/shared": "2.6.0",
+ "@clerk/types": "4.17.0",
+ "cookie": "0.5.0",
+ "tslib": "2.4.1"
+ },
+ "engines": {
+ "node": ">=18.17.0"
+ },
+ "peerDependencies": {
+ "@remix-run/react": "^2.0.0",
+ "@remix-run/server-runtime": "^2.0.0",
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/@clerk/remix/node_modules/cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@clerk/remix/node_modules/tslib": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
+ },
+ "node_modules/@clerk/shared": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@clerk/shared/-/shared-2.6.0.tgz",
+ "integrity": "sha512-ntgDxluwkvtGr73cc6vRQQAa/MAxr49NlroQ4GcAidylmSYTrqouD+SFQp21UQX51sFecGZKPyr2YoTFyxzQoA==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@clerk/types": "4.17.0",
+ "glob-to-regexp": "0.4.1",
+ "js-cookie": "3.0.5",
+ "std-env": "^3.7.0",
+ "swr": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=18.17.0"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-beta",
+ "react-dom": ">=18 || >=19.0.0-beta"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@clerk/types": {
+ "version": "4.17.0",
+ "resolved": "https://registry.npmjs.org/@clerk/types/-/types-4.17.0.tgz",
+ "integrity": "sha512-/GksPLzWLCTbZ1ZNTUs4CMze89XUQNGNy9KJOP56JUaxCy+9iHbIsDyia6zicHXhH8/oIj9SrZv/nlEPNUFkoA==",
+ "dependencies": {
+ "csstype": "3.1.1"
+ },
+ "engines": {
+ "node": ">=18.17.0"
+ }
+ },
+ "node_modules/@clerk/types/node_modules/csstype": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
+ "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
+ },
"node_modules/@conform-to/dom": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@conform-to/dom/-/dom-1.1.5.tgz",
@@ -4711,6 +4841,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
+ },
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -5293,6 +5428,15 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/dotenv": {
"version": "16.4.5",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
@@ -6828,6 +6972,11 @@
"node": ">= 6"
}
},
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
+ },
"node_modules/globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -7791,6 +7940,14 @@
"jiti": "bin/jiti.js"
}
},
+ "node_modules/js-cookie": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -8046,6 +8203,14 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -8073,6 +8238,17 @@
"node": ">=12"
}
},
+ "node_modules/map-obj": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
+ "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/markdown-extensions": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz",
@@ -9236,6 +9412,15 @@
"node": ">= 0.6"
}
},
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -11491,6 +11676,39 @@
"node": ">=8"
}
},
+ "node_modules/snake-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+ "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/snakecase-keys": {
+ "version": "5.4.4",
+ "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-5.4.4.tgz",
+ "integrity": "sha512-YTywJG93yxwHLgrYLZjlC75moVEX04LZM4FHfihjHe1FCXm+QaLOFfSf535aXOAd0ArVQMWUAe8ZPm4VtWyXaA==",
+ "dependencies": {
+ "map-obj": "^4.1.0",
+ "snake-case": "^3.0.4",
+ "type-fest": "^2.5.2"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/snakecase-keys/node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/sonner": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/sonner/-/sonner-1.5.0.tgz",
@@ -11589,6 +11807,11 @@
"node": ">= 0.8"
}
},
+ "node_modules/std-env": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz",
+ "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg=="
+ },
"node_modules/stop-iteration-iterator": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz",
@@ -11913,6 +12136,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/swr": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz",
+ "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==",
+ "dependencies": {
+ "client-only": "^0.0.1",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "peerDependencies": {
+ "react": "^16.11.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/tailwind-merge": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.2.tgz",
@@ -12683,6 +12918,14 @@
}
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
+ "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/util": {
"version": "0.12.5",
"resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
diff --git a/package.json b/package.json
index 9279eed..d37d36e 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"postinstall": "prisma generate"
},
"dependencies": {
+ "@clerk/remix": "^4.2.20",
"@conform-to/react": "^1.1.5",
"@conform-to/zod": "^1.1.5",
"@paralleldrive/cuid2": "^2.2.2",