94 lines
3.1 KiB
TypeScript
94 lines
3.1 KiB
TypeScript
import { Form } from '@inertiajs/react';
|
|
import { Save, X } from 'lucide-react';
|
|
import type { ReactNode } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@/components/ui/dialog';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
type FormDialogProps = {
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
title: string;
|
|
action: React.ComponentProps<typeof Form>['action'];
|
|
resetOnSuccess?: boolean;
|
|
onSuccess?: () => void;
|
|
submitDisabled?: boolean;
|
|
submitLabel?: ReactNode;
|
|
submittingLabel?: ReactNode;
|
|
contentClassName?: string;
|
|
children:
|
|
| ReactNode
|
|
| ((ctx: {
|
|
errors: Record<string, string>;
|
|
processing: boolean;
|
|
}) => ReactNode);
|
|
};
|
|
|
|
export function FormDialog({
|
|
open,
|
|
onOpenChange,
|
|
title,
|
|
action,
|
|
resetOnSuccess,
|
|
onSuccess,
|
|
submitDisabled = false,
|
|
submitLabel = 'Simpan',
|
|
submittingLabel = 'Menyimpan...',
|
|
contentClassName,
|
|
children,
|
|
}: FormDialogProps) {
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent
|
|
className={cn(
|
|
'flex max-h-[85vh] flex-col overflow-hidden',
|
|
contentClassName,
|
|
)}
|
|
>
|
|
<Form
|
|
action={action}
|
|
resetOnSuccess={resetOnSuccess}
|
|
onSuccess={onSuccess}
|
|
className="flex min-h-0 flex-1 flex-col"
|
|
>
|
|
{({ errors, processing }) => (
|
|
<>
|
|
<DialogHeader className="shrink-0">
|
|
<DialogTitle>{title}</DialogTitle>
|
|
</DialogHeader>
|
|
<div className="grid flex-1 gap-4 overflow-y-auto py-4">
|
|
{typeof children === 'function'
|
|
? children({ errors, processing })
|
|
: children}
|
|
</div>
|
|
<DialogFooter className="shrink-0">
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
onClick={() => onOpenChange(false)}
|
|
>
|
|
<X className="h-4 w-4" />
|
|
Batal
|
|
</Button>
|
|
<Button
|
|
type="submit"
|
|
disabled={processing || submitDisabled}
|
|
>
|
|
<Save className="h-4 w-4" />
|
|
{processing ? submittingLabel : submitLabel}
|
|
</Button>
|
|
</DialogFooter>
|
|
</>
|
|
)}
|
|
</Form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|