mirror of
https://codeberg.org/MarkusThielker/finances.git
synced 2025-04-12 05:08:43 +00:00
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