From 4f52e401d459fd435ec5153b389f132b03cb7f52 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Fri, 25 Jul 2025 15:19:23 +0200 Subject: [PATCH] fix link --- .../components/GddSend/TransactionForm.vue | 80 ++++++++++--------- frontend/src/locales/de.json | 7 +- frontend/src/locales/en.json | 7 +- frontend/src/validationSchemas.js | 10 +-- 4 files changed, 58 insertions(+), 46 deletions(-) diff --git a/frontend/src/components/GddSend/TransactionForm.vue b/frontend/src/components/GddSend/TransactionForm.vue index 510ba3786..f37e3171e 100644 --- a/frontend/src/components/GddSend/TransactionForm.vue +++ b/frontend/src/components/GddSend/TransactionForm.vue @@ -130,6 +130,7 @@ lg="6" class="text-lg-end" @mouseover="disableSmartValidState = true" + @mouseleave="debug" > {{ $t('form.check_now') }} @@ -181,41 +182,6 @@ const { toastError } = useAppToast() const radioSelected = ref(props.selected) const userName = ref('') -const validationSchema = computed(() => { - return object({ - memo: memoSchema, - identifier: !userIdentifier.value - ? identifierSchema.required('form.validation.identifier.required') - : identifierSchema, - amount: number() - .required() - .typeError({ - key: 'form.validation.amount.typeError', - values: { min: 0.01, max: props.balance }, - }) - .transform((value, originalValue) => { - if (typeof originalValue === 'string') { - return Number(originalValue.replace(',', '.')) - } - return value - }) - .min(0.01, ({ min }) => ({ key: 'form.validation.amount.min', values: { min } })) - .max(props.balance, ({ max }) => ({ key: 'form.validation.amount.max', values: { max } })) - .test('decimal-places', 'form.validation.amount.decimal-places', (value) => { - if (value === undefined || value === null) return true - return /^\d+(\.\d{0,2})?$/.test(value.toString()) - }), - }) -}) - -const formIsInvalid = computed(() => !validationSchema.value.isValidSync(form)) - -const updateField = (newValue, name) => { - if (typeof name === 'string' && name.length) { - form[name] = newValue - } -} - const userIdentifier = computed(() => { if (route.params.userIdentifier && route.params.communityIdentifier) { return { @@ -226,6 +192,48 @@ const userIdentifier = computed(() => { return null }) +const validationSchema = computed(() => { + const amountSchema = number() + .required() + .typeError({ + key: 'form.validation.amount.typeError', + values: { min: 0.01, max: props.balance }, + }) + .transform((value, originalValue) => { + if (typeof originalValue === 'string') { + return Number(originalValue.replace(',', '.')) + } + return value + }) + .min(0.01, ({ min }) => ({ key: 'form.validation.amount.min', values: { min } })) + .max(props.balance, ({ max }) => ({ key: 'form.validation.amount.max', values: { max } })) + .test('decimal-places', 'form.validation.amount.decimal-places', (value) => { + if (value === undefined || value === null) return true + return /^\d+(\.\d{0,2})?$/.test(value.toString()) + }) + if (!userIdentifier.value && radioSelected.value === SEND_TYPES.send) { + return object({ + memo: memoSchema, + amount: amountSchema, + identifier: identifierSchema, + }) + } else { + // don't need identifier schema if it is a transaction link or identifier was set via url + return object({ + memo: memoSchema, + amount: amountSchema, + }) + } +}) + +const formIsInvalid = computed(() => !validationSchema.value.isValidSync(form)) + +const updateField = (newValue, name) => { + if (typeof name === 'string' && name.length) { + form[name] = newValue + } +} + const isBalanceEmpty = computed(() => props.balance <= 0) const { result: userResult, error: userError } = useQuery( @@ -254,8 +262,8 @@ watch(userError, (error) => { function onSubmit() { const transformedForm = validationSchema.value.cast(form) emit('set-transaction', { - selected: radioSelected.value, ...transformedForm, + selected: radioSelected.value, userName: userName.value, }) } diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 7a68d3819..c9609fb34 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -226,6 +226,10 @@ "typeError": "Die Stunden sollten eine Zahl zwischen {min} und {max} mit höchstens zwei Nachkommastellen sein." }, "gddSendAmount": "Das Feld {_field_} muss eine Zahl zwischen {min} und {max} mit höchstens zwei Nachkommastellen sein.", + "identifier": { + "required": "Der Empfänger ist ein Pflichtfeld.", + "typeError": "Der Empfänger muss eine Email, ein Nutzernamen oder eine Gradido ID sein." + }, "is-not": "Du kannst dir selbst keine Gradidos überweisen!", "memo": { "min": "Die Nachricht sollte mindestens {min} Zeichen lang sein.", @@ -235,8 +239,7 @@ "requiredField": "{fieldName} ist ein Pflichtfeld", "username-allowed-chars": "Der Nutzername darf nur aus Buchstaben (ohne Umlaute), Zahlen, Binde- oder Unterstrichen bestehen.", "username-hyphens": "Binde- oder Unterstriche müssen zwischen Buchstaben oder Zahlen stehen.", - "username-unique": "Der Nutzername ist bereits vergeben.", - "valid-identifier": "Muss eine Email, ein Nutzernamen oder eine Gradido ID sein." + "username-unique": "Der Nutzername ist bereits vergeben." }, "your_amount": "Dein Betrag" }, diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 69825bd7e..67abc2fe7 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -226,6 +226,10 @@ "typeError": "The hours should be a number between {min} and {max} with at most two digits after the decimal point." }, "gddSendAmount": "The {_field_} field must be a number between {min} and {max} with at most two digits after the decimal point.", + "identifier": { + "required": "The recipient is a required field.", + "typeError": "The recipient must be an email, a username or a Gradido ID." + }, "is-not": "You cannot send Gradidos to yourself!", "memo": { "min": "The message should be at least {min} characters long.", @@ -235,8 +239,7 @@ "requiredField": "The {fieldName} field is required", "username-allowed-chars": "The username may only contain letters, numbers, hyphens or underscores.", "username-hyphens": "Hyphens or underscores must be in between letters or numbers.", - "username-unique": "This username is already taken.", - "valid-identifier": "Must be a valid email, username or gradido ID." + "username-unique": "This username is already taken." }, "your_amount": "Your amount" }, diff --git a/frontend/src/validationSchemas.js b/frontend/src/validationSchemas.js index eff976c84..fd995d63a 100644 --- a/frontend/src/validationSchemas.js +++ b/frontend/src/validationSchemas.js @@ -26,14 +26,12 @@ export const memo = string() .min(5, ({ min }) => ({ key: 'form.validation.memo.min', values: { min } })) .max(255, ({ max }) => ({ key: 'form.validation.memo.max', values: { max } })) -export const identifier = string().test( - 'valid-identifier', - 'form.validation.valid-identifier', - (value) => { +export const identifier = string() + .required('form.validation.identifier.required') + .test('valid-identifier', 'form.validation.identifier.typeError', (value) => { const isEmail = !!EMAIL_REGEX.test(value) const isUsername = !!value.match(USERNAME_REGEX) // TODO: use valibot and rules from shared const isGradidoId = validateUuid(value) && versionUuid(value) === 4 return isEmail || isUsername || isGradidoId - }, -) + })