diff --git a/package.json b/package.json index fe2f208..cd42874 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-slot": "^1.0.2", + "@sern/poster": "^1.2.6", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "lucia": "^3.1.1", diff --git a/prisma/migrations/20240517181500_add_bot/migration.sql b/prisma/migrations/20240517181500_add_bot/migration.sql new file mode 100644 index 0000000..9469761 --- /dev/null +++ b/prisma/migrations/20240517181500_add_bot/migration.sql @@ -0,0 +1,15 @@ +-- CreateTable +CREATE TABLE "Bot" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "verified" BOOLEAN NOT NULL, + "inviteLink" TEXT NOT NULL, + "pfpLink" TEXT NOT NULL, + "srcLink" TEXT, + + CONSTRAINT "Bot_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Bot" ADD CONSTRAINT "Bot_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20240517181748_add_bot_id/migration.sql b/prisma/migrations/20240517181748_add_bot_id/migration.sql new file mode 100644 index 0000000..da72b97 --- /dev/null +++ b/prisma/migrations/20240517181748_add_bot_id/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - Added the required column `botId` to the `Bot` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "Bot" ADD COLUMN "botId" TEXT NOT NULL; diff --git a/prisma/migrations/20240517204757_add_description/migration.sql b/prisma/migrations/20240517204757_add_description/migration.sql new file mode 100644 index 0000000..3a8761c --- /dev/null +++ b/prisma/migrations/20240517204757_add_description/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - Added the required column `description` to the `Bot` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "Bot" ADD COLUMN "description" TEXT NOT NULL; diff --git a/prisma/migrations/20240517211538_verified_default_false/migration.sql b/prisma/migrations/20240517211538_verified_default_false/migration.sql new file mode 100644 index 0000000..c909607 --- /dev/null +++ b/prisma/migrations/20240517211538_verified_default_false/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Bot" ALTER COLUMN "verified" SET DEFAULT false; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 96bb15c..291befe 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -14,10 +14,11 @@ datasource db { } model User { - id String @id @default(cuid()) - username String @unique + id String @id @default(cuid()) + username String @unique hashed_password String - sessions Session[] + sessions Session[] + bots Bot[] } model Session { @@ -25,4 +26,18 @@ model Session { userId String expiresAt DateTime user User @relation(references: [id], fields: [userId], onDelete: Cascade) -} \ No newline at end of file +} + +model Bot { + id String @id @default(cuid()) + userId String + user User @relation(references: [id], fields: [userId], onDelete: Cascade) + + name String + description String + verified Boolean @default(false) + inviteLink String + pfpLink String + srcLink String? + botId String +} diff --git a/src/app/add/page.tsx b/src/app/add/page.tsx new file mode 100644 index 0000000..3d794a3 --- /dev/null +++ b/src/app/add/page.tsx @@ -0,0 +1,9 @@ +import BotForm from "@/components/app/BotForm/BotForm"; + +export default function Page() { + return ( + <> + + + ) +} \ No newline at end of file diff --git a/src/app/dashboard/[...id]/page.tsx b/src/app/dashboard/[...id]/page.tsx new file mode 100644 index 0000000..44a4cad --- /dev/null +++ b/src/app/dashboard/[...id]/page.tsx @@ -0,0 +1,24 @@ +import { validateRequest } from "@/lib/auth"; +import { redirect } from "next/navigation"; +import BotForm from "@/components/app/BotForm/BotForm"; +import prisma from "@/lib/db"; +import { nullsToUndefined } from "@/lib/utils"; + +export default async function Page({ params }: { params: { id: string } }) { + const { user } = await validateRequest() + if (!user) return redirect('/auth/signIn') + + const dbFetch = await prisma.bot.findUnique({ + where: { + id: params.id + } + }) + if (!dbFetch) return redirect('/dashboard') + if (dbFetch.userId !== user.id) return redirect('/dashboard') + + return ( + <> + + + ) +} \ No newline at end of file diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx new file mode 100644 index 0000000..21806bd --- /dev/null +++ b/src/app/dashboard/page.tsx @@ -0,0 +1,22 @@ +import UserCard from "@/components/app/UserCard/UserCard"; +import { validateRequest } from "@/lib/auth"; +import prisma from "@/lib/db"; +import { redirect } from "next/navigation"; + +export default async function Page() { + const { user } = await validateRequest() + if (!user) return redirect('/auth/signIn') + + const dbFetch = await prisma.bot.findMany({ + where: { + userId: user.id + } + }) + return ( +
+ {dbFetch.map((bot) => ( + + ))} +
+ ) +} \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index 010b5af..497bfed 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -38,6 +38,7 @@ .dark { --background: 240 21.053% 14.902%; /* base */ + --background-darker: 220 23.077% 12%; /* base but darker */ --foreground: 226.154 63.934% 88.039%; /* text */ --muted: 236.842 16.239% 22.941%; /* surface0 */ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 3083758..a4be4dc 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -10,8 +10,8 @@ import { ThemeProvider } from "@/lib/providers/ThemeProvider"; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { - title: "stack", - description: "The tech stack for your next(.js) project.", + title: "sern Frontpage Bot", + description: "Show your sern bot in the sern.dev frontpage!", }; export default async function RootLayout({ diff --git a/src/app/page.tsx b/src/app/page.tsx index 21d9fd0..a469343 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -11,11 +11,10 @@ export default function Home() {

- The modern tech stack for your next(.js) project + Add your discord bot to sern's front page!

- stack is a comprehensive tech stack that includes everything you need to build and deploy your next - web application. + Do you want to show off your discord bot to the world? Add it to sern's front page!

@@ -26,7 +25,7 @@ export default function Home() {
-
+
diff --git a/src/app/protected/page.tsx b/src/app/protected/page.tsx deleted file mode 100644 index 9f777f2..0000000 --- a/src/app/protected/page.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { validateRequest } from "@/lib/auth"; -import { redirect } from "next/navigation"; - -export default async function Page() { - const { user } = await validateRequest() - if (!user) return redirect('/auth/signIn') - return ( -
-

Welcome {user?.username}!

-

You are actually on a protected route!

-

Your ID is: {user.id}

-
- ) -} \ No newline at end of file diff --git a/src/components/app/BotForm/BotForm.tsx b/src/components/app/BotForm/BotForm.tsx new file mode 100644 index 0000000..7c07046 --- /dev/null +++ b/src/components/app/BotForm/BotForm.tsx @@ -0,0 +1,57 @@ +'use client' + +import { Label } from "@/components/ui/label"; +import { Input } from "@/components/ui/input"; +import SubmitButton from "../SubmitButton/SubmitButton"; +import { submitBotData } from "@/lib/actions"; +import { useFormState } from "react-dom"; +import { useEffect } from "react"; +import { toast } from "sonner"; + +export default function BotForm(props: Props) { + const [submitData, submitDataAction] = useFormState(submitBotData, null); + useEffect(() => { + if (submitData?.error) { + toast.error(submitData.error) + } + }, [submitData]) + return ( +
+ {props.id && } +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ ) +} + +interface Props { + id?: string; + name?: string; + description?: string; + botId?: string; + inviteLink?: string; + srcLink?: string; +} \ No newline at end of file diff --git a/src/components/app/NavBar/NavBar.tsx b/src/components/app/NavBar/NavBar.tsx index b9808ea..89912c3 100644 --- a/src/components/app/NavBar/NavBar.tsx +++ b/src/components/app/NavBar/NavBar.tsx @@ -18,8 +18,8 @@ import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher" export const links = [ { href: '/', name: 'Home' }, - { href: 'https://github.com/SrIzan10/stack', name: 'Github' }, - { href: '/protected', name: 'Protected route' } + { href: '/dashboard', name: 'Dashboard' }, + { href: '/add', name: 'Submit' }, ] function NavbarLinks() { @@ -41,7 +41,7 @@ export default function Navbar() { <>