fixed routing to ticket screen and added markdown editor

This commit is contained in:
Jacob Delgado 2023-10-22 23:22:00 -07:00
parent 4fa957c1a0
commit 7fdcf75739
10 changed files with 142 additions and 9 deletions

View File

@ -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
}

View File

@ -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}

View File

@ -13,6 +13,6 @@
}
body {
color: black;
color: white;
}

View File

@ -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<IssueForm>();
// console.log(register('title'))
// handle form submit
async function onSubmit(event: FormEvent<HTMLFormElement>) {
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 (
<form
className="max-w-xl"
// onSubmit={handleSubmit((data) => console.log(data))}
onSubmit={onSubmit}
>
<input
type="text"
placeholder="Type Here"
className="input w-full border-zinc-300 mb-2"
{...register("title")}
/>
<Controller
name="desciption"
control={control}
render={({ field }) => (
<SimpleMDE placeholder="Description" {...field}></SimpleMDE>
)}
/>
<button className="btn bg-emerald-400 text-black hover:bg-white">
Submit Ticket
</button>
</form>
);
};
export default NewIssuePage;

View File

@ -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 (
<div>
<button className='btn bg-emerald-400 text-black hover:bg-white'><Link href='/issues/new'>New Ticket</Link></button>
</div>
)
}
export default IssuesPage

View File

@ -16,7 +16,7 @@ export default function RootLayout({
children: React.ReactNode
}) {
return (
<html lang="en" data-theme="winter">
<html lang="en" data-theme="night">
<body className={inter.className}>
<NavBar />
<main>{children}</main>

Binary file not shown.

View File

@ -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",

View File

@ -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<typeof prismaClientSingleton>
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

View File

@ -17,7 +17,7 @@ const config: Config = {
},
plugins: [require("daisyui")],
daisyui:{
themes:["winter"],
themes:["night"],
},
}
export default config