Show endcustomer event allowance on dashboard

This commit is contained in:
Codex Agent
2026-01-16 14:17:27 +01:00
parent ada69133a6
commit e8ea663da8
4 changed files with 39 additions and 17 deletions

View File

@@ -2187,6 +2187,9 @@
"limitDays": "Galerietage", "limitDays": "Galerietage",
"limitsTitle": "Limits", "limitsTitle": "Limits",
"remaining": "Verbleibende Events", "remaining": "Verbleibende Events",
"eventAllowance": "Event-Kontingent",
"eventPerPurchase": "1 Event pro Kauf",
"eventPerPurchaseShort": "Pro Kauf",
"purchased": "Gekauft", "purchased": "Gekauft",
"expires": "Läuft ab", "expires": "Läuft ab",
"unlimited": "Unbegrenzt", "unlimited": "Unbegrenzt",

View File

@@ -2191,6 +2191,9 @@
"limitDays": "Gallery days", "limitDays": "Gallery days",
"limitsTitle": "Limits", "limitsTitle": "Limits",
"remaining": "Remaining events", "remaining": "Remaining events",
"eventAllowance": "Event allowance",
"eventPerPurchase": "1 event per purchase",
"eventPerPurchaseShort": "Per purchase",
"purchased": "Purchased", "purchased": "Purchased",
"expires": "Expires", "expires": "Expires",
"unlimited": "Unlimited", "unlimited": "Unlimited",

View File

@@ -168,8 +168,8 @@ export default function MobileDashboardPage() {
const activePackage = const activePackage =
packagesOverview?.activePackage ?? packagesOverview?.packages?.find((pkg) => pkg.active) ?? null; packagesOverview?.activePackage ?? packagesOverview?.packages?.find((pkg) => pkg.active) ?? null;
const remainingEvents = activePackage?.remaining_events ?? null;
const isResellerPackage = activePackage?.package_type === 'reseller'; const isResellerPackage = activePackage?.package_type === 'reseller';
const remainingEvents = isResellerPackage ? (activePackage?.remaining_events ?? null) : null;
const summarySeenPackageId = const summarySeenPackageId =
summarySeenOverride ?? onboardingStatus?.steps?.summary_seen_package_id ?? null; summarySeenOverride ?? onboardingStatus?.steps?.summary_seen_package_id ?? null;
const hasSummaryPackage = const hasSummaryPackage =
@@ -586,10 +586,17 @@ function PackageSummarySheet({
</Text> </Text>
</YStack> </YStack>
<YStack space="$2" marginTop="$2"> <YStack space="$2" marginTop="$2">
<SummaryRow {packageType === 'reseller' ? (
label={t('mobileDashboard.packageSummary.remaining', 'Remaining events')} <SummaryRow
value={formatPackageLimit(remainingEvents, t)} label={t('mobileDashboard.packageSummary.remaining', 'Remaining events')}
/> value={formatPackageLimit(remainingEvents, t)}
/>
) : (
<SummaryRow
label={t('mobileDashboard.packageSummary.eventAllowance', 'Event allowance')}
value={t('mobileDashboard.packageSummary.eventPerPurchase', '1 event per purchase')}
/>
)}
<SummaryRow label={t('mobileDashboard.packageSummary.purchased', 'Purchased')} value={formatDate(purchasedAt)} /> <SummaryRow label={t('mobileDashboard.packageSummary.purchased', 'Purchased')} value={formatDate(purchasedAt)} />
{expiresAt ? ( {expiresAt ? (
<SummaryRow label={t('mobileDashboard.packageSummary.expires', 'Expires')} value={formatDate(expiresAt)} /> <SummaryRow label={t('mobileDashboard.packageSummary.expires', 'Expires')} value={formatDate(expiresAt)} />
@@ -672,19 +679,28 @@ function PackageSummaryBanner({
const { textStrong, muted, border, surface, accentSoft, primary, surfaceMuted, shadow } = useAdminTheme(); const { textStrong, muted, border, surface, accentSoft, primary, surfaceMuted, shadow } = useAdminTheme();
const text = textStrong; const text = textStrong;
const packageName = activePackage.package_name ?? t('mobileDashboard.packageSummary.fallbackTitle', 'Package summary'); const packageName = activePackage.package_name ?? t('mobileDashboard.packageSummary.fallbackTitle', 'Package summary');
const remainingEvents = typeof activePackage.remaining_events === 'number' ? activePackage.remaining_events : null; const remainingEvents =
activePackage.package_type === 'reseller' && typeof activePackage.remaining_events === 'number'
? activePackage.remaining_events
: null;
const hasLimit = remainingEvents !== null; const hasLimit = remainingEvents !== null;
const totalEvents = hasLimit ? activePackage.used_events + remainingEvents : null; const totalEvents = hasLimit ? activePackage.used_events + remainingEvents : null;
const showProgress = hasLimit && (totalEvents ?? 0) > 0; const showProgress = hasLimit && (totalEvents ?? 0) > 0;
const usageLabel = hasLimit const usageLabel =
? t('mobileDashboard.packageSummary.bannerUsage', '{{used}} of {{total}} events used', { activePackage.package_type === 'reseller'
used: activePackage.used_events, ? hasLimit
total: totalEvents ?? 0, ? t('mobileDashboard.packageSummary.bannerUsage', '{{used}} of {{total}} events used', {
}) used: activePackage.used_events,
: t('mobileDashboard.packageSummary.bannerUnlimited', 'Unlimited events'); total: totalEvents ?? 0,
const remainingLabel = hasLimit })
? t('mobileDashboard.packageSummary.bannerRemaining', '{{count}} remaining', { count: remainingEvents }) : t('mobileDashboard.packageSummary.bannerUnlimited', 'Unlimited events')
: t('mobileDashboard.packageSummary.bannerRemainingUnlimited', 'No limit'); : t('mobileDashboard.packageSummary.eventPerPurchase', '1 event per purchase');
const remainingLabel =
activePackage.package_type === 'reseller'
? hasLimit
? t('mobileDashboard.packageSummary.bannerRemaining', '{{count}} remaining', { count: remainingEvents })
: t('mobileDashboard.packageSummary.bannerRemainingUnlimited', 'No limit')
: t('mobileDashboard.packageSummary.eventPerPurchaseShort', 'Per purchase');
const progressMax = totalEvents ?? 0; const progressMax = totalEvents ?? 0;
const progressValue = Math.min(activePackage.used_events, progressMax); const progressValue = Math.min(activePackage.used_events, progressMax);

View File

@@ -20,7 +20,7 @@ const fixtures = vi.hoisted(() => ({
id: 1, id: 1,
package_id: 1, package_id: 1,
package_name: 'Standard', package_name: 'Standard',
package_type: 'standard', package_type: 'reseller',
included_package_slug: null, included_package_slug: null,
active: true, active: true,
used_events: 2, used_events: 2,
@@ -240,7 +240,7 @@ describe('MobileDashboardPage', () => {
eventContext.hasEvents = true; eventContext.hasEvents = true;
eventContext.hasMultipleEvents = false; eventContext.hasMultipleEvents = false;
fixtures.activePackage.package_type = 'standard'; fixtures.activePackage.package_type = 'reseller';
fixtures.activePackage.remaining_events = 3; fixtures.activePackage.remaining_events = 3;
navigateMock.mockClear(); navigateMock.mockClear();
}); });