diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f2bb4a0..8ea93ed 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -31,6 +31,7 @@ model Cards { description String @default("") createdAt DateTime @default(now()) birthday DateTime + paused Boolean @default(false) User User @relation(fields: [creatorId], references: [id]) diff --git a/src/components/EditCard.tsx b/src/components/EditCard.tsx index 7d7fe03..5642329 100644 --- a/src/components/EditCard.tsx +++ b/src/components/EditCard.tsx @@ -5,6 +5,7 @@ export type CardDataValues = { description: string; birthday: string; showAge: boolean; + paused?: boolean; }; // used for type-checking in our textbox component type CardDataTypes = "title" | "description" | "birthday"; diff --git a/src/pages/c/[id]/index.tsx b/src/pages/c/[id]/index.tsx index 0b89431..a80f5f2 100644 --- a/src/pages/c/[id]/index.tsx +++ b/src/pages/c/[id]/index.tsx @@ -11,7 +11,7 @@ import { PropsWithChildren } from "react"; const CardPage: NextPage<{ id: string }> = ({ id }) => { const { - data, + data: cardData, isLoading: cardLoading, isError: cardError, } = api.cards.fetch.useQuery({ @@ -23,7 +23,7 @@ const CardPage: NextPage<{ id: string }> = ({ id }) => { <> {props.children} @@ -40,7 +40,7 @@ const CardPage: NextPage<{ id: string }> = ({ id }) => { ); - if (cardError || !data) + if (cardError || !cardData) return (
@@ -55,8 +55,8 @@ const CardPage: NextPage<{ id: string }> = ({ id }) => { const CardInfo = () => { return (
-

{data.title}

-

{data.description}

+

{cardData.title}

+

{cardData.description}

); }; @@ -73,15 +73,34 @@ const CardPage: NextPage<{ id: string }> = ({ id }) => { if (wishError) return <>; const canShow = !wishesLoading && !wishError && data; + const SignCard = () => { + if (!canShow) return <>; + + if (cardData.paused) { + return ( +
+ +
+ ); + } + + return ( + + + + ); + }; + return ( <>

Wishes

{canShow ? : } - - - + ); }; diff --git a/src/pages/manage/[id].tsx b/src/pages/manage/[id].tsx index a09f039..a57aee7 100644 --- a/src/pages/manage/[id].tsx +++ b/src/pages/manage/[id].tsx @@ -12,7 +12,7 @@ import { api } from "~/utils/api"; const ManageCard: NextPage<{ id: string }> = ({ id }) => { const { - data, + data: cardData, isLoading: cardLoading, isError: isCardError, error: cardError, @@ -44,7 +44,7 @@ const ManageCard: NextPage<{ id: string }> = ({ id }) => { ); - if (cardError ?? !data) { + if (cardError ?? !cardData) { toast.error(cardError?.message ?? ""); return ( @@ -100,14 +100,31 @@ const ManageCard: NextPage<{ id: string }> = ({ id }) => { title="Title" type="title" register={register} - placeholder={data.title} + placeholder={cardData.title} /> + + {/* note: perhaps we should convert this into a component, since this is copied from our create code. */} +
+ +
diff --git a/src/server/api/routers/cards.ts b/src/server/api/routers/cards.ts index e215dd4..9dd6a07 100644 --- a/src/server/api/routers/cards.ts +++ b/src/server/api/routers/cards.ts @@ -9,6 +9,9 @@ import { import type CardWish from "~/interfaces/CardWish"; import { TRPCError } from "@trpc/server"; +const checkFalsy = (...values: (string | boolean | null | undefined)[]) => + values.every((value) => value === null); + export const cardRouter = createTRPCRouter({ create: privateProcedure .input( @@ -58,6 +61,7 @@ export const cardRouter = createTRPCRouter({ cardId: z.string().cuid(), title: z.string().nullish(), description: z.string().nullish(), + paused: z.boolean().nullish(), }), ) .mutation(async ({ ctx, input }) => { @@ -73,19 +77,21 @@ export const cardRouter = createTRPCRouter({ code: "NOT_FOUND", }); - if (!input.title && !input.description) + if (checkFalsy(input.title, input.description, input.paused)) throw new TRPCError({ code: "BAD_REQUEST", - cause: "Either a title or description should be specified.", + cause: "No valid options specified.", }); const update: { title?: string; description?: string; + paused?: boolean; } = {}; if (input.title) update.title = input.title; if (input.description) update.description = input.description; + if (input.paused !== null) update.paused = input.paused; return await ctx.db.cards.update({ where: { @@ -182,6 +188,18 @@ export const cardRouter = createTRPCRouter({ }), ) .mutation(async ({ ctx, input }) => { + const cardInfo = await ctx.db.cards.findUnique({ + where: { + id: input.cardId, + }, + }); + + if (!cardInfo) { + throw new TRPCError({ + code: "NOT_FOUND", + cause: "You cannot send a wish to an inexistent card!", + }); + } const hasWish = await ctx.db.wishes.findFirst({ where: { cardId: input.cardId, @@ -189,11 +207,19 @@ export const cardRouter = createTRPCRouter({ }, }); - if (hasWish) + if (hasWish) { throw new TRPCError({ code: "BAD_REQUEST", cause: "You've already submitted a wish to this card!", }); + } + + if (cardInfo.paused) { + throw new TRPCError({ + code: "BAD_REQUEST", + cause: "Wishes can no longer be submitted to this card!", + }); + } return await ctx.db.wishes.create({ data: {