feat: implement Phase 2 - Core conversion engine and UI
Complete Phase 2 implementation with working unit converter: Core Conversion Engine (lib/units.ts): - Type-safe wrapper for convert-units library - Support for all 23 measures with TypeScript types - getAllMeasures() - Get all available categories - getUnitsForMeasure() - Get units for specific measure - getUnitInfo() - Get detailed unit information - convertUnit() - Convert between two units - convertToAll() - Convert to all compatible units - getCategoryColor() - Get Tailwind color class for measure - formatMeasureName() - Format measure names for display - searchUnits() - Fuzzy search across all units Utility Functions (lib/utils.ts): - cn() - Merge Tailwind classes with clsx and tailwind-merge - formatNumber() - Smart number formatting with scientific notation - debounce() - Debounce helper for inputs - parseNumberInput() - Parse user input to number - getRelativeTime() - Format timestamps UI Components: - Input - Styled input with focus states - Button - 6 variants (default, destructive, outline, secondary, ghost, link) - Card - Card container with header, title, description, content, footer Main Converter Component (components/converter/MainConverter.tsx): - Real-time conversion as user types - Category selection with 23 color-coded buttons - Input field with unit selector - Grid display of all conversions in selected measure - Color-coded result cards with category colors - Responsive layout (1/2/3 column grid) Homepage Updates: - Integrated MainConverter component - Clean header with gradient text - Uses design system colors Dependencies Added: - clsx - Class name utilities - tailwind-merge - Merge Tailwind classes intelligently Features Working: ✓ Select from 23 measurement categories ✓ Real-time conversion to all compatible units ✓ Color-coded categories ✓ Formatted number display ✓ Responsive design 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
78
components/ui/card.tsx
Normal file
78
components/ui/card.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import * as React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const Card = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'rounded-lg border bg-card text-card-foreground shadow-sm',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
Card.displayName = 'Card';
|
||||
|
||||
const CardHeader = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn('flex flex-col space-y-1.5 p-6', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CardHeader.displayName = 'CardHeader';
|
||||
|
||||
const CardTitle = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
React.HTMLAttributes<HTMLHeadingElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<h3
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'text-2xl font-semibold leading-none tracking-tight',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CardTitle.displayName = 'CardTitle';
|
||||
|
||||
const CardDescription = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
React.HTMLAttributes<HTMLParagraphElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<p
|
||||
ref={ref}
|
||||
className={cn('text-sm text-muted-foreground', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CardDescription.displayName = 'CardDescription';
|
||||
|
||||
const CardContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn('p-6 pt-0', className)} {...props} />
|
||||
));
|
||||
CardContent.displayName = 'CardContent';
|
||||
|
||||
const CardFooter = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn('flex items-center p-6 pt-0', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CardFooter.displayName = 'CardFooter';
|
||||
|
||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
|
||||
Reference in New Issue
Block a user