diff --git a/packages/volto-hydra/src/customizations/components/manage/Form/Form.jsx b/packages/volto-hydra/src/customizations/components/manage/Form/Form.jsx
index 00b06a0..ce60d07 100644
--- a/packages/volto-hydra/src/customizations/components/manage/Form/Form.jsx
+++ b/packages/volto-hydra/src/customizations/components/manage/Form/Form.jsx
@@ -324,7 +324,7 @@ class Form extends Component {
) {
this.setState(() => ({ sidebarMetadataIsAvailable: true }));
}
- if (this.props.location.pathname !== prevProps.location.pathname) {
+ if (this.props?.location?.pathname !== prevProps?.location?.pathname) {
this.setState({ formData: this.props.formData });
}
}
diff --git a/packages/volto-hydra/src/customizations/components/manage/Preferences/PersonalPreferences.jsx b/packages/volto-hydra/src/customizations/components/manage/Preferences/PersonalPreferences.jsx
new file mode 100644
index 0000000..86506c3
--- /dev/null
+++ b/packages/volto-hydra/src/customizations/components/manage/Preferences/PersonalPreferences.jsx
@@ -0,0 +1,195 @@
+/**
+ * Personal preferences component.
+ * @module components/manage/Preferences/PersonalPreferences
+ */
+
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import { compose } from 'redux';
+import { map, keys } from 'lodash';
+import { withCookies } from 'react-cookie';
+import { defineMessages, injectIntl } from 'react-intl';
+import { toast } from 'react-toastify';
+
+import { Toast } from '@plone/volto/components';
+import { Form } from '@plone/volto/components/manage/Form';
+import languages from '@plone/volto/constants/Languages';
+import { changeLanguage } from '@plone/volto/actions';
+import { toGettextLang } from '@plone/volto/helpers';
+import config from '@plone/volto/registry';
+
+const urls = {
+ URL1: 'http://localhost:3000',
+ URL2: 'http://localhost:3001',
+ URL3: 'http://localhost:3002',
+};
+
+const messages = defineMessages({
+ personalPreferences: {
+ id: 'Personal Preferences',
+ defaultMessage: 'Personal Preferences',
+ },
+ default: {
+ id: 'Default',
+ defaultMessage: 'Default',
+ },
+ language: {
+ id: 'Language',
+ defaultMessage: 'Language',
+ },
+ languageDescription: {
+ id: 'Your preferred language',
+ defaultMessage: 'Your preferred language',
+ },
+ saved: {
+ id: 'Changes saved',
+ defaultMessage: 'Changes saved',
+ },
+ back: {
+ id: 'Back',
+ defaultMessage: 'Back',
+ },
+ success: {
+ id: 'Success',
+ defaultMessage: 'Success',
+ },
+ frontendUrls: {
+ id: 'Select Frontend URL',
+ defaultMessage: 'Select Frontend URL',
+ },
+ frontendUrl: {
+ id: 'Enter Frontend URL',
+ defaultMessage: 'Enter Frontend URL',
+ },
+ urlsDescription: {
+ id: `Select your Frontend's base URL`,
+ defaultMessage: `Select your Frontend's base URL`,
+ },
+ urlDescription: {
+ id: `OR Enter your Frontend's base URL`,
+ defaultMessage: `OR Enter your Frontend's base URL`,
+ },
+});
+
+/**
+ * PersonalPreferences class.
+ * @class PersonalPreferences
+ * @extends Component
+ */
+class PersonalPreferences extends Component {
+ /**
+ * Property types.
+ * @property {Object} propTypes Property types.
+ * @static
+ */
+ static propTypes = {
+ changeLanguage: PropTypes.func.isRequired,
+ closeMenu: PropTypes.func.isRequired,
+ };
+
+ /**
+ * Constructor
+ * @method constructor
+ * @param {Object} props Component properties
+ * @constructs PersonalPreferences
+ */
+ constructor(props) {
+ super(props);
+ this.onCancel = this.onCancel.bind(this);
+ this.onSubmit = this.onSubmit.bind(this);
+ }
+
+ /**
+ * Submit handler
+ * @method onSubmit
+ * @param {object} data Form data.
+ * @returns {undefined}
+ */
+ onSubmit(data) {
+ let language = data.language || 'en';
+ if (config.settings.supportedLanguages.includes(language)) {
+ const langFileName = toGettextLang(language);
+ import('@root/../locales/' + langFileName + '.json').then((locale) => {
+ this.props.changeLanguage(language, locale.default);
+ });
+ }
+ toast.success(
+