Audit fixes: VIP self-grant, draft leak, onboarding flag, hero personalization, gated downloads
Deploy GitHub Pages / deploy (push) Canceled after 0s
Deploy GitHub Pages / deploy (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
/* Western digits everywhere for consistency with reading times, prices and code. */
|
||||
const dateFormat = new Intl.DateTimeFormat('ar-u-nu-latn', { day: 'numeric', month: 'long', year: 'numeric' })
|
||||
const numberFormat = new Intl.NumberFormat('en-US')
|
||||
|
||||
export function formatDate(value: string | Date | null | undefined): string {
|
||||
if (!value) return ''
|
||||
const date = value instanceof Date ? value : new Date(value)
|
||||
return Number.isNaN(date.getTime()) ? '' : dateFormat.format(date)
|
||||
}
|
||||
|
||||
export const formatNumber = (value: number | null | undefined) => numberFormat.format(value ?? 0)
|
||||
|
||||
/* Single source for the displayed membership price. */
|
||||
export const MEMBERSHIP_PRICE = '$10'
|
||||
|
||||
/* Arabic count agreement for «دليل»: 1 دليل، 2 دليلان، 3–10 أدلة، 11+ دليلاً. */
|
||||
export function guidesLabel(n: number): string {
|
||||
if (n === 0) return 'لا أدلة'
|
||||
if (n === 1) return 'دليل واحد'
|
||||
if (n === 2) return 'دليلان'
|
||||
return `${formatNumber(n)} ${n <= 10 ? 'أدلة' : 'دليلاً'}`
|
||||
}
|
||||
|
||||
export function minutesLabel(n: number | null | undefined): string {
|
||||
const value = n ?? 0
|
||||
if (value === 1) return 'دقيقة واحدة'
|
||||
if (value === 2) return 'دقيقتان'
|
||||
return `${formatNumber(value)} ${value % 100 >= 3 && value % 100 <= 10 ? 'دقائق' : 'دقيقة'}`
|
||||
}
|
||||
Reference in New Issue
Block a user