From 1fe54ca7d8797824a410a03cc3ed9e0789ac2e07 Mon Sep 17 00:00:00 2001 From: andthezhang Date: Sun, 17 Mar 2024 12:23:46 -0700 Subject: [PATCH] init --- .env | 1 + bun.lockb | Bin 0 -> 257316 bytes components.json | 16 ++ drizzle.config.ts | 11 + kirimase.config.json | 18 ++ next.config.mjs | 8 +- package.json | 44 +++- src/app/(app)/account/AccountCard.tsx | 45 ++++ src/app/(app)/account/UpdateEmailCard.tsx | 47 ++++ src/app/(app)/account/UpdateNameCard.tsx | 46 ++++ src/app/(app)/account/UserSettings.tsx | 17 ++ src/app/(app)/account/page.tsx | 16 ++ src/app/(app)/dashboard/page.tsx | 15 ++ src/app/(app)/layout.tsx | 20 ++ src/app/(app)/settings/page.tsx | 106 ++++++++ src/app/(auth)/layout.tsx | 13 + src/app/(auth)/sign-in/page.tsx | 58 +++++ src/app/(auth)/sign-up/page.tsx | 54 +++++ src/app/api/account/route.ts | 15 ++ src/app/globals.css | 91 +++++-- src/app/layout.tsx | 5 +- src/app/loading.tsx | 25 ++ src/app/page.tsx | 282 ++++++++++++++-------- src/components/Navbar.tsx | 45 ++++ src/components/Sidebar.tsx | 55 +++++ src/components/SidebarItems.tsx | 91 +++++++ src/components/ThemeProvider.tsx | 9 + src/components/auth/AuthFormError.tsx | 10 + src/components/auth/SignOutBtn.tsx | 22 ++ src/components/ui/ThemeToggle.tsx | 40 +++ src/components/ui/avatar.tsx | 50 ++++ src/components/ui/button.tsx | 56 +++++ src/components/ui/card.tsx | 79 ++++++ src/components/ui/dropdown-menu.tsx | 200 +++++++++++++++ src/components/ui/input.tsx | 25 ++ src/components/ui/label.tsx | 26 ++ src/components/ui/sonner.tsx | 31 +++ src/config/nav.ts | 15 ++ src/lib/actions/users.ts | 134 ++++++++++ src/lib/auth/lucia.ts | 75 ++++++ src/lib/auth/utils.ts | 69 ++++++ src/lib/db/index.ts | 6 + src/lib/db/migrate.ts | 36 +++ src/lib/db/schema/auth.ts | 36 +++ src/lib/env.mjs | 24 ++ src/lib/utils.ts | 9 + tailwind.config.ts | 84 +++++-- tsconfig.json | 27 ++- 48 files changed, 2049 insertions(+), 158 deletions(-) create mode 100644 .env create mode 100755 bun.lockb create mode 100644 components.json create mode 100644 drizzle.config.ts create mode 100644 kirimase.config.json create mode 100644 src/app/(app)/account/AccountCard.tsx create mode 100644 src/app/(app)/account/UpdateEmailCard.tsx create mode 100644 src/app/(app)/account/UpdateNameCard.tsx create mode 100644 src/app/(app)/account/UserSettings.tsx create mode 100644 src/app/(app)/account/page.tsx create mode 100644 src/app/(app)/dashboard/page.tsx create mode 100644 src/app/(app)/layout.tsx create mode 100644 src/app/(app)/settings/page.tsx create mode 100644 src/app/(auth)/layout.tsx create mode 100644 src/app/(auth)/sign-in/page.tsx create mode 100644 src/app/(auth)/sign-up/page.tsx create mode 100644 src/app/api/account/route.ts create mode 100644 src/app/loading.tsx create mode 100644 src/components/Navbar.tsx create mode 100644 src/components/Sidebar.tsx create mode 100644 src/components/SidebarItems.tsx create mode 100644 src/components/ThemeProvider.tsx create mode 100644 src/components/auth/AuthFormError.tsx create mode 100644 src/components/auth/SignOutBtn.tsx create mode 100644 src/components/ui/ThemeToggle.tsx create mode 100644 src/components/ui/avatar.tsx create mode 100644 src/components/ui/button.tsx create mode 100644 src/components/ui/card.tsx create mode 100644 src/components/ui/dropdown-menu.tsx create mode 100644 src/components/ui/input.tsx create mode 100644 src/components/ui/label.tsx create mode 100644 src/components/ui/sonner.tsx create mode 100644 src/config/nav.ts create mode 100644 src/lib/actions/users.ts create mode 100644 src/lib/auth/lucia.ts create mode 100644 src/lib/auth/utils.ts create mode 100644 src/lib/db/index.ts create mode 100644 src/lib/db/migrate.ts create mode 100644 src/lib/db/schema/auth.ts create mode 100644 src/lib/env.mjs create mode 100644 src/lib/utils.ts diff --git a/.env b/.env new file mode 100644 index 0000000..498ab17 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +DATABASE_URL=postgres://postgres:postgres@localhost:5432/{DB_NAME} \ No newline at end of file diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..bc0fcb0b6dd39f543f3cc992968d5eea27d48ed3 GIT binary patch literal 257316 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�|rYMdJUa^28i{EjfO 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�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 { + config.externals.push("@node-rs/argon2", "@node-rs/bcrypt"); + return config; + }, +}; + export default nextConfig; diff --git a/package.json b/package.json index 233f80e..1385473 100644 --- a/package.json +++ b/package.json @@ -6,22 +6,54 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "db:generate": "drizzle-kit generate:pg", + "db:migrate": "tsx src/lib/db/migrate.ts", + "db:drop": "drizzle-kit drop", + "db:pull": "drizzle-kit introspect:pg", + "db:studio": "drizzle-kit studio", + "db:check": "drizzle-kit check:pg" }, "dependencies": { + "@lucia-auth/adapter-drizzle": "^1.0.4", + "@node-rs/argon2": "^1.8.0", + "@node-rs/bcrypt": "^1.10.1", + "@radix-ui/react-avatar": "^1.0.4", + "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-slot": "^1.0.2", + "@t3-oss/env-nextjs": "^0.9.2", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", + "drizzle-orm": "^0.30.2", + "drizzle-zod": "^0.5.1", + "lucia": "^3.1.1", + "lucide-react": "^0.358.0", + "nanoid": "^5.0.6", + "next": "14.1.3", + "next-themes": "^0.3.0", + "oslo": "^1.1.3", + "postgres": "^3.4.3", "react": "^18", "react-dom": "^18", - "next": "14.1.3" + "sonner": "^1.4.3", + "tailwind-merge": "^2.2.2", + "tailwindcss-animate": "^1.0.7", + "zod": "^3.22.4" }, "devDependencies": { - "typescript": "^5", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "autoprefixer": "^10.0.1", + "dotenv": "^16.4.5", + "drizzle-kit": "^0.20.14", + "eslint": "^8", + "eslint-config-next": "14.1.3", + "pg": "^8.11.3", "postcss": "^8", "tailwindcss": "^3.3.0", - "eslint": "^8", - "eslint-config-next": "14.1.3" + "tsx": "^4.7.1", + "typescript": "^5" } -} +} \ No newline at end of file diff --git a/src/app/(app)/account/AccountCard.tsx b/src/app/(app)/account/AccountCard.tsx new file mode 100644 index 0000000..2e37f10 --- /dev/null +++ b/src/app/(app)/account/AccountCard.tsx @@ -0,0 +1,45 @@ +import { Card } from "@/components/ui/card"; + +interface AccountCardProps { + params: { + header: string; + description: string; + price?: number; + }; + children: React.ReactNode; +} + +export function AccountCard({ params, children }: AccountCardProps) { + const { header, description } = params; + return ( + +

+

{header}

+

{description}

+
+ {children} + + ); +} + +export function AccountCardBody({ children }: { children: React.ReactNode }) { + return
{children}
; +} + +export function AccountCardFooter({ + description, + children, +}: { + children: React.ReactNode; + description: string; +}) { + return ( + + ); +} diff --git a/src/app/(app)/account/UpdateEmailCard.tsx b/src/app/(app)/account/UpdateEmailCard.tsx new file mode 100644 index 0000000..193b545 --- /dev/null +++ b/src/app/(app)/account/UpdateEmailCard.tsx @@ -0,0 +1,47 @@ +"use client"; + +import { useEffect } from "react"; +import { useFormState, useFormStatus } from "react-dom"; + +import { AccountCard, AccountCardFooter, AccountCardBody } from "./AccountCard"; +import { updateUser } from "@/lib/actions/users"; + +import { toast } from "sonner"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; + +export default function UpdateEmailCard({ email }: { email: string }) { + const [state, formAction] = useFormState(updateUser, { + error: "", + }); + + useEffect(() => { + if (state.success == true) toast.success("Updated Email"); + if (state.error) toast.error("Error", { description: state.error }); + }, [state]); + + return ( + +
+ + + + + + +
+
+ ); +} + +const Submit = () => { + const { pending } = useFormStatus(); + return ; +}; + diff --git a/src/app/(app)/account/UpdateNameCard.tsx b/src/app/(app)/account/UpdateNameCard.tsx new file mode 100644 index 0000000..687962e --- /dev/null +++ b/src/app/(app)/account/UpdateNameCard.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { useEffect } from "react"; +import { useFormState, useFormStatus } from "react-dom"; + +import { AccountCard, AccountCardFooter, AccountCardBody } from "./AccountCard"; +import { updateUser } from "@/lib/actions/users"; + +import { toast } from "sonner"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; + +export default function UpdateNameCard({ name }: { name: string }) { + const [state, formAction] = useFormState(updateUser, { + error: "", + }); + + useEffect(() => { + if (state.success == true) toast.success("Updated User"); + if (state.error) toast.error("Error", { description: state.error }); + }, [state]); + + return ( + +
+ + + + + + +
+
+ ); +} + +const Submit = () => { + const { pending } = useFormStatus(); + return ; +}; diff --git a/src/app/(app)/account/UserSettings.tsx b/src/app/(app)/account/UserSettings.tsx new file mode 100644 index 0000000..9d38a40 --- /dev/null +++ b/src/app/(app)/account/UserSettings.tsx @@ -0,0 +1,17 @@ +"use client"; +import UpdateNameCard from "./UpdateNameCard"; +import UpdateEmailCard from "./UpdateEmailCard"; +import { AuthSession } from "@/lib/auth/utils"; + +export default function UserSettings({ + session, +}: { + session: AuthSession["session"]; +}) { + return ( + <> + + + + ); +} diff --git a/src/app/(app)/account/page.tsx b/src/app/(app)/account/page.tsx new file mode 100644 index 0000000..0588287 --- /dev/null +++ b/src/app/(app)/account/page.tsx @@ -0,0 +1,16 @@ +import UserSettings from "./UserSettings"; +import { checkAuth, getUserAuth } from "@/lib/auth/utils"; + +export default async function Account() { + await checkAuth(); + const { session } = await getUserAuth(); + + return ( +
+

Account

+
+ +
+
+ ); +} diff --git a/src/app/(app)/dashboard/page.tsx b/src/app/(app)/dashboard/page.tsx new file mode 100644 index 0000000..2db90a4 --- /dev/null +++ b/src/app/(app)/dashboard/page.tsx @@ -0,0 +1,15 @@ +import SignOutBtn from "@/components/auth/SignOutBtn"; +import { getUserAuth } from "@/lib/auth/utils"; + +export default async function Home() { + const { session } = await getUserAuth(); + return ( +
+

Profile

+
+        {JSON.stringify(session, null, 2)}
+      
+ +
+ ); +} diff --git a/src/app/(app)/layout.tsx b/src/app/(app)/layout.tsx new file mode 100644 index 0000000..b5d0ce8 --- /dev/null +++ b/src/app/(app)/layout.tsx @@ -0,0 +1,20 @@ +import { checkAuth } from "@/lib/auth/utils"; +import { Toaster } from "@/components/ui/sonner"; +import Navbar from "@/components/Navbar"; +import Sidebar from "@/components/Sidebar"; +export default async function AppLayout({ + children, +}: { + children: React.ReactNode; +}) { + await checkAuth(); + return (
+ +
+ +{children} +
+
+ +
) +} \ No newline at end of file diff --git a/src/app/(app)/settings/page.tsx b/src/app/(app)/settings/page.tsx new file mode 100644 index 0000000..a801d9e --- /dev/null +++ b/src/app/(app)/settings/page.tsx @@ -0,0 +1,106 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { useTheme } from "next-themes"; + +export default function Page() { + const { setTheme } = useTheme(); + return ( +
+

Settings

+
+
+

Appearance

+

+ Customize the appearance of the app. Automatically switch between + day and night themes. +

+
+ + + +
+
+ ); +} diff --git a/src/app/(auth)/layout.tsx b/src/app/(auth)/layout.tsx new file mode 100644 index 0000000..1feed78 --- /dev/null +++ b/src/app/(auth)/layout.tsx @@ -0,0 +1,13 @@ +import { getUserAuth } from "@/lib/auth/utils"; +import { redirect } from "next/navigation"; + +export default async function AuthLayout({ + children, +}: { + children: React.ReactNode; +}) { + const session = await getUserAuth(); + if (session?.session) redirect("/dashboard"); + + return (
{children}
); +} diff --git a/src/app/(auth)/sign-in/page.tsx b/src/app/(auth)/sign-in/page.tsx new file mode 100644 index 0000000..ad15a22 --- /dev/null +++ b/src/app/(auth)/sign-in/page.tsx @@ -0,0 +1,58 @@ +"use client"; + +import Link from "next/link"; +import { useFormState } from "react-dom"; +import { useFormStatus } from "react-dom"; + +import { signInAction } from "@/lib/actions/users"; + +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import AuthFormError from "@/components/auth/AuthFormError"; + +export default function SignInPage() { + const [state, formAction] = useFormState(signInAction, { + error: "", + }); + + return ( +
+

+ Sign in to your account +

+ +
+ + +
+ + +
+ + +
+ Don't have an account yet?{" "} + + Create an account + +
+
+ ); +} + +const SubmitButton = () => { + const { pending } = useFormStatus(); + return ( + + ); +}; \ No newline at end of file diff --git a/src/app/(auth)/sign-up/page.tsx b/src/app/(auth)/sign-up/page.tsx new file mode 100644 index 0000000..0ea7ce1 --- /dev/null +++ b/src/app/(auth)/sign-up/page.tsx @@ -0,0 +1,54 @@ +"use client"; + +import Link from "next/link"; +import { useFormState } from "react-dom"; +import { useFormStatus } from "react-dom"; + +import { signUpAction } from "@/lib/actions/users"; + +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import AuthFormError from "@/components/auth/AuthFormError"; + + +export default function SignUpPage() { + const [state, formAction] = useFormState(signUpAction, { + error: "", + }); + + return ( +
+

Create an account

+ +
+ + +
+ + +
+ + +
+ Already have an account?{" "} + + Sign in + +
+
+ ); +} + +const SubmitButton = () => { + const { pending } = useFormStatus(); + return ( + + ); +}; diff --git a/src/app/api/account/route.ts b/src/app/api/account/route.ts new file mode 100644 index 0000000..cce581a --- /dev/null +++ b/src/app/api/account/route.ts @@ -0,0 +1,15 @@ +import { getUserAuth } from "@/lib/auth/utils"; +import { db } from "@/lib/db/index"; +import { users } from "@/lib/db/schema/auth"; +import { eq } from "drizzle-orm"; +import { revalidatePath } from "next/cache"; + +export async function PUT(request: Request) { + const { session } = await getUserAuth(); + if (!session) return new Response("Error", { status: 400 }); + const body = (await request.json()) as { name?: string; email?: string }; + + await db.update(users).set({ ...body }).where(eq(users.id, session.user.id)); + revalidatePath("/account"); + return new Response(JSON.stringify({ message: "ok" }), { status: 200 }); +} diff --git a/src/app/globals.css b/src/app/globals.css index 875c01e..77d3522 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,33 +1,76 @@ @tailwind base; @tailwind components; @tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 0 0% 3.9%; -:root { - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; -} + --card: 0 0% 100%; + --card-foreground: 0 0% 3.9%; + + --popover: 0 0% 100%; + --popover-foreground: 0 0% 3.9%; + + --primary: 0 0% 9%; + --primary-foreground: 0 0% 98%; + + --secondary: 0 0% 96.1%; + --secondary-foreground: 0 0% 9%; + + --muted: 0 0% 96.1%; + --muted-foreground: 0 0% 45.1%; + + --accent: 0 0% 96.1%; + --accent-foreground: 0 0% 9%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; + --border: 0 0% 89.8%; + --input: 0 0% 89.8%; + --ring: 0 0% 3.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 0 0% 3.9%; + --foreground: 0 0% 98%; + + --card: 0 0% 3.9%; + --card-foreground: 0 0% 98%; + + --popover: 0 0% 3.9%; + --popover-foreground: 0 0% 98%; + + --primary: 0 0% 98%; + --primary-foreground: 0 0% 9%; + + --secondary: 0 0% 14.9%; + --secondary-foreground: 0 0% 98%; + + --muted: 0 0% 14.9%; + --muted-foreground: 0 0% 63.9%; + + --accent: 0 0% 14.9%; + --accent-foreground: 0 0% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + + --border: 0 0% 14.9%; + --input: 0 0% 14.9%; + --ring: 0 0% 83.1%; } } - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} - -@layer utilities { - .text-balance { - text-wrap: balance; + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; } } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 3314e47..03f7b34 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "./globals.css"; +import { ThemeProvider } from "@/components/ThemeProvider"; const inter = Inter({ subsets: ["latin"] }); @@ -16,7 +17,9 @@ export default function RootLayout({ }>) { return ( - {children} + +{children} + ); } diff --git a/src/app/loading.tsx b/src/app/loading.tsx new file mode 100644 index 0000000..5df6350 --- /dev/null +++ b/src/app/loading.tsx @@ -0,0 +1,25 @@ +export default function Loading() { + return ( +
+
+ + Loading... +
+
+ ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index b81507d..0a69b41 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,113 +1,183 @@ -import Image from "next/image"; +/** + * v0 by Vercel. + * @see https://v0.dev/t/PmwTvNfrVgf + * Documentation: https://v0.dev/docs#integrating-generated-code-into-your-nextjs-app + */ +import Link from "next/link"; -export default function Home() { +export default function LandingPage() { return ( -
-
-

- Get started by editing  - src/app/page.tsx -

- -
- -
- Next.js Logo -
- -
- -

- Docs{" "} - - -> - -

-

- Find in-depth information about Next.js features and API. -

-
- - -

- Learn{" "} - - -> - -

-

- Learn about Next.js in an interactive course with quizzes! -

-
+ Features + + + Sign In + + + +
+
+
+
+
+
+
+

+ The complete platform
+ for building the Web +

+

+ Give your team the toolkit to stop configuring and start + innovating. Securely build, deploy, and scale the best web + experiences. +

+
+
+ + Get Started + + + Contact Sales + +
+
+
+
+
+
+
+
+
+
+ Key Features +
+

+ Faster iteration. More innovation. +

+

+ The platform for rapid progress. Let your team focus on + shipping features instead of managing infrastructure with + automated CI/CD. +

+
+
+
+
+
+
    +
  • +
    +

    Collaboration

    +

    + Make collaboration seamless with built-in code review + tools. +

    +
    +
  • +
  • +
    +

    Automation

    +

    + Automate your workflow with continuous integration. +

    +
    +
  • +
  • +
    +

    Scale

    +

    + Deploy to the cloud with a single click and scale with + ease. +

    +
    +
  • +
+
+
+
+
- -

- Templates{" "} - - -> - -

-

- Explore starter templates for Next.js. -

-
+
+
+
+
+

+ Sign Up for Updates +

+

+ Stay updated with the latest product news and updates. +

+
+
+
+ + +
+
+
+
+
+
+
+

+ © 2024 Acme Inc. All rights reserved. +

+ +
+
+ ); +} - -

- Deploy{" "} - - -> - -

-

- Instantly deploy your Next.js site to a shareable URL with Vercel. -

-
- -
+function MountainIcon(props: any) { + return ( + + + ); } diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx new file mode 100644 index 0000000..26b5257 --- /dev/null +++ b/src/components/Navbar.tsx @@ -0,0 +1,45 @@ +"use client"; + +import Link from "next/link"; +import { useState } from "react"; +import { usePathname } from "next/navigation"; + +import { Button } from "@/components/ui/button"; + +import { AlignRight } from "lucide-react"; +import { defaultLinks } from "@/config/nav"; + +export default function Navbar() { + const [open, setOpen] = useState(false); + const pathname = usePathname(); + return ( +
+ + {open ? ( +
+
    + {defaultLinks.map((link) => ( +
  • setOpen(false)} className=""> + + {link.title} + +
  • + ))} +
+
+ ) : null} +
+ ); +} diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx new file mode 100644 index 0000000..8d1d63f --- /dev/null +++ b/src/components/Sidebar.tsx @@ -0,0 +1,55 @@ +import Link from "next/link"; + +import SidebarItems from "./SidebarItems"; +import { Avatar, AvatarFallback } from "./ui/avatar"; + +import { AuthSession, getUserAuth } from "@/lib/auth/utils"; + +const Sidebar = async () => { + const session = await getUserAuth(); + if (session.session === null) return null; + + return ( + + ); +}; + +export default Sidebar; + +const UserDetails = ({ session }: { session: AuthSession }) => { + if (session.session === null) return null; + const { user } = session.session; + + if (!user?.name || user.name.length == 0) return null; + + return ( + +
+
+

{user.name ?? "John Doe"}

+

+ {user.email ?? "john@doe.com"} +

+
+ + + {user.name + ? user.name + ?.split(" ") + .map((word) => word[0].toUpperCase()) + .join("") + : "~"} + + +
+ + ); +}; diff --git a/src/components/SidebarItems.tsx b/src/components/SidebarItems.tsx new file mode 100644 index 0000000..7dea48b --- /dev/null +++ b/src/components/SidebarItems.tsx @@ -0,0 +1,91 @@ +"use client"; + +import Link from "next/link"; +import { usePathname } from "next/navigation"; + +import { LucideIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; +import { defaultLinks, additionalLinks } from "@/config/nav"; + +export interface SidebarLink { + title: string; + href: string; + icon: LucideIcon; +} + +const SidebarItems = () => { + return ( + <> + + {additionalLinks.length > 0 + ? additionalLinks.map((l) => ( + + )) + : null} + + ); +}; +export default SidebarItems; + +const SidebarLinkGroup = ({ + links, + title, + border, +}: { + links: SidebarLink[]; + title?: string; + border?: boolean; +}) => { + const fullPathname = usePathname(); + const pathname = "/" + fullPathname.split("/")[1]; + + return ( +
+ {title ? ( +

+ {title} +

+ ) : null} +
    + {links.map((link) => ( +
  • + +
  • + ))} +
+
+ ); +}; +const SidebarLink = ({ + link, + active, +}: { + link: SidebarLink; + active: boolean; +}) => { + return ( + +
+
+ + {link.title} +
+ + ); +}; diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx new file mode 100644 index 0000000..b0ff266 --- /dev/null +++ b/src/components/ThemeProvider.tsx @@ -0,0 +1,9 @@ +"use client"; + +import * as React from "react"; +import { ThemeProvider as NextThemesProvider } from "next-themes"; +import { type ThemeProviderProps } from "next-themes/dist/types"; + +export function ThemeProvider({ children, ...props }: ThemeProviderProps) { + return {children}; +} diff --git a/src/components/auth/AuthFormError.tsx b/src/components/auth/AuthFormError.tsx new file mode 100644 index 0000000..afc706e --- /dev/null +++ b/src/components/auth/AuthFormError.tsx @@ -0,0 +1,10 @@ +export default function AuthFormError({ state }: { state: { error: string } }) { + if (state.error) + return ( +
+

Error

+

{state.error}

+
+ ); + return null; +} diff --git a/src/components/auth/SignOutBtn.tsx b/src/components/auth/SignOutBtn.tsx new file mode 100644 index 0000000..ba0d225 --- /dev/null +++ b/src/components/auth/SignOutBtn.tsx @@ -0,0 +1,22 @@ +"use client"; + +import { Button } from "../ui/button"; +import { useFormStatus } from "react-dom"; +import { signOutAction } from "@/lib/actions/users"; + +export default function SignOutBtn() { + return ( +
+ + + ); +} + +const Btn = () => { + const { pending } = useFormStatus(); + return ( + + ); +}; diff --git a/src/components/ui/ThemeToggle.tsx b/src/components/ui/ThemeToggle.tsx new file mode 100644 index 0000000..63ff415 --- /dev/null +++ b/src/components/ui/ThemeToggle.tsx @@ -0,0 +1,40 @@ +"use client"; + +import * as React from "react"; +import { MoonIcon, SunIcon } from "lucide-react"; +import { useTheme } from "next-themes"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; + +export function ModeToggle() { + const { setTheme } = useTheme(); + + return ( + + + + + + setTheme("light")}> + Light + + setTheme("dark")}> + Dark + + setTheme("system")}> + System + + + + ); +} diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx new file mode 100644 index 0000000..51e507b --- /dev/null +++ b/src/components/ui/avatar.tsx @@ -0,0 +1,50 @@ +"use client" + +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" + +import { cn } from "@/lib/utils" + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +Avatar.displayName = AvatarPrimitive.Root.displayName + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarImage.displayName = AvatarPrimitive.Image.displayName + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..0ba4277 --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx new file mode 100644 index 0000000..afa13ec --- /dev/null +++ b/src/components/ui/card.tsx @@ -0,0 +1,79 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx new file mode 100644 index 0000000..f69a0d6 --- /dev/null +++ b/src/components/ui/dropdown-menu.tsx @@ -0,0 +1,200 @@ +"use client" + +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/lib/utils" + +const DropdownMenu = DropdownMenuPrimitive.Root + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger + +const DropdownMenuGroup = DropdownMenuPrimitive.Group + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal + +const DropdownMenuSub = DropdownMenuPrimitive.Sub + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +DropdownMenuShortcut.displayName = "DropdownMenuShortcut" + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +} diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx new file mode 100644 index 0000000..677d05f --- /dev/null +++ b/src/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx new file mode 100644 index 0000000..5341821 --- /dev/null +++ b/src/components/ui/label.tsx @@ -0,0 +1,26 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const labelVariants = cva( + "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" +) + +const Label = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, ...props }, ref) => ( + +)) +Label.displayName = LabelPrimitive.Root.displayName + +export { Label } diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx new file mode 100644 index 0000000..452f4d9 --- /dev/null +++ b/src/components/ui/sonner.tsx @@ -0,0 +1,31 @@ +"use client" + +import { useTheme } from "next-themes" +import { Toaster as Sonner } from "sonner" + +type ToasterProps = React.ComponentProps + +const Toaster = ({ ...props }: ToasterProps) => { + const { theme = "system" } = useTheme() + + return ( + + ) +} + +export { Toaster } diff --git a/src/config/nav.ts b/src/config/nav.ts new file mode 100644 index 0000000..e909bcf --- /dev/null +++ b/src/config/nav.ts @@ -0,0 +1,15 @@ +import { SidebarLink } from "@/components/SidebarItems"; +import { Cog, Globe, HomeIcon } from "lucide-react"; + +type AdditionalLinks = { + title: string; + links: SidebarLink[]; +}; + +export const defaultLinks: SidebarLink[] = [ + { href: "/dashboard", title: "Home", icon: HomeIcon }, + { href: "/account", title: "Account", icon: Cog }, + { href: "/settings", title: "Settings", icon: Cog }, +]; + +export const additionalLinks: AdditionalLinks[] = []; diff --git a/src/lib/actions/users.ts b/src/lib/actions/users.ts new file mode 100644 index 0000000..af2a4da --- /dev/null +++ b/src/lib/actions/users.ts @@ -0,0 +1,134 @@ +"use server"; + +import { revalidatePath } from "next/cache"; +import { redirect } from "next/navigation"; + +import { Argon2id } from "oslo/password"; +import { lucia, validateRequest } from "../auth/lucia"; +import { generateId } from "lucia"; +import { eq } from "drizzle-orm"; +import { db } from "@/lib/db/index"; + +import { + genericError, + setAuthCookie, + validateAuthFormData, + getUserAuth, +} from "../auth/utils"; +import { users, updateUserSchema } from "../db/schema/auth"; + +interface ActionResult { + error: string; +} + +export async function signInAction( + _: ActionResult, + formData: FormData, +): Promise { + const { data, error } = validateAuthFormData(formData); + if (error !== null) return { error }; + + try { + const [existingUser] = await db + .select() + .from(users) + .where(eq(users.email, data.email.toLowerCase())); + if (!existingUser) { + return { + error: "Incorrect username or password", + }; + } + + const validPassword = await new Argon2id().verify( + existingUser.hashedPassword, + data.password, + ); + if (!validPassword) { + return { + error: "Incorrect username or password", + }; + } + + const session = await lucia.createSession(existingUser.id, {}); + const sessionCookie = lucia.createSessionCookie(session.id); + setAuthCookie(sessionCookie); + + return redirect("/dashboard"); + } catch (e) { + return genericError; + } +} + +export async function signUpAction( + _: ActionResult, + formData: FormData, +): Promise { + const { data, error } = validateAuthFormData(formData); + + if (error !== null) return { error }; + + const hashedPassword = await new Argon2id().hash(data.password); + const userId = generateId(15); + + try { + await db.insert(users).values({ + id: userId, + email: data.email, + hashedPassword, + }); + } catch (e) { + return genericError; + } + + const session = await lucia.createSession(userId, {}); + const sessionCookie = lucia.createSessionCookie(session.id); + setAuthCookie(sessionCookie); + return redirect("/dashboard"); +} + +export async function signOutAction(): Promise { + const { session } = await validateRequest(); + if (!session) { + return { + error: "Unauthorized", + }; + } + + await lucia.invalidateSession(session.id); + + const sessionCookie = lucia.createBlankSessionCookie(); + setAuthCookie(sessionCookie); + redirect("/sign-in"); +} + +export async function updateUser( + _: any, + formData: FormData, +): Promise { + const { session } = await getUserAuth(); + if (!session) return { error: "Unauthorised" }; + + const name = formData.get("name") ?? undefined; + const email = formData.get("email") ?? undefined; + + const result = updateUserSchema.safeParse({ name, email }); + + if (!result.success) { + const error = result.error.flatten().fieldErrors; + if (error.name) return { error: "Invalid name - " + error.name[0] }; + if (error.email) return { error: "Invalid email - " + error.email[0] }; + return genericError; + } + + try { + await db + .update(users) + .set({ ...result.data }) + .where(eq(users.id, session.user.id)); + revalidatePath("/account"); + return { success: true, error: "" }; + } catch (e) { + return genericError; + } +} + diff --git a/src/lib/auth/lucia.ts b/src/lib/auth/lucia.ts new file mode 100644 index 0000000..f37c6db --- /dev/null +++ b/src/lib/auth/lucia.ts @@ -0,0 +1,75 @@ +import { cookies } from 'next/headers' +import { cache } from 'react' + +import { type Session, type User, Lucia } from 'lucia' +import { db } from "@/lib/db/index"; + +import { DrizzlePostgreSQLAdapter } from "@lucia-auth/adapter-drizzle"; +import { sessions, users } from "../db/schema/auth"; + + +export const adapter = new DrizzlePostgreSQLAdapter(db, sessions, users); + +export const lucia = new Lucia(adapter, { + sessionCookie: { + expires: false, + attributes: { + secure: process.env.NODE_ENV === 'production', + }, + }, + getUserAttributes: (attributes) => { + return { + // attributes has the type of DatabaseUserAttributes + email: attributes.email, + name: attributes.name, + } + }, +}) + +declare module 'lucia' { + interface Register { + Lucia: typeof lucia + DatabaseUserAttributes: DatabaseUserAttributes + } +} + +interface DatabaseUserAttributes { + email: string + name: string; +} + +export const validateRequest = cache( + async (): Promise< + { user: User; session: Session } | { user: null; session: null } + > => { + const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null + if (!sessionId) { + return { + user: null, + session: null, + } + } + + const result = await lucia.validateSession(sessionId) + // next.js throws when you attempt to set cookie when rendering page + try { + if (result.session && result.session.fresh) { + const sessionCookie = lucia.createSessionCookie(result.session.id) + cookies().set( + sessionCookie.name, + sessionCookie.value, + sessionCookie.attributes + ) + } + if (!result.session) { + const sessionCookie = lucia.createBlankSessionCookie() + cookies().set( + sessionCookie.name, + sessionCookie.value, + sessionCookie.attributes + ) + } + } catch {} + return result + } +) diff --git a/src/lib/auth/utils.ts b/src/lib/auth/utils.ts new file mode 100644 index 0000000..96d3206 --- /dev/null +++ b/src/lib/auth/utils.ts @@ -0,0 +1,69 @@ +import { redirect } from 'next/navigation' +import { cookies } from 'next/headers' + +import { type Cookie } from 'lucia' + +import { validateRequest } from './lucia' +import { UsernameAndPassword, authenticationSchema } from '../db/schema/auth' + +export type AuthSession = { + session: { + user: { + id: string + name?: string + email?: string + username?: string + } + } | null +} +export const getUserAuth = async (): Promise => { + const { session, user } = await validateRequest() + if (!session) return { session: null } + return { + session: { + user: { + id: user.id, + email: user.email, + name: user.name, + }, + }, + } +} + +export const checkAuth = async () => { + const { session } = await validateRequest() + if (!session) redirect('/sign-in') +} + +export const genericError = { error: 'Error, please try again.' } + +export const setAuthCookie = (cookie: Cookie) => { + // cookies().set(cookie.name, cookie.value, cookie.attributes); // <- suggested approach from the docs, but does not work with `next build` locally + cookies().set(cookie); +} + +const getErrorMessage = (errors: any): string => { + if (errors.email) return 'Invalid Email' + if (errors.password) return 'Invalid Password - ' + errors.password[0] + return '' // return a default error message or an empty string +} + +export const validateAuthFormData = ( + formData: FormData +): + | { data: UsernameAndPassword; error: null } + | { data: null; error: string } => { + const email = formData.get('email') + const password = formData.get('password') + const result = authenticationSchema.safeParse({ email, password }) + + if (!result.success) { + return { + data: null, + error: getErrorMessage(result.error.flatten().fieldErrors), + } + } + + return { data: result.data, error: null } +} + diff --git a/src/lib/db/index.ts b/src/lib/db/index.ts new file mode 100644 index 0000000..d0c05ff --- /dev/null +++ b/src/lib/db/index.ts @@ -0,0 +1,6 @@ +import { drizzle } from "drizzle-orm/postgres-js"; +import postgres from "postgres"; +import { env } from "@/lib/env.mjs"; + +export const client = postgres(env.DATABASE_URL); +export const db = drizzle(client); \ No newline at end of file diff --git a/src/lib/db/migrate.ts b/src/lib/db/migrate.ts new file mode 100644 index 0000000..03b3bb6 --- /dev/null +++ b/src/lib/db/migrate.ts @@ -0,0 +1,36 @@ +import { env } from "@/lib/env.mjs"; + +import { drizzle } from "drizzle-orm/postgres-js"; +import { migrate } from "drizzle-orm/postgres-js/migrator"; +import postgres from "postgres"; + + +const runMigrate = async () => { + if (!env.DATABASE_URL) { + throw new Error("DATABASE_URL is not defined"); + } + + +const connection = postgres(env.DATABASE_URL, { max: 1 }); + +const db = drizzle(connection); + + + console.log("⏳ Running migrations..."); + + const start = Date.now(); + + await migrate(db, { migrationsFolder: 'src/lib/db/migrations' }); + + const end = Date.now(); + + console.log("✅ Migrations completed in", end - start, "ms"); + + process.exit(0); +}; + +runMigrate().catch((err) => { + console.error("❌ Migration failed"); + console.error(err); + process.exit(1); +}); \ No newline at end of file diff --git a/src/lib/db/schema/auth.ts b/src/lib/db/schema/auth.ts new file mode 100644 index 0000000..5654a96 --- /dev/null +++ b/src/lib/db/schema/auth.ts @@ -0,0 +1,36 @@ +import { z } from "zod"; +import { pgTable, timestamp, text } from "drizzle-orm/pg-core"; + +export const users = pgTable("user", { + id: text("id").primaryKey(), + email: text("email").notNull().unique(), + hashedPassword: text("hashed_password").notNull(), + name: text("name"), +}); + +export const sessions = pgTable("session", { + id: text("id").primaryKey(), + userId: text("user_id") + .notNull() + .references(() => users.id), + expiresAt: timestamp("expires_at", { + withTimezone: true, + mode: "date" + }).notNull() +}); + + +export const authenticationSchema = z.object({ + email: z.string().email().min(5).max(31), + password: z + .string() + .min(4, { message: "must be at least 4 characters long" }) + .max(15, { message: "cannot be more than 15 characters long" }), +}); + +export const updateUserSchema = z.object({ + name: z.string().min(3).optional(), + email: z.string().min(4).optional(), +}); + +export type UsernameAndPassword = z.infer; diff --git a/src/lib/env.mjs b/src/lib/env.mjs new file mode 100644 index 0000000..6a0a110 --- /dev/null +++ b/src/lib/env.mjs @@ -0,0 +1,24 @@ +import { createEnv } from "@t3-oss/env-nextjs"; +import { z } from "zod"; + +export const env = createEnv({ + server: { + NODE_ENV: z + .enum(["development", "test", "production"]) + .default("development"), + DATABASE_URL: z.string().min(1), + + }, + client: { + // NEXT_PUBLIC_PUBLISHABLE_KEY: z.string().min(1), + }, + // If you're using Next.js < 13.4.4, you'll need to specify the runtimeEnv manually + // runtimeEnv: { + // DATABASE_URL: process.env.DATABASE_URL, + // NEXT_PUBLIC_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_PUBLISHABLE_KEY, + // }, + // For Next.js >= 13.4.4, you only need to destructure client variables: + experimental__runtimeEnv: { + // NEXT_PUBLIC_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_PUBLISHABLE_KEY, + }, +}); diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..199deca --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,9 @@ +import { customAlphabet } from "nanoid"; +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} + +export const nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz0123456789"); diff --git a/tailwind.config.ts b/tailwind.config.ts index e9a0944..061375e 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,20 +1,76 @@ -import type { Config } from "tailwindcss"; +const { fontFamily } = require("tailwindcss/defaultTheme") -const config: Config = { - content: [ - "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", - "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}", - ], +/** @type {import('tailwindcss').Config} */ +module.exports = { + darkMode: ["class"], + content: ["src/app/**/*.{ts,tsx}", "src/components/**/*.{ts,tsx}"], theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, extend: { - backgroundImage: { - "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", - "gradient-conic": - "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: `var(--radius)`, + md: `calc(var(--radius) - 2px)`, + sm: "calc(var(--radius) - 4px)", + }, + fontFamily: { + sans: ["var(--font-sans)", ...fontFamily.sans], + }, + keyframes: { + "accordion-down": { + from: { height: 0 }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: 0 }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", }, }, }, - plugins: [], -}; -export default config; + plugins: [require("tailwindcss-animate")], +} diff --git a/tsconfig.json b/tsconfig.json index 7b28589..c5a7b07 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,10 @@ { "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -18,9 +22,20 @@ } ], "paths": { - "@/*": ["./src/*"] - } + "@/*": [ + "./src/*" + ] + }, + "target": "esnext", + "baseUrl": "./" }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] -} + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file