From 293869e1743c925519d938ebeeff033c773a1ec6 Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Wed, 7 Feb 2024 16:57:47 +0000 Subject: [PATCH] [ui] Styling the bookmarks page --- .eslintrc.json | 1 + bun.lockb | Bin 241872 -> 260504 bytes web/app/bookmarks/components/AddLink.tsx | 15 +- web/app/bookmarks/components/LinkCard.tsx | 74 ++++++-- web/app/bookmarks/components/LinksGrid.tsx | 2 +- web/components/ui/button.tsx | 56 ++++++ web/components/ui/card.tsx | 79 ++++++++ web/components/ui/dropdown-menu.tsx | 200 +++++++++++++++++++++ web/components/ui/imageCard.tsx | 56 ++++++ web/components/ui/input.tsx | 25 +++ web/package.json | 2 + 11 files changed, 490 insertions(+), 20 deletions(-) create mode 100644 web/components/ui/button.tsx create mode 100644 web/components/ui/card.tsx create mode 100644 web/components/ui/dropdown-menu.tsx create mode 100644 web/components/ui/imageCard.tsx create mode 100644 web/components/ui/input.tsx diff --git a/.eslintrc.json b/.eslintrc.json index 26977516..38293435 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -13,6 +13,7 @@ "no-redeclare": "off", "@next/next/no-html-link-for-pages": "off", "no-undef": "off", + "react/jsx-no-undef": "off", "no-unused-vars": [ "error", { diff --git a/bun.lockb b/bun.lockb index fc5566d0532193a0298f16b4f379a747edccd54f..f4f09e8a2c750c540881e8b8ca6d19dda4cae6d5 100755 GIT binary patch delta 41289 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 { const [_resp, error] = await APIClient.bookmarkLink(link); if (error) { + // TODO: Proper error handling alert(error.message); return; } @@ -18,8 +22,8 @@ export default function AddLink() { }; return ( -
- + - +
); } diff --git a/web/app/bookmarks/components/LinkCard.tsx b/web/app/bookmarks/components/LinkCard.tsx index 103f97ef..75973f7e 100644 --- a/web/app/bookmarks/components/LinkCard.tsx +++ b/web/app/bookmarks/components/LinkCard.tsx @@ -1,19 +1,67 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { + ImageCard, + ImageCardBody, + ImageCardFooter, + ImageCardTitle, +} from "@/components/ui/imageCard"; import { ZBookmarkedLink } from "@/lib/types/api/links"; +import { MoreHorizontal, Trash2 } from "lucide-react"; import Link from "next/link"; -export default async function LinkCard({ link }: { link: ZBookmarkedLink }) { +export function LinkOptions() { + // TODO: Implement deletion + return ( + + + + + + + + Delete + + + + ); +} + +export default function LinkCard({ link }: { link: ZBookmarkedLink }) { + const parsedUrl = new URL(link.url); + return ( - -
-

- {link.details?.favicon && ( - // eslint-disable-next-line @next/next/no-img-element - - )} - {link.details?.title ?? link.id} -

-

{link.details?.description ?? link.url}

-
- + + + + {link.details?.title ?? parsedUrl.host} + + + + +
+
+ + {parsedUrl.host} + +
+ +
+
+
); } diff --git a/web/app/bookmarks/components/LinksGrid.tsx b/web/app/bookmarks/components/LinksGrid.tsx index 83aaca80..4b82df98 100644 --- a/web/app/bookmarks/components/LinksGrid.tsx +++ b/web/app/bookmarks/components/LinksGrid.tsx @@ -12,7 +12,7 @@ export default async function LinksGrid() { const links = await getLinks(session.user.id); return ( -
+
{links.map((l) => ( ))} diff --git a/web/components/ui/button.tsx b/web/components/ui/button.tsx new file mode 100644 index 00000000..0ba42773 --- /dev/null +++ b/web/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/web/components/ui/card.tsx b/web/components/ui/card.tsx new file mode 100644 index 00000000..afa13ecf --- /dev/null +++ b/web/components/ui/card.tsx @@ -0,0 +1,79 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/web/components/ui/dropdown-menu.tsx b/web/components/ui/dropdown-menu.tsx new file mode 100644 index 00000000..f69a0d64 --- /dev/null +++ b/web/components/ui/dropdown-menu.tsx @@ -0,0 +1,200 @@ +"use client" + +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/lib/utils" + +const DropdownMenu = DropdownMenuPrimitive.Root + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger + +const DropdownMenuGroup = DropdownMenuPrimitive.Group + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal + +const DropdownMenuSub = DropdownMenuPrimitive.Sub + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +DropdownMenuShortcut.displayName = "DropdownMenuShortcut" + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +} diff --git a/web/components/ui/imageCard.tsx b/web/components/ui/imageCard.tsx new file mode 100644 index 00000000..1394ae08 --- /dev/null +++ b/web/components/ui/imageCard.tsx @@ -0,0 +1,56 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +export function ImageCard({ + children, + image, + className, + ...props +}: React.HTMLAttributes & { image?: string }) { + return ( +
+
+
{children}
+
+ ); +} + +export function ImageCardTitle({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
+ ); +} + +export function ImageCardBody({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
+ ); +} + +export function ImageCardFooter({ + className, + ...props +}: React.HTMLAttributes) { + return
; +} diff --git a/web/components/ui/input.tsx b/web/components/ui/input.tsx new file mode 100644 index 00000000..677d05fd --- /dev/null +++ b/web/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/web/package.json b/web/package.json index 6a043a77..09249bab 100644 --- a/web/package.json +++ b/web/package.json @@ -12,6 +12,8 @@ "dependencies": { "@next-auth/prisma-adapter": "^1.0.7", "@next/eslint-plugin-next": "^14.1.0", + "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-slot": "^1.0.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "install": "^0.13.0",