'use client'; import { useState, useEffect, useCallback } from 'react'; import { ArrowLeftRight, BarChart3, Grid3X3 } from 'lucide-react'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; 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'; type Tab = 'category' | 'convert'; const CATEGORY_ICONS: Partial> = { length: '📏', mass: '⚖️', temperature: '🌡️', speed: '⚡', time: '⏱️', area: '⬛', volume: '🧊', digital: '💾', energy: '⚡', pressure: '🔵', power: '🔆', frequency: '〰️', angle: '📐', current: '⚡', voltage: '🔌', }; 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 (
{/* ── Mobile tab switcher ────────────────────────────────── */}
{(['category', 'convert'] as Tab[]).map((t) => ( ))}
{/* ── 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="flex-1 min-w-0 bg-transparent border border-border/40 rounded-lg px-3 py-2 text-sm font-mono outline-none focus:border-primary/50 transition-colors placeholder:text-muted-foreground/30 tabular-nums" /> {/* 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 ( ); })}
)}
); }