Expand package limit and feature details
This commit is contained in:
@@ -21,6 +21,12 @@ import { ADMIN_EVENT_VIEW_PATH, adminPath } from '../constants';
|
||||
import { buildPackageUsageMetrics, PackageUsageMetric, usagePercent } from './billingUsage';
|
||||
import { useBackNavigation } from './hooks/useBackNavigation';
|
||||
import { useAdminTheme } from './theme';
|
||||
import {
|
||||
collectPackageFeatures,
|
||||
formatEventUsage,
|
||||
getPackageFeatureLabel,
|
||||
getPackageLimitEntries,
|
||||
} from './lib/packageSummary';
|
||||
|
||||
export default function MobileBillingPage() {
|
||||
const { t } = useTranslation('management');
|
||||
@@ -254,9 +260,17 @@ export default function MobileBillingPage() {
|
||||
function PackageCard({ pkg, label, isActive = false }: { pkg: TenantPackageSummary; label?: string; isActive?: boolean }) {
|
||||
const { t } = useTranslation('management');
|
||||
const { border, primary, accentSoft, textStrong, muted } = useAdminTheme();
|
||||
const remaining = pkg.remaining_events ?? (pkg.package_limits?.max_events_per_year as number | undefined) ?? 0;
|
||||
const limits = (pkg.package_limits ?? null) as Record<string, unknown> | null;
|
||||
const remaining = pkg.remaining_events ?? (limits?.max_events_per_year as number | undefined) ?? 0;
|
||||
const expires = pkg.expires_at ? formatDate(pkg.expires_at) : null;
|
||||
const usageMetrics = buildPackageUsageMetrics(pkg);
|
||||
const limitEntries = getPackageLimitEntries(limits, t);
|
||||
const featureKeys = collectPackageFeatures(pkg);
|
||||
const eventUsageText = formatEventUsage(
|
||||
typeof pkg.used_events === 'number' ? pkg.used_events : null,
|
||||
typeof limits?.max_events_per_year === 'number' ? (limits?.max_events_per_year as number) : null,
|
||||
t
|
||||
);
|
||||
return (
|
||||
<MobileCard
|
||||
borderColor={isActive ? primary : border}
|
||||
@@ -285,6 +299,43 @@ function PackageCard({ pkg, label, isActive = false }: { pkg: TenantPackageSumma
|
||||
{renderFeatureBadge(pkg, t, 'branding_allowed', t('billing.features.branding', 'Branding'))}
|
||||
{renderFeatureBadge(pkg, t, 'watermark_allowed', t('billing.features.watermark', 'Watermark'))}
|
||||
</XStack>
|
||||
{eventUsageText ? (
|
||||
<Text fontSize="$xs" color={muted}>
|
||||
{eventUsageText}
|
||||
</Text>
|
||||
) : null}
|
||||
{limitEntries.length ? (
|
||||
<YStack space="$1.5" marginTop="$2">
|
||||
<Text fontSize="$xs" color={muted}>
|
||||
{t('mobileBilling.details.limitsTitle', 'Limits')}
|
||||
</Text>
|
||||
{limitEntries.map((entry) => (
|
||||
<XStack key={entry.key} alignItems="center" justifyContent="space-between">
|
||||
<Text fontSize="$xs" color={muted}>
|
||||
{entry.label}
|
||||
</Text>
|
||||
<Text fontSize="$xs" color={textStrong} fontWeight="700">
|
||||
{entry.value}
|
||||
</Text>
|
||||
</XStack>
|
||||
))}
|
||||
</YStack>
|
||||
) : null}
|
||||
{featureKeys.length ? (
|
||||
<YStack space="$1.5" marginTop="$2">
|
||||
<Text fontSize="$xs" color={muted}>
|
||||
{t('mobileBilling.details.featuresTitle', 'Features')}
|
||||
</Text>
|
||||
{featureKeys.map((feature) => (
|
||||
<XStack key={feature} alignItems="center" space="$2">
|
||||
<Sparkles size={14} color={primary} />
|
||||
<Text fontSize="$xs" color={textStrong}>
|
||||
{getPackageFeatureLabel(feature, t)}
|
||||
</Text>
|
||||
</XStack>
|
||||
))}
|
||||
</YStack>
|
||||
) : null}
|
||||
{usageMetrics.length ? (
|
||||
<YStack space="$2" marginTop="$2">
|
||||
{usageMetrics.map((metric) => (
|
||||
|
||||
Reference in New Issue
Block a user