N-FIN-47: introduce reusable server action trigger component
This commit is contained in:
parent
c64c5fed35
commit
410d96a8b8
1 changed files with 53 additions and 0 deletions
53
src/components/form/serverActionTrigger.tsx
Normal file
53
src/components/form/serverActionTrigger.tsx
Normal file
|
@ -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<T = any>
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||
VariantProps<typeof buttonVariants> {
|
||||
asChild?: boolean;
|
||||
action: () => Promise<ActionResponse<T>>;
|
||||
callback?: (data: T) => void;
|
||||
}
|
||||
|
||||
const ServerActionTrigger = React.forwardRef<HTMLButtonElement, ButtonWithActionProps>(
|
||||
({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 (
|
||||
<Comp
|
||||
className={cn(buttonVariants({variant, size, className}))}
|
||||
ref={ref}
|
||||
{...{...props, action: undefined, callback: undefined}}
|
||||
onClick={handleSubmit}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
ServerActionTrigger.displayName = 'ServerActionTrigger';
|
||||
|
||||
export { ServerActionTrigger };
|
Loading…
Add table
Reference in a new issue