diff options
| author | MohamedBassem <me@mbassem.com> | 2024-02-15 16:03:24 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-02-15 16:03:24 +0000 |
| commit | 97d18d7ac3bc6ab4f40618e74f021ee63a4cf7b6 (patch) | |
| tree | 1baa3a602da8c2a67b6c4807dcc27c329a2351c4 /packages | |
| parent | 25d399c1abbccc28a899ef43a3c945a86f680af9 (diff) | |
| download | karakeep-97d18d7ac3bc6ab4f40618e74f021ee63a4cf7b6.tar.zst | |
ui: Usage images for link cards
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/web/app/dashboard/bookmarks/components/LinkCard.tsx | 68 | ||||
| -rw-r--r-- | packages/web/app/dashboard/error.tsx | 10 | ||||
| -rw-r--r-- | packages/web/app/dashboard/not-found.tsx | 10 | ||||
| -rw-r--r-- | packages/web/components/ui/imageCard.tsx | 46 |
4 files changed, 83 insertions, 51 deletions
diff --git a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx index 00e4ef26..7413c2fe 100644 --- a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx +++ b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx @@ -1,7 +1,9 @@ import { Badge } from "@/components/ui/badge"; import { ImageCard, + ImageCardBanner, ImageCardBody, + ImageCardContent, ImageCardFooter, ImageCardTitle, } from "@/components/ui/imageCard"; @@ -13,40 +15,56 @@ export default function LinkCard({ bookmark }: { bookmark: ZBookmark }) { const link = bookmark.content; const parsedUrl = new URL(link.url); + // A dummy white pixel for when there's no image. + // TODO: Better handling for cards with no images + const image = + link.imageUrl ?? + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdj+P///38ACfsD/QVDRcoAAAAASUVORK5CYII="; + return ( <ImageCard className={ "border-grey-100 border bg-gray-50 duration-300 ease-in hover:border-blue-300 hover:transition-all" } - image={link?.imageUrl ?? undefined} > - <ImageCardTitle> - <Link className="line-clamp-2" href={link.url}> - {link?.title ?? parsedUrl.host} - </Link> - </ImageCardTitle> - <ImageCardBody className="overflow-clip py-2"> - {bookmark.tags.map((t) => ( - <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 href={link.url}> + <ImageCardBanner src={image} /> + </Link> + <ImageCardContent> + <ImageCardTitle> + <Link className="line-clamp-2" href={link.url}> + {link?.title ?? parsedUrl.host} </Link> - ))} - </ImageCardBody> - <ImageCardFooter> - <div className="flex justify-between text-gray-500"> - <div className="my-auto"> - <Link className="line-clamp-1 hover:text-black" href={link.url}> - {parsedUrl.host} + </ImageCardTitle> + {/* There's a hack here. Every tag has the full hight of the container itself. That why, when we enable flex-wrap, + the overflowed don't show up. */} + <ImageCardBody className="flex h-full flex-wrap space-x-1 overflow-hidden"> + {bookmark.tags.map((t) => ( + <Link + className="flex h-full flex-col justify-end" + key={t.id} + href={`/dashboard/tags/${t.name}`} + > + <Badge + variant="default" + className="text-nowrap bg-gray-300 text-gray-500 hover:text-white" + > + #{t.name} + </Badge> </Link> + ))} + </ImageCardBody> + <ImageCardFooter> + <div className="flex justify-between text-gray-500"> + <div className="my-auto"> + <Link className="line-clamp-1 hover:text-black" href={link.url}> + {parsedUrl.host} + </Link> + </div> + <BookmarkOptions bookmark={bookmark} /> </div> - <BookmarkOptions bookmark={bookmark} /> - </div> - </ImageCardFooter> + </ImageCardFooter> + </ImageCardContent> </ImageCard> ); } diff --git a/packages/web/app/dashboard/error.tsx b/packages/web/app/dashboard/error.tsx index 2bba0e98..556e59a3 100644 --- a/packages/web/app/dashboard/error.tsx +++ b/packages/web/app/dashboard/error.tsx @@ -1,9 +1,9 @@ "use client"; export default function Error() { - return ( - <div className="flex size-full"> - <div className="m-auto text-3xl">Something went wrong</div> - </div> - ); + return ( + <div className="flex size-full"> + <div className="m-auto text-3xl">Something went wrong</div> + </div> + ); } diff --git a/packages/web/app/dashboard/not-found.tsx b/packages/web/app/dashboard/not-found.tsx index abd1ebae..64df220c 100644 --- a/packages/web/app/dashboard/not-found.tsx +++ b/packages/web/app/dashboard/not-found.tsx @@ -1,7 +1,7 @@ export default function NotFound() { - return ( - <div className="flex size-full"> - <div className="m-auto text-3xl">Not Found :(</div> - </div> - ); + return ( + <div className="flex size-full"> + <div className="m-auto text-3xl">Not Found :(</div> + </div> + ); } diff --git a/packages/web/components/ui/imageCard.tsx b/packages/web/components/ui/imageCard.tsx index dae7da3f..f10ebdb5 100644 --- a/packages/web/components/ui/imageCard.tsx +++ b/packages/web/components/ui/imageCard.tsx @@ -3,51 +3,65 @@ import * as React from "react"; import { cn } from "@/lib/utils"; export function ImageCard({ - children, - image, className, ...props -}: React.HTMLAttributes<HTMLDivElement> & { image?: string }) { +}: React.HTMLAttributes<HTMLDivElement>) { return ( <div className={cn("h-96 overflow-hidden rounded-lg shadow-md", className)} {...props} - > - <div - className="h-3/5 bg-cover bg-center" - style={{ - backgroundImage: image ? `url(${image})` : undefined, - }} - ></div> - <div className="flex h-2/5 flex-col p-2">{children}</div> - </div> + /> ); } -export function ImageCardTitle({ +export function ImageCardBanner({ + className, + ...props +}: React.ImgHTMLAttributes<HTMLImageElement>) { + return ( + // eslint-disable-next-line @next/next/no-img-element + <img + className={cn("h-56 min-h-56 w-full object-cover", className)} + alt="card banner" + {...props} + /> + ); +} + +export function ImageCardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) { return ( <div - className={cn("order-first flex-none text-lg font-bold", className)} + className={cn( + "flex h-40 min-h-40 flex-col justify-between p-2", + className, + )} {...props} /> ); } -export function ImageCardBody({ +export function ImageCardTitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) { return ( <div - className={cn("order-1 grow text-lg font-bold", className)} + className={cn("order-first flex-none text-lg font-bold", className)} {...props} /> ); } +export function ImageCardBody({ + className, + ...props +}: React.HTMLAttributes<HTMLDivElement>) { + return <div className={cn("order-1", className)} {...props} />; +} + export function ImageCardFooter({ className, ...props |
