diff options
| author | MohamedBassem <me@mbassem.com> | 2024-02-13 20:49:42 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-02-13 20:59:52 +0000 |
| commit | da03fce5e5373e4791ccf0a885aaecff513156fe (patch) | |
| tree | 533d16aa8a7b4caaff9d84189d7f4c0a8579ba5f /packages | |
| parent | ff4482613ae70688e433d7c42784f0e24a569965 (diff) | |
| download | karakeep-da03fce5e5373e4791ccf0a885aaecff513156fe.tar.zst | |
feature: Implement a usable but ugly all tags and a single tag page
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/db/prisma/schema.prisma | 1 | ||||
| -rw-r--r-- | packages/web/app/dashboard/bookmarks/components/Bookmarks.tsx | 19 | ||||
| -rw-r--r-- | packages/web/app/dashboard/bookmarks/components/LinkCard.tsx | 15 | ||||
| -rw-r--r-- | packages/web/app/dashboard/components/Sidebar.tsx | 13 | ||||
| -rw-r--r-- | packages/web/app/dashboard/tags/[tagName]/page.tsx | 51 | ||||
| -rw-r--r-- | packages/web/app/dashboard/tags/page.tsx | 36 | ||||
| -rw-r--r-- | packages/web/server/api/routers/bookmarks.ts | 29 | ||||
| -rw-r--r-- | packages/web/server/api/routers/tags.ts | 0 |
8 files changed, 135 insertions, 29 deletions
diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index 5c575c97..e77297c6 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -102,6 +102,7 @@ model BookmarkedLink { model BookmarkTags { id String @id @default(cuid()) + // TODO: Tags are unique per user not globally name String @unique createdAt DateTime @default(now()) diff --git a/packages/web/app/dashboard/bookmarks/components/Bookmarks.tsx b/packages/web/app/dashboard/bookmarks/components/Bookmarks.tsx index d7e3f1f3..bd144a67 100644 --- a/packages/web/app/dashboard/bookmarks/components/Bookmarks.tsx +++ b/packages/web/app/dashboard/bookmarks/components/Bookmarks.tsx @@ -20,20 +20,17 @@ export default async function Bookmarks({ archived, }); - if (bookmarks.bookmarks.length == 0) { - // TODO: This needs to be polished - return ( - <> - <div className="container pb-4 text-2xl">{title}</div> - <div className="container">No bookmarks</div> - </> - ); - } - + // TODO: This needs to be polished return ( <> <div className="container pb-4 text-2xl">{title}</div> - <BookmarksGrid bookmarks={bookmarks.bookmarks} /> + <div className="container"> + {bookmarks.bookmarks.length == 0 ? ( + "No bookmarks" + ) : ( + <BookmarksGrid bookmarks={bookmarks.bookmarks} /> + )} + </div> </> ); } diff --git a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx index abd4bff7..00e4ef26 100644 --- a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx +++ b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx @@ -27,13 +27,14 @@ export default function LinkCard({ bookmark }: { bookmark: ZBookmark }) { </ImageCardTitle> <ImageCardBody className="overflow-clip py-2"> {bookmark.tags.map((t) => ( - <Badge - variant="default" - className="bg-gray-300 text-gray-500 hover:text-white" - key={t.id} - > - #{t.name} - </Badge> + <Link key={t.id} href={`/dashboard/tags/${t.name}`}> + <Badge + variant="default" + className="bg-gray-300 text-gray-500 hover:text-white" + > + #{t.name} + </Badge> + </Link> ))} </ImageCardBody> <ImageCardFooter> diff --git a/packages/web/app/dashboard/components/Sidebar.tsx b/packages/web/app/dashboard/components/Sidebar.tsx index 0563e26f..30179166 100644 --- a/packages/web/app/dashboard/components/Sidebar.tsx +++ b/packages/web/app/dashboard/components/Sidebar.tsx @@ -1,13 +1,4 @@ -import { Button } from "@/components/ui/button"; -import { - Archive, - MoreHorizontal, - Star, - Tag, - Home, - Brain, - Settings, -} from "lucide-react"; +import { Archive, Star, Tag, Home, Brain, Settings } from "lucide-react"; import { redirect } from "next/navigation"; import SidebarItem from "./SidebarItem"; import { getServerAuthSession } from "@/server/auth"; @@ -46,7 +37,7 @@ export default async function Sidebar() { name="Archive" path="/dashboard/bookmarks/archive" /> - <SidebarItem logo={<Tag />} name="Tags" path="#" /> + <SidebarItem logo={<Tag />} name="Tags" path="/dashboard/tags" /> <SidebarItem logo={<Settings />} name="Settings" diff --git a/packages/web/app/dashboard/tags/[tagName]/page.tsx b/packages/web/app/dashboard/tags/[tagName]/page.tsx new file mode 100644 index 00000000..e55c7d7e --- /dev/null +++ b/packages/web/app/dashboard/tags/[tagName]/page.tsx @@ -0,0 +1,51 @@ +import { getServerAuthSession } from "@/server/auth"; +import { prisma } from "@remember/db"; +import { notFound, redirect } from "next/navigation"; +import BookmarksGrid from "../../bookmarks/components/BookmarksGrid"; +import { api } from "@/server/api/client"; + +export default async function TagPage({ + params, +}: { + params: { tagName: string }; +}) { + const session = await getServerAuthSession(); + if (!session) { + redirect("/"); + } + const tag = await prisma.bookmarkTags.findUnique({ + where: { + userId: session.user.id, + name: params.tagName, + }, + select: { + id: true, + }, + }); + + if (!tag) { + // TODO: Better error message when the tag is not there + notFound(); + } + + const bookmarkIds = await prisma.tagsOnBookmarks.findMany({ + where: { + tagId: tag.id, + }, + select: { + bookmarkId: true, + }, + }); + + const bookmarks = await api.bookmarks.getBookmarksById({ + ids: bookmarkIds.map((b) => b.bookmarkId), + archived: false, + }); + + return ( + <div className="flex flex-col"> + <span className="container py-4 text-2xl">#{params.tagName}</span> + <BookmarksGrid bookmarks={bookmarks.bookmarks} /> + </div> + ); +} diff --git a/packages/web/app/dashboard/tags/page.tsx b/packages/web/app/dashboard/tags/page.tsx new file mode 100644 index 00000000..546ee28d --- /dev/null +++ b/packages/web/app/dashboard/tags/page.tsx @@ -0,0 +1,36 @@ +import { Button } from "@/components/ui/button"; +import { getServerAuthSession } from "@/server/auth"; +import { prisma } from "@remember/db"; +import Link from "next/link"; +import { redirect } from "next/navigation"; + +export default async function TagsPage() { + const session = await getServerAuthSession(); + if (!session) { + redirect("/"); + } + + const tags = await prisma.bookmarkTags.findMany({ + where: { + userId: session.user.id, + }, + }); + + return ( + <div className="container mt-2 space-y-3"> + <span className="text-2xl">All Tags</span> + <hr /> + <div className="flex flex-wrap space-x-2"> + {tags.map((t) => ( + <Link + className="block rounded-xl bg-black p-2 text-white" + key={t.id} + href={`/dashboard/tags/${t.name}`} + > + {t.name} + </Link> + ))} + </div> + </div> + ); +} diff --git a/packages/web/server/api/routers/bookmarks.ts b/packages/web/server/api/routers/bookmarks.ts index 0b97563f..953dab66 100644 --- a/packages/web/server/api/routers/bookmarks.ts +++ b/packages/web/server/api/routers/bookmarks.ts @@ -136,4 +136,33 @@ export const bookmarksAppRouter = router({ return { bookmarks }; }), + getBookmarksById: authedProcedure + .input( + zGetBookmarksRequestSchema.merge( + z.object({ + ids: z.array(z.string()), + }), + ), + ) + .output(zGetBookmarksResponseSchema) + .query(async ({ input, ctx }) => { + const bookmarks = ( + await prisma.bookmark.findMany({ + where: { + id: { + in: input.ids, + }, + userId: ctx.user.id, + archived: input.archived, + favourited: input.favourited, + }, + orderBy: { + createdAt: "desc", + }, + select: defaultBookmarkFields, + }) + ).map(toZodSchema); + + return { bookmarks }; + }), }); diff --git a/packages/web/server/api/routers/tags.ts b/packages/web/server/api/routers/tags.ts new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/packages/web/server/api/routers/tags.ts |
