'use client'; import { useState, useEffect, useCallback } from 'react'; import { ArrowLeftRight, BarChart3, Grid3X3, Copy } from 'lucide-react'; import { toast } from 'sonner'; import SearchUnits from './SearchUnits'; import VisualComparison from './VisualComparison'; import { getAllMeasures, getUnitsForMeasure, convertToAll, convertUnit, formatMeasureName, type Measure, type ConversionResult, } from '@/lib/units/units'; import { parseNumberInput, formatNumber, cn } from '@/lib/utils'; import { MobileTabs } from '@/components/ui/mobile-tabs'; type Tab = 'category' | 'convert'; export default function MainConverter() { const [selectedMeasure, setSelectedMeasure] = useState('length'); const [selectedUnit, setSelectedUnit] = useState('m'); const [targetUnit, setTargetUnit] = useState('ft'); const [inputValue, setInputValue] = useState('1'); const [conversions, setConversions] = useState([]); const [showChart, setShowChart] = useState(false); const [tab, setTab] = useState('category'); const measures = getAllMeasures(); const units = getUnitsForMeasure(selectedMeasure); useEffect(() => { const numValue = parseNumberInput(inputValue); if (numValue !== null && selectedUnit) { setConversions(convertToAll(numValue, selectedUnit)); } else { setConversions([]); } }, [inputValue, selectedUnit]); useEffect(() => { const availableUnits = getUnitsForMeasure(selectedMeasure); if (availableUnits.length > 0) { setSelectedUnit(availableUnits[0]); setTargetUnit(availableUnits[1] ?? availableUnits[0]); } }, [selectedMeasure]); const handleSwapUnits = useCallback(() => { const numValue = parseNumberInput(inputValue); if (numValue !== null) { setInputValue(convertUnit(numValue, selectedUnit, targetUnit).toString()); } setSelectedUnit(targetUnit); setTargetUnit(selectedUnit); }, [selectedUnit, targetUnit, inputValue]); const handleSearchSelect = useCallback((unit: string, measure: Measure) => { setSelectedMeasure(measure); setSelectedUnit(unit); setTab('convert'); }, []); const handleCategorySelect = useCallback((measure: Measure) => { setSelectedMeasure(measure); setTab('convert'); }, []); const handleValueChange = useCallback( (value: number, unit: string, _dragging: boolean) => { setInputValue(convertUnit(value, unit, selectedUnit).toString()); }, [selectedUnit] ); const resultValue = (() => { const n = parseNumberInput(inputValue); return n !== null ? convertUnit(n, selectedUnit, targetUnit) : null; })(); return (
setTab(v as Tab)} /> {/* ── Main layout ────────────────────────────────────────── */}
{/* Left panel: search + categories */}
{/* Search */}
Search
{/* Category list */}
Categories {measures.length}
{measures.map((measure) => { const isSelected = selectedMeasure === measure; const unitCount = getUnitsForMeasure(measure).length; return ( ); })}
{/* Right panel: converter + results */}
{/* Converter card */}
Convert {formatMeasureName(selectedMeasure)} {/* Input row */}
{/* Value input */} setInputValue(e.target.value)} placeholder="0" className="w-full bg-transparent border border-border/40 rounded-lg px-3 py-2.5 text-base font-mono outline-none focus:border-primary/50 transition-colors placeholder:text-muted-foreground/30 tabular-nums" /> {/* Unit selectors + swap */}
{/* From unit */} {/* Swap */} {/* To unit */}
{/* Result display */} {resultValue !== null && (
Result
{formatNumber(resultValue)} {targetUnit}
)}
{/* All conversions */}
All Conversions {/* Grid / Chart toggle */}
{showChart ? ( ) : (
{conversions.map((conversion) => { const isTarget = targetUnit === conversion.unit; return ( ); })}
)}
); }