fix(ui): tarifs publics unifiés et prix annuel lisible
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:
47
memento-note/lib/billing/price-catalog.ts
Normal file
47
memento-note/lib/billing/price-catalog.ts
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user