diff options
Diffstat (limited to 'apps/web/components/dashboard/bookmarks')
4 files changed, 100 insertions, 1 deletions
diff --git a/apps/web/components/dashboard/bookmarks/AssetCard.tsx b/apps/web/components/dashboard/bookmarks/AssetCard.tsx new file mode 100644 index 00000000..460dbe98 --- /dev/null +++ b/apps/web/components/dashboard/bookmarks/AssetCard.tsx @@ -0,0 +1,76 @@ +"use client"; + +import Image from "next/image"; +import { isBookmarkStillTagging } from "@/lib/bookmarkUtils"; +import { api } from "@/lib/trpc"; +import { cn } from "@/lib/utils"; + +import type { ZBookmark } from "@hoarder/trpc/types/bookmarks"; + +import BookmarkActionBar from "./BookmarkActionBar"; +import TagList from "./TagList"; + +export default function AssetCard({ + bookmark: initialData, + className, +}: { + bookmark: ZBookmark; + className?: string; +}) { + const { data: bookmark } = api.bookmarks.getBookmark.useQuery( + { + bookmarkId: initialData.id, + }, + { + initialData, + refetchInterval: (query) => { + const data = query.state.data; + if (!data) { + return false; + } + if (isBookmarkStillTagging(data)) { + return 1000; + } + return false; + }, + }, + ); + const bookmarkedAsset = bookmark.content; + if (bookmarkedAsset.type != "asset") { + throw new Error("Unexpected bookmark type"); + } + + return ( + <div + className={cn( + className, + cn( + "flex h-min max-h-96 flex-col gap-y-1 overflow-hidden rounded-lg shadow-md", + ), + )} + > + {bookmarkedAsset.assetType == "image" && ( + <div className="relative h-56 max-h-56"> + <Image + alt="asset" + src={`/api/assets/${bookmarkedAsset.assetId}`} + fill={true} + className="rounded-t-lg object-cover" + /> + </div> + )} + <div className="flex flex-col gap-y-1 overflow-hidden p-2"> + <div className="flex h-full flex-wrap gap-1 overflow-hidden"> + <TagList + bookmark={bookmark} + loading={isBookmarkStillTagging(bookmark)} + /> + </div> + <div className="flex w-full justify-between"> + <div /> + <BookmarkActionBar bookmark={bookmark} /> + </div> + </div> + </div> + ); +} diff --git a/apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx b/apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx index 69aa60a3..4209192e 100644 --- a/apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx +++ b/apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx @@ -1,5 +1,6 @@ "use client"; +import Image from "next/image"; import Link from "next/link"; import { BackButton } from "@/components/ui/back-button"; import { Skeleton } from "@/components/ui/skeleton"; @@ -70,6 +71,22 @@ export default function BookmarkPreview({ content = <Markdown className="prose">{bookmark.content.text}</Markdown>; break; } + case "asset": { + switch (bookmark.content.assetType) { + case "image": { + content = ( + <div className="relative w-full"> + <Image + alt="asset" + fill={true} + src={`/api/assets/${bookmark.content.assetId}`} + /> + </div> + ); + } + } + break; + } } return ( diff --git a/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx b/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx index b689a192..b40e6e42 100644 --- a/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx +++ b/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx @@ -14,6 +14,7 @@ import type { ZGetBookmarksResponse, } from "@hoarder/trpc/types/bookmarks"; +import AssetCard from "./AssetCard"; import EditorCard from "./EditorCard"; import LinkCard from "./LinkCard"; import TextCard from "./TextCard"; @@ -47,6 +48,9 @@ function renderBookmark(bookmark: ZBookmark) { case "text": comp = <TextCard bookmark={bookmark} />; break; + case "asset": + comp = <AssetCard bookmark={bookmark} />; + break; } return <BookmarkCard key={bookmark.id}>{comp}</BookmarkCard>; } diff --git a/apps/web/components/dashboard/bookmarks/EditorCard.tsx b/apps/web/components/dashboard/bookmarks/EditorCard.tsx index 28e8f41f..44c5889b 100644 --- a/apps/web/components/dashboard/bookmarks/EditorCard.tsx +++ b/apps/web/components/dashboard/bookmarks/EditorCard.tsx @@ -69,7 +69,9 @@ export default function EditorCard({ className }: { className?: string }) { <Textarea disabled={isPending} className="h-full w-full resize-none border-none text-lg focus-visible:ring-0" - placeholder={"Paste a link or write a note ..."} + placeholder={ + "Paste a link, write a note or drag and drop an image in here ..." + } onKeyDown={(e) => { if (e.key === "Enter" && e.metaKey) { form.handleSubmit(onSubmit, onError)(); |
