import { useParams, Link } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Helmet } from 'react-helmet-async'; import { CheckCircle, XCircle, MinusCircle, ArrowRight, Swords, Trophy, ExternalLink } from 'lucide-react'; import AdSlot from '@/components/layout/AdSlot'; import { getComparisonPage, getComparisonPagesByTool, type ComparisonFeature } from '@/config/comparisonData'; import { getToolSEO } from '@/config/seoData'; import { getSiteOrigin, buildSocialImageUrl, getOgLocale, generateWebPage, generateFAQ } from '@/utils/seo'; function FeatureIcon({ value }: { value: boolean | 'partial' }) { if (value === true) return ; if (value === 'partial') return ; return ; } function FeatureLabel({ value }: { value: boolean | 'partial' }) { if (value === true) return Yes; if (value === 'partial') return Partial; return No; } export default function ComparisonPage() { const { slug } = useParams<{ slug: string }>(); const { t, i18n } = useTranslation(); const comparison = slug ? getComparisonPage(slug) : undefined; if (!comparison) { return (

{t('pages.comparison.notFound')}

{t('pages.comparison.browseTools')}
); } const ourTool = getToolSEO(comparison.ourToolSlug); const origin = getSiteOrigin(typeof window !== 'undefined' ? window.location.origin : ''); const canonicalUrl = `${origin}/compare/${comparison.slug}`; const socialImageUrl = buildSocialImageUrl(origin); const currentOgLocale = getOgLocale(i18n.language); const prefix = `pages.comparison.${comparison.i18nKey}`; const title = t(`${prefix}.title`); const metaDescription = t(`${prefix}.metaDescription`); const faqItems = t(`${prefix}.faqs`, { returnObjects: true }) as Array<{ q: string; a: string }>; const faqs = Array.isArray(faqItems) ? faqItems : []; const webPageSchema = generateWebPage({ name: title, description: metaDescription, url: canonicalUrl, }); const faqSchema = faqs.length > 0 ? generateFAQ(faqs.map((f) => ({ question: f.q, answer: f.a }))) : null; // Related comparisons const relatedComparisons = comparison.relatedComparisonSlugs .map((s) => getComparisonPage(s)) .filter(Boolean); // Related tools const relatedTools = comparison.relatedToolSlugs .map((s) => getToolSEO(s)) .filter(Boolean); return ( <> {title} | {t('common.appName')} {faqSchema && ( )}
{/* Hero */}
{t('pages.comparison.badge')}

{t(`${prefix}.heading`)}

{t(`${prefix}.subtitle`)}

{/* Feature Comparison Table */}

{t('pages.comparison.featureComparison')}

{/* Table header */}
{t('pages.comparison.feature')}
{t('common.appName')}
{comparison.competitorName}
{/* Feature rows */} {comparison.features.map((feature: ComparisonFeature, idx: number) => (
{t(`pages.comparison.features.${feature.key}`)}
))}
{/* Our Advantages */}

{t(`${prefix}.advantagesTitle`)}

{(() => { const advantages = t(`${prefix}.advantages`, { returnObjects: true }) as string[]; return Array.isArray(advantages) ? (
    {advantages.map((adv, idx) => (
  • {adv}
  • ))}
) : null; })()}
{/* Verdict */}

{t('pages.comparison.verdictTitle')}

{t(`${prefix}.verdict`)}

{/* CTA */}
{ourTool ? t(`tools.${ourTool.i18nKey}.title`) : comparison.ourToolSlug}

{t('pages.comparison.ctaSubtext')}

{/* FAQ */} {faqs.length > 0 && (

{t('pages.comparison.faqTitle')}

{faqs.map((faq, idx) => (
{faq.q}

{faq.a}

))}
)} {/* Related Comparisons */} {relatedComparisons.length > 0 && (

{t('pages.comparison.relatedComparisons')}

{relatedComparisons.map((comp) => ( {t(`pages.comparison.${comp!.i18nKey}.heading`)} ))}
)} {/* Related Tools */} {relatedTools.length > 0 && (

{t('pages.comparison.relatedTools')}

{relatedTools.map((tool) => (

{t(`tools.${tool!.i18nKey}.title`)}

{t(`tools.${tool!.i18nKey}.shortDesc`)}

))}
)}
); }