aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-02-13 20:49:42 +0000
committerMohamedBassem <me@mbassem.com>2024-02-13 20:59:52 +0000
commitda03fce5e5373e4791ccf0a885aaecff513156fe (patch)
tree533d16aa8a7b4caaff9d84189d7f4c0a8579ba5f /packages
parentff4482613ae70688e433d7c42784f0e24a569965 (diff)
downloadkarakeep-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.prisma1
-rw-r--r--packages/web/app/dashboard/bookmarks/components/Bookmarks.tsx19
-rw-r--r--packages/web/app/dashboard/bookmarks/components/LinkCard.tsx15
-rw-r--r--packages/web/app/dashboard/components/Sidebar.tsx13
-rw-r--r--packages/web/app/dashboard/tags/[tagName]/page.tsx51
-rw-r--r--packages/web/app/dashboard/tags/page.tsx36
-rw-r--r--packages/web/server/api/routers/bookmarks.ts29
-rw-r--r--packages/web/server/api/routers/tags.ts0
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