All files / components/records DeleteRecordDialog.tsx

100% Statements 11/11
100% Branches 8/8
100% Functions 4/4
100% Lines 11/11

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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                                                                132x   132x 4x 4x 4x 4x   4x         132x     58x                             132x                               1x                                                                        
/**
 * Delete record dialog component
 * Confirmation dialog for deleting a record
 */
 
import { useState } from 'react';
import { AppDialog } from '@/components/common/AppDialog';
import { Button } from '@/components/ui/button';
import { AlertTriangle } from 'lucide-react';
import type { FieldDefinition } from '@/services/collections.service';
import type { RecordData } from '@/types/records.types';
import { formatFieldValue } from '@/lib/form-helpers';
 
interface DeleteRecordDialogProps {
	open: boolean;
	onOpenChange: (open: boolean) => void;
	onConfirm: (recordId: string) => Promise<void>;
	schema: FieldDefinition[];
	collectionName: string;
	record: RecordData | null;
	recordId: string;
}
 
export default function DeleteRecordDialog({
	open,
	onOpenChange,
	onConfirm,
	schema,
	collectionName,
	record,
	recordId,
}: DeleteRecordDialogProps) {
	const [isDeleting, setIsDeleting] = useState(false);
 
	const handleConfirm = async () => {
		setIsDeleting(true);
		try {
			await onConfirm(recordId);
			onOpenChange(false);
		} finally {
			setIsDeleting(false);
		}
	};
 
	// Get a summary of the record (first few fields)
	const recordSummary = record ? (
		<div className="space-y-1">
			{schema.slice(0, 4).map((field) => (
				<div key={field.name} className="text-sm">
					<span className="text-muted-foreground">{field.name}:</span>{' '}
					<span className="font-medium">
						{formatFieldValue(record[field.name], field.type)}
					</span>
				</div>
			))}
			{schema.length > 4 && (
				<div className="text-sm text-muted-foreground italic">
					...and {schema.length - 4} more fields
				</div>
			)}
		</div>
	) : null;
 
	return (
		<AppDialog
			open={open}
			onOpenChange={onOpenChange}
			title="Delete Record"
			description={
				<>
					Are you sure you want to delete this record from{' '}
					<strong>{collectionName}</strong>? This action cannot be undone.
				</>
			}
			footer={
				<>
					<Button
						type="button"
						variant="outline"
						onClick={() => onOpenChange(false)}
						disabled={isDeleting}
					>
						Cancel
					</Button>
					<Button variant="destructive" onClick={handleConfirm} disabled={isDeleting}>
						{isDeleting ? 'Deleting...' : 'Delete Record'}
					</Button>
				</>
			}
		>
			<div className="space-y-4">
				<div className="flex items-start gap-3 bg-amber-50 dark:bg-amber-950/20 border border-amber-200 dark:border-amber-900 rounded-lg p-4">
					<AlertTriangle className="h-5 w-5 text-amber-600 dark:text-amber-500 flex-shrink-0 mt-0.5" />
					<div className="text-sm text-amber-900 dark:text-amber-200">
						<strong>Warning:</strong> Deleting this record will permanently remove it from the
						database. If other records reference this record, they may be affected depending
						on the cascade delete settings.
					</div>
				</div>
 
				{recordSummary && (
					<div className="bg-muted rounded-lg p-4">
						<p className="text-xs text-muted-foreground mb-2 uppercase font-semibold">
							Record to delete:
						</p>
						{recordSummary}
						<div className="mt-2 text-xs text-muted-foreground font-mono">
							ID: {recordId.slice(0, 16)}...
						</div>
					</div>
				)}
			</div>
		</AppDialog>
	);
}