diff --git a/app/(auth)/sign-in/[[...sign-in]]/page.tsx b/app/(auth)/sign-in/[[...sign-in]]/page.tsx new file mode 100644 index 0000000..6e026aa --- /dev/null +++ b/app/(auth)/sign-in/[[...sign-in]]/page.tsx @@ -0,0 +1,85 @@ +'use client' + +import * as Clerk from '@clerk/elements/common' +import * as SignIn from '@clerk/elements/sign-in' + +export default function SignInPage() { + return ( +
+ + +
+ + + + +

+ Sign in to Clover +

+
+ + + + {/* GOOGLE LOGIN */} + + Login with Google + + + {/* EMAIL & PASSWORD */} +
+ + Email + + + + + + Password + + + +
+ + {/* SUBMIT BUTTON */} + + Sign In + + +

+ No account?{' '} + + Create an account + +

+
+
+
+ ) +} + diff --git a/app/(auth)/sign-up/[[...sign-up]]/page.tsx b/app/(auth)/sign-up/[[...sign-up]]/page.tsx new file mode 100644 index 0000000..c11e354 --- /dev/null +++ b/app/(auth)/sign-up/[[...sign-up]]/page.tsx @@ -0,0 +1,118 @@ + +'use client' + +import * as Clerk from '@clerk/elements/common' +import * as SignUp from '@clerk/elements/sign-up' + +export default function SignUpPage() { + return ( +
+ + +
+ + + + +

Create Account

+
+ + + +
+ + Email + + + + + + Password + + + +
+ + + Sign Up + + +

+ Already have an account?{' '} + + Sign in + +

+
+ + {/* Verification Step */} + +
+

Verify Email Code

+
+ + + + + Email Code + + + + + Verify + + + +

+ Already have an account?{' '} + + Sign in + +

+
+ + {/* Continue Registration Step */} + +
+

Continue Registration

+
+ + + + Username + + + + + Continue + + +

+ Already have an account?{' '} + + Sign in + +

+
+
+
+ ) +} + diff --git a/app/_components/Header.tsx b/app/_components/Header.tsx index db87d24..3000b48 100644 --- a/app/_components/Header.tsx +++ b/app/_components/Header.tsx @@ -1,3 +1,4 @@ +"use client"; import Image from 'next/image' import React from 'react' import { Button } from "@/components/ui/button"; @@ -11,6 +12,7 @@ import { NavigationMenuList, NavigationMenuTrigger, } from "@/components/ui/navigation-menu"; +import { UserButton, useUser } from '@clerk/nextjs'; const courses = [ { @@ -72,6 +74,9 @@ const courses = [ function Header() { + + const{user}= useUser(); + return (
@@ -119,9 +124,14 @@ function Header() { - + {!user? + + + + :
+ + +
}
) } diff --git a/app/_components/Hero.tsx b/app/_components/Hero.tsx index b002ebb..651055c 100644 --- a/app/_components/Hero.tsx +++ b/app/_components/Hero.tsx @@ -1,6 +1,7 @@ import React from 'react' import Image from 'next/image' import { Button } from '@/components/ui/button' +import Link from "next/link"; function Hero() { return ( @@ -12,8 +13,9 @@ function Hero() {

Coding Adventure

Beginner friendly coding course and Projects

- + +
) diff --git a/app/layout.tsx b/app/layout.tsx index 9123c94..dc926ac 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono, Inter, Pixelify_Sans,Jersey_10 } from "next/font/google"; import "./globals.css"; import { ThemeProvider } from "next-themes"; +import {ClerkProvider} from '@clerk/nextjs' const geistSans = Geist({ variable: "--font-geist-sans", @@ -35,6 +36,7 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( + + ); } diff --git a/middleware.ts b/middleware.ts new file mode 100644 index 0000000..0b8834f --- /dev/null +++ b/middleware.ts @@ -0,0 +1,21 @@ +import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' + +const isPublicRoute = createRouteMatcher([ + '/sign-in(.*)', + '/sign-up(.*)','/' +]) + +export default clerkMiddleware(async (auth, req) => { + if (!isPublicRoute(req)) { + await auth.protect() + } +}) + +export const config = { + matcher: [ + // Skip Next.js internals and all static files, unless found in search params + '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', + // Always run for API routes + '/(api|trpc)(.*)', + ], +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9a3687c..edf62ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,8 @@ "name": "codebox", "version": "0.1.0", "dependencies": { + "@clerk/elements": "^0.23.85", + "@clerk/nextjs": "^6.35.4", "@hookform/resolvers": "^5.2.2", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-alert-dialog": "^1.1.15", @@ -87,6 +89,141 @@ "node": ">=6.9.0" } }, + "node_modules/@clerk/backend": { + "version": "2.23.2", + "resolved": "https://registry.npmjs.org/@clerk/backend/-/backend-2.23.2.tgz", + "integrity": "sha512-8f+tb4VeLb0nmpjNtoh71mz2+91Z9e9Ojw2/0vNtA1emy0OSSWVV1LmhgDJtlvd1QaQYrYaKSx251N0YiR2Cag==", + "license": "MIT", + "dependencies": { + "@clerk/shared": "^3.35.2", + "@clerk/types": "^4.101.2", + "cookie": "1.0.2", + "standardwebhooks": "^1.0.0", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=18.17.0" + } + }, + "node_modules/@clerk/clerk-react": { + "version": "5.56.2", + "resolved": "https://registry.npmjs.org/@clerk/clerk-react/-/clerk-react-5.56.2.tgz", + "integrity": "sha512-ya7hJxibzS8qg0jTRbXRgg1YKvm1TDATWBGswiydkc23XQOTNqjP6nKUNujudQ18Rg1NsWzEyiaKPNmLOsAAcQ==", + "license": "MIT", + "dependencies": { + "@clerk/shared": "^3.35.2", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" + } + }, + "node_modules/@clerk/elements": { + "version": "0.23.85", + "resolved": "https://registry.npmjs.org/@clerk/elements/-/elements-0.23.85.tgz", + "integrity": "sha512-WxdCZBIQ1NpYAtbiTzN0wy1L0chsbDkHcRJBaRZA87FaC6BtEwUbccBSA2iwj/Ii1az5i8tb4ZL07cKiL41uJQ==", + "license": "MIT", + "dependencies": { + "@clerk/clerk-react": "^5.56.2", + "@clerk/shared": "^3.35.2", + "@clerk/types": "^4.101.2", + "@radix-ui/primitive": "^1.1.3", + "@radix-ui/react-form": "^0.1.8", + "@radix-ui/react-slot": "^1.2.3", + "@xstate/react": "^6.0.0", + "client-only": "^0.0.1", + "tslib": "2.8.1", + "type-fest": "^4.41.0", + "xstate": "^5.20.2" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "next": "^13.5.7 || ^14.2.25 || ^15.2.3 || ^16", + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "next": { + "optional": true + } + } + }, + "node_modules/@clerk/nextjs": { + "version": "6.35.4", + "resolved": "https://registry.npmjs.org/@clerk/nextjs/-/nextjs-6.35.4.tgz", + "integrity": "sha512-+xCFSIC/lm+s3XqVSHNtsOZUW0gDJJmsZs99HK2yeuUrC/za7hfh0x0Jaw1yWtk1TdLLTFbeWv46F4gi3tZDgg==", + "license": "MIT", + "dependencies": { + "@clerk/backend": "^2.23.2", + "@clerk/clerk-react": "^5.56.2", + "@clerk/shared": "^3.35.2", + "@clerk/types": "^4.101.2", + "server-only": "0.0.1", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "next": "^13.5.7 || ^14.2.25 || ^15.2.3 || ^16", + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" + } + }, + "node_modules/@clerk/shared": { + "version": "3.35.2", + "resolved": "https://registry.npmjs.org/@clerk/shared/-/shared-3.35.2.tgz", + "integrity": "sha512-TXWHWWZYgIkuk6jGFMMHtnjxVw92JJY/krckQnzR8kXqSFbs4Pvrkf5zm1HH+97v4nL0w2GC9XAdolQYOsTk0A==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "csstype": "3.1.3", + "dequal": "2.0.3", + "glob-to-regexp": "0.4.1", + "js-cookie": "3.0.5", + "std-env": "^3.9.0", + "swr": "2.3.4" + }, + "engines": { + "node": ">=18.17.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@clerk/shared/node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/@clerk/types": { + "version": "4.101.2", + "resolved": "https://registry.npmjs.org/@clerk/types/-/types-4.101.2.tgz", + "integrity": "sha512-R5zsWKwLYkzq6fhOoK7hPSivOnixnE+7dHZualSFtrT7mHJoOaDIRfn3r8xFZlGI7OXFHd7LItNwTDuU+Hcb9Q==", + "license": "MIT", + "dependencies": { + "@clerk/shared": "^3.35.2" + }, + "engines": { + "node": ">=18.17.0" + } + }, "node_modules/@date-fns/tz": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.4.1.tgz", @@ -1353,6 +1490,57 @@ } } }, + "node_modules/@radix-ui/react-form": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.1.8.tgz", + "integrity": "sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-label": "2.1.7", + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-form/node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-hover-card": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", @@ -2412,6 +2600,12 @@ "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", "license": "MIT" }, + "node_modules/@stablelib/base64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz", + "integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==", + "license": "MIT" + }, "node_modules/@standard-schema/utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", @@ -2791,6 +2985,25 @@ "@types/react": "^19.2.0" } }, + "node_modules/@xstate/react": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@xstate/react/-/react-6.0.0.tgz", + "integrity": "sha512-xXlLpFJxqLhhmecAXclBECgk+B4zYSrDTl8hTfPZBogkn82OHKbm9zJxox3Z/YXoOhAQhKFTRLMYGdlbhc6T9A==", + "license": "MIT", + "dependencies": { + "use-isomorphic-layout-effect": "^1.1.2", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "xstate": "^5.20.0" + }, + "peerDependenciesMeta": { + "xstate": { + "optional": true + } + } + }, "node_modules/aria-hidden": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", @@ -2866,6 +3079,15 @@ "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -3015,6 +3237,15 @@ "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", "license": "MIT" }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -3098,6 +3329,12 @@ "node": ">=6.0.0" } }, + "node_modules/fast-sha256": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", + "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", + "license": "Unlicense" + }, "node_modules/get-nonce": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", @@ -3107,6 +3344,12 @@ "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==", + "license": "BSD-2-Clause" + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -3143,6 +3386,15 @@ "jiti": "lib/jiti-cli.mjs" } }, + "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==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3841,6 +4093,12 @@ "node": ">=10" } }, + "node_modules/server-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", + "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", + "license": "MIT" + }, "node_modules/sharp": { "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", @@ -3905,6 +4163,22 @@ "node": ">=0.10.0" } }, + "node_modules/standardwebhooks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.0.0.tgz", + "integrity": "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==", + "license": "MIT", + "dependencies": { + "@stablelib/base64": "^1.0.0", + "fast-sha256": "^1.3.0" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "license": "MIT" + }, "node_modules/styled-jsx": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", @@ -3928,6 +4202,19 @@ } } }, + "node_modules/swr": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.4.tgz", + "integrity": "sha512-bYd2lrhc+VarcpkgWclcUi92wYCpOgMws9Sd1hG1ntAu0NEy+14CbotuFjshBU2kt9rYj9TSmDcybpxpeTU1fg==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/tailwind-merge": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", @@ -3981,6 +4268,18 @@ "url": "https://github.com/sponsors/Wombosvideo" } }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -4023,6 +4322,20 @@ } } }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz", + "integrity": "sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/use-sidecar": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", @@ -4089,6 +4402,16 @@ "d3-timer": "^3.0.1" } }, + "node_modules/xstate": { + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/xstate/-/xstate-5.24.0.tgz", + "integrity": "sha512-h/213ThFfZbOefUWrLc9ZvYggEVBr0jrD2dNxErxNMLQfZRN19v+80TaXFho17hs8Q2E1mULtm/6nv12um0C4A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/xstate" + } + }, "node_modules/zod": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", diff --git a/package.json b/package.json index 5fb7997..bc2e7d1 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "start": "next start" }, "dependencies": { + "@clerk/elements": "^0.23.85", + "@clerk/nextjs": "^6.35.4", "@hookform/resolvers": "^5.2.2", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-alert-dialog": "^1.1.15", diff --git a/public/banner2.gif b/public/banner2.gif new file mode 100644 index 0000000..67c98b9 Binary files /dev/null and b/public/banner2.gif differ