import { useEffect, useRef, useState } from 'react' import { Button, type ButtonProps } from '@pikku/mantine/core' import { m } from '@/i18n/messages' import { useLocale } from '@/i18n/config' import { type I18nString, type I18nNode } from '@pikku/react' /** * A button that requires two clicks to fire, guarding against accidental * state transitions. The first click "arms" it — the label swaps to a * confirm prompt and the colour goes red; the second click commits and * disarms. If left untouched it auto-reverts after `resetMs`. * * Disarming happens synchronously on the confirming click (not on mutation * success), so a failed mutation leaves a normal, retryable button — the * caller's `loading` prop drives the in-flight visual. */ type ConfirmButtonProps = ButtonProps & { onConfirm: () => void /** Label shown in the armed state. Defaults to the localized "Confirm?". */ confirmLabel?: I18nString /** Colour while armed. */ confirmColor?: string /** Auto-revert delay in ms. */ resetMs?: number children?: I18nNode 'data-testid'?: string } export function ConfirmButton({ onConfirm, confirmLabel, confirmColor = 'red', resetMs = 3000, color, variant, children, 'data-testid': testId, ...rest }: ConfirmButtonProps) { useLocale() const [armed, setArmed] = useState(false) const timer = useRef | undefined>(undefined) useEffect(() => () => clearTimeout(timer.current), []) const handleClick = () => { if (armed) { clearTimeout(timer.current) setArmed(false) onConfirm() return } setArmed(true) timer.current = setTimeout(() => setArmed(false), resetMs) } return ( ) }