All files / components/common AppDialog.tsx

100% Statements 1/1
100% Branches 4/4
100% Functions 1/1
100% Lines 1/1

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68                                                                              3450x                                                        
import * as React from 'react';
import { cn } from '@/lib/utils';
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
    DialogDescription,
    DialogFooter,
} from '@/components/ui/dialog';
 
interface AppDialogProps {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    title: React.ReactNode;
    description?: React.ReactNode;
    children: React.ReactNode;
    footer?: React.ReactNode;
    /** Override max-width, e.g. "sm:max-w-xl" or "max-w-4xl". Defaults to "sm:max-w-lg". */
    className?: string;
    /** Override default body padding and scroll behavior. Defaults to "px-6 py-4 overflow-y-auto". */
    bodyClassName?: string;
}
 
/**
 * Shared dialog shell used by all CRUD/form dialogs.
 * Provides a consistent layout: fixed header, scrollable body, fixed footer.
 * Matches the add/update provider dialog pattern.
 */
export function AppDialog({
    open,
    onOpenChange,
    title,
    description,
    children,
    footer,
    className,
    bodyClassName,
}: AppDialogProps) {
    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent
                className={cn(
                    'p-0 overflow-hidden flex flex-col max-h-[90vh] sm:max-w-lg',
                    className
                )}
            >
                <DialogHeader className="p-6 pb-0">
                    <DialogTitle>{title}</DialogTitle>
                    {description && (
                        <DialogDescription>{description}</DialogDescription>
                    )}
                </DialogHeader>
 
                <div className={cn("flex-1 overflow-y-auto px-6 py-4 min-h-0", bodyClassName)}>
                    {children}
                </div>
 
                {footer && (
                    <DialogFooter className="px-6 pb-6 pt-4 border-t">
                        {footer}
                    </DialogFooter>
                )}
            </DialogContent>
        </Dialog>
    );
}