From 1249b5aaf7263b0ccfacdf9babab11f7da16ef45 Mon Sep 17 00:00:00 2001 From: Chisomchima Date: Tue, 19 Nov 2024 09:15:02 +0100 Subject: [PATCH] feat: add send email verification button --- i18n/en.pot | 13 ++++++-- src/layout/FormFields.component.js | 27 ++++++++++++++++- src/layout/VerifyEmail.component.js | 47 +++++++++++++++++++++++++++++ src/profile/Profile.component.js | 1 + src/userSettingsMapping.js | 5 +++ 5 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 src/layout/VerifyEmail.component.js diff --git a/i18n/en.pot b/i18n/en.pot index 15c29834..d6e69e8e 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-19T05:39:42.631Z\n" +"PO-Revision-Date: 2024-11-19T05:39:42.631Z\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" @@ -343,6 +346,9 @@ msgstr "No options" msgid "System default" msgstr "System default" +msgid "Verify Email" +msgstr "Verify Email" + msgid "User profile" msgstr "User profile" @@ -588,6 +594,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..6ebc2289 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: { @@ -235,8 +236,15 @@ function createAvatarEditor(fieldBase, d2, valueStore) { } function createFieldBaseObject(fieldName, mapping, valueStore) { + console.log('Field:', fieldName, 'Mapping:', mapping) + + 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() @@ -345,15 +353,32 @@ class FormFields extends Component { this.disposable.unsubscribe() } + handleEmailVerification = async () => { + await VerifyEmail() + } + 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) .map((field) => wrapFieldWithLabel(field)) + // Append the Verify Email button after the 'email' field + const emailFieldIndex = fieldNames.indexOf('email') + if (emailFieldIndex !== -1) { + const verifyEmailField = { + name: 'emailVerification', + component: VerifyEmail, + props: {}, + } + + fields.splice(emailFieldIndex + 1, 0, verifyEmailField) + } + return ( diff --git a/src/layout/VerifyEmail.component.js b/src/layout/VerifyEmail.component.js new file mode 100644 index 00000000..2676615d --- /dev/null +++ b/src/layout/VerifyEmail.component.js @@ -0,0 +1,47 @@ +import { useAlert } from '@dhis2/app-runtime' +import { getInstance as getD2 } from 'd2' +import { blue400 } from 'material-ui/styles/colors.js' +import React from 'react' + +export function VerifyEmail() { + const errorAlert = useAlert(({ message }) => message, { critical: true }) + const successAlert = useAlert(({ message }) => message, { success: true }) + + const handleEmailVerification = async () => { + try { + const d2 = await getD2() + const api = d2.Api.getApi() + api.baseUrl = 'http://localhost:8080/' + + const res = await api.post('account/sendEmailVerification') + console.log('Response:', res) + successAlert.show({ + message: 'Email verification link sent successfully!', + }) + } catch (err) { + console.error('Error:', err) + errorAlert.show({ + message: + err.message || 'Failed to send email verification link.', + }) + } + } + + return ( + + ) +} diff --git a/src/profile/Profile.component.js b/src/profile/Profile.component.js index 3c0dc680..1e9c1657 100644 --- a/src/profile/Profile.component.js +++ b/src/profile/Profile.component.js @@ -25,6 +25,7 @@ function EditProfile() { 'skype', 'telegram', 'twitter', + 'emailVerification', ] const pageLabel = i18n.t('Edit user profile') diff --git a/src/userSettingsMapping.js b/src/userSettingsMapping.js index b7ca284c..21edf7f0 100644 --- a/src/userSettingsMapping.js +++ b/src/userSettingsMapping.js @@ -32,6 +32,11 @@ const settingsKeyMapping = { type: 'textfield', validators: ['email'], }, + emailVerification: { + label: i18n.t('E-mail Verification'), + type: 'submit', + multiLine: true, + }, phoneNumber: { label: i18n.t('Mobile phone number'), type: 'textfield',