import { useEffect, useId, type ReactNode } from 'react' import { useBlocker } from 'react-router' import { Button } from '../ui/Button.tsx' import { Sheet } from '../ui/Sheet.tsx' import styles from './LeaveGuard.module.css' // LeaveGuard asks before leaving the screen with unsaved changes. export function LeaveGuard({ dirty }: { dirty: boolean }) { const blocker = useBlocker( ({ currentLocation, nextLocation }) => dirty && currentLocation.pathname !== nextLocation.pathname, ) useEffect(() => { if (!dirty) return const onBeforeUnload = (event: BeforeUnloadEvent) => event.preventDefault() window.addEventListener('beforeunload', onBeforeUnload) return () => window.removeEventListener('beforeunload', onBeforeUnload) }, [dirty]) return ( blocker.reset?.()} onConfirm={() => blocker.proceed?.()} > Your changes on this screen have not been saved. ) } type ConfirmProps = { open: boolean title: string children: ReactNode confirmLabel: string cancelLabel?: string busy?: boolean error?: string | null onCancel: () => void onConfirm: () => void } // Confirm is a sheet asking the household to confirm one action. export function Confirm({ open, title, children, confirmLabel, cancelLabel = 'Cancel', busy = false, error = null, onCancel, onConfirm, }: ConfirmProps) { const titleId = useId() return (

{title}

{children}

{error !== null && (

{error}

)}
) }