--- import { getLocaleFromUrl, loadTranslations } from '../utils/i18n'; const { softwareList } = Astro.props; const locale = getLocaleFromUrl(Astro.url); const t = await loadTranslations(locale); // Get all unique platforms from the software list const allPlatforms = new Set(); softwareList.forEach(software => { software.platforms?.forEach(platform => allPlatforms.add(platform)); }); const platforms = Array.from(allPlatforms).sort(); // Get all unique features from the software list const allFeatures = new Set(); softwareList.forEach(software => { software.features?.forEach(feature => allFeatures.add(feature)); }); const features = Array.from(allFeatures).sort(); // Get all metric types const metrics = [ { id: 'easeOfUse', name: t.voting.usability }, { id: 'featureRichness', name: t.voting.features }, { id: 'valueForMoney', name: t.voting.value }, { id: 'support', name: t.voting.support }, { id: 'reliability', name: t.voting.reliability }, ]; ---
{softwareList.map(software => ( ))} {softwareList.map(software => ( ))} {softwareList.map(software => ( ))} {softwareList.map(software => ( ))} {['Free', 'Paid', 'Subscription'].map(pricingModel => ( {softwareList.map(software => { const plan = software.pricing?.find(p => p.model.toLowerCase().includes(pricingModel.toLowerCase())); return ( ); })} ))} {softwareList.map(software => { const metrics = software.metrics || {}; const metricKeys = Object.keys(metrics); let averageRating = 0; let totalVotes = 0; if (metricKeys.length > 0) { let totalRating = 0; metricKeys.forEach(key => { totalRating += metrics[key].average || 0; totalVotes += metrics[key].count || 0; }); averageRating = totalRating / metricKeys.length; } return ( ); })} {metrics.map(metric => ( {softwareList.map(software => { const metricData = software.metrics?.[metric.id] || { average: 0, count: 0 }; const rating = metricData.average || 0; const voteCount = metricData.count || 0; return ( ); })} ))} {features.map(feature => ( {softwareList.map(software => { const hasFeature = software.features?.some(f => f === feature || f.includes(feature)); return ( ); })} ))} {platforms.map(platform => ( {softwareList.map(software => { const supportsPlatform = software.platforms?.includes(platform); return ( ); })} ))}
Features
{software.logo && (
{software.name}
)} {software.name}
General Information
Description

{software.description}

Website Visit site
Categories
{software.categories?.map(category => ( {category} ))}
Pricing
{pricingModel} Plan {plan ? (
{plan.price}
    {plan.features?.slice(0, 3).map(feature => (
  • {feature}
  • ))} {plan.features?.length > 3 && (
  • +{plan.features.length - 3} more
  • )}
) : ( )}
Ratings
Average Rating
{averageRating.toFixed(1)}
{totalVotes > 0 && (
Based on {totalVotes} ratings
)}
{metric.name}
{rating.toFixed(1)}/5 {voteCount} votes
Features
{feature} {hasFeature ? ( ) : ( )}
Platforms
{platform} {supportsPlatform ? ( ) : ( )}