From 08a5694e451218f1bcb2ad9eb42fd93250afbb96 Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Fri, 9 Feb 2024 01:50:35 +0000 Subject: [refactor] Extract the bookmark model to be a high level model to support other type of bookmarks --- .../web/app/api/v1/bookmarks/[bookmarkId]/route.ts | 32 ++++++++++++++ packages/web/app/api/v1/bookmarks/route.ts | 47 +++++++++++++++++++++ packages/web/app/api/v1/links/[linkId]/route.ts | 32 -------------- packages/web/app/api/v1/links/route.ts | 49 ---------------------- .../bookmarks/components/BookmarksGrid.tsx | 27 ++++++++++++ .../dashboard/bookmarks/components/LinkCard.tsx | 15 +++---- .../dashboard/bookmarks/components/LinksGrid.tsx | 21 ---------- packages/web/app/dashboard/bookmarks/page.tsx | 4 +- 8 files changed, 116 insertions(+), 111 deletions(-) create mode 100644 packages/web/app/api/v1/bookmarks/[bookmarkId]/route.ts create mode 100644 packages/web/app/api/v1/bookmarks/route.ts delete mode 100644 packages/web/app/api/v1/links/[linkId]/route.ts delete mode 100644 packages/web/app/api/v1/links/route.ts create mode 100644 packages/web/app/dashboard/bookmarks/components/BookmarksGrid.tsx delete mode 100644 packages/web/app/dashboard/bookmarks/components/LinksGrid.tsx (limited to 'packages/web/app') diff --git a/packages/web/app/api/v1/bookmarks/[bookmarkId]/route.ts b/packages/web/app/api/v1/bookmarks/[bookmarkId]/route.ts new file mode 100644 index 00000000..6adcf771 --- /dev/null +++ b/packages/web/app/api/v1/bookmarks/[bookmarkId]/route.ts @@ -0,0 +1,32 @@ +import { authOptions } from "@/lib/auth"; +import { deleteBookmark } from "@/lib/services/bookmarks"; +import { Prisma } from "@remember/db"; + +import { getServerSession } from "next-auth"; +import { NextRequest } from "next/server"; + +export async function DELETE( + _request: NextRequest, + { params }: { params: { bookmarkId: string } }, +) { + // TODO: We probably should be using an API key here instead of the session; + const session = await getServerSession(authOptions); + if (!session) { + return new Response(null, { status: 401 }); + } + + try { + await deleteBookmark(params.bookmarkId, session.user.id); + } catch (e: unknown) { + if ( + e instanceof Prisma.PrismaClientKnownRequestError && + e.code === "P2025" // RecordNotFound + ) { + return new Response(null, { status: 404 }); + } else { + throw e; + } + } + + return new Response(null, { status: 201 }); +} diff --git a/packages/web/app/api/v1/bookmarks/route.ts b/packages/web/app/api/v1/bookmarks/route.ts new file mode 100644 index 00000000..b9305ca8 --- /dev/null +++ b/packages/web/app/api/v1/bookmarks/route.ts @@ -0,0 +1,47 @@ +import { authOptions } from "@/lib/auth"; +import { bookmarkLink, getBookmarks } from "@/lib/services/bookmarks"; + +import { + zNewBookmarkRequestSchema, + ZGetBookmarksResponse, + ZBookmark, +} from "@/lib/types/api/bookmarks"; +import { getServerSession } from "next-auth"; +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(request: NextRequest) { + // TODO: We probably should be using an API key here instead of the session; + const session = await getServerSession(authOptions); + if (!session) { + return new Response(null, { status: 401 }); + } + + const linkRequest = zNewBookmarkRequestSchema.safeParse(await request.json()); + + if (!linkRequest.success) { + return NextResponse.json( + { + error: linkRequest.error.toString(), + }, + { status: 400 }, + ); + } + + const bookmark = await bookmarkLink(linkRequest.data.url, session.user.id); + + let response: ZBookmark = { ...bookmark }; + return NextResponse.json(response, { status: 201 }); +} + +export async function GET() { + // TODO: We probably should be using an API key here instead of the session; + const session = await getServerSession(authOptions); + if (!session) { + return new Response(null, { status: 401 }); + } + + const bookmarks = await getBookmarks(session.user.id); + + let response: ZGetBookmarksResponse = { bookmarks }; + return NextResponse.json(response); +} diff --git a/packages/web/app/api/v1/links/[linkId]/route.ts b/packages/web/app/api/v1/links/[linkId]/route.ts deleted file mode 100644 index 39449d6d..00000000 --- a/packages/web/app/api/v1/links/[linkId]/route.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { authOptions } from "@/lib/auth"; -import { unbookmarkLink } from "@/lib/services/links"; -import { Prisma } from "@remember/db"; - -import { getServerSession } from "next-auth"; -import { NextRequest } from "next/server"; - -export async function DELETE( - _request: NextRequest, - { params }: { params: { linkId: string } }, -) { - // TODO: We probably should be using an API key here instead of the session; - const session = await getServerSession(authOptions); - if (!session) { - return new Response(null, { status: 401 }); - } - - try { - await unbookmarkLink(params.linkId, session.user.id); - } catch (e: unknown) { - if ( - e instanceof Prisma.PrismaClientKnownRequestError && - e.code === "P2025" // RecordNotFound - ) { - return new Response(null, { status: 404 }); - } else { - throw e; - } - } - - return new Response(null, { status: 201 }); -} diff --git a/packages/web/app/api/v1/links/route.ts b/packages/web/app/api/v1/links/route.ts deleted file mode 100644 index 87541634..00000000 --- a/packages/web/app/api/v1/links/route.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { authOptions } from "@/lib/auth"; -import { bookmarkLink, getLinks } from "@/lib/services/links"; - -import { - zNewBookmarkedLinkRequestSchema, - ZGetLinksResponse, - ZBookmarkedLink, -} from "@/lib/types/api/links"; -import { getServerSession } from "next-auth"; -import { NextRequest, NextResponse } from "next/server"; - -export async function POST(request: NextRequest) { - // TODO: We probably should be using an API key here instead of the session; - const session = await getServerSession(authOptions); - if (!session) { - return new Response(null, { status: 401 }); - } - - const linkRequest = zNewBookmarkedLinkRequestSchema.safeParse( - await request.json(), - ); - - if (!linkRequest.success) { - return NextResponse.json( - { - error: linkRequest.error.toString(), - }, - { status: 400 }, - ); - } - - const link = await bookmarkLink(linkRequest.data.url, session.user.id); - - let response: ZBookmarkedLink = { ...link }; - return NextResponse.json(response, { status: 201 }); -} - -export async function GET() { - // TODO: We probably should be using an API key here instead of the session; - const session = await getServerSession(authOptions); - if (!session) { - return new Response(null, { status: 401 }); - } - - const links = await getLinks(session.user.id); - - let response: ZGetLinksResponse = { links }; - return NextResponse.json(response); -} diff --git a/packages/web/app/dashboard/bookmarks/components/BookmarksGrid.tsx b/packages/web/app/dashboard/bookmarks/components/BookmarksGrid.tsx new file mode 100644 index 00000000..2b6b19b6 --- /dev/null +++ b/packages/web/app/dashboard/bookmarks/components/BookmarksGrid.tsx @@ -0,0 +1,27 @@ +import { getServerSession } from "next-auth"; +import { redirect } from "next/navigation"; +import { authOptions } from "@/lib/auth"; +import { getBookmarks } from "@/lib/services/bookmarks"; +import LinkCard from "./LinkCard"; +import { ZBookmark } from "@/lib/types/api/bookmarks"; + +function renderBookmark(bookmark: ZBookmark) { + switch (bookmark.content.type) { + case "link": + return ; + } +} + +export default async function BookmarksGrid() { + const session = await getServerSession(authOptions); + if (!session) { + redirect("/"); + } + const bookmarks = await getBookmarks(session.user.id); + + return ( +
+ {bookmarks.map((b) => renderBookmark(b))} +
+ ); +} diff --git a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx index b5a051e8..1cbd8865 100644 --- a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx +++ b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx @@ -16,7 +16,7 @@ import { } from "@/components/ui/imageCard"; import { useToast } from "@/components/ui/use-toast"; import APIClient from "@/lib/api"; -import { ZBookmarkedLink } from "@/lib/types/api/links"; +import { ZBookmark } from "@/lib/types/api/bookmarks"; import { MoreHorizontal, Trash2 } from "lucide-react"; import Link from "next/link"; import { useRouter } from "next/navigation"; @@ -26,7 +26,7 @@ export function LinkOptions({ linkId }: { linkId: string }) { const router = useRouter(); const unbookmarkLink = async () => { - let [_, error] = await APIClient.unbookmarkLink(linkId); + let [_, error] = await APIClient.deleteBookmark(linkId); if (error) { toast({ @@ -59,7 +59,8 @@ export function LinkOptions({ linkId }: { linkId: string }) { ); } -export default function LinkCard({ link }: { link: ZBookmarkedLink }) { +export default function LinkCard({ bookmark }: { bookmark: ZBookmark }) { + const link = bookmark.content; const parsedUrl = new URL(link.url); return ( @@ -67,15 +68,15 @@ export default function LinkCard({ link }: { link: ZBookmarkedLink }) { className={ "bg-gray-50 duration-300 ease-in border border-grey-100 hover:transition-all hover:border-blue-300" } - image={link.details?.imageUrl ?? undefined} + image={link?.imageUrl ?? undefined} > - {link.details?.title ?? parsedUrl.host} + {link?.title ?? parsedUrl.host} - {link.tags.map((t) => ( + {bookmark.tags.map((t) => ( - + diff --git a/packages/web/app/dashboard/bookmarks/components/LinksGrid.tsx b/packages/web/app/dashboard/bookmarks/components/LinksGrid.tsx deleted file mode 100644 index 66f0d766..00000000 --- a/packages/web/app/dashboard/bookmarks/components/LinksGrid.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { getServerSession } from "next-auth"; -import { redirect } from "next/navigation"; -import { authOptions } from "@/lib/auth"; -import { getLinks } from "@/lib/services/links"; -import LinkCard from "./LinkCard"; - -export default async function LinksGrid() { - const session = await getServerSession(authOptions); - if (!session) { - redirect("/"); - } - const links = await getLinks(session.user.id); - - return ( -
- {links.map((l) => ( - - ))} -
- ); -} diff --git a/packages/web/app/dashboard/bookmarks/page.tsx b/packages/web/app/dashboard/bookmarks/page.tsx index b4158893..b9eabfe8 100644 --- a/packages/web/app/dashboard/bookmarks/page.tsx +++ b/packages/web/app/dashboard/bookmarks/page.tsx @@ -1,5 +1,5 @@ import AddLink from "./components/AddLink"; -import LinksGrid from "./components/LinksGrid"; +import BookmarksGrid from "./components/BookmarksGrid"; import type { Metadata } from "next"; export const metadata: Metadata = { @@ -13,7 +13,7 @@ export default async function Bookmarks() {
- +
); -- cgit v1.2.3-70-g09d2