Skip to content

Commit

Permalink
Add alert-dialog, update PostCard
Browse files Browse the repository at this point in the history
and PostEditorForm components, and add
PostDeleteDialog component
  • Loading branch information
thebkht committed Nov 6, 2023
1 parent d05a0d4 commit f6235c1
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 26 deletions.
12 changes: 8 additions & 4 deletions components/blog/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { handlePostSave } from "../bookmark";
import { useEffect, useState } from "react";
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "../ui/dropdown-menu";
import Link from "next/link";
import PostDeleteDialog from "./post-delete-dialog";

export default function PostTabs({ post: initialPost, className, session, author, comments }: { post: any, className?: string, session: any, author: any, comments: boolean | undefined }) {
const [post, setPost] = useState<any>(initialPost);
Expand All @@ -26,6 +27,7 @@ export default function PostTabs({ post: initialPost, className, session, author
const [open, setOpen] = useState(comments);
const isLiked = post?.likes?.some((like: any) => like.authorId === session?.id);
const isSaved = post?.savedUsers?.some((savedUser: any) => savedUser.userId === session?.id);
const [showDeleteAlert, setShowDeleteAlert] = useState<boolean>(false)
return (
<>
<div className={cn("px-2 py-1 border-y flex justify-between w-full bg-background", className)}>
Expand Down Expand Up @@ -71,16 +73,18 @@ export default function PostTabs({ post: initialPost, className, session, author
<span>Edit</span>
</Link>
</DropdownMenuItem>
<DropdownMenuItem>
<Trash2 className="mr-2 h-4 w-4" />
<span>Delete</span>
</DropdownMenuItem>
<DropdownMenuItem className="flex cursor-pointer items-center text-destructive focus:text-destructive"
onSelect={() => setShowDeleteAlert(true)} >
<Trash2 className="mr-2 h-4 w-4" />
<span>Delete</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}
</div>
</div>
<PostDeleteDialog post={post} user={session} open={showDeleteAlert} onOpenChange={setShowDeleteAlert} />
</>
)
}
40 changes: 24 additions & 16 deletions components/blog/post-delete-dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import { useRouter } from "next/navigation";
import { handleDelete } from "../delete";
import { Button } from "../ui/button";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, DialogClose, DialogFooter } from "../ui/dialog";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,

} from "@/components/ui/alert-dialog"
import { Trash2 } from "lucide-react";


export default function PostDeleteDialog({ post, user, children, ...props }: React.ComponentPropsWithoutRef<typeof Dialog> & { post: any, user: any }) {
export default function PostDeleteDialog({ post, user, ...props }: React.ComponentPropsWithoutRef<typeof AlertDialog> & { post: any, user: any }) {
const router = useRouter()
return (
<Dialog>
<DialogTrigger>
{children}
</DialogTrigger>
<DialogContent className="flex flex-col justify-center md:w-72">
<AlertDialog {...props}>
<AlertDialogContent className="flex flex-col justify-center !w-72 !rounded-lg">
<div className="flex h-20 w-20 items-center justify-center rounded-full bg-muted mx-auto">
<Trash2 className={"h-10 w-10"} strokeWidth={1.25} />
</div>
Expand All @@ -22,19 +30,19 @@ export default function PostDeleteDialog({ post, user, children, ...props }: Rea
Are you sure you want to delete this post? This action cannot be undone.
</p>
</div>
<DialogFooter className="!flex-row">
<DialogClose asChild>
<Button className="m-auto" size={"lg"} variant="outline">Cancel</Button>
</DialogClose>
<Button onClick={
<AlertDialogFooter className="!flex-row !justify-center space-x-2">
<AlertDialogCancel className="mt-0">
Cancel
</AlertDialogCancel>
<AlertDialogAction onClick={
async () => {
handleDelete(post?.id, user)
await fetch(`/api/revalidate?path=/${user?.username}`)
router.push(`/${user?.username}`)
}
} className="m-auto" size={"lg"} variant="destructive">Delete</Button>
</DialogFooter>
</DialogContent>
</Dialog>
} className="bg-red-600 focus:ring-red-600">Delete</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}
14 changes: 12 additions & 2 deletions components/blog/post-more-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,20 @@ import {
LinkedinShareButton
} from 'next-share'
import { Icons } from "../icon";
import React from "react";
import { handleDelete } from "../delete";
import { useRouter } from "next/navigation";
import PostDeleteDialog from "./post-delete-dialog";

export default function PostMoreActions({ post, session, className, children, ...props }: React.ComponentPropsWithoutRef<typeof DropdownMenu> & { post: any, session: any, className?: string }) {
const copylink = (link: string) => {
navigator.clipboard.writeText(link)
}
const router = useRouter()
const [showDeleteAlert, setShowDeleteAlert] = React.useState<boolean>(false)
return (
<DropdownMenu>
<>
<DropdownMenu>
<DropdownMenuTrigger asChild>
{children}
</DropdownMenuTrigger>
Expand All @@ -50,7 +57,8 @@ export default function PostMoreActions({ post, session, className, children, ..
<span>Edit</span>
</Link>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownMenuItem className="flex cursor-pointer items-center text-destructive focus:text-destructive"
onSelect={() => setShowDeleteAlert(true)} >
<Trash2 className="mr-2 h-4 w-4" />
<span>Delete</span>
</DropdownMenuItem>
Expand Down Expand Up @@ -95,5 +103,7 @@ export default function PostMoreActions({ post, session, className, children, ..
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
<PostDeleteDialog post={post} user={session} open={showDeleteAlert} onOpenChange={setShowDeleteAlert} />
</>
)
}
6 changes: 3 additions & 3 deletions components/editor/post-editor-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ export function PostEditorForm(props: { post: any, user: any }) {

// when value changes, wait 750ms than save it as a draft
const [lastSavedTime, setLastSavedTime] = useState<number>(Date.now());
const [showDeleteAlert, setShowDeleteAlert] = React.useState<boolean>(false)
useEffect(() => {
setIsSaving(true);
const timeout = setTimeout(saveDraft, 15000);
Expand Down Expand Up @@ -575,9 +576,8 @@ export function PostEditorForm(props: { post: any, user: any }) {
</DialogContent>
</Dialog>

<PostDeleteDialog post={props.post} user={props.user}>
<Button size={"icon"} variant={"outline"} className="!mt-3" disabled={isSaving}>{isSaving ? <Icons.spinner className="h-[1.2rem] w-[1.2rem] animate-spin" /> : <Trash2 className="h-[1.2rem] w-[1.2rem]" />}</Button>
</PostDeleteDialog>
<Button size={"icon"} variant={"outline"} className="!mt-3" disabled={isSaving} onClick={() => setShowDeleteAlert(true)}>{isSaving ? <Icons.spinner className="h-[1.2rem] w-[1.2rem] animate-spin" /> : <Trash2 className="h-[1.2rem] w-[1.2rem]" />}</Button>
<PostDeleteDialog post={props.post} user={props.user} open={showDeleteAlert} onOpenChange={setShowDeleteAlert}/>


<Button size={"icon"} variant={"secondary"} onClick={
Expand Down
2 changes: 1 addition & 1 deletion components/tags/post-card-v2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function PostCard(
}
{
props.user && (
props.session.id === props.post.author?.id && (
props.session?.id === props.post.author?.id && (
<Badge variant={"outline"} className="text-xs font-normal capitalize mr-1">
{props.post.visibility}
</Badge>
Expand Down
141 changes: 141 additions & 0 deletions components/ui/alert-dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
"use client"

import * as React from "react"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"

import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"

const AlertDialog = AlertDialogPrimitive.Root

const AlertDialogTrigger = AlertDialogPrimitive.Trigger

const AlertDialogPortal = AlertDialogPrimitive.Portal

const AlertDialogOverlay = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<AlertDialogPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
ref={ref}
/>
))
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName

const AlertDialogContent = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
>(({ className, ...props }, ref) => (
<AlertDialogPortal>
<AlertDialogOverlay />
<AlertDialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full",
className
)}
{...props}
/>
</AlertDialogPortal>
))
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName

const AlertDialogHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
)
AlertDialogHeader.displayName = "AlertDialogHeader"

const AlertDialogFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
AlertDialogFooter.displayName = "AlertDialogFooter"

const AlertDialogTitle = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<AlertDialogPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold", className)}
{...props}
/>
))
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName

const AlertDialogDescription = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
>(({ className, ...props }, ref) => (
<AlertDialogPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
AlertDialogDescription.displayName =
AlertDialogPrimitive.Description.displayName

const AlertDialogAction = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Action>,
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
>(({ className, ...props }, ref) => (
<AlertDialogPrimitive.Action
ref={ref}
className={cn(buttonVariants(), className)}
{...props}
/>
))
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName

const AlertDialogCancel = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
>(({ className, ...props }, ref) => (
<AlertDialogPrimitive.Cancel
ref={ref}
className={cn(
buttonVariants({ variant: "outline" }),
"mt-2 sm:mt-0",
className
)}
{...props}
/>
))
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName

export {
AlertDialog,
AlertDialogPortal,
AlertDialogOverlay,
AlertDialogTrigger,
AlertDialogContent,
AlertDialogHeader,
AlertDialogFooter,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogAction,
AlertDialogCancel,
}
29 changes: 29 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@hookform/resolvers": "^3.3.1",
"@prisma/client": "^5.5.2",
"@prisma/extension-accelerate": "^0.6.2",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-aspect-ratio": "^1.0.3",
"@radix-ui/react-avatar": "^1.0.3",
"@radix-ui/react-checkbox": "^1.0.4",
Expand Down

0 comments on commit f6235c1

Please sign in to comment.