From eadc3269cf926725b50791da3403d9a688c5c8b2 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Mon, 8 Jul 2024 10:20:58 +0200 Subject: [PATCH] refactor: remove PUT --- README.md | 8 --- app/api/protected/customer-form/[id]/route.ts | 58 ++++++------------- app/customer-form/[id]/page.tsx | 29 ++++++---- utils/types.ts | 14 ++++- utils/validateApiRequestContext.ts | 11 ++++ utils/validateContext.ts | 12 ---- 6 files changed, 57 insertions(+), 75 deletions(-) create mode 100644 utils/validateApiRequestContext.ts delete mode 100644 utils/validateContext.ts diff --git a/README.md b/README.md index ca76ca1..5ecd808 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,6 @@ - [ ] Get premium Vercel account for database - [ ] Add middleware for authentication -- [ ] Add user profile and settings (i.e. language) -- [ ] Add user roles -- [ ] Add user permissions -- [ ] Add customer form CRUD with protected routes -- [ ] Customize Auth0 login page -- [ ] Add user notifications and emails -- [ ] Add user invoices -- [ ] Add cron jobs to import data ## Commands diff --git a/app/api/protected/customer-form/[id]/route.ts b/app/api/protected/customer-form/[id]/route.ts index e2abc96..b1646be 100644 --- a/app/api/protected/customer-form/[id]/route.ts +++ b/app/api/protected/customer-form/[id]/route.ts @@ -1,18 +1,16 @@ import { getSession, withApiAuthRequired } from '@auth0/nextjs-auth0'; -import { CustomerFormType } from '@prisma/client'; import prisma from '@prisma/prisma'; import { createErrorResponse } from '@utils/createErrorResponse'; -import { CustomerForm } from '@utils/types'; -import { validateContext } from '@utils/validateContext'; -import { NextRequest, NextResponse } from 'next/server'; +import { validateApiRequestContext } from '@utils/validateApiRequestContext'; +import { NextResponse } from 'next/server'; -export const GET = withApiAuthRequired(async (request, context) => { +export const GET = withApiAuthRequired(async (_, context) => { const session = await getSession(); - let id; + let params; try { - id = validateContext(context); + params = validateApiRequestContext(context); } catch (error) { return createErrorResponse('Internal server error', 500); } @@ -26,8 +24,15 @@ export const GET = withApiAuthRequired(async (request, context) => { try { const customerForm = await prisma.customerForm.findUnique({ where: { - id, + id: params.id, createdBy: { email: userEmail } + }, + select: { + id: true, + type: true, + text: true, + createdAt: true, + updatedAt: true } }); @@ -42,49 +47,20 @@ export const GET = withApiAuthRequired(async (request, context) => { } }); -export async function PUT( - request: NextRequest, - { params }: { params: CustomerForm } -) { +export const DELETE = withApiAuthRequired(async (_, context) => { const session = await getSession(); - const result = await prisma.customerForm.update({ - where: { - id: params.id, - createdBy: { - email: session?.user.email - } - }, - data: { - type: params.type as CustomerFormType, - text: params.text - } - }); - - if (!result) { - return NextResponse.json( - { success: false, message: 'Something went wrong.' }, - { status: 500 } - ); - } - - return NextResponse.json({ success: true, data: result }); -} - -export const DELETE = withApiAuthRequired(async (request, context) => { - const session = await getSession(); - - let id; + let params; try { - id = validateContext(context); + params = validateApiRequestContext(context); } catch (error) { return createErrorResponse('Internal server error', 500); } const result = await prisma.customerForm.delete({ where: { - id: id, + id: params.id, createdBy: { email: session?.user.email } diff --git a/app/customer-form/[id]/page.tsx b/app/customer-form/[id]/page.tsx index 030d74a..d7e3853 100644 --- a/app/customer-form/[id]/page.tsx +++ b/app/customer-form/[id]/page.tsx @@ -17,22 +17,27 @@ export default withPageAuthRequired(function SingleCustomerForm({ useEffect(() => { (async () => { - const response = await axios.get( - `/api/protected/customer-form/${params.id}` - ); + try { + const response = await axios.get( + `/api/protected/customer-form/${params.id}` + ); - const validatedResponse = CustomerFormSchema.safeParse( - response.data.data - ); + const validatedResponse = CustomerFormSchema.safeParse( + response.data.data + ); - if (!validatedResponse.success) { - console.error(validatedResponse.error); - return; + if (!validatedResponse.success) { + console.error(validatedResponse.error); + return; + } + + setCustomerForm(validatedResponse.data); + } catch (error) { + console.error(error); + router.push('/customer-form'); } - - setCustomerForm(validatedResponse.data); })(); - }, [params.id]); + }, [params.id, router]); async function handleDelete() { if (!customerForm) { diff --git a/utils/types.ts b/utils/types.ts index 9220262..efe1efe 100644 --- a/utils/types.ts +++ b/utils/types.ts @@ -7,6 +7,14 @@ export const CustomerFormCreateSchema = z.object({ export type CustomerFormCreate = z.infer; +export const CustomerFormUpdateSchema = z.object({ + id: z.string(), + type: z.string().optional(), + text: z.string().optional() +}); + +export type CustomerFormUpdate = z.infer; + export const CustomerFormSchema = z.object({ id: z.string(), type: z.string(), @@ -19,8 +27,10 @@ export const CustomerFormListSchema = z.array(CustomerFormSchema); export type CustomerForm = z.infer; -export const ContextSchema = z.object({ +export const ApiResponseContextSchema = z.object({ params: z.object({ - id: z.string() + id: z.string(), + type: z.string().optional(), + text: z.string().optional() }) }); diff --git a/utils/validateApiRequestContext.ts b/utils/validateApiRequestContext.ts new file mode 100644 index 0000000..fa1181c --- /dev/null +++ b/utils/validateApiRequestContext.ts @@ -0,0 +1,11 @@ +import { ApiResponseContextSchema } from '@utils/types'; + +export function validateApiRequestContext(context: any) { + const validatedContext = ApiResponseContextSchema.safeParse(context); + + if (!validatedContext.success) { + throw new Error('Invalid context'); + } + + return validatedContext.data.params; +} diff --git a/utils/validateContext.ts b/utils/validateContext.ts deleted file mode 100644 index 701100a..0000000 --- a/utils/validateContext.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ContextSchema } from '@utils/types'; - -export function validateContext(context: any) { - const validatedContext = ContextSchema.safeParse(context); - if (!validatedContext.success) { - throw new Error('Invalid context'); - } - - const { id } = validatedContext.data.params; - - return id; -}