fix(ui): tarifs publics unifiés et prix annuel lisible
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 7m5s
CI / Deploy production (on server) (push) Successful in 24s

La page tarifs reprend la barre du site public. En annuel, Pro affiche
8,25 € par mois (99 € l’année), plus le 99 € comme gros chiffre.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Antigravity
2026-09-01 17:43:05 +00:00
parent dcd7f38c11
commit 4fc5e3ce04
21 changed files with 721 additions and 602 deletions

View File

@@ -0,0 +1,47 @@
export type BillingTier = 'PRO' | 'BUSINESS'
export type BillingInterval = 'month' | 'year'
export interface DynamicPrice {
display: string
amount: number
currency: string
}
export const DEFAULT_PRICES: Record<BillingTier, Record<BillingInterval, DynamicPrice>> = {
PRO: {
month: { display: '9,90 €', amount: 9.9, currency: 'EUR' },
year: { display: '99,00 €', amount: 99, currency: 'EUR' },
},
BUSINESS: {
month: { display: '29,90 €', amount: 29.9, currency: 'EUR' },
year: { display: '299,00 €', amount: 299, currency: 'EUR' },
},
}
export function formatBillingAmount(amount: number, currency = 'EUR'): string {
const c = currency.toUpperCase()
if (c === 'EUR') {
return `${amount.toLocaleString('fr-FR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} €`
}
if (c === 'USD') {
return `$${amount.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
}
if (c === 'GBP') {
return `£${amount.toLocaleString('en-GB', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
}
return `${amount.toLocaleString('fr-FR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${c}`
}
/** Prix annuel ramené au mois (99 € / an → 8,25 € / mois). */
export function yearToMonthlyEquivalent(yearAmount: number): number {
return Math.round((yearAmount / 12) * 100) / 100
}
/** Remise réelle : 9,90 € × 12 vs 99 € / an → 17 %. */
export function annualDiscountPercent(monthlyAmount: number, yearlyAmount: number): number {
const paidMonthlyForYear = monthlyAmount * 12
if (paidMonthlyForYear <= 0) return 0
const raw = (1 - yearlyAmount / paidMonthlyForYear) * 100
if (!Number.isFinite(raw) || raw <= 0) return 0
return Math.round(raw)
}