update ui update and fix layout issue
This commit is contained in:
80
src/shared/utils/format.ts
Normal file
80
src/shared/utils/format.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Formatting lives here so a rupee looks the same in a KPI, an axis tick and a
|
||||
* tooltip. Locale is pinned to en-IN — this is an Indian retail product, and
|
||||
* lakh/crore grouping is what merchants read.
|
||||
*
|
||||
* Every formatter is pure and locale-explicit: relying on the runtime default
|
||||
* would make the server and client disagree and produce hydration mismatches.
|
||||
*/
|
||||
|
||||
const NUM = new Intl.NumberFormat('en-IN');
|
||||
const INR = new Intl.NumberFormat('en-IN', {
|
||||
style: 'currency',
|
||||
currency: 'INR',
|
||||
maximumFractionDigits: 0,
|
||||
});
|
||||
|
||||
export function formatCount(v: number): string {
|
||||
return NUM.format(Math.round(v));
|
||||
}
|
||||
|
||||
export function formatInr(v: number): string {
|
||||
return INR.format(Math.round(v));
|
||||
}
|
||||
|
||||
/** Drops a trailing ".0" so axis ticks read ₹90k rather than ₹90.0k. */
|
||||
function trim(n: number): string {
|
||||
return n.toFixed(1).replace(/\.0$/, '');
|
||||
}
|
||||
|
||||
/** Axis-scale currency: ₹1.2L rather than ₹1,20,000. */
|
||||
export function formatInrCompact(v: number): string {
|
||||
if (Math.abs(v) >= 10000000) return `₹${trim(v / 10000000)}Cr`;
|
||||
if (Math.abs(v) >= 100000) return `₹${trim(v / 100000)}L`;
|
||||
if (Math.abs(v) >= 1000) return `₹${trim(v / 1000)}k`;
|
||||
return `₹${Math.round(v)}`;
|
||||
}
|
||||
|
||||
export function formatCompact(v: number): string {
|
||||
if (Math.abs(v) >= 10000000) return `${trim(v / 10000000)}Cr`;
|
||||
if (Math.abs(v) >= 100000) return `${trim(v / 100000)}L`;
|
||||
if (Math.abs(v) >= 1000) return `${trim(v / 1000)}k`;
|
||||
return String(Math.round(v));
|
||||
}
|
||||
|
||||
export function formatPct(v: number, digits = 1): string {
|
||||
return `${v.toFixed(digits)}%`;
|
||||
}
|
||||
|
||||
export function formatLyt(v: number): string {
|
||||
return `${NUM.format(Math.round(v))} LYT`;
|
||||
}
|
||||
|
||||
/** Signed delta for the KPI change chip. */
|
||||
export function formatDelta(v: number): string {
|
||||
return `${v > 0 ? '+' : ''}${v.toFixed(1)}%`;
|
||||
}
|
||||
|
||||
/** "12 Aug" — short axis label for a yyyy-mm-dd key. */
|
||||
export function formatDayLabel(iso: string | number): string {
|
||||
const d = new Date(String(iso));
|
||||
if (Number.isNaN(d.getTime())) return String(iso);
|
||||
return new Intl.DateTimeFormat('en-IN', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
timeZone: 'UTC',
|
||||
}).format(d);
|
||||
}
|
||||
|
||||
export function formatByUnit(unit: 'count' | 'inr' | 'lyt' | 'pct') {
|
||||
switch (unit) {
|
||||
case 'inr':
|
||||
return formatInr;
|
||||
case 'lyt':
|
||||
return formatLyt;
|
||||
case 'pct':
|
||||
return (v: number) => formatPct(v);
|
||||
default:
|
||||
return formatCount;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user