fix plan issues
Build & Push / Pipeline Tests (push) Successful in 2m1s
Test / Type Check (all packages) (push) Successful in 53s
Build & Push / Build & Push Docker Image (push) Successful in 5m29s
Test / API Unit Tests (push) Successful in 1m18s
Test / Homepage Unit Tests (push) Successful in 46s
Test / Carplace Unit Tests (push) Successful in 43s
Test / Admin Unit Tests (push) Successful in 40s
Test / Dashboard Unit Tests (push) Successful in 42s
Test / API Integration Tests (push) Successful in 1m9s

This commit is contained in:
root
2026-08-30 23:36:40 -04:00
parent 66877d66c2
commit c0eb1de7a7
16 changed files with 77 additions and 424 deletions
@@ -139,7 +139,13 @@ const PLAN_LABELS: Record<Plan, string> = {
ENTERPRISE: 'Enterprise',
}
function mergePlanPrices(overrides?: Record<string, Record<string, Record<string, number>>> | null) {
type PlanPriceOverrides = Record<string, Record<string, Record<string, unknown>>>
function isValidPriceAmount(amount: unknown): amount is number {
return typeof amount === 'number' && Number.isInteger(amount) && amount > 0
}
function mergePlanPrices(overrides?: PlanPriceOverrides | null) {
const result: Record<string, Record<string, Record<string, number>>> = {
STARTER: {
MONTHLY: { ...PLAN_PRICES.STARTER.MONTHLY },
@@ -162,7 +168,10 @@ function mergePlanPrices(overrides?: Record<string, Record<string, Record<string
for (const [plan, periods] of Object.entries(overrides ?? {})) {
result[plan] = result[plan] ?? {}
for (const [period, currencies] of Object.entries(periods ?? {})) {
result[plan]![period] = { ...(result[plan]?.[period] ?? {}), ...currencies }
result[plan]![period] = { ...(result[plan]?.[period] ?? {}) }
for (const [currencyCode, amount] of Object.entries(currencies ?? {})) {
if (isValidPriceAmount(amount)) result[plan]![period]![currencyCode] = amount
}
}
}
@@ -554,7 +563,7 @@ export default function SubscriptionPage() {
const fetchPlanData = useCallback(async () => {
const [prices, features] = await Promise.all([
apiFetch<Record<string, Record<string, Record<string, number>>>>('/subscriptions/plans'),
apiFetch<PlanPriceOverrides>('/subscriptions/plans'),
apiFetch<PlanFeature[]>('/subscriptions/features'),
])
setPlanPrices(mergePlanPrices(prices))
@@ -984,7 +993,7 @@ export default function SubscriptionPage() {
{isActive && <span className="badge-green">{copy.active}</span>}
</div>
<p className="mt-2 text-2xl font-black text-slate-900 dark:text-zinc-100">
{price ? formatCurrency(price, 'MAD') : '—'}
{isValidPriceAmount(price) ? formatCurrency(price, 'MAD') : '—'}
<span className="text-sm font-normal text-slate-500 dark:text-zinc-400">/{billingPeriod === 'MONTHLY' ? copy.perMonthShort : copy.perYearShort}</span>
</p>
<ul className="mt-3 space-y-1">
@@ -1069,7 +1078,7 @@ export default function SubscriptionPage() {
<div>
<p className="text-sm text-slate-500 dark:text-zinc-400">{copy.total}</p>
<p className="text-xl font-black text-slate-900 dark:text-zinc-100">
{payableAmount ? formatCurrency(payableAmount, 'MAD') : '—'}
{isValidPriceAmount(payableAmount) ? formatCurrency(payableAmount, 'MAD') : '—'}
{!upgradeProration ? (
<span className="text-sm font-normal text-slate-500 ml-1 dark:text-zinc-400">/{billingPeriod === 'MONTHLY' ? copy.perMonth : copy.perYear}</span>
) : null}