import { useDeferredValue } from 'react'; import { useTranslation } from 'react-i18next'; import { useSearchParams } from 'react-router-dom'; import SEOHead from '@/components/seo/SEOHead'; import { generateOrganization, generateWebSite, getSiteOrigin } from '@/utils/seo'; import { FileText, FileOutput, Minimize2, ImageIcon, Film, Hash, Eraser, Layers, Scissors, RotateCw, Image, FileImage, Droplets, Lock, Unlock, ListOrdered, PenLine, GitBranch, Scaling, ScanText, Sheet, ArrowUpDown, QrCode, Code, MessageSquare, Languages, Table, Search, X, Crop, FileDown, Wrench, Presentation, Barcode, } from 'lucide-react'; import ToolCard from '@/components/shared/ToolCard'; import HeroUploadZone from '@/components/shared/HeroUploadZone'; import AdSlot from '@/components/layout/AdSlot'; import SocialProofStrip from '@/components/shared/SocialProofStrip'; import { getHomepageTools, type ToolEntry } from '@/config/toolManifest'; // Map icon names from manifest to lucide components const ICON_MAP: Record> = { FileText, FileOutput, Minimize2, ImageIcon, Film, Hash, Eraser, Layers, Scissors, RotateCw, Image, FileImage, Droplets, Lock, Unlock, ListOrdered, PenLine, GitBranch, Scaling, ScanText, Sheet, ArrowUpDown, QrCode, Code, MessageSquare, Languages, Table, Crop, FileDown, Wrench, Presentation, Barcode, }; function renderToolIcon(tool: ToolEntry) { const IconComponent = ICON_MAP[tool.iconName]; if (!IconComponent) return null; return ; } interface ToolInfo { key: string; path: string; icon: React.ReactNode; bgColor: string; } function manifestToToolInfo(tools: readonly ToolEntry[]): ToolInfo[] { return tools.map((t) => ({ key: t.i18nKey, path: `/tools/${t.slug}`, icon: renderToolIcon(t), bgColor: t.bgColor, })); } const pdfTools: ToolInfo[] = manifestToToolInfo(getHomepageTools('pdf')); const otherTools: ToolInfo[] = manifestToToolInfo(getHomepageTools('other')); export default function HomePage() { const { t } = useTranslation(); const siteOrigin = getSiteOrigin(typeof window !== 'undefined' ? window.location.origin : ''); const [searchParams, setSearchParams] = useSearchParams(); const query = searchParams.get('q') || ''; const deferredQuery = useDeferredValue(query.trim().toLowerCase()); const matchesTool = (tool: ToolInfo) => { if (!deferredQuery) { return true; } const haystack = `${t(`tools.${tool.key}.title`)} ${t(`tools.${tool.key}.shortDesc`)}`.toLowerCase(); return haystack.includes(deferredQuery); }; const filteredPdfTools = pdfTools.filter(matchesTool); const filteredOtherTools = otherTools.filter(matchesTool); const updateQuery = (value: string) => { const nextParams = new URLSearchParams(searchParams); if (value.trim()) { nextParams.set('q', value); } else { nextParams.delete('q'); } setSearchParams(nextParams, { replace: true }); }; return ( <> {/* Hero Section */}

{t('home.hero')}

{t('home.heroSub')}

{/* Smart Upload Zone */}
{/* Ad Slot */}

{t('common.search')}

{t('home.searchToolsPlaceholder')}

{query && ( )}

{t('common.developers')}

{t('pages.developers.ctaTitle')}

{t('pages.developers.ctaSubtitle')}

{/* Tools Grid */}

{t('home.pdfTools')}

{filteredPdfTools.map((tool) => ( ))}

{t('home.otherTools', 'Other Tools')}

{filteredOtherTools.map((tool) => ( ))}
{filteredPdfTools.length + filteredOtherTools.length === 0 && (

{t('home.noSearchResults')}

)}
{/* Features / Why Choose Us */}

{t('home.featuresTitle', 'A smarter way to convert and edit online')}

{t('home.feature1Title', 'One complete workspace')}

{t('home.feature1Desc', 'Edit, convert, compress, merge, split without switching tabs.')}

100%

{t('home.feature2Title', 'Accuracy you can trust')}

{t('home.feature2Desc', 'Get pixel-perfect, editable files in seconds with zero quality loss.')}

{t('home.feature3Title', 'Built-in security')}

{t('home.feature3Desc', 'Access files securely, protected by automatic encryption.')}

{/* Ad Slot - Bottom */} ); }