/** * Shared plan and traffic tier definitions for pricing and billing (Change plan). * Backend supports plan_id solo, team, business and limit 10k–10M; month/year interval. */ export const PLAN_ID_SOLO = 'solo' export const PLAN_ID_TEAM = 'team' export const PLAN_ID_BUSINESS = 'business' /** Sites limit per plan. Returns null for free (no limit enforced in UI). */ export function getSitesLimitForPlan(planId: string | null | undefined): number | null { if (!planId || planId === 'free') return null switch (planId) { case 'solo': return 1 case 'team': return 5 case 'business': return 10 default: return null } } /** Traffic tiers available for Solo plan (pageview limits). */ export const TRAFFIC_TIERS = [ { label: '10k', value: 10000 }, { label: '50k', value: 50000 }, { label: '100k', value: 100000 }, { label: '250k', value: 250000 }, { label: '500k', value: 500000 }, { label: '1M', value: 1000000 }, { label: '2.5M', value: 2500000 }, { label: '5M', value: 5000000 }, { label: '10M', value: 10000000 }, ] as const export function getTierIndexForLimit(limit: number): number { const idx = TRAFFIC_TIERS.findIndex((t) => t.value === limit) return idx >= 0 ? idx : 2 } export function getLimitForTierIndex(index: number): number { if (index < 0 || index >= TRAFFIC_TIERS.length) return 100000 return TRAFFIC_TIERS[index].value } /** Maximum data retention (months) allowed per plan. */ export function getMaxRetentionMonthsForPlan(planId: string | null | undefined): number { switch (planId) { case 'business': return 36 case 'team': return 24 case 'solo': return 12 default: return 6 } } /** Selectable retention options (months) for the given plan. */ export function getRetentionOptionsForPlan(planId: string | null | undefined): { label: string; value: number }[] { const base = [ { label: '1 month', value: 1 }, { label: '3 months', value: 3 }, { label: '6 months', value: 6 }, ] const solo = [...base, { label: '1 year', value: 12 }] const team = [...solo, { label: '2 years', value: 24 }] const business = [...team, { label: '3 years', value: 36 }] switch (planId) { case 'business': return business case 'team': return team case 'solo': return solo default: return base } } /** Human-readable label for a retention value in months. */ export function formatRetentionMonths(months: number): string { if (months === 0) return 'Forever' if (months === 1) return '1 month' if (months < 12) return `${months} months` const years = months / 12 if (Number.isInteger(years)) return years === 1 ? '1 year' : `${years} years` return `${months} months` }