import { useState, useEffect, useRef } from 'react' import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Textarea } from '@/components/ui/textarea' import { formatShortcutDisplay } from '../hooks/appCommandCatalog' import type { CommitMode } from '../hooks/useCommitFlow' type CommitDialogCopy = { title: string description: string actionLabel: string shortcutHint: string } function getDialogCopy(commitMode: CommitMode): CommitDialogCopy { const submitShortcut = formatShortcutDisplay({ display: '⌘↵' }) if (commitMode === 'local') { return { title: 'Commit', description: 'This vault has no git remote configured. Tolaria will create a local commit only.', actionLabel: 'Commit', shortcutHint: `${submitShortcut} to commit locally`, } } return { title: 'Commit & Push', description: 'Review changed files and enter a commit message before committing and pushing.', actionLabel: 'Commit & Push', shortcutHint: `${submitShortcut} to commit`, } } function changedFilesLabel(modifiedCount: number): string { return `${modifiedCount} file${modifiedCount !== 1 ? 's' : ''} changed` } function isSubmitShortcut(event: React.KeyboardEvent): boolean { return event.key === 'Enter' && (event.metaKey || event.ctrlKey) } function isCloseShortcut(event: React.KeyboardEvent): boolean { return event.key === 'Escape' } interface CommitDialogProps { open: boolean modifiedCount: number commitMode?: CommitMode suggestedMessage?: string onCommit: (message: string) => void onClose: () => void } export function CommitDialog({ open, modifiedCount, commitMode = 'push', suggestedMessage, onCommit, onClose, }: CommitDialogProps) { const [message, setMessage] = useState('') const inputRef = useRef(null) const copy = getDialogCopy(commitMode) useEffect(() => { if (open) { setMessage(suggestedMessage ?? '') // eslint-disable-line react-hooks/set-state-in-effect -- reset on dialog open setTimeout(() => inputRef.current?.focus(), 50) } }, [open]) // eslint-disable-line react-hooks/exhaustive-deps -- only reset when dialog opens const handleSubmit = () => { const trimmed = message.trim() if (!trimmed) return onCommit(trimmed) } const handleKeyDown = (e: React.KeyboardEvent) => { if (isSubmitShortcut(e)) { e.preventDefault() handleSubmit() } else if (isCloseShortcut(e)) { onClose() } } return ( { if (!isOpen) onClose() }}>
{copy.title} {changedFilesLabel(modifiedCount)}
{copy.description}