import { CalendarBlank as CalendarIcon, Check, X } from '@phosphor-icons/react' import { useState } from 'react' import { Button } from '@/components/ui/button' import { Calendar } from '@/components/ui/calendar' import { Input } from '@/components/ui/input' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { type PropertyDisplayMode, formatDateValue, toISODate, } from '../utils/propertyTypes' import { StatusPill, StatusDropdown } from './StatusDropdown' import { DISPLAY_MODE_OPTIONS, DISPLAY_MODE_ICONS } from '../utils/propertyTypes' import { translate, type AppLocale } from '../lib/i18n' import { useDateDisplayFormat } from '../hooks/useAppPreferences' function parseDateValue(value: string): Date | undefined { const iso = toISODate(value) const d = new Date(iso + 'T00:00:00') return isNaN(d.getTime()) ? undefined : d } function dateToISO(day: Date): string { const yyyy = day.getFullYear() const mm = String(day.getMonth() + 1).padStart(2, '0') const dd = String(day.getDate()).padStart(2, '0') return `${yyyy}-${mm}-${dd}` } const ADD_INPUT_CLASS = "h-[26px] min-w-[60px] flex-1 rounded border border-border bg-muted px-1.5 text-[12px] text-foreground outline-none focus:border-primary" function isValidNumberValue(value: string): boolean { const trimmed = value.trim() if (trimmed === '') return false return Number.isFinite(Number(trimmed)) } function canSubmitProperty({ key, value, displayMode }: { key: string; value: string; displayMode: PropertyDisplayMode }): boolean { if (!key.trim()) return false return displayMode !== 'number' || isValidNumberValue(value) } function AddBooleanInput({ value, locale, onChange }: { value: string; locale: AppLocale; onChange: (v: string) => void }) { const boolVal = value.toLowerCase() === 'true' return ( ) } function AddDateInput({ value, locale, onChange, }: { value: string locale: AppLocale onChange: (v: string) => void }) { const dateDisplayFormat = useDateDisplayFormat() const selectedDate = value ? parseDateValue(value) : undefined const formatted = value ? formatDateValue(value, dateDisplayFormat) : '' return ( { if (day) onChange(dateToISO(day)) }} defaultMonth={selectedDate} /> ) } function AddStatusInput({ value, onChange, vaultStatuses }: { value: string; onChange: (v: string) => void; vaultStatuses: string[] }) { const [showDropdown, setShowDropdown] = useState(false) return ( {showDropdown && ( { onChange(v); setShowDropdown(false) }} onCancel={() => setShowDropdown(false)} /> )} ) } function AddNumberInput({ value, onChange, onKeyDown }: { value: string onChange: (v: string) => void onKeyDown: (e: React.KeyboardEvent) => void }) { return ( onChange(event.target.value)} onKeyDown={onKeyDown} data-testid="add-property-number-input" /> ) } function AddPropertyValueInput({ displayMode, value, onChange, onKeyDown, vaultStatuses, locale }: { displayMode: PropertyDisplayMode; value: string; onChange: (v: string) => void onKeyDown: (e: React.KeyboardEvent) => void; vaultStatuses: string[] locale: AppLocale }) { switch (displayMode) { case 'number': return case 'boolean': return case 'date': return case 'status': return case 'tags': return ( onChange(e.target.value)} onKeyDown={onKeyDown} /> ) default: return ( onChange(e.target.value)} onKeyDown={onKeyDown} /> ) } } export function AddPropertyForm({ onAdd, onCancel, vaultStatuses, locale = 'en' }: { onAdd: (key: string, value: string, displayMode: PropertyDisplayMode) => void; onCancel: () => void vaultStatuses: string[] locale?: AppLocale }) { const [newKey, setNewKey] = useState('') const [newValue, setNewValue] = useState('') const [displayMode, setDisplayMode] = useState('text') const canSubmit = canSubmitProperty({ key: newKey, value: newValue, displayMode }) const handleModeChange = (mode: PropertyDisplayMode) => { setDisplayMode(mode) if (mode === 'boolean') setNewValue('false') else if (mode !== displayMode) setNewValue('') } const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && canSubmit) onAdd(newKey, newValue, displayMode) else if (e.key === 'Escape') onCancel() } return (
setNewKey(e.target.value)} onKeyDown={handleKeyDown} autoFocus />
) }