in frontend/src/components/landing/PlanMatrix.tsx [619:692]
monthly_price: getBundlePrice(props.runtimeData, l10n),
})}
</h2>
)}
{isPeriodicalPremiumAvailableInCountry(props.runtimeData) && (
<p className={styles["bundle-offer-content"]}>
{l10n.getString("plan-matrix-offer-body", { savings: "40%" })}
</p>
)}
<section id="pricing" className={styles["table-wrapper"]}>
{desktopView}
{mobileView}
</section>
</div>
);
};
type DesktopFeatureProps = {
feature: keyof FeatureList;
runtimeData?: RuntimeData;
};
const DesktopFeature = (props: DesktopFeatureProps) => {
return (
<tr>
<Localized
id={`plan-matrix-feature-${props.feature}`}
elems={{
"vpn-logo": <VpnWordmark />,
}}
>
<th scope="row" />
</Localized>
<td>
<AvailabilityListing availability={freeFeatures[props.feature]} />
</td>
<td>
<AvailabilityListing availability={premiumFeatures[props.feature]} />
</td>
<td>
<AvailabilityListing availability={phoneFeatures[props.feature]} />
</td>
<td>
<AvailabilityListing availability={bundleFeatures[props.feature]} />
</td>
</tr>
);
};
type MobileFeatureListProps = {
list: FeatureList;
};
const MobileFeatureList = (props: MobileFeatureListProps) => {
const l10n = useL10n();
const lis = Object.entries(props.list)
.filter(
([_feature, availability]) =>
typeof availability !== "boolean" || availability,
)
.map(([feature, availability]) => {
const variables =
typeof availability === "number"
? { mask_limit: availability }
: undefined;
const featureDescription =
feature === "email-masks" && availability === Number.POSITIVE_INFINITY
? l10n.getString("plan-matrix-feature-list-email-masks-unlimited")
: l10n.getString(`plan-matrix-feature-mobile-${feature}`, variables);
return (
<li key={feature}>
<Localized
id={`plan-matrix-feature-mobile-${feature}`}
elems={{