'use client'; import { FunctionComponent } from 'react'; import { useLocale, useTranslations } from 'next-intl'; import Box from '@mui/material/Box'; import Typography, { TypographyProps } from '@mui/material/Typography'; import { formatIrrToToman } from '@/utils'; export type MoneySize = 'sm' | 'md' | 'lg' | 'xl'; export type MoneyTone = 'default' | 'emphasis' | 'muted' | 'error'; const SIZE_VARIANT: Record = { sm: 'body2', md: 'body1', lg: 'h6', // The C6/confirmation "prominent total" hero figure — the single most important number on a payment // screen gets its own weight class, above the existing card/row emphasis. xl: 'h4', }; // House weight system has no 600 face (see typography.ts) — 700 for the strong tones, 500/400 otherwise. const TONE_STYLE: Record = { default: { color: 'inherit', fontWeight: 500 }, emphasis: { color: 'var(--bal-money-emphasis)', fontWeight: 700 }, muted: { color: 'var(--bal-text-secondary)', fontWeight: 400 }, error: { color: 'var(--bal-error)', fontWeight: 700 }, }; export interface MoneyProps extends Omit { /** A served IRR digit-string, straight off the wire. `` only formats — it never computes. */ amountIrr: string; size?: MoneySize; tone?: MoneyTone; /** Marks the amount as a deduction (a commission, a fee): prefixes an explicit `−` sign, held together * with the digits in a forced `dir="ltr"` run so the sign never gets swallowed inside RTL text — never * relies on a bare Unicode minus floating in a Persian paragraph. Defaults `tone` to `muted` unless the * caller overrides it. */ deduction?: boolean; /** Hides the "تومان"/"Toman" unit label — the bare grouped number only. */ hideUnit?: boolean; /** Renders the amount with a line-through (e.g. a superseded price next to a discounted one). */ strikethrough?: boolean; } /** * The single display primitive for every served IRR amount: formats via `utils/money.ts` (BigInt, * Toman + Persian digits) and never computes a figure itself. Replaces the 24 hand-assembled * `formatIrrToToman(x) + t('currency_toman')` call sites — including the ones that colored the total * terracotta (`--bal-secondary` fails AA contrast for small text; emphasis uses `--bal-money-emphasis` * instead, see the frontend-designer skill). * @component Money */ const Money: FunctionComponent = ({ amountIrr, size = 'md', tone, deduction = false, hideUnit = false, strikethrough = false, sx, ...rest }) => { const locale = useLocale(); const tc = useTranslations('common'); const effectiveTone = tone ?? (deduction ? 'muted' : 'default'); const { color, fontWeight } = TONE_STYLE[effectiveTone]; const formatted = formatIrrToToman(amountIrr, locale); return ( {deduction ? ( {'−'} {formatted} ) : ( formatted )} {hideUnit ? null : ` ${tc('currency_toman')}`} ); }; export default Money;