From 55781e8cc917f33e92625478f95853487e06baea Mon Sep 17 00:00:00 2001 From: Lukas Weiss Date: Tue, 20 Jun 2023 09:05:44 +0200 Subject: [PATCH] format date for date error messages --- src/translations/de.json | 2 +- src/zod/makeZodErrorMap.ts | 83 ++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/translations/de.json b/src/translations/de.json index d702920..5cc3c2f 100644 --- a/src/translations/de.json +++ b/src/translations/de.json @@ -7,7 +7,7 @@ "validation/date.exact": "Muss genau {value} sein", "validation/date.invalid_date": "Ungültiges Datum", "validation/date.too_big.exclusive": "Muss vor {value} sein", - "validation/date.too_big.inclusive": "Muss höchstens {value} sein", + "validation/date.too_big.inclusive": "Darf höchstens {value} sein", "validation/date.too_small.exclusive": "Muss nach {value} sein", "validation/date.too_small.inclusive": "Muss mindestens {value} sein", "validation/default": "Ungültige Eingabe", diff --git a/src/zod/makeZodErrorMap.ts b/src/zod/makeZodErrorMap.ts index 5f25693..2165969 100644 --- a/src/zod/makeZodErrorMap.ts +++ b/src/zod/makeZodErrorMap.ts @@ -1,4 +1,4 @@ -import { IntlShape } from '@formatjs/intl' +import { FormatDateOptions, IntlShape } from '@formatjs/intl' import { z } from 'zod' import { errorMessages } from './errorMessages' @@ -7,7 +7,7 @@ export function makeZodErrorMap( issue: z.ZodIssueOptionalMessage, intl: IntlShape ) { - const descriptorItem = getDescriptorItem(issue) + const descriptorItem = getDescriptorItem(issue, intl) return descriptorItem.key in errorMessages ? { @@ -19,7 +19,10 @@ export function makeZodErrorMap( : { message: intl.formatMessage(errorMessages['default']) } } -export function getDescriptorItem(issue: z.ZodIssueOptionalMessage): { +export function getDescriptorItem( + issue: z.ZodIssueOptionalMessage, + intl: IntlShape +): { key: string values?: Record } { @@ -39,43 +42,61 @@ export function getDescriptorItem(issue: z.ZodIssueOptionalMessage): { return { key: `date.${issue.code}` } } + if ( + issue.code === z.ZodIssueCode.too_small && + issue.type === 'string' && + issue.minimum === 1 + ) { + return { key: 'string.required' } + } + if ( issue.code === z.ZodIssueCode.too_small || issue.code === z.ZodIssueCode.too_big ) { - if (issue.exact) { - return { - key: `${issue.type}.exact`, - values: { - value: - issue.code === z.ZodIssueCode.too_small - ? issue.minimum - : issue.code === z.ZodIssueCode.too_big - ? issue.maximum - : '?', - }, - } - } + let value = + issue.code === z.ZodIssueCode.too_small + ? issue.minimum + : issue.code === z.ZodIssueCode.too_big + ? issue.maximum + : '-' + + if (issue.type === 'date') { + const date = new Date(value) - if ( - issue.code === z.ZodIssueCode.too_small && - issue.type === 'string' && - issue.minimum === 1 - ) { - return { key: 'string.required' } + if (isNaN(date.getTime())) { + value = '-' + } else { + const dateOptions: FormatDateOptions = { + day: '2-digit', + month: '2-digit', + year: 'numeric', + } + + const timeOptions: FormatDateOptions | null = + date.getUTCHours() === 0 && date.getUTCMinutes() === 0 + ? null + : { + hour: '2-digit', + minute: '2-digit', + } + + value = intl.formatDate(value, { + timeZone: 'UTC', + ...dateOptions, + ...timeOptions, + }) + } } return { - key: `${issue.type}.${issue.code}.${ - issue.inclusive ? 'inclusive' : 'exclusive' - }`, + key: issue.exact + ? `${issue.type}.exact` + : `${issue.type}.${issue.code}.${ + issue.inclusive ? 'inclusive' : 'exclusive' + }`, values: { - value: - issue.code === z.ZodIssueCode.too_small - ? issue.minimum - : issue.code === z.ZodIssueCode.too_big - ? issue.maximum - : '?', + value, }, } }