@swan-io/shared-business 13.1.3 → 13.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swan-io/shared-business",
3
- "version": "13.1.3",
3
+ "version": "13.1.6",
4
4
  "engines": {
5
5
  "node": "^22.12.0"
6
6
  },
@@ -25,7 +25,7 @@
25
25
  ],
26
26
  "license": "MIT",
27
27
  "peerDependencies": {
28
- "@swan-io/lake": "13.1.3"
28
+ "@swan-io/lake": "13.1.6"
29
29
  },
30
30
  "dependencies": {
31
31
  "@formatjs/intl": "^3.1.6",
@@ -50,6 +50,6 @@
50
50
  "@types/react-dom": "^19.1.7",
51
51
  "@types/react-native": "^0.72.8",
52
52
  "type-fest": "^4.41.0",
53
- "@swan-io/lake": "13.1.3"
53
+ "@swan-io/lake": "13.1.6"
54
54
  }
55
55
  }
@@ -1,6 +1,6 @@
1
1
  import { StyleProp, ViewStyle } from "react-native";
2
2
  import { CountryCCA3 } from "../constants/countries";
3
- export type TransactionType = "SepaCreditTransfer" | "Fees" | "SepaDirectDebit" | "Card";
3
+ export type TransactionType = "SepaCreditTransfer" | "SepaDirectDebit" | "Card";
4
4
  type AddressInfo = {
5
5
  addressLine1: string;
6
6
  addressLine2?: string;
@@ -20,6 +20,8 @@ type Transaction = {
20
20
  transactionType: TransactionType;
21
21
  transactionSide: "Credit" | "Debit";
22
22
  transactionAmount: Amount;
23
+ counterparty: string;
24
+ maskedPan?: string;
23
25
  };
24
26
  type CreditStatementV1Props = {
25
27
  version: "v1";
@@ -32,15 +34,13 @@ type CreditStatementV1Props = {
32
34
  bic: string;
33
35
  openingDate: string;
34
36
  closingDate: string;
35
- openingBalance: Amount;
36
37
  transactions: Transaction[];
37
- totalsCredit: Amount;
38
- totalsDebit: Amount;
39
- closingBalance: Amount;
40
- feesDebit: Amount;
41
- feesCredit: Amount;
38
+ issueDate: string;
39
+ issuerName: string;
40
+ siret: string;
41
+ repaymentDate: string;
42
42
  };
43
- export declare const CreditStatementV1: ({ partnerLogoUrl, accountHolderType, accountHolderName, accountHolderAddress, iban, bic, openingDate, closingDate, openingBalance, transactions, feesDebit, feesCredit, totalsCredit, totalsDebit, closingBalance, }: CreditStatementV1Props) => import("react/jsx-runtime").JSX.Element;
43
+ export declare const CreditStatementV1: ({ partnerLogoUrl, accountHolderType, accountHolderName, accountHolderAddress, iban, bic, openingDate, closingDate, transactions, issueDate, issuerName, siret, repaymentDate, }: CreditStatementV1Props) => import("react/jsx-runtime").JSX.Element;
44
44
  export type CreditStatementProps = CreditStatementV1Props;
45
45
  export declare const CreditStatement: (props: CreditStatementProps) => import("react/jsx-runtime").JSX.Element;
46
46
  export {};
@@ -1,70 +1,60 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Box } from "@swan-io/lake/src/components/Box";
3
+ import { LakeText } from "@swan-io/lake/src/components/LakeText";
3
4
  import { Separator } from "@swan-io/lake/src/components/Separator";
4
5
  import { Space } from "@swan-io/lake/src/components/Space";
5
6
  import { SwanLogo } from "@swan-io/lake/src/components/SwanLogo";
6
- import { colors, fonts, invariantColors, primaryFontStyle, spacings, } from "@swan-io/lake/src/constants/design";
7
+ import { colors, invariantColors, spacings } from "@swan-io/lake/src/constants/design";
7
8
  import { isNotNullish, isNotNullishOrEmpty } from "@swan-io/lake/src/utils/nullish";
8
- import { StyleSheet, Text } from "react-native";
9
+ import dayjs from "dayjs";
10
+ import { printFormat } from "iban";
11
+ import { StyleSheet } from "react-native";
9
12
  import { match } from "ts-pattern";
10
13
  import { getCountryName } from "../constants/countries";
11
- import { formatCurrencySymbol, t } from "../utils/i18n";
14
+ import { formatNestedMessage, locale, t } from "../utils/i18n";
12
15
  const LOGO_MAX_HEIGHT = 24;
13
16
  const LOGO_MAX_WIDTH = 150;
14
- const getTextStyle = (type, fontSize) => ({
15
- ...(type === "mono" ? { fontFamily: fonts.iban } : primaryFontStyle),
16
- color: colors.gray[900],
17
- fontSize,
18
- lineHeight: fontSize * 1.25,
19
- fontWeight: "400",
20
- });
21
17
  const styles = StyleSheet.create({
22
18
  container: {
23
19
  width: 793,
24
20
  padding: 56,
25
21
  backgroundColor: invariantColors.white,
26
22
  },
27
- partnershipText: {
28
- ...getTextStyle("sans", 14),
29
- color: colors.gray[500],
23
+ address: {
24
+ fontSize: 13,
25
+ },
26
+ smallText: {
27
+ fontSize: 12,
28
+ },
29
+ mediumText: {
30
+ fontSize: 14,
31
+ },
32
+ subtitle: {
33
+ fontSize: 18,
34
+ fontWeight: "400",
30
35
  },
31
36
  pageTitle: {
32
- ...getTextStyle("sans", 20),
37
+ fontSize: 20,
33
38
  color: colors.swan[500],
34
39
  fontWeight: "600",
35
40
  },
36
41
  sectionTitle: {
37
- ...getTextStyle("sans", 14),
42
+ fontSize: 18,
38
43
  color: colors.swan[500],
39
- fontWeight: "500",
40
- lineHeight: 24,
41
- },
42
- totalAmount: {
43
- ...getTextStyle("sans", 20),
44
- lineHeight: 28,
45
44
  fontWeight: "600",
45
+ lineHeight: 24,
46
46
  },
47
47
  titleColumn: {
48
- ...getTextStyle("sans", 15),
49
- fontWeight: "500",
48
+ fontSize: 14,
49
+ fontWeight: "600",
50
50
  paddingVertical: spacings[4],
51
51
  minWidth: spacings[96],
52
52
  lineHeight: 24,
53
53
  },
54
- openingBalanceText: {
55
- ...getTextStyle("sans", 14),
56
- textAlign: "right",
57
- },
58
- textColumn: {
59
- ...getTextStyle("sans", 14),
60
- color: "colors.gray[700]",
61
- // lineHeight: 20,
62
- paddingVertical: spacings[4],
63
- },
64
54
  text: {
65
- ...getTextStyle("sans", 14),
66
- color: colors.gray[700],
55
+ fontSize: 13,
67
56
  lineHeight: 24,
57
+ textAlign: "right",
68
58
  },
69
59
  row: {
70
60
  textAlign: "right",
@@ -72,16 +62,6 @@ const styles = StyleSheet.create({
72
62
  fontWeight: "600",
73
63
  width: "20%",
74
64
  },
75
- closingBalanceRow: {
76
- ...getTextStyle("sans", 14),
77
- backgroundColor: colors.gray[50],
78
- width: "50%",
79
- },
80
- footer: {
81
- ...getTextStyle("sans", 10),
82
- color: colors.gray[500],
83
- fontWeight: "300",
84
- },
85
65
  defaultLogo: {
86
66
  height: LOGO_MAX_HEIGHT,
87
67
  width: (45 / 10) * LOGO_MAX_HEIGHT,
@@ -92,18 +72,11 @@ const styles = StyleSheet.create({
92
72
  position: "relative",
93
73
  top: 0.5,
94
74
  },
75
+ rightColumnContent: { width: "15%", textAlign: "right", fontWeight: "400" },
95
76
  });
96
- const Title = ({ text, align = "left", style, }) => (_jsx(Text, { style: [
97
- styles.titleColumn,
98
- style,
99
- {
100
- textAlign: align,
101
- },
102
- ], children: text }));
103
77
  const translateTransaction = (transaction) => {
104
78
  return match(transaction)
105
79
  .with("Card", () => t("accountStatement.card"))
106
- .with("Fees", () => t("accountStatement.fees"))
107
80
  .with("SepaCreditTransfer", () => t("accountStatement.creditTransfer"))
108
81
  .with("SepaDirectDebit", () => t("accountStatement.directDebit"))
109
82
  .exhaustive();
@@ -114,20 +87,21 @@ const logoStyle = {
114
87
  objectFit: "contain",
115
88
  objectPosition: "left",
116
89
  };
117
- export const CreditStatementV1 = ({ partnerLogoUrl, accountHolderType, accountHolderName, accountHolderAddress, iban, bic, openingDate, closingDate, openingBalance, transactions, feesDebit, feesCredit, totalsCredit, totalsDebit, closingBalance, }) => {
118
- return (_jsxs(Box, { style: styles.container, direction: "column", justifyContent: "spaceBetween", children: [_jsxs(Box, { children: [_jsx(Box, { direction: "row", justifyContent: "spaceBetween", children: _jsxs(Box, { direction: "row", alignItems: "center", children: [isNotNullishOrEmpty(partnerLogoUrl) ? (_jsx("img", { src: partnerLogoUrl, style: logoStyle })) : (_jsx(SwanLogo, { style: styles.defaultLogo })), _jsx(Separator, { horizontal: true, space: 8 }), _jsx(Text, { style: styles.partnershipText, children: t("accountStatement.partnership") }), _jsx(Space, { width: 4 }), _jsx(SwanLogo, { color: colors.gray[900], style: styles.swanLogo })] }) }), _jsx(Space, { height: 24 }), _jsx(Text, { style: styles.pageTitle, children: t("creditStatement.titleDocument") }), _jsx(Text, { style: styles.text, children: accountHolderType === "Company"
119
- ? t("accountStatement.titleDocument.companyDescription")
120
- : t("accountStatement.titleDocument.individualDescription") }), _jsx(Space, { height: 12 }), _jsxs(Box, { direction: "column", children: [_jsx(Text, { style: styles.sectionTitle, children: accountHolderName }), _jsx(Text, { style: styles.text, children: accountHolderAddress.addressLine1 }), isNotNullish(accountHolderAddress.addressLine2) && (_jsx(Text, { children: accountHolderAddress.addressLine2 })), _jsx(Text, { style: styles.text, children: `${accountHolderAddress.postalCode} ${accountHolderAddress.city}, ${getCountryName(accountHolderAddress.country)}` })] }), _jsx(Space, { height: 12 }), _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.iban") }), _jsx(Text, { style: styles.text, children: iban }), _jsx(Space, { height: 4 }), _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.bic") }), _jsx(Text, { style: styles.text, children: bic }), _jsx(Space, { height: 24 }), _jsxs(Box, { direction: "row", justifyContent: "spaceBetween", children: [_jsx(Box, { direction: "column", justifyContent: "end", children: _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.date", { openingDate, closingDate }) }) }), _jsxs(Box, { direction: "column", children: [_jsx(Text, { style: styles.openingBalanceText, children: t("accountStatement.openingBalance") }), _jsx(Text, { style: styles.totalAmount, children: formatCurrencySymbol(Number(openingBalance.value), openingBalance.currency) })] })] }), _jsx(Space, { height: 24 }), _jsxs(_Fragment, { children: [_jsxs(Box, { direction: "row", children: [_jsx(Text, { style: [styles.titleColumn, { width: "15%" }], children: t("accountStatement.column.date") }), _jsx(Text, { style: [styles.titleColumn, { width: "22%" }], children: t("accountStatement.column.type") }), _jsx(Text, { style: [styles.titleColumn, { width: "33%" }], children: t("accountStatement.column.description") }), _jsx(Text, { style: [styles.titleColumn, { width: "15%", textAlign: "right" }], children: t("creditStatement.column.credit") }), _jsx(Text, { style: [styles.titleColumn, { width: "15%", textAlign: "right" }], children: t("creditStatement.column.debit") })] }), _jsx(Box, { direction: "column", children: transactions.map(({ transactionAmount, transactionDate, transactionLabel, transactionSide, transactionType, transactionId, }) => (_jsxs(Box, { direction: "row", children: [_jsx(Text, { style: [styles.textColumn, { width: "15%" }], children: transactionDate }), _jsx(Text, { style: [styles.textColumn, { width: "22%" }], children: translateTransaction(transactionType) }), _jsx(Text, { style: [styles.textColumn, { width: "33%" }], children: transactionLabel }), _jsx(Text, { style: [
121
- styles.textColumn,
122
- { width: "15%", textAlign: "right", fontWeight: "600" },
123
- ], children: transactionSide === "Credit" ? transactionAmount.value : "" }), _jsx(Text, { style: [
124
- styles.textColumn,
125
- { width: "15%", textAlign: "right", fontWeight: "600" },
126
- ], children: transactionSide === "Debit" ? transactionAmount.value : "" })] }, transactionId))) })] }), _jsx(Space, { height: 24 }), _jsxs(Box, { direction: "column", children: [_jsxs(Box, { direction: "row", justifyContent: "end", children: [_jsx(Text, { style: [styles.row], children: t("accountStatement.column.fees") }), _jsx(Text, { style: [styles.row, { width: "15%" }], children: feesCredit.value }), _jsx(Text, { style: [styles.row, { width: "15%" }], children: feesDebit.value })] }), _jsx(Space, { height: 12 }), _jsxs(Box, { direction: "row", justifyContent: "end", children: [_jsx(Text, { style: styles.row, children: t("accountStatement.column.totals") }), _jsx(Text, { style: [styles.row, { width: "15%" }], children: totalsCredit.value }), _jsx(Text, { style: [styles.row, { width: "15%" }], children: totalsDebit.value })] })] }), _jsx(Space, { height: 12 }), _jsx(Box, { direction: "row", justifyContent: "end", children: _jsxs(Box, { direction: "row", justifyContent: "spaceBetween", alignItems: "center", style: { width: "50%" }, children: [_jsx(Title, { align: "right", text: t("accountStatement.closingBalance"), style: { width: "40%" } }), _jsx(Title, { text: formatCurrencySymbol(Number(closingBalance.value), closingBalance.currency), style: {
127
- width: "60%",
128
- ...getTextStyle("sans", 20),
129
- fontWeight: "600",
130
- }, align: "right" })] }) })] }), _jsxs(Box, { children: [_jsx(Separator, { space: 24 }), _jsx(Text, { style: styles.footer, children: t("transactionStatement.footer") })] })] }));
90
+ const formatMaskedPan = (value) => `••${value.slice(-4)}`;
91
+ export const CreditStatementV1 = ({ partnerLogoUrl, accountHolderType, accountHolderName, accountHolderAddress, iban, bic, openingDate, closingDate, transactions, issueDate, issuerName, siret, repaymentDate, }) => {
92
+ return (_jsxs(Box, { style: styles.container, direction: "column", justifyContent: "spaceBetween", children: [_jsxs(Box, { direction: "row", justifyContent: "spaceBetween", alignItems: "start", children: [_jsxs(Box, { direction: "row", alignItems: "center", children: [isNotNullishOrEmpty(partnerLogoUrl) ? (_jsx("img", { src: partnerLogoUrl, style: logoStyle })) : (_jsx(SwanLogo, { style: styles.defaultLogo })), _jsx(Separator, { horizontal: true, space: 8 }), _jsx(LakeText, { style: styles.mediumText, children: t("accountStatement.partnership") }), _jsx(Space, { width: 4 }), _jsx(SwanLogo, { color: colors.gray[900], style: styles.swanLogo })] }), _jsxs(Box, { children: [_jsx(LakeText, { style: styles.pageTitle, children: t("creditStatement.titleDocument") }), _jsx(LakeText, { style: styles.text, color: colors.gray[700], children: accountHolderType === "Company"
93
+ ? t("accountStatement.titleDocument.companyDescription")
94
+ : t("accountStatement.titleDocument.individualDescription") }), _jsx(LakeText, { align: "right", style: styles.smallText, children: t("creditStatement.issueDate", {
95
+ issueDate: dayjs(issueDate).format(locale.dateFormat),
96
+ }) })] })] }), _jsx(Space, { height: 12 }), _jsxs(Box, { direction: "column", children: [_jsx(LakeText, { style: styles.sectionTitle, children: accountHolderName }), _jsx(Space, { height: 16 }), _jsx(LakeText, { style: styles.address, children: accountHolderAddress.addressLine1 }), isNotNullish(accountHolderAddress.addressLine2) && (_jsx(LakeText, { children: accountHolderAddress.addressLine2 })), _jsx(LakeText, { style: styles.address, children: `${accountHolderAddress.postalCode} ${accountHolderAddress.city}, ${getCountryName(accountHolderAddress.country)}` })] }), _jsx(Space, { height: 12 }), _jsxs(Box, { direction: "row", children: [_jsxs(Box, { direction: "column", grow: 1, children: [_jsxs(Box, { direction: "row", alignItems: "center", children: [_jsx(LakeText, { variant: "semibold", style: styles.mediumText, color: colors.gray[900], children: t("accountStatement.iban") }), _jsx(Space, { width: 4 }), _jsx(LakeText, { color: colors.gray[500], style: styles.mediumText, children: printFormat(iban) })] }), _jsx(Space, { height: 4 }), _jsxs(Box, { direction: "row", alignItems: "center", children: [_jsx(LakeText, { variant: "semibold", style: styles.mediumText, color: colors.gray[900], children: t("accountStatement.bic") }), _jsx(Space, { width: 4 }), _jsx(LakeText, { color: colors.gray[500], style: styles.mediumText, children: bic })] })] }), _jsxs(Box, { direction: "column", grow: 1, children: [_jsx(LakeText, { variant: "semibold", style: styles.mediumText, color: colors.gray[900], children: issuerName }), _jsx(Space, { height: 4 }), _jsxs(Box, { direction: "row", alignItems: "center", children: [_jsx(LakeText, { variant: "semibold", style: styles.mediumText, children: t("creditStatement.siret") }), _jsx(Space, { width: 4 }), _jsx(LakeText, { color: colors.gray[500], style: styles.mediumText, children: siret })] })] })] }), _jsx(Space, { height: 24 }), _jsx(LakeText, { color: colors.gray[500], style: styles.smallText, children: formatNestedMessage("creditStatement.additionalDetails", {
97
+ bold: chunk => (_jsx(LakeText, { color: colors.gray[900], variant: "semibold", style: { fontSize: 12 }, children: chunk })),
98
+ openingDate: dayjs(openingDate).format(locale.dateFormat),
99
+ closingDate: dayjs(closingDate).format(locale.dateFormat),
100
+ repaymentDate: dayjs(repaymentDate).format(locale.dateFormat),
101
+ }) }), _jsx(Space, { height: 24 }), _jsx(Box, { direction: "row", justifyContent: "spaceBetween", children: _jsx(Box, { direction: "column", justifyContent: "end", children: _jsx(LakeText, { style: styles.subtitle, color: colors.gray[900], children: t("accountStatement.date", {
102
+ openingDate: dayjs(openingDate).format(locale.dateFormat),
103
+ closingDate: dayjs(closingDate).format(locale.dateFormat),
104
+ }) }) }) }), _jsx(Space, { height: 16 }), _jsxs(_Fragment, { children: [_jsxs(Box, { direction: "row", children: [_jsx(LakeText, { style: [styles.titleColumn, { width: "15%" }], color: colors.gray[700], children: t("accountStatement.column.date") }), _jsx(LakeText, { style: [styles.titleColumn, { width: "55%" }], color: colors.gray[700], children: t("accountStatement.column.description") }), _jsx(LakeText, { style: [styles.titleColumn, { width: "15%", textAlign: "right" }], color: colors.gray[700], children: t("creditStatement.column.debit") }), _jsx(LakeText, { style: [styles.titleColumn, { width: "15%", textAlign: "right" }], color: colors.gray[700], children: t("creditStatement.column.credit") })] }), _jsx(Space, { height: 12 }), _jsx(Box, { direction: "column", children: transactions.map(({ transactionAmount, transactionDate, transactionLabel, transactionSide, transactionType, transactionId, counterparty, maskedPan, }) => (_jsxs(_Fragment, { children: [_jsxs(Box, { direction: "row", children: [_jsx(LakeText, { style: [styles.smallText, { width: "15%" }], color: colors.gray[700], children: dayjs(transactionDate).format(locale.dateFormat) }), _jsxs(Box, { direction: "column", style: { width: "55%" }, children: [_jsx(LakeText, { style: styles.smallText, color: colors.gray[700], children: `${translateTransaction(transactionType)} ${transactionLabel}` }), _jsx(LakeText, { style: styles.smallText, color: colors.gray[500], children: `${counterparty} ${maskedPan ? formatMaskedPan(maskedPan) : ""}` })] }), _jsx(LakeText, { color: colors.gray[700], style: [styles.smallText, styles.rightColumnContent], children: transactionSide === "Debit" ? `- ${transactionAmount.value}` : "" }), _jsx(LakeText, { color: colors.gray[700], style: [styles.smallText, styles.rightColumnContent], children: transactionSide === "Credit" ? transactionAmount.value : "" })] }, transactionId), _jsx(Space, { height: 8 })] }))) })] }), _jsx(Space, { height: 24 })] }));
131
105
  };
132
106
  export const CreditStatement = (props) => match(props)
133
107
  .with({ version: "v1" }, props => _jsx(CreditStatementV1, { ...props }))
@@ -15,6 +15,7 @@ import { match } from "ts-pattern";
15
15
  import { extractDate, formatExtractedDate } from "../utils/date";
16
16
  import { t } from "../utils/i18n";
17
17
  import { getMostLikelyUserCountry } from "../utils/localization";
18
+ import { validateDate } from "../utils/validation";
18
19
  const months = [
19
20
  { value: "01", name: t("datePicker.month.january") },
20
21
  { value: "02", name: t("datePicker.month.february") },
@@ -57,7 +58,7 @@ const order = match(getMostLikelyUserCountry().cca2)
57
58
  .with("US", () => "MDY")
58
59
  .with("CN", "JP", "KR", "KP", "TW", "HU", "MN", "LT", "BT", () => "YMD")
59
60
  .otherwise(() => "DMY");
60
- export const InlineDatePicker = ({ value, label, readOnly = false, onValueChange, validate = () => undefined, error: externalError, style, }) => {
61
+ export const InlineDatePicker = ({ value, label, readOnly = false, onValueChange, validate = validateDate, error: externalError, style, }) => {
61
62
  const { desktop } = useResponsive(breakpoints.small);
62
63
  // We can't rely on blurred, since 3 inputs / select are mapped on
63
64
  // 1 field. The first onBlur update the field internal state from
@@ -65,6 +66,7 @@ export const InlineDatePicker = ({ value, label, readOnly = false, onValueChange
65
66
  // validate will not be triggered again since the field has already
66
67
  // blurred = true
67
68
  const touched = useRef(new Set());
69
+ const mountWithInitialValue = useRef(value != null);
68
70
  const { Field, validateField } = useForm({
69
71
  date: {
70
72
  initialValue: isNotNullish(value) ? extractDate(value) : undefined,
@@ -89,7 +91,8 @@ export const InlineDatePicker = ({ value, label, readOnly = false, onValueChange
89
91
  },
90
92
  });
91
93
  const validateDate = () => {
92
- if (touched.current.has("day") && touched.current.has("month") && touched.current.has("year")) {
94
+ if (mountWithInitialValue.current ||
95
+ (touched.current.has("day") && touched.current.has("month") && touched.current.has("year"))) {
93
96
  validateField("date");
94
97
  }
95
98
  };
@@ -67,8 +67,11 @@
67
67
  "common.skipToContent": "Zum Inhalt springen",
68
68
  "copyButton.copiedTooltip": "In die Zwischenablage kopiert",
69
69
  "copyButton.copyTooltip": "Zum Kopieren anklicken",
70
+ "creditStatement.additionalDetails": "Der Kontoauszug vom <bold>{openingDate}</bold> bis <bold>{closingDate}</bold> enthält alle Gebühren und erhaltenen Zahlungen bis zum {closingDate}. Ihre nächste automatische Lastschrift erfolgt ab {repaymentDate}.\n\nIm Falle einer abgelehnten Bankabbuchung aufgrund unzureichender Mittel können wir diese Abbuchung mindestens <bold>3 bis 4 Tage</bold> nach der Benachrichtigung durch Ihre Bank erneut einreichen.",
70
71
  "creditStatement.column.credit": "Gutschrift",
71
72
  "creditStatement.column.debit": "Lastschrift",
73
+ "creditStatement.issueDate": "Ausgabedatum {issueDate}",
74
+ "creditStatement.siret": "SIRET",
72
75
  "creditStatement.titleDocument": "Rückzahlungsaufstellung",
73
76
  "datePicker.day": "Tag",
74
77
  "datePicker.day.friday": "Freitag",
@@ -111,10 +114,10 @@
111
114
  "fileTile.status.Refused": "Abgelehnt",
112
115
  "fileTile.status.Validated": "Validiert",
113
116
  "fileTile.uploading": "Hochladen…",
114
- "monthlyPaymentVolume.between10000And50000": "Zwischen 10.000 und 50.000 €",
115
- "monthlyPaymentVolume.between50000And100000": "Zwischen 50.000 und 100.000 €",
116
- "monthlyPaymentVolume.lessThan10000": "Weniger als 10.000 €",
117
- "monthlyPaymentVolume.moreThan100000": "Mehr als 100.000 €",
117
+ "monthlyPaymentVolume.between10000And50000": "Zwischen 10.000 und 50.000 € pro Monat",
118
+ "monthlyPaymentVolume.between50000And100000": "Zwischen 50.000 und 100.000 € pro Monat",
119
+ "monthlyPaymentVolume.lessThan10000": "Weniger als 10.000 € pro Monat",
120
+ "monthlyPaymentVolume.moreThan100000": "Mehr als 100.000 € pro Monat",
118
121
  "registrationPage.defaultNumberLabel": "Registrierungsnummer",
119
122
  "registrationPage.withOrganismLabel": "Ist Ihre Firma bereits im {organismName} eingetragen?",
120
123
  "registrationPage.withoutOrganismNameLabel": "Sind Sie registriert?",
@@ -407,5 +410,6 @@
407
410
  "transactionStatement.type.SepaInstantCreditTransferIn": "SEPA Sofortüberweisung erhalten",
408
411
  "transactionStatement.type.SepaInstantCreditTransferOut": "SEPA Sofortüberweisung gesendet",
409
412
  "validation.birthdateCannotBeFuture": "Geburtsdatum darf nicht in der Zukunft liegen",
410
- "validation.invalidBirthDate": "Bitte geben Sie ein gültiges Geburtsdatum ein."
413
+ "validation.invalidBirthDate": "Bitte geben Sie ein gültiges Geburtsdatum ein.",
414
+ "validation.invalidDate": "Bitte geben Sie ein gültiges Datum ein."
411
415
  }
@@ -24,6 +24,9 @@
24
24
  "creditStatement.titleDocument": "Repayment statement",
25
25
  "creditStatement.column.credit": "Credit",
26
26
  "creditStatement.column.debit": "Debit",
27
+ "creditStatement.issueDate": "Issue date {issueDate}",
28
+ "creditStatement.siret": "SIRET",
29
+ "creditStatement.additionalDetails": "The statement from <bold>{openingDate}</bold> to <bold>{closingDate}</bold> includes all fees and payments received up to {closingDate}. Your next automatic debit will occur starting from {repaymentDate}.\n\nIn the event of a rejected bank withdrawal due to insufficient funds, we may represent this withdrawal at least <bold>3 to 4 days</bold> after the rejection notified by your bank.",
27
30
  "addressFormPart.addressLabel": "Type your address",
28
31
  "addressFormPart.cityLabel": "City",
29
32
  "addressFormPart.placeholder": "Start typing…",
@@ -111,10 +114,10 @@
111
114
  "fileTile.status.Refused": "Refused",
112
115
  "fileTile.status.Validated": "Validated",
113
116
  "fileTile.uploading": "Uploading…",
114
- "monthlyPaymentVolume.between10000And50000": "Between €10,000 and €50,000",
115
- "monthlyPaymentVolume.between50000And100000": "Between €50,000 and €100,000",
116
- "monthlyPaymentVolume.lessThan10000": "Less than €10,000",
117
- "monthlyPaymentVolume.moreThan100000": "More than €100,000",
117
+ "monthlyPaymentVolume.between10000And50000": "Between €10,000 and €50,000 by month",
118
+ "monthlyPaymentVolume.between50000And100000": "Between €50,000 and €100,000 by month",
119
+ "monthlyPaymentVolume.lessThan10000": "Less than €10,000 by month",
120
+ "monthlyPaymentVolume.moreThan100000": "More than €100,000 by month",
118
121
  "registrationPage.defaultNumberLabel": "Registration number",
119
122
  "registrationPage.withOrganismLabel": "Are you registered to {organismName}?",
120
123
  "registrationPage.withoutOrganismNameLabel": "Are you registered?",
@@ -407,5 +410,6 @@
407
410
  "transactionStatement.type.SepaInstantCreditTransferIn": "SEPA Instant Credit Transfer received",
408
411
  "transactionStatement.type.SepaInstantCreditTransferOut": "SEPA Instant Credit Transfer sent",
409
412
  "validation.birthdateCannotBeFuture": "Birthdate cannot be in the future",
410
- "validation.invalidBirthDate": "Please enter a valid birth date."
413
+ "validation.invalidBirthDate": "Please enter a valid birth date.",
414
+ "validation.invalidDate": "Please enter a valid date."
411
415
  }
@@ -67,8 +67,11 @@
67
67
  "common.skipToContent": "Saltar al contenido",
68
68
  "copyButton.copiedTooltip": "Copiado al portapapeles",
69
69
  "copyButton.copyTooltip": "Haz clic para copiar",
70
+ "creditStatement.additionalDetails": "El estado de cuenta desde <bold>{openingDate}</bold> hasta <bold>{closingDate}</bold> incluye todas las comisiones y pagos recibidos hasta el {closingDate}. Tu próximo débito automático se realizará a partir del {repaymentDate}.\n\nEn caso de un rechazo de retiro bancario debido a fondos insuficientes, podemos representar este retiro al menos <bold>3 a 4 días</bold> después del rechazo notificado por tu banco.",
70
71
  "creditStatement.column.credit": "Crédito",
71
72
  "creditStatement.column.debit": "Débito",
73
+ "creditStatement.issueDate": "Fecha de emisión {issueDate}",
74
+ "creditStatement.siret": "SIRET",
72
75
  "creditStatement.titleDocument": "Estado de reembolso",
73
76
  "datePicker.day": "Día",
74
77
  "datePicker.day.friday": "Viernes",
@@ -111,10 +114,10 @@
111
114
  "fileTile.status.Refused": "Rechazado",
112
115
  "fileTile.status.Validated": "Validado",
113
116
  "fileTile.uploading": "Subiendo…",
114
- "monthlyPaymentVolume.between10000And50000": "Entre 10 000 y 50 000 euros",
115
- "monthlyPaymentVolume.between50000And100000": "Entre 50 000 y 100 000 euros",
116
- "monthlyPaymentVolume.lessThan10000": "Menos de 10 000 euros",
117
- "monthlyPaymentVolume.moreThan100000": "Más de 100 000 euros",
117
+ "monthlyPaymentVolume.between10000And50000": "Entre 10 000 y 50 000 euros por mes",
118
+ "monthlyPaymentVolume.between50000And100000": "Entre 50 000 y 100 000 euros por mes",
119
+ "monthlyPaymentVolume.lessThan10000": "Menos de 10 000 euros por mes",
120
+ "monthlyPaymentVolume.moreThan100000": "Más de 100 000 euros por mes",
118
121
  "registrationPage.defaultNumberLabel": "Número de registro",
119
122
  "registrationPage.withOrganismLabel": "¿Estás registrado en {organismName}?",
120
123
  "registrationPage.withoutOrganismNameLabel": "¿Estás registrado?",
@@ -407,5 +410,6 @@
407
410
  "transactionStatement.type.SepaInstantCreditTransferIn": "Transferencia SEPA instantánea recibida",
408
411
  "transactionStatement.type.SepaInstantCreditTransferOut": "Transferencia SEPA instantánea enviada",
409
412
  "validation.birthdateCannotBeFuture": "La fecha de nacimiento no puede estar en el futuro",
410
- "validation.invalidBirthDate": "Por favor, introduce una fecha de nacimiento válida."
413
+ "validation.invalidBirthDate": "Por favor, introduce una fecha de nacimiento válida.",
414
+ "validation.invalidDate": "Por favor, introduce una fecha válida."
411
415
  }
@@ -67,8 +67,11 @@
67
67
  "common.skipToContent": "Ohita ja siirry sisältöön",
68
68
  "copyButton.copiedTooltip": "Kopioitu leikepöydälle",
69
69
  "copyButton.copyTooltip": "Kopioi napsauttamalla",
70
+ "creditStatement.additionalDetails": "Tiliote ajalta <bold>{openingDate}</bold> - <bold>{closingDate}</bold> sisältää kaikki maksut ja saapuneet maksut {closingDate} asti. Seuraava automaattinen veloitus tapahtuu {repaymentDate} alkaen.\n\nJos pankkisiirto hylätään riittämättömien varojen vuoksi, voimme edustaa tätä siirtoa vähintään <bold>3-4 päivää</bold> hylkäyksen jälkeen, jonka pankkisi on ilmoittanut.",
70
71
  "creditStatement.column.credit": "Hyvitys",
71
72
  "creditStatement.column.debit": "Velka",
73
+ "creditStatement.issueDate": "Päiväys {issueDate}",
74
+ "creditStatement.siret": "SIRET",
72
75
  "creditStatement.titleDocument": "Takaisinmaksuilmoitus",
73
76
  "datePicker.day": "Päivä",
74
77
  "datePicker.day.friday": "Perjantai",
@@ -111,10 +114,10 @@
111
114
  "fileTile.status.Refused": "Hylätty",
112
115
  "fileTile.status.Validated": "Vahvistettu",
113
116
  "fileTile.uploading": "Ladataan...",
114
- "monthlyPaymentVolume.between10000And50000": "10 000 euron ja 50 000 euron välillä",
115
- "monthlyPaymentVolume.between50000And100000": "50 000 euron ja 100 000 euron välillä",
116
- "monthlyPaymentVolume.lessThan10000": "Vähemmän kuin 10 000 euroa",
117
- "monthlyPaymentVolume.moreThan100000": "Enemmän kuin 100 000 euroa",
117
+ "monthlyPaymentVolume.between10000And50000": "10 000 euron ja 50 000 euron välillä per kuukausi",
118
+ "monthlyPaymentVolume.between50000And100000": "50 000 euron ja 100 000 euron välillä per kuukausi",
119
+ "monthlyPaymentVolume.lessThan10000": "Vähemmän kuin 10 000 euroa per kuukausi",
120
+ "monthlyPaymentVolume.moreThan100000": "Enemmän kuin 100 000 euroa per kuukausi",
118
121
  "registrationPage.defaultNumberLabel": "Rekisteröintinumero",
119
122
  "registrationPage.withOrganismLabel": "Oletko yrityksesi rekisteröity kohteeseen {organismName}?",
120
123
  "registrationPage.withoutOrganismNameLabel": "Onko yrityksesi rekisteröity?",
@@ -407,5 +410,6 @@
407
410
  "transactionStatement.type.SepaInstantCreditTransferIn": "SEPA Instant -tilisiirto vastaanotettu",
408
411
  "transactionStatement.type.SepaInstantCreditTransferOut": "SEPA Instant -tilisiirto lähetetty",
409
412
  "validation.birthdateCannotBeFuture": "Syntymäaika ei voi olla tulevaisuudessa",
410
- "validation.invalidBirthDate": "Syötä syntymäaika oikeassa muodossa."
413
+ "validation.invalidBirthDate": "Syötä syntymäaika oikeassa muodossa.",
414
+ "validation.invalidDate": "Syötä kelvollinen päivämäärä."
411
415
  }
@@ -67,8 +67,11 @@
67
67
  "common.skipToContent": "Aller au contenu",
68
68
  "copyButton.copiedTooltip": "Copié dans le presse-papier",
69
69
  "copyButton.copyTooltip": "Cliquez pour copier",
70
+ "creditStatement.additionalDetails": "Le relevé du <bold>{openingDate}</bold> au <bold>{closingDate}</bold> inclut tous les frais et paiements reçus jusqu'au {closingDate}. Votre prochain prélèvement automatique débutera à partir du {repaymentDate}.\n\nEn cas de rejet de prélèvement bancaire pour insuffisance de fonds, nous pouvons représenter ce prélèvement au moins <bold>3 à 4 jours</bold> après le rejet notifié par votre banque.",
70
71
  "creditStatement.column.credit": "Crédit",
71
72
  "creditStatement.column.debit": "Débit",
73
+ "creditStatement.issueDate": "Date d'émission {issueDate}",
74
+ "creditStatement.siret": "SIRET",
72
75
  "creditStatement.titleDocument": "Relevé de remboursement",
73
76
  "datePicker.day": "Jour",
74
77
  "datePicker.day.friday": "Vendredi",
@@ -111,10 +114,10 @@
111
114
  "fileTile.status.Refused": "Refusé",
112
115
  "fileTile.status.Validated": "Validé",
113
116
  "fileTile.uploading": "Téléchargement…",
114
- "monthlyPaymentVolume.between10000And50000": "Entre 10 000 € et 50 000 €",
115
- "monthlyPaymentVolume.between50000And100000": "Entre 50 000 € et 100 000 €",
116
- "monthlyPaymentVolume.lessThan10000": "Moins de 10 000 €",
117
- "monthlyPaymentVolume.moreThan100000": "Plus de 100 000 €",
117
+ "monthlyPaymentVolume.between10000And50000": "Entre 10 000 € et 50 000 € par mois",
118
+ "monthlyPaymentVolume.between50000And100000": "Entre 50 000 € et 100 000 € par mois",
119
+ "monthlyPaymentVolume.lessThan10000": "Moins de 10 000 € par mois",
120
+ "monthlyPaymentVolume.moreThan100000": "Plus de 100 000 € par mois",
118
121
  "registrationPage.defaultNumberLabel": "Numéro d'immatriculation",
119
122
  "registrationPage.withOrganismLabel": "Êtes-vous immatriculé au {organismName}?",
120
123
  "registrationPage.withoutOrganismNameLabel": "Êtes-vous immatriculé?",
@@ -407,5 +410,6 @@
407
410
  "transactionStatement.type.SepaInstantCreditTransferIn": "Virement SEPA instantané reçu",
408
411
  "transactionStatement.type.SepaInstantCreditTransferOut": "Virement SEPA instantané envoyé",
409
412
  "validation.birthdateCannotBeFuture": "La date de naissance ne peut pas être dans le futur",
410
- "validation.invalidBirthDate": "Veuillez saisir une date de naissance valide."
413
+ "validation.invalidBirthDate": "Veuillez saisir une date de naissance valide.",
414
+ "validation.invalidDate": "Veuillez saisir une date valide."
411
415
  }
@@ -67,8 +67,11 @@
67
67
  "common.skipToContent": "Salta al contenuto",
68
68
  "copyButton.copiedTooltip": "Copiato negli appunti",
69
69
  "copyButton.copyTooltip": "Clicca per copiare",
70
+ "creditStatement.additionalDetails": "Il rendiconto dal <bold>{openingDate}</bold> al <bold>{closingDate}</bold> include tutte le commissioni e i pagamenti ricevuti fino al {closingDate}. Il prossimo addebito automatico avverrà a partire dal {repaymentDate}.\n\nIn caso di mancato prelievo bancario a causa di fondi insufficienti, potremmo rappresentare questo prelievo almeno <bold>3 o 4 giorni</bold> dopo il rifiuto comunicato dalla tua banca.",
70
71
  "creditStatement.column.credit": "Credito",
71
72
  "creditStatement.column.debit": "Addebito",
73
+ "creditStatement.issueDate": "Data di emissione {issueDate}",
74
+ "creditStatement.siret": "SIRET",
72
75
  "creditStatement.titleDocument": "Riepilogo dei rimborsi",
73
76
  "datePicker.day": "Giorno",
74
77
  "datePicker.day.friday": "Venerdì",
@@ -111,10 +114,10 @@
111
114
  "fileTile.status.Refused": "Rifiutato",
112
115
  "fileTile.status.Validated": "Convalidato",
113
116
  "fileTile.uploading": "Caricamento…",
114
- "monthlyPaymentVolume.between10000And50000": "Tra €10.000 e €50.000",
115
- "monthlyPaymentVolume.between50000And100000": "Tra €50.000 e €100.000",
116
- "monthlyPaymentVolume.lessThan10000": "Meno di €10.000",
117
- "monthlyPaymentVolume.moreThan100000": "Più di €100.000",
117
+ "monthlyPaymentVolume.between10000And50000": "Tra €10.000 e €50.000 al mese",
118
+ "monthlyPaymentVolume.between50000And100000": "Tra €50.000 e €100.000 al mese",
119
+ "monthlyPaymentVolume.lessThan10000": "Meno di €10.000 al mese",
120
+ "monthlyPaymentVolume.moreThan100000": "Più di €100.000 al mese",
118
121
  "registrationPage.defaultNumberLabel": "Numero di registrazione",
119
122
  "registrationPage.withOrganismLabel": "È registrato a {organismName}?",
120
123
  "registrationPage.withoutOrganismNameLabel": "È registrato?",
@@ -407,5 +410,6 @@
407
410
  "transactionStatement.type.SepaInstantCreditTransferIn": "Bonifico istantaneo SEPA ricevuto",
408
411
  "transactionStatement.type.SepaInstantCreditTransferOut": "Bonifico istantaneo SEPA inviato",
409
412
  "validation.birthdateCannotBeFuture": "La data di nascita non può essere nel futuro",
410
- "validation.invalidBirthDate": "Inserisci una data di nascita valida."
413
+ "validation.invalidBirthDate": "Inserisci una data di nascita valida.",
414
+ "validation.invalidDate": "Inserisci una data valida."
411
415
  }
@@ -67,8 +67,11 @@
67
67
  "common.skipToContent": "Doorgaan naar artikel",
68
68
  "copyButton.copiedTooltip": "Gekopieerd naar klembord",
69
69
  "copyButton.copyTooltip": "Klik om te kopiëren",
70
+ "creditStatement.additionalDetails": "Het overzicht van <bold>{openingDate}</bold> tot <bold>{closingDate}</bold> omvat alle kosten en ontvangen betalingen tot {closingDate}. Uw volgende automatische incasso zal starten vanaf {repaymentDate}.\n\nBij een geweigerde bankafschrijving wegens onvoldoende saldo, kunnen wij deze afschrijving op zijn vroegst <bold>3 tot 4 dagen</bold> na de melding van uw bank opnieuw aanbieden.",
70
71
  "creditStatement.column.credit": "Credit",
71
72
  "creditStatement.column.debit": "Debit",
73
+ "creditStatement.issueDate": "Uitgiftedatum {issueDate}",
74
+ "creditStatement.siret": "SIRET",
72
75
  "creditStatement.titleDocument": "Terugbetalingsverklaring",
73
76
  "datePicker.day": "Dag",
74
77
  "datePicker.day.friday": "Vrijdag",
@@ -111,10 +114,10 @@
111
114
  "fileTile.status.Refused": "Geweigerd",
112
115
  "fileTile.status.Validated": "Gevalideerd",
113
116
  "fileTile.uploading": "Bezig met uploaden…",
114
- "monthlyPaymentVolume.between10000And50000": "€ 10.000,- tot € 50.000,-",
115
- "monthlyPaymentVolume.between50000And100000": "€ 50.000,- tot € 100.000,-",
116
- "monthlyPaymentVolume.lessThan10000": "Minder dan € 10.000,-",
117
- "monthlyPaymentVolume.moreThan100000": "Meer dan € 100.000,-",
117
+ "monthlyPaymentVolume.between10000And50000": "€ 10.000,- tot € 50.000,- per maand",
118
+ "monthlyPaymentVolume.between50000And100000": "€ 50.000,- tot € 100.000,- per maand",
119
+ "monthlyPaymentVolume.lessThan10000": "Minder dan € 10.000,- per maand",
120
+ "monthlyPaymentVolume.moreThan100000": "Meer dan € 100.000,- per maand",
118
121
  "registrationPage.defaultNumberLabel": "Registratienummer",
119
122
  "registrationPage.withOrganismLabel": "Bent u geregistreerd bij {organismName}?",
120
123
  "registrationPage.withoutOrganismNameLabel": "Bent u geregistreerd?",
@@ -407,5 +410,6 @@
407
410
  "transactionStatement.type.SepaInstantCreditTransferIn": "SEPA Instant-overschrijving ontvangen",
408
411
  "transactionStatement.type.SepaInstantCreditTransferOut": "SEPA Instant-overschrijving verzonden",
409
412
  "validation.birthdateCannotBeFuture": "Geboortedatum kan niet in de toekomst liggen",
410
- "validation.invalidBirthDate": "Voer een geldige geboortedatum in."
413
+ "validation.invalidBirthDate": "Voer een geldige geboortedatum in.",
414
+ "validation.invalidDate": "Voer alstublieft een geldige datum in."
411
415
  }
@@ -67,8 +67,11 @@
67
67
  "common.skipToContent": "Saltar para o conteúdo",
68
68
  "copyButton.copiedTooltip": "Copiado para a área de transferência",
69
69
  "copyButton.copyTooltip": "Clique para copiar",
70
+ "creditStatement.additionalDetails": "O extrato de <bold>{openingDate}</bold> a <bold>{closingDate}</bold> inclui todas as taxas e pagamentos recebidos até {closingDate}. Seu próximo débito automático ocorrerá a partir de {repaymentDate}.\n\nNo caso de uma retirada bancária rejeitada devido a fundos insuficientes, podemos representar esta retirada pelo menos <bold>3 a 4 dias</bold> após a rejeição notificada pelo seu banco.",
70
71
  "creditStatement.column.credit": "Crédito",
71
72
  "creditStatement.column.debit": "Débito",
73
+ "creditStatement.issueDate": "Data de emissão {issueDate}",
74
+ "creditStatement.siret": "SIRET",
72
75
  "creditStatement.titleDocument": "Declaração de reembolso",
73
76
  "datePicker.day": "Dia",
74
77
  "datePicker.day.friday": "Sexta-feira",
@@ -111,10 +114,10 @@
111
114
  "fileTile.status.Refused": "Recusado",
112
115
  "fileTile.status.Validated": "Validado",
113
116
  "fileTile.uploading": "Carregando…",
114
- "monthlyPaymentVolume.between10000And50000": "Entre €10.000 e €50.000",
115
- "monthlyPaymentVolume.between50000And100000": "Entre €50.000 e €100.000",
116
- "monthlyPaymentVolume.lessThan10000": "Menos de €10.000",
117
- "monthlyPaymentVolume.moreThan100000": "Mais de €100.000",
117
+ "monthlyPaymentVolume.between10000And50000": "Entre €10.000 e €50.000 por mês",
118
+ "monthlyPaymentVolume.between50000And100000": "Entre €50.000 e €100.000 por mês",
119
+ "monthlyPaymentVolume.lessThan10000": "Menos de €10.000 por mês",
120
+ "monthlyPaymentVolume.moreThan100000": "Mais de €100.000 por mês",
118
121
  "registrationPage.defaultNumberLabel": "Número de registo",
119
122
  "registrationPage.withOrganismLabel": "Está registado no {organismName}?",
120
123
  "registrationPage.withoutOrganismNameLabel": "Está registado?",
@@ -407,5 +410,6 @@
407
410
  "transactionStatement.type.SepaInstantCreditTransferIn": "Transferência de crédito instantânea SEPA recebida",
408
411
  "transactionStatement.type.SepaInstantCreditTransferOut": "Transferência de crédito instantânea SEPA enviada",
409
412
  "validation.birthdateCannotBeFuture": "A data de nascimento não pode estar no futuro",
410
- "validation.invalidBirthDate": "Por favor, introduza uma data de nascimento válida."
413
+ "validation.invalidBirthDate": "Por favor, introduza uma data de nascimento válida.",
414
+ "validation.invalidDate": "Por favor, insira uma data válida."
411
415
  }
@@ -10,4 +10,5 @@ export declare const validateIndividualTaxNumber: (accountCountry: AccountCountr
10
10
  export declare const validateCompanyTaxNumber: (accountCountry: AccountCountry) => Validator<string | undefined>;
11
11
  export { printFormat as printIbanFormat } from "iban";
12
12
  export declare const validateIban: (iban: string) => string | undefined;
13
+ export declare const validateDate: (value: ExtractedDate | undefined) => string | undefined;
13
14
  export declare const validateBirthdate: (value: ExtractedDate | undefined) => string | undefined;
@@ -111,6 +111,15 @@ export const validateIban = (iban) => {
111
111
  return t("error.iban.invalid");
112
112
  }
113
113
  };
114
+ export const validateDate = (value) => {
115
+ if (isNullish(value)) {
116
+ return t("validation.invalidDate");
117
+ }
118
+ const date = dayjs.utc(formatExtractedDate(value), "YYYY-MM-DD", true);
119
+ if (!date.isValid()) {
120
+ return t("validation.invalidDate");
121
+ }
122
+ };
114
123
  export const validateBirthdate = (value) => {
115
124
  if (isNullish(value)) {
116
125
  return t("validation.invalidBirthDate");