- Introduced `FieldCurrencyInput` component for handling currency input in forms, supporting formatted display while maintaining numeric values. - Implemented `RenderCurrency` component for displaying currency values with proper formatting. - Enhanced `CurrencyUtils` to include parsing and formatting functions for Rupiah, ensuring accurate representation in UI. - Updated various components and forms to utilize the new currency input and rendering capabilities, improving user experience in financial data entry. - Added unit tests for currency input and formatting functionalities to ensure reliability and correctness. These changes enhance the application's handling of currency inputs and displays, providing a more user-friendly experience for financial transactions.
54 lines
1.4 KiB
TypeScript
54 lines
1.4 KiB
TypeScript
import { z } from 'zod';
|
|
import { CURRENCY_DATA_SCALE } from '@repo/utils';
|
|
|
|
export const PRICE_DECIMAL_SCALE = CURRENCY_DATA_SCALE;
|
|
export const QUANTITY_DECIMAL_SCALE = 4;
|
|
|
|
function coerceDecimalInput(value: unknown) {
|
|
if (value === '' || value === null || value === undefined) {
|
|
return undefined;
|
|
}
|
|
if (typeof value === 'number') {
|
|
return Number.isFinite(value) ? String(value) : value;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
export function toDecimalStringValue(value: unknown): string | undefined {
|
|
const next = coerceDecimalInput(value);
|
|
return typeof next === 'string' ? next : undefined;
|
|
}
|
|
|
|
function decimalPattern(maxDecimals: number) {
|
|
return new RegExp(`^\\d+(\\.\\d{1,${maxDecimals}})?$`);
|
|
}
|
|
|
|
export function decimalStringSchema(
|
|
t: (key: string) => string,
|
|
fieldKey = 'common:fields.price',
|
|
maxDecimals = QUANTITY_DECIMAL_SCALE,
|
|
) {
|
|
return z.preprocess(
|
|
coerceDecimalInput,
|
|
z.string().regex(decimalPattern(maxDecimals), {
|
|
message: JSON.stringify({ key: 'validation:invalid_format', values: { field: t(fieldKey) } }),
|
|
}),
|
|
);
|
|
}
|
|
|
|
export function optionalDecimalStringSchema(
|
|
t: (key: string) => string,
|
|
fieldKey = 'common:fields.price',
|
|
maxDecimals = PRICE_DECIMAL_SCALE,
|
|
) {
|
|
return z.preprocess(
|
|
coerceDecimalInput,
|
|
z
|
|
.string()
|
|
.regex(decimalPattern(maxDecimals), {
|
|
message: JSON.stringify({ key: 'validation:invalid_format', values: { field: t(fieldKey) } }),
|
|
})
|
|
.optional(),
|
|
);
|
|
}
|