Add package summary banner
This commit is contained in:
27
resources/js/admin/mobile/lib/packageSummary.test.ts
Normal file
27
resources/js/admin/mobile/lib/packageSummary.test.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { formatPackageLimit, getPackageFeatureLabel } from './packageSummary';
|
||||
|
||||
const t = (key: string, options?: Record<string, unknown> | string) => {
|
||||
if (typeof options === 'string') {
|
||||
return options;
|
||||
}
|
||||
return (options?.defaultValue as string | undefined) ?? key;
|
||||
};
|
||||
|
||||
describe('packageSummary helpers', () => {
|
||||
it('returns translated labels for known features', () => {
|
||||
expect(getPackageFeatureLabel('priority_support', t)).toBe('Priority support');
|
||||
});
|
||||
|
||||
it('falls back to raw feature key for unknown features', () => {
|
||||
expect(getPackageFeatureLabel('custom_feature', t)).toBe('custom_feature');
|
||||
});
|
||||
|
||||
it('formats unlimited package limits', () => {
|
||||
expect(formatPackageLimit(null, t)).toBe('Unlimited');
|
||||
});
|
||||
|
||||
it('formats numeric package limits', () => {
|
||||
expect(formatPackageLimit(12, t)).toBe('12');
|
||||
});
|
||||
});
|
||||
65
resources/js/admin/mobile/lib/packageSummary.ts
Normal file
65
resources/js/admin/mobile/lib/packageSummary.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
type Translate = (key: string, options?: Record<string, unknown> | string) => string;
|
||||
|
||||
const FEATURE_LABELS: Record<string, { key: string; fallback: string }> = {
|
||||
priority_support: {
|
||||
key: 'mobileDashboard.packageSummary.feature.priority_support',
|
||||
fallback: 'Priority support',
|
||||
},
|
||||
custom_domain: {
|
||||
key: 'mobileDashboard.packageSummary.feature.custom_domain',
|
||||
fallback: 'Custom domain',
|
||||
},
|
||||
analytics: {
|
||||
key: 'mobileDashboard.packageSummary.feature.analytics',
|
||||
fallback: 'Analytics',
|
||||
},
|
||||
team_management: {
|
||||
key: 'mobileDashboard.packageSummary.feature.team_management',
|
||||
fallback: 'Team management',
|
||||
},
|
||||
moderation_tools: {
|
||||
key: 'mobileDashboard.packageSummary.feature.moderation_tools',
|
||||
fallback: 'Moderation tools',
|
||||
},
|
||||
prints: {
|
||||
key: 'mobileDashboard.packageSummary.feature.prints',
|
||||
fallback: 'Print uploads',
|
||||
},
|
||||
photo_likes_enabled: {
|
||||
key: 'mobileDashboard.packageSummary.feature.photo_likes_enabled',
|
||||
fallback: 'Photo likes',
|
||||
},
|
||||
event_checklist: {
|
||||
key: 'mobileDashboard.packageSummary.feature.event_checklist',
|
||||
fallback: 'Event checklist',
|
||||
},
|
||||
advanced_analytics: {
|
||||
key: 'mobileDashboard.packageSummary.feature.advanced_analytics',
|
||||
fallback: 'Advanced analytics',
|
||||
},
|
||||
branding_allowed: {
|
||||
key: 'mobileDashboard.packageSummary.feature.branding_allowed',
|
||||
fallback: 'Branding',
|
||||
},
|
||||
watermark_allowed: {
|
||||
key: 'mobileDashboard.packageSummary.feature.watermark_allowed',
|
||||
fallback: 'Watermarks',
|
||||
},
|
||||
};
|
||||
|
||||
export function getPackageFeatureLabel(feature: string, t: Translate): string {
|
||||
const entry = FEATURE_LABELS[feature];
|
||||
if (entry) {
|
||||
return t(entry.key, entry.fallback);
|
||||
}
|
||||
|
||||
return t(`mobileDashboard.packageSummary.feature.${feature}`, feature);
|
||||
}
|
||||
|
||||
export function formatPackageLimit(value: number | null | undefined, t: Translate): string {
|
||||
if (value === null || value === undefined) {
|
||||
return t('mobileDashboard.packageSummary.unlimited', 'Unlimited');
|
||||
}
|
||||
|
||||
return String(value);
|
||||
}
|
||||
Reference in New Issue
Block a user