/** * @license * SPDX-License-Identifier: Apache-2.0 */ import React, { useState, useEffect, useRef } from 'react'; import { FileText, Image as ImageIcon, Type, Settings, Menu, X, ChevronDown, ChevronRight, Merge, Scissors, Zap, FileCode, FileSpreadsheet, FileVideo, FileAudio, RotateCw, Lock, Unlock, Hash, Stamp, QrCode, Key, Calculator, Pipette, RefreshCw, Code, Mic, Volume2, Timer, Download, Upload, Search, Github, Twitter, Linkedin, Facebook, Heart } from 'lucide-react'; import { motion, AnimatePresence } from 'motion/react'; // --- Types --- interface Tool { id: string; title: string; description: string; icon: React.ReactNode; category: 'pdf' | 'image' | 'text' | 'utility'; } // --- Constants --- const TOOLS: Tool[] = [ // PDF Tools { id: 'merge-pdf', title: 'Merge PDF', description: 'Combine multiple PDFs into one document.', icon: , category: 'pdf' }, { id: 'split-pdf', title: 'Split PDF', description: 'Extract pages or split a PDF into multiple files.', icon: , category: 'pdf' }, { id: 'compress-pdf', title: 'Compress PDF', description: 'Reduce PDF file size while maintaining quality.', icon: , category: 'pdf' }, { id: 'pdf-to-word', title: 'PDF to Word', description: 'Convert PDF documents to editable Word files.', icon: , category: 'pdf' }, { id: 'word-to-pdf', title: 'Word to PDF', description: 'Convert Word documents to high-quality PDFs.', icon: , category: 'pdf' }, { id: 'pdf-to-pp', title: 'PDF to PowerPoint', description: 'Convert PDF slides to PowerPoint presentations.', icon: , category: 'pdf' }, { id: 'pp-to-pdf', title: 'PowerPoint to PDF', description: 'Convert PowerPoint slides to PDF format.', icon: , category: 'pdf' }, { id: 'pdf-to-excel', title: 'PDF to Excel', description: 'Extract data from PDF tables to Excel sheets.', icon: , category: 'pdf' }, { id: 'excel-to-pdf', title: 'Excel to PDF', description: 'Convert Excel spreadsheets to PDF documents.', icon: , category: 'pdf' }, { id: 'pdf-to-jpg', title: 'PDF to JPG', description: 'Convert PDF pages into high-quality JPG images.', icon: , category: 'pdf' }, { id: 'jpg-to-pdf', title: 'JPG to PDF', description: 'Convert JPG images into a single PDF file.', icon: , category: 'pdf' }, { id: 'organize-pdf', title: 'Organize PDF', description: 'Reorder, rotate, or remove pages from your PDF.', icon: , category: 'pdf' }, { id: 'edit-pdf', title: 'Edit PDF', description: 'Add text, images, or shapes to your PDF document.', icon: , category: 'pdf' }, { id: 'rotate-pdf', title: 'Rotate PDF', description: 'Rotate PDF pages to portrait or landscape.', icon: , category: 'pdf' }, { id: 'unlock-pdf', title: 'Unlock PDF', description: 'Remove passwords and restrictions from PDFs.', icon: , category: 'pdf' }, { id: 'protect-pdf', title: 'Protect PDF', description: 'Add a password and encrypt your PDF files.', icon: , category: 'pdf' }, { id: 'page-numbers', title: 'Add Page Numbers', description: 'Insert page numbers into your PDF easily.', icon: , category: 'pdf' }, { id: 'watermark', title: 'Add Watermark', description: 'Add text or image watermarks to your PDF.', icon: , category: 'pdf' }, // Image Tools { id: 'img-compress', title: 'Image Compressor', description: 'Reduce image file size without losing quality.', icon: , category: 'image' }, { id: 'img-convert', title: 'Image Converter', description: 'Convert between JPG, PNG, and WEBP formats.', icon: , category: 'image' }, // Utility Tools { id: 'qr-gen', title: 'QR Code Generator', description: 'Create custom QR codes for URLs or text.', icon: , category: 'utility' }, { id: 'pass-gen', title: 'Password Generator', description: 'Generate secure, random passwords.', icon: , category: 'utility' }, { id: 'word-counter', title: 'Word Counter', description: 'Count words and characters in your text.', icon: , category: 'utility' }, { id: 'age-calc', title: 'Age Calculator', description: 'Calculate exact age between two dates.', icon: , category: 'utility' }, { id: 'bmi-calc', title: 'BMI Calculator', description: 'Calculate your Body Mass Index.', icon: , category: 'utility' }, { id: 'color-picker', title: 'Color Picker', description: 'Pick colors and get HEX/RGB values.', icon: , category: 'utility' }, { id: 'unit-conv', title: 'Unit Converter', description: 'Convert between various measurement units.', icon: , category: 'utility' }, { id: 'json-fmt', title: 'JSON Formatter', description: 'Prettify or minify your JSON data.', icon: , category: 'utility' }, { id: 'tts', title: 'Text to Speech', description: 'Convert written text into natural speech.', icon: , category: 'utility' }, { id: 'stt', title: 'Speech to Text', description: 'Transcribe your voice into text.', icon: , category: 'utility' }, { id: 'timer', title: 'Timer / Stopwatch', description: 'Track time with a futuristic stopwatch.', icon: , category: 'utility' }, { id: 'vid-compress', title: 'Video Compressor', description: 'Simulated video compression tool.', icon: , category: 'utility' }, { id: 'aud-convert', title: 'Audio Converter', description: 'Convert between audio formats.', icon: , category: 'utility' }, ]; // --- Components --- const Navbar: React.FC<{ toggleSidebar: () => void }> = ({ toggleSidebar }) => ( ); const Sidebar: React.FC<{ isOpen: boolean, onClose: () => void, activeCategory: string, setActiveCategory: (cat: string) => void }> = ({ isOpen, onClose, activeCategory, setActiveCategory }) => { const categories = [ { id: 'all', label: 'All Tools', icon: }, { id: 'pdf', label: 'PDF Tools', icon: }, { id: 'image', label: 'Image Tools', icon: }, { id: 'utility', label: 'Utility Tools', icon: }, ]; return ( <> {isOpen && ( )} ); }; const ToolCard: React.FC<{ tool: Tool, onClick: () => void }> = ({ tool, onClick }) => (
{tool.icon}

{tool.title}

{tool.description}

); const ToolModal: React.FC<{ tool: Tool, onClose: () => void }> = ({ tool, onClose }) => { const [status, setStatus] = useState<'idle' | 'uploading' | 'processing' | 'done'>('idle'); const [progress, setProgress] = useState(0); const [files, setFiles] = useState([]); const [result, setResult] = useState(null); const fileInputRef = useRef (null); // Tool-specific states const [textInput, setTextInput] = useState(''); const [password, setPassword] = useState(''); const [bmi, setBmi] = useState<{ weight: string, height: string, result: string | null }>({ weight: '', height: '', result: null }); const [age, setAge] = useState<{ birthDate: string, result: string | null }>({ birthDate: '', result: null }); const [jsonInput, setJsonInput] = useState(''); const [unit, setUnit] = useState({ value: '', from: 'cm', to: 'inch', result: '' }); const [timer, setTimer] = useState({ time: 0, isActive: false }); const [isListening, setIsListening] = useState(false); const timerRef = useRef(null); useEffect(() => { if (timer.isActive) { timerRef.current = setInterval(() => { setTimer(prev => ({ ...prev, time: prev.time + 1 })); }, 1000); } else { if (timerRef.current) clearInterval(timerRef.current); } return () => { if (timerRef.current) clearInterval(timerRef.current); }; }, [timer.isActive]); const handleFileChange = (e: React.ChangeEvent) => { if (e.target.files) { setFiles(Array.from(e.target.files)); } }; const simulateProcess = async () => { if (files.length === 0 && !['pass-gen', 'age-calc', 'bmi-calc', 'json-fmt', 'tts', 'timer', 'color-picker'].includes(tool.id)) return; setStatus('uploading'); let p = 0; const interval = setInterval(() => { p += 10; setProgress(p); if (p >= 100) { clearInterval(interval); setStatus('processing'); setTimeout(() => { setStatus('done'); // For real tools, we'd set the result here if (tool.category === 'pdf' || tool.category === 'image') { setResult('download_ready'); } }, 1500); } }, 100); }; const generatePassword = () => { const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+"; let retVal = ""; for (let i = 0; i < 16; ++i) { retVal += charset.charAt(Math.floor(Math.random() * charset.length)); } setPassword(retVal); }; const calculateBMI = () => { const w = parseFloat(bmi.weight); const h = parseFloat(bmi.height) / 100; if (w > 0 && h > 0) { const res = (w / (h * h)).toFixed(2); setBmi(prev => ({ ...prev, result: res })); } }; const calculateAge = () => { if (!age.birthDate) return; const birth = new Date(age.birthDate); const now = new Date(); let years = now.getFullYear() - birth.getFullYear(); const m = now.getMonth() - birth.getMonth(); if (m < 0 || (m === 0 && now.getDate() < birth.getDate())) { years--; } setAge(prev => ({ ...prev, result: years.toString() })); }; const formatJSON = () => { try { const obj = JSON.parse(jsonInput); setJsonInput(JSON.stringify(obj, null, 2)); } catch (e) { alert("Invalid JSON"); } }; const convertUnits = () => { const val = parseFloat(unit.value); if (isNaN(val)) return; let res = 0; if (unit.from === 'cm' && unit.to === 'inch') res = val / 2.54; if (unit.from === 'inch' && unit.to === 'cm') res = val * 2.54; if (unit.from === 'kg' && unit.to === 'lb') res = val * 2.20462; if (unit.from === 'lb' && unit.to === 'kg') res = val / 2.20462; setUnit(prev => ({ ...prev, result: res.toFixed(2) })); }; const processImage = async () => { if (files.length === 0) return; setStatus('processing'); const file = files[0]; const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.onload = () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = img.width; canvas.height = img.height; ctx?.drawImage(img, 0, 0); let mime = 'image/jpeg'; if (tool.id === 'img-convert') { // Simple toggle for demo mime = file.type === 'image/png' ? 'image/jpeg' : 'image/png'; } const dataUrl = canvas.toDataURL(mime, 0.7); setResult(dataUrl); setStatus('done'); }; img.src = e.target?.result as string; }; reader.readAsDataURL(file); }; const speakText = () => { if (!textInput) return; const utterance = new SpeechSynthesisUtterance(textInput); window.speechSynthesis.speak(utterance); }; const startListening = () => { const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition; if (!SpeechRecognition) { alert("Speech recognition not supported in this browser."); return; } const recognition = new SpeechRecognition(); recognition.onstart = () => setIsListening(true); recognition.onend = () => setIsListening(false); recognition.onresult = (event: any) => { const transcript = event.results[0][0].transcript; setTextInput(prev => prev + " " + transcript); }; recognition.start(); }; const renderToolUI = () => { switch (tool.id) { case 'qr-gen': return (
setTextInput(e.target.value)} /> {textInput && (
QR Code
)}
); case 'pass-gen': return (

{password || "••••••••••••••••"}

); case 'bmi-calc': return (
setBmi(prev => ({ ...prev, weight: e.target.value }))} /> setBmi(prev => ({ ...prev, height: e.target.value }))} />
{bmi.result &&
BMI: {bmi.result}
}
); case 'age-calc': return (
setAge(prev => ({ ...prev, birthDate: e.target.value }))} /> {age.result &&
Age: {age.result} Years
}
); case 'json-fmt': return (