import React, { useState, useCallback } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { File, Image, Loader2, CheckCircle, XCircle, AlertTriangle } from 'lucide-react'; import { cn } from '@/lib/utils'; import { motion } from 'framer-motion'; // Supported conversion formats (can be extended) const supportedFormats = [ { value: 'jpeg', label: 'JPEG' }, { value: 'png', label: 'PNG' }, { value: 'webp', label: 'WebP' }, { value: 'gif', label: 'GIF' }, { value: 'bmp', label: 'BMP' }, { value: 'tiff', label: 'TIFF' }, { value: 'raw', label: 'RAW' }, // Added RAW { value: 'svg', label: 'SVG' }, // Added SVG { value: 'ico', label: 'ICO' }, // Added ICO ]; // Animation variants const containerVariants = { hidden: { opacity: 0 }, visible: { opacity: 1, transition: { staggerChildren: 0.2, // Stagger the appearance of child elements }, }, }; const itemVariants = { hidden: { y: 20, opacity: 0 }, visible: { y: 0, opacity: 1 }, }; const ImageConverterApp = () => { const [imageFile, setImageFile] = useState(null); const [selectedFormat, setSelectedFormat] = useState('jpeg'); const [convertedImage, setConvertedImage] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); // Function to handle file selection const handleFileChange = useCallback((e: React.ChangeEvent ) => { const file = e.target.files?.[0]; if (file) { // Basic file type validation (client-side) if (!file.type.startsWith('image/')) { setError('Invalid file type. Please select an image.'); setImageFile(null); setConvertedImage(null); setSuccess(false); return; } // Limit file size to 5MB (client-side) if (file.size > 5 * 1024 * 1024) { setError('File size exceeds 5MB limit.'); setImageFile(null); setConvertedImage(null); setSuccess(false); return; } setImageFile(file); setError(null); // Clear any previous error setConvertedImage(null); // Clear previous conversion setSuccess(false); } }, []); // Function to handle format selection const handleFormatChange = useCallback((value: string) => { setSelectedFormat(value); setConvertedImage(null); // Clear previous conversion on format change setSuccess(false); }, []); // Function to handle image conversion const handleConvert = useCallback(async () => { if (!imageFile) { setError('Please select an image to convert.'); return; } setLoading(true); setError(null); setSuccess(false); setConvertedImage(null); // Clear any previous result const formData = new FormData(); formData.append('image', imageFile); formData.append('format', selectedFormat); try { // Simulate an API call (replace with your actual backend endpoint) const response = await fetch('/api/convert', { // Replace '/api/convert' method: 'POST', body: formData, }); if (!response.ok) { // Handle HTTP errors (e.g., 400, 500) let errorMessage = 'Conversion failed.'; if (response.status === 400) { errorMessage = 'Invalid image format or file.'; } else if (response.status === 413) { errorMessage = 'File size too large. Maximum is 5MB.'; } else if (response.status === 500) { errorMessage = 'Server error. Please try again later.'; } throw new Error(errorMessage); } const blob = await response.blob(); const reader = new FileReader(); reader.onloadend = () => { const base64data = reader.result as string; setConvertedImage(base64data); setLoading(false); setSuccess(true); }; reader.onerror = () => { setError('Error reading converted image data.'); setLoading(false); }; reader.readAsDataURL(blob); } catch (err: any) { setError(err.message || 'An error occurred during conversion.'); setLoading(false); setSuccess(false); } }, [imageFile, selectedFormat]); // Function to handle image download const handleDownload = useCallback(() => { if (!convertedImage) return; const link = document.createElement('a'); link.href = convertedImage; const formatExtension = selectedFormat === 'jpeg' ? 'jpg' : selectedFormat; // .jpeg is not a valid extension link.download = `converted_image.${formatExtension}`; document.body.appendChild(link); link.click(); document.body.removeChild(link); }, [convertedImage, selectedFormat]); return (

Image Converter

Select an image to convert (max 5MB).

{/* Display result (success or error) */} {(success || error) && ( {success ? ( <>

Conversion successful!

{convertedImage && ( )}
) : ( <>

Error:

{error}

)}
)}
{/* Display preview of original and converted images */} {(imageFile || convertedImage) && (

Preview

{/* Original Image Preview */} {imageFile && (

Original Image

Original
)} {/* Converted Image Preview */} {convertedImage && (

Converted Image

Converted
)}
)}
); }; export default ImageConverterApp;