From 15a75a3d71d92c0cf2a8c30108f346665e1c5118 Mon Sep 17 00:00:00 2001 From: Jaleel Bennett Date: Fri, 2 Aug 2024 10:28:18 -0400 Subject: [PATCH] fix(bookmarks): including url into bookmark db entry --- app/article/article-wrapper.tsx | 9 +++- app/bookmarks/bookmark-wrapper.tsx | 52 +++++++++++------- app/bookmarks/bookmark.ts | 2 + app/bookmarks/components/bookmark-button.tsx | 4 +- app/bookmarks/components/bookmark-list.tsx | 13 +++++ .../components/create-bookmark-form.tsx | 1 + components/article-wrapper.tsx | 54 ------------------- components/article.tsx | 3 ++ components/ui/toaster.tsx | 35 ------------ data-access/bookmarks.ts | 6 ++- server/db/schema.ts | 1 + use-cases/bookmarks.ts | 2 +- 12 files changed, 68 insertions(+), 114 deletions(-) delete mode 100644 components/article-wrapper.tsx delete mode 100644 components/ui/toaster.tsx diff --git a/app/article/article-wrapper.tsx b/app/article/article-wrapper.tsx index a54cbbf..268bc87 100644 --- a/app/article/article-wrapper.tsx +++ b/app/article/article-wrapper.tsx @@ -69,7 +69,14 @@ async function ArticleLoader({ ); } - return
; + return ( +
+ ); } export async function ArticleWrapper({ url }: { url: string }) { diff --git a/app/bookmarks/bookmark-wrapper.tsx b/app/bookmarks/bookmark-wrapper.tsx index 789844b..22f5c32 100644 --- a/app/bookmarks/bookmark-wrapper.tsx +++ b/app/bookmarks/bookmark-wrapper.tsx @@ -11,10 +11,13 @@ import { Icons } from "@/components/icons"; import { getBookmarksAction } from "./bookmark"; import { ErrorCard } from "@/components/error-card"; import { User } from "lucia"; +import { BookmarkButton } from "./components/bookmark-button"; +import Balancer from "react-wrap-balancer"; export type Bookmark = { id: number; } & z.infer & { + articleUrl: string; createdAt: Date; updatedAt: Date | null; }; @@ -45,26 +48,37 @@ async function BookmarkLoader({ user }: { user: User }) { if (!data || data.length === 0) { return (
- - Error -
-

No bookmarked articles

-

- You haven't bookmarked any articles yet. Click the button - below to start bookmarking. -

+
+
+ + Bookmarks + + + Manage your bookmarked articles +
- + + Error +
+

No bookmarked articles

+

+ You haven't bookmarked any articles yet. Click the button + below to start bookmarking. +

+ +
+
+
); } diff --git a/app/bookmarks/bookmark.ts b/app/bookmarks/bookmark.ts index c75631d..b9079c0 100644 --- a/app/bookmarks/bookmark.ts +++ b/app/bookmarks/bookmark.ts @@ -28,6 +28,7 @@ export const createBookmarkAction = authenticatedAction publicationName: z.string(), readTime: z.string(), publishDate: z.string(), + articleUrl: z.string(), }), ) .handler(async ({ input }) => { @@ -42,6 +43,7 @@ export const createBookmarkAction = authenticatedAction publicationName: input.publicationName, readTime: input.readTime, publishDate: input.publishDate, + articleUrl: input.articleUrl, }); } revalidatePath(input.path); diff --git a/app/bookmarks/components/bookmark-button.tsx b/app/bookmarks/components/bookmark-button.tsx index 45095af..1726143 100644 --- a/app/bookmarks/components/bookmark-button.tsx +++ b/app/bookmarks/components/bookmark-button.tsx @@ -12,7 +12,7 @@ import { import { SparkleBg } from "@/components/sparkle-bg"; import { CreateBookmarkForm } from "./create-bookmark-form"; -export async function BookmarkButton() { +export async function BookmarkButton({ text = "New" }: { text?: string }) { return ( @@ -22,7 +22,7 @@ export async function BookmarkButton() { )} >
- New + {text}
diff --git a/app/bookmarks/components/bookmark-list.tsx b/app/bookmarks/components/bookmark-list.tsx index 242d28a..9cdbc9f 100644 --- a/app/bookmarks/components/bookmark-list.tsx +++ b/app/bookmarks/components/bookmark-list.tsx @@ -8,7 +8,9 @@ import { Button } from "@/components/ui/button"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { AvatarImage } from "@radix-ui/react-avatar"; import Link from "next/link"; +import Cookies from "js-cookie"; import { cn, formatDate } from "@/lib/utils"; +import { v4 as uuidv4 } from "uuid"; import { AlertDialog, AlertDialogAction, @@ -56,6 +58,7 @@ export default function BookmarksList({ bookmarks: Bookmark[]; userId: number; }) { + // const id = uuidv4(); const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); @@ -141,7 +144,16 @@ export default function BookmarksList({ className={cn( `relative flex w-full transform-gpu cursor-pointer flex-col gap-2 rounded-xl border bg-white p-2 shadow-sm transition-all duration-200 ease-in-out [box-shadow:0_0_0_1px_rgba(0,0,0,.03),0_2px_4px_rgba(0,0,0,.05),0_12px_24px_rgba(0,0,0,.05)] hover:scale-[103%] dark:bg-transparent dark:backdrop-blur-md dark:[border:1px_solid_rgba(255,255,255,.1)] dark:[box-shadow:0_-20px_80px_-20px_#ffffff1f_inset]`, )} + // onClick={() => { + // Cookies.set(id, bookmark.articleUrl, { + // expires: 1 / 288, // Cookie expires in 5 minutes (1/288 of a day) + // secure: true, + // path: "/", + // sameSite: "strict", // Cookie is sent only when the request is coming from the same origin + // }); + // }} > + {/* */}
@@ -223,6 +235,7 @@ export default function BookmarksList({ {extractFirstSentence(bookmark.content)} + {/* */} )) ) : ( diff --git a/app/bookmarks/components/create-bookmark-form.tsx b/app/bookmarks/components/create-bookmark-form.tsx index 7b1522e..cc8235f 100644 --- a/app/bookmarks/components/create-bookmark-form.tsx +++ b/app/bookmarks/components/create-bookmark-form.tsx @@ -115,6 +115,7 @@ export function CreateBookmarkForm() { authorImageURL: scrapedArticle?.authorInformation.authorImageURL || "", authorProfileURL: scrapedArticle?.authorInformation.authorProfileURL || "", + articleUrl: values.url, publicationName: scrapedArticle?.publicationInformation.publicationName || "", readTime: scrapedArticle?.publicationInformation.readTime || "", diff --git a/components/article-wrapper.tsx b/components/article-wrapper.tsx deleted file mode 100644 index ca9c4c6..0000000 --- a/components/article-wrapper.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { - ArticleDetails, - scrapeArticleContent, -} from "@/app/article/actions/article"; -import { headers } from "next/headers"; -import { SuspenseIf } from "./suspense-if"; -import { Article } from "./article"; -import { unstable_cache } from "next/cache"; -import { ArticleSkeleton } from "./article-skeleton"; -import { ErrorCard } from "./error-card"; -import { getCurrentUser } from "@/lib/session"; -import { getUser } from "@/data-access/users"; -import { redirect } from "next/navigation"; - -export const getCachedArticle = unstable_cache( - async (url) => scrapeArticleContent(url), - ["url"], -); - -async function ArticleLoader({ url }: { url: string }) { - // const content = await getCachedArticle(url); - const content = await scrapeArticleContent(url); - if (!content) { - return ; - } - - const userSession = await getCurrentUser(); - if (!userSession) { - redirect("/signin"); - } - - const user = await getUser(userSession.id); - if (!user) { - redirect("/signin"); - } - - // return
; -} - -export async function ArticleWrapper({ url }: { url: string }) { - let article: ArticleDetails | null = null; - - // if browser is requesting html it means it's the first page load - if (headers().get("accept")?.includes("text/html")) { - // article = await getCachedArticle(url); - article = await scrapeArticleContent(url); - } - - return ( - }> - - - ); -} diff --git a/components/article.tsx b/components/article.tsx index caea4bf..bddd1d0 100644 --- a/components/article.tsx +++ b/components/article.tsx @@ -29,6 +29,7 @@ export function Article({ content, user, readingHistoryId, + url, }: { content: ArticleDetails; user: { @@ -36,6 +37,7 @@ export function Article({ id: number; emailVerified: Date | null; }; + url: string; readingHistoryId: number; }) { const safeHTMLContent = DOMPurify.sanitize(content?.content || "", { @@ -228,6 +230,7 @@ export function Article({ content?.authorInformation.authorProfileURL || "", publicationName: content?.publicationInformation.publicationName || "", + articleUrl: url, readTime: content?.publicationInformation.readTime || calculateReadTime(content?.content as string), diff --git a/components/ui/toaster.tsx b/components/ui/toaster.tsx deleted file mode 100644 index 7d82ed5..0000000 --- a/components/ui/toaster.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client"; - -import { - Toast, - ToastClose, - ToastDescription, - ToastProvider, - ToastTitle, - ToastViewport, -} from "@/components/ui/toast"; -import { useToast } from "@/components/ui/use-toast"; - -export function Toaster() { - const { toasts } = useToast(); - - return ( - - {toasts.map(function ({ id, title, description, action, ...props }) { - return ( - -
- {title && {title}} - {description && ( - {description} - )} -
- {action} - -
- ); - })} - -
- ); -} diff --git a/data-access/bookmarks.ts b/data-access/bookmarks.ts index f0fdca6..0ea74ae 100644 --- a/data-access/bookmarks.ts +++ b/data-access/bookmarks.ts @@ -6,13 +6,14 @@ import { z } from "zod"; export async function createBookark( userId: number, - articleDetails: z.infer, + articleDetails: z.infer & { articleUrl: string }, ) { const existingBookmark = await db.query.bookmarks.findFirst({ where: eq(bookmarks.userId, userId) && eq(bookmarks.title, articleDetails.title) && - eq(bookmarks.publishDate, articleDetails.publishDate ?? ""), + eq(bookmarks.publishDate, articleDetails.publishDate ?? "") && + eq(bookmarks.articleUrl, articleDetails.articleUrl), }); if (existingBookmark) { @@ -31,6 +32,7 @@ export async function createBookark( publicationName: articleDetails.publicationName, readTime: articleDetails.readTime, publishDate: articleDetails.publishDate, + articleUrl: articleDetails.articleUrl, createdAt: new Date(), }) .onConflictDoNothing() diff --git a/server/db/schema.ts b/server/db/schema.ts index 4054fe8..083c383 100644 --- a/server/db/schema.ts +++ b/server/db/schema.ts @@ -83,6 +83,7 @@ export const bookmarks = sqliteTable("bookmark", { authorName: text("author_name"), authorImageURL: text("author_image_url"), authorProfileURL: text("author_profile_url"), + articleUrl: text("article_url").notNull(), publicationName: text("publication_name"), readTime: text("read_time"), publishDate: text("publish_date"), diff --git a/use-cases/bookmarks.ts b/use-cases/bookmarks.ts index e075182..7c79b29 100644 --- a/use-cases/bookmarks.ts +++ b/use-cases/bookmarks.ts @@ -10,7 +10,7 @@ import { z } from "zod"; export async function createBookmarkUseCase( userId: number, - articleDetails: z.infer, + articleDetails: z.infer & { articleUrl: string }, ) { const bookmark = await createBookark(userId, articleDetails);