diff --git a/Websites/jefes-nextjs/app/api/issues/route.ts b/Websites/jefes-nextjs/app/api/issues/route.ts new file mode 100644 index 0000000..c0924ef --- /dev/null +++ b/Websites/jefes-nextjs/app/api/issues/route.ts @@ -0,0 +1,27 @@ +import { NextRequest, NextResponse } from "next/server"; +import { z } from 'zod'; +import prisma from "@/prisma/client"; + +// validate the request with zod +const createIssueSchema = z.object({ + title: z.string().min(1).max(255), // confirms string is between 1-255 characters + description: z.string().min(1), // confirms string has min length of 1 +}); + +// send request +export async function POST(request: NextRequest) { + // return request with a promise + const body = await request.json(); + + // validate the data + const validation = createIssueSchema.safeParse(body); + if (!validation.success) + return NextResponse.json(validation.error.errors, {status: 400}) // Send error 400 if data is invalid + + const newIssue = await prisma.issue.create({ + data: { title: body.title, description: body.description } + }); + + // return the issue to the client + return NextResponse.json(newIssue, {status: 201}); // status 201 means an object was created +} \ No newline at end of file diff --git a/Websites/jefes-nextjs/app/components/NavBar/NavBar.tsx b/Websites/jefes-nextjs/app/components/NavBar/NavBar.tsx index 94883de..8292e52 100644 --- a/Websites/jefes-nextjs/app/components/NavBar/NavBar.tsx +++ b/Websites/jefes-nextjs/app/components/NavBar/NavBar.tsx @@ -5,6 +5,7 @@ import Image from "next/image"; import Jefes from "../../../public/jefes_logo.jpg"; import { usePathname } from "next/navigation"; import classnames from 'classnames'; +import issues from "@/app/issues"; const NavBar = () => { const currentPath = usePathname(); @@ -12,8 +13,10 @@ const NavBar = () => { // Create an array to hold the list items const links = [ - { label: "Dashboard", href: "/Dashboard" }, - { label: "Issues", href: "/Issues" }, + { label: "Dashboard", href: "/dashboard" }, + { label: "Issues", href: "/issues" }, + { label: "Keira", href: "/issues" }, + { label: "Jacob", href: "/issues" }, ]; return ( @@ -28,9 +31,9 @@ const NavBar = () => { // className={`${link.href === currentPath ? 'text-zinc-900' : 'text-zinc-500 hover:text-zinc-800'}`} // replace with classnames object instead className={classnames({ - 'text-zinc-900': link.href === currentPath, - 'text-zinc-500' : link.href !== currentPath, - 'hover:text-zinc-800': true, + 'text-emerald-400': link.href === currentPath, + 'text-white' : link.href !== currentPath, + 'hover:text-zinc-500': true, })} href={link.href}> {link.label} diff --git a/Websites/jefes-nextjs/app/globals.css b/Websites/jefes-nextjs/app/globals.css index 28f6920..7dabf6b 100644 --- a/Websites/jefes-nextjs/app/globals.css +++ b/Websites/jefes-nextjs/app/globals.css @@ -13,6 +13,6 @@ } body { - color: black; + color: white; } diff --git a/Websites/jefes-nextjs/app/issues/new/page.tsx b/Websites/jefes-nextjs/app/issues/new/page.tsx new file mode 100644 index 0000000..474055c --- /dev/null +++ b/Websites/jefes-nextjs/app/issues/new/page.tsx @@ -0,0 +1,58 @@ +"use client"; +import React from "react"; +import SimpleMDE from "react-simplemde-editor"; +import "easymde/dist/easymde.min.css"; +import { useForm, Controller } from "react-hook-form"; +import { FormEvent } from "react"; + +interface IssueForm { + title: string; + description: string; +} + +const NewIssuePage = () => { + const { register, control, handleSubmit } = useForm(); + // console.log(register('title')) + + // handle form submit + async function onSubmit(event: FormEvent) { + event.preventDefault(); + + const formData = new FormData(event.currentTarget); + const response = await fetch("/api/issues", { + method: "POST", + body: formData, + }); + + // Handle response if necessary + // const data = await response.json(); + // ... + } + + return ( +
console.log(data))} + onSubmit={onSubmit} + > + + ( + + )} + /> + + + ); +}; + +export default NewIssuePage; diff --git a/Websites/jefes-nextjs/app/issues/page.tsx b/Websites/jefes-nextjs/app/issues/page.tsx new file mode 100644 index 0000000..b8a9d23 --- /dev/null +++ b/Websites/jefes-nextjs/app/issues/page.tsx @@ -0,0 +1,22 @@ +import Link from 'next/link' +import React from 'react' +import type { NextApiRequest, NextApiResponse } from 'next' + +const IssuesPage = () => { + async function handler( + req: NextApiRequest, + res: NextApiResponse, + ) { + const data = req.body + console.log(...data) + res.redirect(307, '/issues') + } + + return ( +
+ +
+ ) +} + +export default IssuesPage \ No newline at end of file diff --git a/Websites/jefes-nextjs/app/layout.tsx b/Websites/jefes-nextjs/app/layout.tsx index c39ec4b..56d1b2d 100644 --- a/Websites/jefes-nextjs/app/layout.tsx +++ b/Websites/jefes-nextjs/app/layout.tsx @@ -16,7 +16,7 @@ export default function RootLayout({ children: React.ReactNode }) { return ( - +
{children}
diff --git a/Websites/jefes-nextjs/bun.lockb b/Websites/jefes-nextjs/bun.lockb index 2facaef..564cb33 100755 Binary files a/Websites/jefes-nextjs/bun.lockb and b/Websites/jefes-nextjs/bun.lockb differ diff --git a/Websites/jefes-nextjs/package.json b/Websites/jefes-nextjs/package.json index cb8ff7f..be0599c 100644 --- a/Websites/jefes-nextjs/package.json +++ b/Websites/jefes-nextjs/package.json @@ -11,11 +11,15 @@ "dependencies": { "@prisma/client": "5.4.2", "classnames": "^2.3.2", + "easymde": "^2.18.0", "next": "13.5.6", "prisma": "^5.4.2", "react": "^18", "react-dom": "^18", - "react-icons": "^4.11.0" + "react-hook-form": "^7.47.0", + "react-icons": "^4.11.0", + "react-simplemde-editor": "^5.2.0", + "zod": "^3.22.4" }, "devDependencies": { "@types/node": "^20", diff --git a/Websites/jefes-nextjs/prisma/client.ts b/Websites/jefes-nextjs/prisma/client.ts new file mode 100644 index 0000000..c72d247 --- /dev/null +++ b/Websites/jefes-nextjs/prisma/client.ts @@ -0,0 +1,19 @@ +import { PrismaClient } from '@prisma/client' + +// ensures there is only one instance of prisma at any given moment + +const prismaClientSingleton = () => { + return new PrismaClient() +} + +type PrismaClientSingleton = ReturnType + +const globalForPrisma = globalThis as unknown as { + prisma: PrismaClientSingleton | undefined +} + +const prisma = globalForPrisma.prisma ?? prismaClientSingleton() + +export default prisma + +if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma \ No newline at end of file diff --git a/Websites/jefes-nextjs/tailwind.config.ts b/Websites/jefes-nextjs/tailwind.config.ts index f126cc7..5780c04 100644 --- a/Websites/jefes-nextjs/tailwind.config.ts +++ b/Websites/jefes-nextjs/tailwind.config.ts @@ -17,7 +17,7 @@ const config: Config = { }, plugins: [require("daisyui")], daisyui:{ - themes:["winter"], + themes:["night"], }, } export default config