diff --git a/src/components/form/serverActionTrigger.tsx b/src/components/form/serverActionTrigger.tsx new file mode 100644 index 0000000..ce5b431 --- /dev/null +++ b/src/components/form/serverActionTrigger.tsx @@ -0,0 +1,53 @@ +'use client'; + +import { buttonVariants } from '@/components/ui/button'; +import React from 'react'; +import { Slot } from '@radix-ui/react-slot'; +import { cn } from '@/lib/utils'; +import { useRouter } from 'next/navigation'; +import { toast } from 'sonner'; +import { sonnerContent } from '@/components/ui/sonner'; +import type { VariantProps } from 'class-variance-authority'; +import { ActionResponse } from '@/lib/types/actionResponse'; + +export interface ButtonWithActionProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; + action: () => Promise>; + callback?: (data: T) => void; +} + +const ServerActionTrigger = React.forwardRef( + ({className, variant, size, asChild = false, ...props}, ref) => { + + const router = useRouter(); + + const Comp = asChild ? Slot : 'button'; + + const handleSubmit = async () => { + const response = await props.action(); + toast(sonnerContent(response)); + if (props.callback) { + props.callback(response); + } + if (response.redirect) { + router.push(response.redirect); + } + }; + + // TODO: add optional confirmation dialog + + return ( + + ); + }, +); +ServerActionTrigger.displayName = 'ServerActionTrigger'; + +export { ServerActionTrigger };