diff --git a/i18n/en.pot b/i18n/en.pot index 15c29834..c8c1135b 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2023-02-27T14:55:39.217Z\n" -"PO-Revision-Date: 2023-02-27T14:55:39.217Z\n" +"POT-Creation-Date: 2024-11-21T08:20:57.566Z\n" +"PO-Revision-Date: 2024-11-21T08:20:57.566Z\n" msgid "Never" msgstr "Never" @@ -289,6 +289,9 @@ msgstr "Could not disable two factor authentication" msgid "Two factor authentication was disabled successfully" msgstr "Two factor authentication was disabled successfully" +msgid "Please choose a profile avatar less than {{- maxSize}}MB in size." +msgstr "Please choose a profile avatar less than {{- maxSize}}MB in size." + msgid "Failed to upload profile picture" msgstr "Failed to upload profile picture" @@ -364,6 +367,15 @@ msgstr "Personal access tokens" msgid "About DHIS2" msgstr "About DHIS2" +msgid "Email verification link sent successfully!" +msgstr "Email verification link sent successfully!" + +msgid "Failed to send email verification link." +msgstr "Failed to send email verification link." + +msgid "Verify Email" +msgstr "Verify Email" + msgid "Manage personal access tokens" msgstr "Manage personal access tokens" @@ -588,6 +600,9 @@ msgstr "Other" msgid "E-mail" msgstr "E-mail" +msgid "E-mail Verification" +msgstr "E-mail Verification" + msgid "Mobile phone number" msgstr "Mobile phone number" diff --git a/src/layout/FormFields.component.js b/src/layout/FormFields.component.js index ac50956f..c01d84c3 100644 --- a/src/layout/FormFields.component.js +++ b/src/layout/FormFields.component.js @@ -16,6 +16,7 @@ import userSettingsStore from '../settings/userSettings.store.js' import userSettingsKeyMapping from '../userSettingsMapping.js' import AvatarEditor from './AvatarEditor.component.js' import AppTheme from './theme.js' +import { VerifyEmail } from './VerifyEmail.component.js' const styles = { header: { @@ -234,9 +235,21 @@ function createAvatarEditor(fieldBase, d2, valueStore) { }) } +function createVerifyButton(fieldBase, valueStore) { + return Object.assign({}, fieldBase, { + component: VerifyEmail, + props: { userEmail: valueStore.state['email'] || '' }, + }) +} + function createFieldBaseObject(fieldName, mapping, valueStore) { + if (!mapping) { + log.warn(`Mapping not found for field: ${fieldName}`) + return null // Skip this field + } + const state = valueStore.state - const hintText = mapping.hintText + const hintText = mapping.hintText || '' const valueString = Object.prototype.hasOwnProperty.call(state, fieldName) ? String(state[fieldName]).trim() @@ -265,6 +278,7 @@ function createFieldBaseObject(fieldName, mapping, valueStore) { function createField(fieldName, valueStore, d2) { const mapping = userSettingsKeyMapping[fieldName] const fieldBase = createFieldBaseObject(fieldName, mapping, valueStore) + switch (mapping.type) { case 'textfield': return createTextField(fieldBase, mapping) @@ -278,6 +292,8 @@ function createField(fieldName, valueStore, d2) { return createAccountEditor(fieldBase, d2, valueStore) case 'avatar': return createAvatarEditor(fieldBase, d2, valueStore) + case 'submit': + return createVerifyButton(fieldBase, valueStore) default: log.warn( `Unknown control type "${mapping.type}" encountered for field "${fieldName}"` @@ -348,7 +364,7 @@ class FormFields extends Component { renderFields(fieldNames) { const d2 = this.context.d2 const valueStore = this.props.valueStore - + // Create the regular fields const fields = fieldNames .map((fieldName) => createField(fieldName, valueStore, d2)) .filter((field) => !!field.name) diff --git a/src/layout/VerifyEmail.component.js b/src/layout/VerifyEmail.component.js new file mode 100644 index 00000000..92e0d833 --- /dev/null +++ b/src/layout/VerifyEmail.component.js @@ -0,0 +1,57 @@ +import { useAlert, useDataMutation, useConfig } from '@dhis2/app-runtime' +import { Button } from '@dhis2/ui' +import PropTypes from 'prop-types' +import React from 'react' +import i18n from '../locales/index.js' + +const sendEmailVerificationMutation = { + resource: 'account/sendEmailVerification', + type: 'create', +} + +export function VerifyEmail({ userEmail }) { + const errorAlert = useAlert(({ message }) => message, { critical: true }) + const successAlert = useAlert(({ message }) => message, { success: true }) + const { systemInfo } = useConfig() + + const [mutateEmailVerification, { loading: mutationLoading }] = + useDataMutation(sendEmailVerificationMutation, { + onComplete: () => { + successAlert.show({ + message: i18n.t( + 'Email verification link sent successfully!' + ), + }) + }, + onError: (err) => { + errorAlert.show({ + message: + err.message || + i18n.t('Failed to send email verification link.'), + }) + }, + }) + + const emailConfigured = systemInfo?.emailConfigured + + if (!emailConfigured) { + return null // If emailConfigured is false, don't display the button + } + + return ( +