@@ -38,18 +38,24 @@ function moneyCents(value: string): bigint | null {
|
||||
const MIN_BALANCE_KOPECKS = -9_223_372_036_854_775_808n;
|
||||
const MAX_BALANCE_KOPECKS = 9_223_372_036_854_775_807n;
|
||||
|
||||
const moneySchema = z.string().refine((value) => {
|
||||
const cents = moneyCents(value);
|
||||
return (
|
||||
cents !== null &&
|
||||
cents >= MIN_BALANCE_KOPECKS &&
|
||||
cents <= MAX_BALANCE_KOPECKS
|
||||
);
|
||||
}, validationMessage("bank.validation.money"));
|
||||
const positiveMoneySchema = moneySchema.refine((value) => {
|
||||
const cents = moneyCents(value);
|
||||
return cents === null || cents > 0n;
|
||||
}, validationMessage("bank.validation.positive"));
|
||||
const moneySchema = z.string().refine(
|
||||
(value) => {
|
||||
const cents = moneyCents(value);
|
||||
return (
|
||||
cents !== null &&
|
||||
cents >= MIN_BALANCE_KOPECKS &&
|
||||
cents <= MAX_BALANCE_KOPECKS
|
||||
);
|
||||
},
|
||||
{ error: validationMessage("bank.validation.money") },
|
||||
);
|
||||
const positiveMoneySchema = moneySchema.refine(
|
||||
(value) => {
|
||||
const cents = moneyCents(value);
|
||||
return cents === null || cents > 0n;
|
||||
},
|
||||
{ error: validationMessage("bank.validation.positive") },
|
||||
);
|
||||
const bankDateSchema = z
|
||||
.string()
|
||||
.refine(
|
||||
@@ -59,7 +65,7 @@ const bankDateSchema = z
|
||||
!Number.isNaN(Date.parse(`${value}T00:00:00Z`)) &&
|
||||
new Date(`${value}T00:00:00Z`).toISOString().slice(0, 10) === value &&
|
||||
value <= bankToday(),
|
||||
validationMessage("bank.validation.date"),
|
||||
{ error: validationMessage("bank.validation.date") },
|
||||
);
|
||||
const bankCardSchema = z.object({
|
||||
name: z
|
||||
@@ -77,15 +83,12 @@ const bankCardSchema = z.object({
|
||||
MAX_CARD_NAME_LENGTH,
|
||||
validationMessage("bank.validation.bankName")(undefined),
|
||||
),
|
||||
lastFour: z
|
||||
.string()
|
||||
.refine(
|
||||
(value) => !value || /^\d{4}$/.test(value),
|
||||
validationMessage("bank.validation.lastFour"),
|
||||
),
|
||||
lastFour: z.string().refine((value) => !value || /^\d{4}$/.test(value), {
|
||||
error: validationMessage("bank.validation.lastFour"),
|
||||
}),
|
||||
paymentSystem: z
|
||||
.enum(["", "mir", "visa", "mastercard"], {
|
||||
errorMap: validationMessage("bank.validation.paymentSystem"),
|
||||
error: validationMessage("bank.validation.paymentSystem"),
|
||||
})
|
||||
.optional(),
|
||||
openingBalance: moneySchema,
|
||||
|
||||
@@ -71,7 +71,7 @@ const CategoryManager: FC<CategoryManagerProps> = (props) => {
|
||||
.refine(
|
||||
(value) =>
|
||||
value.length > 0 && value.length <= MAX_CATEGORY_NAME_LENGTH,
|
||||
validationMessage("bank.validation.category"),
|
||||
{ error: validationMessage("bank.validation.category") },
|
||||
)
|
||||
.refine(
|
||||
(value) =>
|
||||
@@ -81,7 +81,7 @@ const CategoryManager: FC<CategoryManagerProps> = (props) => {
|
||||
c.name.toLocaleLowerCase("ru-RU") ===
|
||||
value.toLocaleLowerCase("ru-RU"),
|
||||
),
|
||||
validationMessage("bank.validation.duplicate"),
|
||||
{ error: validationMessage("bank.validation.duplicate") },
|
||||
),
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -25,7 +25,7 @@ const email = z
|
||||
value.split("@").length === 2 &&
|
||||
value.split("@").every(Boolean) &&
|
||||
!value.split("").some(isEmailCharacterInvalid),
|
||||
validationMessage("auth.validation.invalidEmail"),
|
||||
{ error: validationMessage("auth.validation.invalidEmail") },
|
||||
);
|
||||
const password = z
|
||||
.string()
|
||||
@@ -33,7 +33,7 @@ const password = z
|
||||
(value) =>
|
||||
new TextEncoder().encode(value).length >= MIN_PASSWORD_BYTES &&
|
||||
new TextEncoder().encode(value).length <= MAX_PASSWORD_BYTES,
|
||||
validationMessage("auth.validation.invalidPasswordLength"),
|
||||
{ error: validationMessage("auth.validation.invalidPasswordLength") },
|
||||
);
|
||||
|
||||
const loginSchema = z.object({
|
||||
@@ -43,10 +43,10 @@ const loginSchema = z.object({
|
||||
});
|
||||
const registerSchema = loginSchema.refine(
|
||||
(value) => value.password === value.passwordConfirmation,
|
||||
(value) => ({
|
||||
{
|
||||
path: ["passwordConfirmation"],
|
||||
...validationMessage("auth.validation.passwordsDoNotMatch")(value),
|
||||
}),
|
||||
error: validationMessage("auth.validation.passwordsDoNotMatch"),
|
||||
},
|
||||
);
|
||||
|
||||
type AuthFormValues = z.input<typeof loginSchema>;
|
||||
|
||||
@@ -44,14 +44,16 @@ type AccountIncomePageViewModel =
|
||||
const datePattern = /^\d{4}-\d{2}-\d{2}$/;
|
||||
const draftDate = z
|
||||
.string()
|
||||
.refine((value) => parseDraftDate(value) !== null, {
|
||||
error: validationMessage("income.validation.date"),
|
||||
})
|
||||
.refine(
|
||||
(value) => parseDraftDate(value) !== null,
|
||||
validationMessage("income.validation.date"),
|
||||
)
|
||||
.refine((value) => {
|
||||
const date = parseDraftDate(value);
|
||||
return !date || date <= moscowDate(new Date());
|
||||
}, validationMessage("income.validation.future"));
|
||||
(value) => {
|
||||
const date = parseDraftDate(value);
|
||||
return !date || date <= moscowDate(new Date());
|
||||
},
|
||||
{ error: validationMessage("income.validation.future") },
|
||||
);
|
||||
const incomeFormSchema = z.object({ from: draftDate, to: draftDate }).refine(
|
||||
({ from, to }) => {
|
||||
const start = parseDraftDate(from);
|
||||
|
||||
Reference in New Issue
Block a user