fixed routing to ticket screen and added markdown editor
This commit is contained in:
parent
4fa957c1a0
commit
7fdcf75739
27
Websites/jefes-nextjs/app/api/issues/route.ts
Normal file
27
Websites/jefes-nextjs/app/api/issues/route.ts
Normal 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
|
||||
}
|
||||
@ -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}
|
||||
|
||||
@ -13,6 +13,6 @@
|
||||
}
|
||||
|
||||
body {
|
||||
color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
58
Websites/jefes-nextjs/app/issues/new/page.tsx
Normal file
58
Websites/jefes-nextjs/app/issues/new/page.tsx
Normal 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;
|
||||
22
Websites/jefes-nextjs/app/issues/page.tsx
Normal file
22
Websites/jefes-nextjs/app/issues/page.tsx
Normal 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
|
||||
@ -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.
@ -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",
|
||||
|
||||
19
Websites/jefes-nextjs/prisma/client.ts
Normal file
19
Websites/jefes-nextjs/prisma/client.ts
Normal 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
|
||||
@ -17,7 +17,7 @@ const config: Config = {
|
||||
},
|
||||
plugins: [require("daisyui")],
|
||||
daisyui:{
|
||||
themes:["winter"],
|
||||
themes:["night"],
|
||||
},
|
||||
}
|
||||
export default config
|
||||
|
||||
Loading…
Reference in New Issue
Block a user