From 94b7b9a83c9ca329e4ad317b9f2bb8ebc2ec0db2 Mon Sep 17 00:00:00 2001 From: Alex Frantz Date: Thu, 21 Mar 2024 01:40:07 -0400 Subject: [PATCH] order number support --- prisma/schema.prisma | 9 ++--- src/components/SocialCard.tsx | 19 +++++----- src/pages/create.tsx | 62 ++++++++++++++++++++++++++++++--- src/pages/links.tsx | 51 ++++++++++++--------------- src/server/api/routers/links.ts | 29 +++++++++++++-- 5 files changed, 122 insertions(+), 48 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ac55073..b229351 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -8,7 +8,7 @@ datasource db { } model BlogPost { - id String @id @default(uuid()) @map("_id") + id Int @id @default(autoincrement()) name String image String contents String @@ -23,7 +23,7 @@ model BlogPost { } model Post { - id String @id @default(uuid()) @map("_id") + id Int @id @default(autoincrement()) type String name String reviewContents String @@ -38,9 +38,10 @@ model Post { } model SocialLink { - id String @id @default(uuid()) @map("_id") + id Int @id @default(autoincrement()) name String url String + orderNumber Int @default(0) @@index([name]) } @@ -85,7 +86,7 @@ model User { } model VerificationToken { - identifier String @id @map("_id") + identifier String token String @unique expires DateTime diff --git a/src/components/SocialCard.tsx b/src/components/SocialCard.tsx index 63b179e..ca39b8d 100644 --- a/src/components/SocialCard.tsx +++ b/src/components/SocialCard.tsx @@ -3,22 +3,25 @@ import { Trash } from "grommet-icons" type SocialCardProps = { name: string, + id: number, url: string, - showDelete: boolean, + isAuthenticated: boolean, deleteCallback: () => void } export default function SocialMediaCard(props: SocialCardProps) { return ( -
- { - props.showDelete && - } +
-
-

{props.name}

-
+

{props.name}

+ + { props.isAuthenticated && ( + <> + +

ID: {props.id}

+ + )}
) } \ No newline at end of file diff --git a/src/pages/create.tsx b/src/pages/create.tsx index 1e8817e..5d750f1 100644 --- a/src/pages/create.tsx +++ b/src/pages/create.tsx @@ -16,15 +16,16 @@ export default function CreatePage() { // trpc hooks const linksMutation = api.links.create.useMutation() - function onLinkSubmit(event: FormEvent) { + function onLinkCreateSubmit(event: FormEvent) { const form = event.target as HTMLFormElement const urlRegex = new RegExp("^((https):\/\/)?(www.)?[a-z0-9]+\.[a-z]+(\/[a-zA-Z0-9#]+\/?)*$") const titleElement = form.elements.namedItem('title') as HTMLInputElement; const urlElement = form.elements.namedItem('url') as HTMLInputElement; + const orderElement = form.elements.namedItem("orderNumber") as HTMLInputElement; const urlMatches = urlElement.value.match(urlRegex) - if (!titleElement.value || !urlElement.value) { + if (!titleElement.value || !urlElement.value || (orderElement.value && isNaN(Number(orderElement.value)))) { event.preventDefault(); setMessage("One or more values were missing!") @@ -37,7 +38,39 @@ export default function CreatePage() { } else { const object = { name: titleElement.value, - url: urlElement.value + url: urlElement.value, + orderNumber: Number(orderElement.value) || 0 + } + + linksMutation.mutate(object) + } + } + function onLinkUpdateSubmit(event: FormEvent) { + const form = event.target as HTMLFormElement + const urlRegex = new RegExp("^((https):\/\/)?(www.)?[a-z0-9]+\.[a-z]+(\/[a-zA-Z0-9#]+\/?)*$") + + const idElement = form.elements.namedItem("id") as HTMLInputElement; + const titleElement = form.elements.namedItem('title') as HTMLInputElement; + const urlElement = form.elements.namedItem('url') as HTMLInputElement; + const orderElement = form.elements.namedItem("orderNumber") as HTMLInputElement; + const urlMatches = urlElement.value.match(urlRegex) + + if (!idElement.value || isNaN(Number(idElement.value)) || (orderElement.value && isNaN(Number(orderElement.value)))) { + event.preventDefault(); + + setMessage("One or more values were missing!") + setTimeout(() => setMessage(null), 5000) + } else if (urlMatches != null && !urlMatches[1]) { + event.preventDefault(); + + setMessage("An invalid URL was provided!") + setTimeout(() => setMessage(null), 5000) + } else { + const object = { + id: Number(idElement.value), + name: titleElement.value, + url: urlElement.value, + orderNumber: Number(orderElement.value) || 0 } linksMutation.mutate(object) @@ -47,15 +80,34 @@ export default function CreatePage() { return (
-
+

Create Link


-
+ + + + + + + +

{message}

+
+
+

Update Link

+ +
+
+
+ +
+ + + diff --git a/src/pages/links.tsx b/src/pages/links.tsx index 2a42819..558d205 100644 --- a/src/pages/links.tsx +++ b/src/pages/links.tsx @@ -2,43 +2,16 @@ import SocialCard from '@/components/SocialCard' import Head from '@/components/Head'; import { api } from "@/utils/api"; import { useSession } from 'next-auth/react'; -import { useRouter } from 'next/router'; import Image from 'next/image'; import Link from 'next/link'; -import React, {useState, useEffect} from 'react'; export default function Links() { - const router = useRouter(); const {status} = useSession(); - const [links, setLinks] = useState(null); // trpc hooks const { data: linkData } = api.links.getAll.useQuery() const deleteMutation = api.links.delete.useMutation() - useEffect(() => { - if (!links && linkData) { - const allLinks = []; - - for (const link of linkData) { - allLinks.push( - { - deleteMutation.mutate(link.id); - router.reload() - }} - /> - ) - } - - setLinks(allLinks) - } - }) - return (
@@ -57,7 +30,29 @@ export default function Links() {
{ - links && links.length > 0 ? links :

Uh oh, there are no links here!

+ linkData ? + linkData.sort((a,b) => { + if (a.orderNumber < b.orderNumber) { + return -1 + } else if (a.orderNumber > b.orderNumber) { + return 1 + } + + return 0 + }).map((v,k) => { + return { + deleteMutation.mutate(v.id); + }} + isAuthenticated={ status === "authenticated" } + /> + }) + : +

Uh oh, there are no links here!

}
diff --git a/src/server/api/routers/links.ts b/src/server/api/routers/links.ts index b61f266..d922355 100644 --- a/src/server/api/routers/links.ts +++ b/src/server/api/routers/links.ts @@ -10,20 +10,43 @@ export const linksRouter = createTRPCRouter({ .input( z.object({ name: z.string().min(1), - url: z.string().min(1) + url: z.string().min(1), + orderNumber: z.number().optional() }) ) .mutation(async ({ctx, input}) => { return ctx.db.socialLink.create({ data: { name: input.name, - url: input.url + url: input.url, + orderNumber: input.orderNumber + } + }) + }), + update: protectedProcedure + .input( + z.object({ + id: z.number(), + name: z.string().min(1).optional(), + url: z.string().min(1).optional(), + orderNumber: z.number().optional(), + }) + ) + .mutation(async ({ctx, input}) => { + return ctx.db.socialLink.update({ + data: { + name: input.name, + url: input.url, + orderNumber: input.orderNumber + }, + where: { + id: input.id } }) }), delete: protectedProcedure .input( - z.string().min(1) + z.number().min(1) ) .mutation(async ({ctx, input}) => { return ctx.db.socialLink.delete({