From dc6e0eab70421749faaa9a802d66c1901f3e9b50 Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Sun, 31 Mar 2024 16:34:52 +0100 Subject: feature: Add support deleting tags --- apps/web/app/dashboard/lists/[listId]/page.tsx | 8 +-- apps/web/app/dashboard/tags/[tagName]/page.tsx | 15 +++--- .../components/dashboard/tags/DeleteTagButton.tsx | 59 ++++++++++++++++++++++ packages/trpc/routers/tags.ts | 26 ++++++++++ 4 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 apps/web/components/dashboard/tags/DeleteTagButton.tsx diff --git a/apps/web/app/dashboard/lists/[listId]/page.tsx b/apps/web/app/dashboard/lists/[listId]/page.tsx index e27e1841..4d7df133 100644 --- a/apps/web/app/dashboard/lists/[listId]/page.tsx +++ b/apps/web/app/dashboard/lists/[listId]/page.tsx @@ -1,9 +1,8 @@ -import { notFound, redirect } from "next/navigation"; +import { notFound } from "next/navigation"; import Bookmarks from "@/components/dashboard/bookmarks/Bookmarks"; import DeleteListButton from "@/components/dashboard/lists/DeleteListButton"; import { BookmarkListContextProvider } from "@/lib/hooks/list-context"; import { api } from "@/server/api/client"; -import { getServerAuthSession } from "@/server/auth"; import { TRPCError } from "@trpc/server"; export default async function ListPage({ @@ -11,11 +10,6 @@ export default async function ListPage({ }: { params: { listId: string }; }) { - const session = await getServerAuthSession(); - if (!session) { - redirect("/"); - } - let list; try { list = await api.lists.get({ listId: params.listId }); diff --git a/apps/web/app/dashboard/tags/[tagName]/page.tsx b/apps/web/app/dashboard/tags/[tagName]/page.tsx index 0e9e722e..3705a6d1 100644 --- a/apps/web/app/dashboard/tags/[tagName]/page.tsx +++ b/apps/web/app/dashboard/tags/[tagName]/page.tsx @@ -1,7 +1,7 @@ -import { notFound, redirect } from "next/navigation"; +import { notFound } from "next/navigation"; import Bookmarks from "@/components/dashboard/bookmarks/Bookmarks"; +import DeleteTagButton from "@/components/dashboard/tags/DeleteTagButton"; import { api } from "@/server/api/client"; -import { getServerAuthSession } from "@/server/auth"; import { TRPCError } from "@trpc/server"; export default async function TagPage({ @@ -9,10 +9,6 @@ export default async function TagPage({ }: { params: { tagName: string }; }) { - const session = await getServerAuthSession(); - if (!session) { - redirect("/"); - } const tagName = decodeURIComponent(params.tagName); let tag; @@ -29,7 +25,12 @@ export default async function TagPage({ return ( {tagName}

} + header={ +
+ {tagName} + +
+ } query={{ archived: false, tagId: tag.id }} /> ); diff --git a/apps/web/components/dashboard/tags/DeleteTagButton.tsx b/apps/web/components/dashboard/tags/DeleteTagButton.tsx new file mode 100644 index 00000000..4cff1680 --- /dev/null +++ b/apps/web/components/dashboard/tags/DeleteTagButton.tsx @@ -0,0 +1,59 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import { ActionButton } from "@/components/ui/action-button"; +import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog"; +import { Button } from "@/components/ui/button"; +import { toast } from "@/components/ui/use-toast"; +import { api } from "@/lib/trpc"; +import { Trash2 } from "lucide-react"; + +export default function DeleteTagButton({ + tagName, + tagId, +}: { + tagName: string; + tagId: string; +}) { + const router = useRouter(); + + const apiUtils = api.useUtils(); + + const { mutate: deleteTag, isPending } = api.tags.delete.useMutation({ + onSuccess: () => { + apiUtils.tags.list.invalidate(); + apiUtils.bookmarks.getBookmark.invalidate(); + toast({ + description: `Tag "${tagName}" has been deleted!`, + }); + router.push("/"); + }, + onError: () => { + toast({ + variant: "destructive", + description: `Something went wrong`, + }); + }, + }); + return ( + ( + deleteTag({ tagId: tagId })} + > + Delete + + )} + > + + + ); +} diff --git a/packages/trpc/routers/tags.ts b/packages/trpc/routers/tags.ts index 211c3633..f6ce752d 100644 --- a/packages/trpc/routers/tags.ts +++ b/packages/trpc/routers/tags.ts @@ -104,6 +104,32 @@ export const tagsAppRouter = router({ bookmarks: res.flatMap((t) => (t.bookmarkId ? [t.bookmarkId] : [])), }; }), + delete: authedProcedure + .input( + z + .object({ + tagId: z.string(), + }) + .or( + z.object({ + tagName: z.string(), + }), + ), + ) + .use(ensureTagOwnership) + .mutation(async ({ input, ctx }) => { + const res = await ctx.db + .delete(bookmarkTags) + .where( + and( + conditionFromInput(input, ctx.user.id), + eq(bookmarkTags.userId, ctx.user.id), + ), + ); + if (res.changes == 0) { + throw new TRPCError({ code: "NOT_FOUND" }); + } + }), list: authedProcedure .output( z.object({ -- cgit v1.2.3-70-g09d2