Add town and currency fields to user settings
Adds two new fields to user settings form: - Town field: Text input for city/town (required when 2D code enabled) - Currency field: Select dropdown with ISO 4217 currency codes (EUR default) Updates: - Database schema: Added town and currency fields to UserSettings - Validation: Both fields required when 2D code is enabled - Form UI: Added input fields with proper validation and error handling - Translations: Added Croatian and English labels and error messages - Currency options: 36 ISO 4217 codes with EUR at top as default 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,9 @@ export type State = {
|
||||
firstName?: string[];
|
||||
lastName?: string[];
|
||||
street?: string[];
|
||||
town?: string[];
|
||||
iban?: string[];
|
||||
currency?: string[];
|
||||
show2dCodeInMonthlyStatement?: string[];
|
||||
};
|
||||
message?: string | null;
|
||||
@@ -31,6 +33,7 @@ const FormSchema = (t: IntlTemplateFn) => z.object({
|
||||
firstName: z.string().optional(),
|
||||
lastName: z.string().optional(),
|
||||
street: z.string().optional(),
|
||||
town: z.string().optional(),
|
||||
iban: z.string()
|
||||
.optional()
|
||||
.refine(
|
||||
@@ -42,6 +45,7 @@ const FormSchema = (t: IntlTemplateFn) => z.object({
|
||||
},
|
||||
{ message: t("iban-invalid") }
|
||||
),
|
||||
currency: z.string().optional(),
|
||||
show2dCodeInMonthlyStatement: z.boolean().optional().nullable(),
|
||||
})
|
||||
.refine((data) => {
|
||||
@@ -71,6 +75,15 @@ const FormSchema = (t: IntlTemplateFn) => z.object({
|
||||
message: t("street-required"),
|
||||
path: ["street"],
|
||||
})
|
||||
.refine((data) => {
|
||||
if (data.show2dCodeInMonthlyStatement) {
|
||||
return !!data.town && data.town.trim().length > 0;
|
||||
}
|
||||
return true;
|
||||
}, {
|
||||
message: t("town-required"),
|
||||
path: ["town"],
|
||||
})
|
||||
.refine((data) => {
|
||||
if (data.show2dCodeInMonthlyStatement) {
|
||||
if (!data.iban || data.iban.trim().length === 0) {
|
||||
@@ -84,6 +97,15 @@ const FormSchema = (t: IntlTemplateFn) => z.object({
|
||||
}, {
|
||||
message: t("iban-required"),
|
||||
path: ["iban"],
|
||||
})
|
||||
.refine((data) => {
|
||||
if (data.show2dCodeInMonthlyStatement) {
|
||||
return !!data.currency && data.currency.trim().length > 0;
|
||||
}
|
||||
return true;
|
||||
}, {
|
||||
message: t("currency-required"),
|
||||
path: ["currency"],
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -113,7 +135,9 @@ export const updateUserSettings = withUser(async (user: AuthenticatedUser, prevS
|
||||
firstName: formData.get('firstName') || undefined,
|
||||
lastName: formData.get('lastName') || undefined,
|
||||
street: formData.get('street') || undefined,
|
||||
town: formData.get('town') || undefined,
|
||||
iban: formData.get('iban') || undefined,
|
||||
currency: formData.get('currency') || undefined,
|
||||
show2dCodeInMonthlyStatement: formData.get('generateTenantCode') === 'on',
|
||||
});
|
||||
|
||||
@@ -126,7 +150,7 @@ export const updateUserSettings = withUser(async (user: AuthenticatedUser, prevS
|
||||
};
|
||||
}
|
||||
|
||||
const { firstName, lastName, street, iban, show2dCodeInMonthlyStatement } = validatedFields.data;
|
||||
const { firstName, lastName, street, town, iban, currency, show2dCodeInMonthlyStatement } = validatedFields.data;
|
||||
|
||||
// Normalize IBAN: remove spaces and convert to uppercase
|
||||
const normalizedIban = iban ? iban.replace(/\s/g, '').toUpperCase() : null;
|
||||
@@ -140,7 +164,9 @@ export const updateUserSettings = withUser(async (user: AuthenticatedUser, prevS
|
||||
firstName: firstName || null,
|
||||
lastName: lastName || null,
|
||||
street: street || null,
|
||||
town: town || null,
|
||||
iban: normalizedIban,
|
||||
currency: currency || null,
|
||||
show2dCodeInMonthlyStatement: show2dCodeInMonthlyStatement ?? false,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user