design-comuni-plone-theme 11.21.1 → 11.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +30 -0
  3. package/RELEASE.md +18 -0
  4. package/locales/de/LC_MESSAGES/volto.po +40 -5
  5. package/locales/en/LC_MESSAGES/volto.po +40 -5
  6. package/locales/es/LC_MESSAGES/volto.po +40 -5
  7. package/locales/fr/LC_MESSAGES/volto.po +40 -5
  8. package/locales/it/LC_MESSAGES/volto.po +40 -5
  9. package/locales/volto.pot +41 -6
  10. package/package.json +1 -1
  11. package/publiccode.yml +2 -2
  12. package/src/components/ItaliaTheme/AppExtras/GenericAppExtras.jsx +1 -2
  13. package/src/components/ItaliaTheme/Blocks/EventSearch/DefaultFilters.js +1 -11
  14. package/src/components/ItaliaTheme/CustomerSatisfaction/FeedbackForm.jsx +3 -18
  15. package/src/components/ItaliaTheme/LoginAgid/LoginAgid.jsx +2 -5
  16. package/src/components/ItaliaTheme/Search/Search.jsx +2 -3
  17. package/src/components/ItaliaTheme/Unauthorized/Unauthorized.jsx +2 -5
  18. package/src/components/ItaliaTheme/View/PersonaView/PersonaDocumenti.jsx +50 -0
  19. package/src/components/ItaliaTheme/View/UOView/UOMetadati.jsx +12 -0
  20. package/src/components/ItaliaTheme/View/UOView/UOView.jsx +3 -0
  21. package/src/components/ItaliaTheme/View/index.js +1 -0
  22. package/src/config/italiaConfig.js +1 -0
  23. package/src/customizations/volto/actions/vocabularies/vocabularies.js +2 -2
  24. package/src/customizations/volto/components/manage/Blocks/Search/SearchBlockView.jsx +35 -9
  25. package/src/customizations/volto/components/manage/Blocks/Search/components/SearchDetails.jsx +2 -3
  26. package/src/customizations/volto/components/manage/Blocks/Search/hocs/withSearch.jsx +6 -4
  27. package/src/customizations/volto/components/theme/Footer/Footer.jsx +7 -13
  28. package/src/customizations/volto/helpers/BodyClass/BodyClass.jsx +78 -0
  29. package/src/customizations/volto-form-block/components/FormResult.jsx +39 -9
  30. package/src/customizations/volto-form-block/components/Sidebar.jsx +325 -0
  31. package/src/customizations/volto-form-block/components/View.jsx +390 -0
  32. package/src/customizations/volto-form-block/fieldSchema.js +174 -0
  33. package/src/customizations/volto-form-block/formSchema.js +237 -0
  34. package/src/overrideTranslations.jsx +26 -0
@@ -32,10 +32,6 @@ const messages = defineMessages({
32
32
  id: 'feedback_form_title',
33
33
  defaultMessage: 'How clear is the information on this page?',
34
34
  },
35
- service_title: {
36
- id: 'feedback_form_title_service',
37
- defaultMessage: 'How easy was it to use this service?',
38
- },
39
35
  yes: {
40
36
  id: 'feedback_form_yes',
41
37
  defaultMessage: 'Yes',
@@ -120,7 +116,7 @@ const messages = defineMessages({
120
116
  },
121
117
  });
122
118
 
123
- const FeedbackForm = ({ contentType, pathname }) => {
119
+ const FeedbackForm = ({ title, pathname }) => {
124
120
  const intl = useIntl();
125
121
  const location = useLocation();
126
122
  const path = pathname ?? location.pathname ?? '/';
@@ -273,18 +269,7 @@ const FeedbackForm = ({ contentType, pathname }) => {
273
269
  className="title-medium-2-semi-bold mb-0"
274
270
  data-element="feedback-title"
275
271
  >
276
- {/* Il validatore a quanto pare fa il check per titolo.
277
- Il titolo da specifiche deve essere diverso per Servizi, ma loro non lo sanno
278
- https://github.com/italia/pa-website-validator/blob/main/src/storage/municipality/feedbackComponentStructure.ts#L8
279
- */}
280
- {/* {contentType === 'Servizio'
281
- ? intl.formatMessage(messages.service_title)
282
- : intl.formatMessage(messages.title)} */}
283
-
284
- {/* Aggiunto titolo per compatibilità modello AGID di io-cittadino */}
285
- {contentType === 'ModelloPratica'
286
- ? intl.formatMessage(messages.service_title)
287
- : intl.formatMessage(messages.title)}
272
+ {title || intl.formatMessage(messages.title)}
288
273
  </h2>
289
274
  <div className="rating-container mb-0">
290
275
  <RTRating
@@ -455,7 +440,7 @@ const FeedbackForm = ({ contentType, pathname }) => {
455
440
  };
456
441
 
457
442
  FeedbackForm.propTypes = {
458
- contentType: PropTypes.string,
443
+ title: PropTypes.string,
459
444
  pathname: PropTypes.string,
460
445
  };
461
446
 
@@ -11,10 +11,7 @@ import { defineMessages, useIntl } from 'react-intl';
11
11
  import { withRouter } from 'react-router-dom';
12
12
  import { Login } from '@plone/volto/components';
13
13
  import { Row, Col, Container } from 'design-react-kit';
14
- import {
15
- RemoveBodyClass,
16
- LoginAgidButtons,
17
- } from 'design-comuni-plone-theme/components/ItaliaTheme';
14
+ import { LoginAgidButtons } from 'design-comuni-plone-theme/components/ItaliaTheme';
18
15
  import { Button } from 'design-react-kit';
19
16
  import { useLocation } from 'react-router-dom';
20
17
  import { getBaseUrl } from '@plone/volto/helpers';
@@ -72,7 +69,7 @@ const LoginAgid = (props) => {
72
69
  <div id="page-login">
73
70
  <Helmet title={intl.formatMessage(messages.login)} />
74
71
  <BodyClass className="public-ui" />
75
- <RemoveBodyClass className="cms-ui" />
72
+ <BodyClass className="cms-ui" remove={true} />
76
73
  <Container className="view-wrapper py-5">
77
74
  <Row className="view-container">
78
75
  <Col xs={12} lg={{ size: 10, offset: 1 }}>
@@ -24,7 +24,7 @@ import {
24
24
  import { Skiplink, SkiplinkItem } from 'design-react-kit';
25
25
  import { useLocation, useHistory } from 'react-router-dom';
26
26
 
27
- import { Helmet, flattenToAppURL } from '@plone/volto/helpers';
27
+ import { Helmet, flattenToAppURL, BodyClass } from '@plone/volto/helpers';
28
28
  import { resetSubsite } from 'volto-subsites';
29
29
 
30
30
  import {
@@ -33,7 +33,6 @@ import {
33
33
  SearchTopics,
34
34
  SearchCTs,
35
35
  Icon,
36
- RemoveBodyClass,
37
36
  SearchResultItem,
38
37
  } from 'design-comuni-plone-theme/components/ItaliaTheme';
39
38
  import {
@@ -727,7 +726,7 @@ const Search = () => {
727
726
  </Container>
728
727
  </div>
729
728
  {/*force remove body class for subsite search pages*/}
730
- <RemoveBodyClass className="cms-ui" />
729
+ <BodyClass className="cms-ui" remove={true} />
731
730
  </>
732
731
  );
733
732
  };
@@ -13,10 +13,7 @@ import { BodyClass } from '@plone/volto/helpers';
13
13
  import { useLocation } from 'react-router-dom';
14
14
  import { getBaseUrl } from '@plone/volto/helpers';
15
15
  import config from '@plone/volto/registry';
16
- import {
17
- LoginAgidButtons,
18
- RemoveBodyClass,
19
- } from 'design-comuni-plone-theme/components/ItaliaTheme';
16
+ import { LoginAgidButtons } from 'design-comuni-plone-theme/components/ItaliaTheme';
20
17
 
21
18
  /**
22
19
  * unauthorized function.
@@ -58,7 +55,7 @@ const Unauthorized = (props) => {
58
55
  return (
59
56
  <div id="unauthorized-agid" className="view-wrapper">
60
57
  <BodyClass className="public-ui" />
61
- <RemoveBodyClass className="cms-ui" />
58
+ <BodyClass className="cms-ui" remove={true} />
62
59
 
63
60
  <Container className="view-wrapper py-5">
64
61
  {spidLoginUrl || spidLogin ? (
@@ -53,6 +53,16 @@ const messages = defineMessages({
53
53
  id: 'altri_documenti_persona',
54
54
  defaultMessage: 'Altri documenti',
55
55
  },
56
+
57
+ dichiarazioni_di_insussistenza_e_incompatibilita: {
58
+ id: 'dichiarazioni_di_insussistenza_e_incompatibilita',
59
+ defaultMessage: 'Dichiarazioni di insussistenza e incompatibilità',
60
+ },
61
+
62
+ emolumenti_a_carico_della_finanza_pubblica: {
63
+ id: 'emolumenti_a_carico_della_finanza_pubblica',
64
+ defaultMessage: 'Emolumenti a carico della finanza pubblica',
65
+ },
56
66
  });
57
67
 
58
68
  const PersonaDocumenti = ({ content }) => {
@@ -205,6 +215,46 @@ const PersonaDocumenti = ({ content }) => {
205
215
  />
206
216
  </RichTextSection>
207
217
  )}
218
+ {content.dichiarazioni_di_insussistenza_e_incompatibilita?.download && (
219
+ <RichTextSection
220
+ tag_id="dichiarazioni_di_insussistenza_e_incompatibilita"
221
+ title={intl.formatMessage(
222
+ messages.dichiarazioni_di_insussistenza_e_incompatibilita,
223
+ )}
224
+ >
225
+ <div className="card-wrapper card-teaser-wrapper card-teaser-wrapper-equal">
226
+ <Attachment
227
+ download_url={
228
+ content.dichiarazioni_di_insussistenza_e_incompatibilita
229
+ .download
230
+ }
231
+ title={
232
+ content.dichiarazioni_di_insussistenza_e_incompatibilita
233
+ .filename
234
+ }
235
+ />
236
+ </div>
237
+ </RichTextSection>
238
+ )}
239
+ {content.emolumenti_a_carico_della_finanza_pubblica?.download && (
240
+ <RichTextSection
241
+ tag_id="emolumenti_a_carico_della_finanza_pubblica"
242
+ title={intl.formatMessage(
243
+ messages.emolumenti_a_carico_della_finanza_pubblica,
244
+ )}
245
+ >
246
+ <div className="card-wrapper card-teaser-wrapper card-teaser-wrapper-equal">
247
+ <Attachment
248
+ download_url={
249
+ content.emolumenti_a_carico_della_finanza_pubblica.download
250
+ }
251
+ title={
252
+ content.emolumenti_a_carico_della_finanza_pubblica.filename
253
+ }
254
+ />
255
+ </div>
256
+ </RichTextSection>
257
+ )}
208
258
  </>
209
259
  );
210
260
  };
@@ -0,0 +1,12 @@
1
+ import PropTypes from 'prop-types';
2
+ import { Metadata } from 'design-comuni-plone-theme/components/ItaliaTheme/View';
3
+
4
+ const UOMetadati = ({ content }) => {
5
+ return <Metadata content={content} showSectionTitle={false} />;
6
+ };
7
+
8
+ UOMetadati.propTypes = {
9
+ content: PropTypes.object,
10
+ };
11
+
12
+ export default UOMetadati;
@@ -19,6 +19,7 @@ import {
19
19
  UODocuments,
20
20
  UOWhatDoesItDo,
21
21
  UOMoreInfos,
22
+ UOMetadati,
22
23
  RelatedItemInEvidence,
23
24
  SkipToMainContent,
24
25
  ContentTypeViewSections,
@@ -46,6 +47,8 @@ export const UOViewSectionsOrder = [
46
47
  { /* DOCUMENTI */ component: UODocuments },
47
48
 
48
49
  { /* ULTERIORI INFORMAZIONI */ component: UOMoreInfos },
50
+
51
+ { /*METADATI*/ component: UOMetadati },
49
52
  ];
50
53
 
51
54
  /**
@@ -183,6 +183,7 @@ export UOContacts from 'design-comuni-plone-theme/components/ItaliaTheme/View/UO
183
183
  export UOContactsLocations from 'design-comuni-plone-theme/components/ItaliaTheme/View/UOView/UOContactsParts/UOContactsLocations';
184
184
  export UOContactsContacts from 'design-comuni-plone-theme/components/ItaliaTheme/View/UOView/UOContactsParts/UOContactsContacts';
185
185
  export UOContactsSediSecondarie from 'design-comuni-plone-theme/components/ItaliaTheme/View/UOView/UOContactsParts/UOContactsSediSecondarie';
186
+ export UOMetadati from 'design-comuni-plone-theme/components/ItaliaTheme/View/UOView/UOMetadati';
186
187
 
187
188
  export UODocuments from 'design-comuni-plone-theme/components/ItaliaTheme/View/UOView/UODocuments';
188
189
  export UOWhatDoesItDo from 'design-comuni-plone-theme/components/ItaliaTheme/View/UOView/UOWhatDoesItDo';
@@ -279,6 +279,7 @@ export default function applyConfig(voltoConfig) {
279
279
  ],
280
280
  },
281
281
  enableFeedbackForm: true,
282
+ noFeedbackFormFor: ['ModelloPratica'],
282
283
  enableFeedbackFormCaptcha: false,
283
284
  enableVoltoFormBlockCaptcha: true,
284
285
  splitMegamenuColumns: true, //se impostato a false, non spezza le colonne con intestazioni nel megamenu
@@ -36,7 +36,7 @@ export function getVocabulary({
36
36
  const vocabulary = getVocabName(vocabNameOrURL);
37
37
  const contextualVocabularies = config.settings.contextualVocabularies;
38
38
  const vocabPath =
39
- contextualVocabularies && contextualVocabularies.includes(vocabulary)
39
+ contextualVocabularies && contextualVocabularies.includes(vocabulary) && vocabulary !== vocabNameOrURL
40
40
  ? flattenToAppURL(vocabNameOrURL)
41
41
  : `/@vocabularies/${vocabulary}`;
42
42
  let queryString = `b_start=${start}${size ? '&b_size=' + size : ''}`;
@@ -74,7 +74,7 @@ export function getVocabularyTokenTitle({
74
74
  const vocabulary = getVocabName(vocabNameOrURL);
75
75
  const contextualVocabularies = config.settings.contextualVocabularies;
76
76
  const vocabPath =
77
- contextualVocabularies && contextualVocabularies.includes(vocabulary)
77
+ contextualVocabularies && contextualVocabularies.includes(vocabulary) && vocabulary !== vocabNameOrURL
78
78
  ? flattenToAppURL(vocabNameOrURL)
79
79
  : `/@vocabularies/${vocabulary}`;
80
80
  const queryString = {
@@ -2,6 +2,9 @@
2
2
  - Agid styling
3
3
  - Add class .block.listing in listing body container div to use
4
4
  existing listing template styles
5
+ - Inspired from
6
+ https://github.com/plone/volto/commit/211d9bea13119cc430db9d53a4740a860781ca2e
7
+ the way to handle search sort
5
8
  */
6
9
 
7
10
  import React from 'react';
@@ -9,15 +12,15 @@ import React from 'react';
9
12
  import ListingBody from '@plone/volto/components/manage/Blocks/Listing/ListingBody';
10
13
  import { withBlockExtensions } from '@plone/volto/helpers';
11
14
 
12
- import config from '@plone/volto/registry';
13
- import cx from 'classnames';
14
15
  import {
15
- withSearch,
16
16
  withQueryString,
17
+ withSearch,
17
18
  } from '@plone/volto/components/manage/Blocks/Search/hocs';
18
- import { compose } from 'redux';
19
- import { useSelector } from 'react-redux';
19
+ import config from '@plone/volto/registry';
20
+ import cx from 'classnames';
20
21
  import { isEqual, isFunction } from 'lodash';
22
+ import { useSelector } from 'react-redux';
23
+ import { compose } from 'redux';
21
24
 
22
25
  const getListingBodyVariation = (data) => {
23
26
  const { variations } = config.blocks.blocksConfig.listing;
@@ -57,12 +60,36 @@ const applyDefaults = (data, root) => {
57
60
  v: root || '/',
58
61
  },
59
62
  ];
60
- return {
63
+
64
+ const searchBySearchableText = data.query.filter(
65
+ (item) => item['i'] === 'SearchableText',
66
+ ).length;
67
+
68
+ const sort_on =
69
+ searchBySearchableText === 0
70
+ ? data?.sort_on
71
+ ? { sort_on: data.sort_on }
72
+ : { sort_on: 'effective' }
73
+ : undefined;
74
+
75
+ const sort_order =
76
+ searchBySearchableText === 0
77
+ ? data?.sort_order
78
+ ? { sort_order: data.sort_order }
79
+ : { sort_order: 'descending' }
80
+ : undefined;
81
+
82
+ const result = {
61
83
  ...data,
62
- sort_on: data?.sort_on || 'effective',
63
- sort_order: data?.sort_order || 'descending',
64
84
  query: data?.query?.length ? data.query : defaultQuery,
65
85
  };
86
+ if (!sort_on) {
87
+ delete result.sort_on;
88
+ }
89
+ if (!sort_order) {
90
+ delete result.sort_order;
91
+ }
92
+ return result;
66
93
  };
67
94
 
68
95
  const SearchBlockView = (props) => {
@@ -89,7 +116,6 @@ const SearchBlockView = (props) => {
89
116
 
90
117
  const root = useSelector((state) => state.breadcrumbs.root);
91
118
  const listingBodyData = applyDefaults(searchData, root);
92
-
93
119
  const { variations } = config.blocks.blocksConfig.listing;
94
120
  const listingBodyVariation = variations.find(({ id }) => id === selectedView);
95
121
  if (!Layout) return null;
@@ -2,9 +2,8 @@
2
2
  - Agid styling
3
3
 
4
4
  */
5
- import React from 'react';
6
- import { defineMessages, useIntl } from 'react-intl';
7
5
  import { commonSearchBlockMessages } from 'design-comuni-plone-theme/helpers';
6
+ import { defineMessages, useIntl } from 'react-intl';
8
7
 
9
8
  const messages = defineMessages({
10
9
  searchResults: {
@@ -26,7 +25,7 @@ const SearchDetails = ({ total, text, as = 'p', data }) => {
26
25
  searchedtext: text,
27
26
  })}
28
27
  </>
29
- )}
28
+ )}{' '}
30
29
  {data.showTotalResults && (
31
30
  <>
32
31
  {intl.formatMessage(messages.searchResults)}: <b>{total}</b>
@@ -1,10 +1,10 @@
1
1
  /* CUSTOMIZATIONS:
2
2
  - Read puntual comments in code
3
3
  */
4
+ import qs from 'query-string';
4
5
  import React from 'react';
5
6
  import { useSelector } from 'react-redux';
6
- import qs from 'query-string';
7
- import { useLocation, useHistory } from 'react-router-dom';
7
+ import { useHistory, useLocation } from 'react-router-dom';
8
8
 
9
9
  import { resolveExtension } from '@plone/volto/helpers/Extensions/withBlockExtensions';
10
10
  import config from '@plone/volto/registry';
@@ -236,7 +236,7 @@ const withSearch = (options) => (WrappedComponent) => {
236
236
  const { inputDelay = 1000 } = options || {};
237
237
 
238
238
  function WithSearch(props) {
239
- const { data, id, editable = false } = props;
239
+ const { data, id, editable = false, properties } = props;
240
240
 
241
241
  const [locationSearchData, setLocationSearchData] = useSearchBlockState(
242
242
  id,
@@ -325,8 +325,10 @@ const withSearch = (options) => (WrappedComponent) => {
325
325
  const querystringResults = useSelector(
326
326
  (state) => state.querystringsearch.subrequests,
327
327
  );
328
+ const subrequestID = properties?.UID + '-' + id;
328
329
  const totalItems =
329
- querystringResults[id]?.total || querystringResults[id]?.items?.length;
330
+ querystringResults[subrequestID]?.total ||
331
+ querystringResults[subrequestID]?.items?.length;
330
332
 
331
333
  return (
332
334
  <WrappedComponent
@@ -21,22 +21,18 @@ import config from '@plone/volto/registry';
21
21
  * @extends Component
22
22
  */
23
23
 
24
- const Footer = ({ intl }) => {
24
+ const Footer = () => {
25
25
  useGoogleAnalytics();
26
26
  const currentContent = useSelector((state) => state.content?.data);
27
- let contentType = null;
28
- if (currentContent != null) {
29
- contentType = currentContent?.['@type'];
30
- }
31
- // const NoFeedbackFormFor = ['Plone Site', 'LRF', 'Subsite'];
32
- const NoFeedbackFormFor = [];
27
+ const contentType = currentContent ? currentContent['@type'] : null;
28
+ const noFeedbackFormFor = config.settings.siteProperties.noFeedbackFormFor || [];
33
29
 
34
- let content = (
30
+ return (
35
31
  <>
36
- {contentType != null &&
37
- NoFeedbackFormFor.indexOf(contentType) < 0 &&
32
+ {contentType &&
33
+ !noFeedbackFormFor.includes(contentType) &&
38
34
  config.settings.siteProperties.enableFeedbackForm && (
39
- <FeedbackForm contentType={contentType} />
35
+ <FeedbackForm />
40
36
  )}
41
37
 
42
38
  <SubsiteFooter />
@@ -46,8 +42,6 @@ const Footer = ({ intl }) => {
46
42
  </footer>
47
43
  </>
48
44
  );
49
-
50
- return content;
51
45
  };
52
46
 
53
47
  export default Footer;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * CUSTOMIZATIONS:
3
+ * - handle bodyclass removal
4
+ */
5
+ import { Component, Children } from 'react';
6
+ import PropTypes from 'prop-types';
7
+ import withSideEffect from 'react-side-effect';
8
+
9
+ /**
10
+ * @export
11
+ * @class BodyClass
12
+ * @extends {Component}
13
+ */
14
+ class BodyClass extends Component {
15
+ /**
16
+ * Render method.
17
+ * @method render
18
+ * @returns {string} Markup for the component.
19
+ */
20
+ render() {
21
+ if (this.props.children) {
22
+ return Children.only(this.props.children);
23
+ }
24
+ return null;
25
+ }
26
+ }
27
+
28
+ BodyClass.propTypes = {
29
+ children: PropTypes.element,
30
+ className: PropTypes.string,
31
+ remove: PropTypes.bool,
32
+ };
33
+
34
+ BodyClass.defaultProps = {
35
+ children: null,
36
+ className: null,
37
+ remove: false,
38
+ };
39
+
40
+ /**
41
+ * reducePropsToState
42
+ * @function reducePropsToState
43
+ * @param {*} propsList propsList
44
+ * @returns {List} classList
45
+ */
46
+ function reducePropsToState(propsList) {
47
+ let classList = [];
48
+ propsList.forEach((props) => {
49
+ if (props.className) {
50
+ if (props.remove) {
51
+ classList = classList.filter((c) => c !== props.className);
52
+ } else {
53
+ classList = classList.concat(props.className.split(' '));
54
+ }
55
+ }
56
+ });
57
+ return classList;
58
+ }
59
+
60
+ /**
61
+ * handleStateChangeOnClient
62
+ * @function handleStateChangeOnClient
63
+ * @param {*} classList classList
64
+ * @returns {null} null
65
+ */
66
+ function handleStateChangeOnClient(classList) {
67
+ document.body.className = '';
68
+ classList.forEach((className) => {
69
+ if (!document.body.classList.contains(className)) {
70
+ document.body.classList.add(className);
71
+ }
72
+ });
73
+ }
74
+
75
+ export default withSideEffect(
76
+ reducePropsToState,
77
+ handleStateChangeOnClient,
78
+ )(BodyClass);
@@ -1,6 +1,7 @@
1
1
  /*
2
2
  CUSTOMIZATIONS:
3
3
  - used design-react-kit components to render form result
4
+ - added warning message when subscription limit (if set) has been exceeded
4
5
  */
5
6
  import React from 'react';
6
7
  import { useIntl, defineMessages } from 'react-intl';
@@ -12,6 +13,15 @@ const messages = defineMessages({
12
13
  id: 'form_submit_success',
13
14
  defaultMessage: 'Sent!',
14
15
  },
16
+ success_warning: {
17
+ id: 'form_submit_success_warning',
18
+ defaultMessage: "You've been added to the waiting list",
19
+ },
20
+ success_warning_description: {
21
+ id: 'form_submit_success_warning_description',
22
+ defaultMessage:
23
+ "Your data has been submitted, but the subscription limit has been reached and you've been added to the waiting list.",
24
+ },
15
25
  reset: {
16
26
  id: 'form_reset',
17
27
  defaultMessage: 'Clear',
@@ -47,20 +57,40 @@ const replaceMessage = (text, sent_data) => {
47
57
  const FormResult = ({ formState, data, resetFormState }) => {
48
58
  const intl = useIntl();
49
59
  return (
50
- <Alert color="success" fade isOpen tag="div" transition={alertTransition}>
51
- <h4>{intl.formatMessage(messages.success)}</h4>
60
+ <Alert
61
+ color={!formState.warning ? 'success' : 'warning'}
62
+ fade
63
+ isOpen
64
+ tag="div"
65
+ transition={alertTransition}
66
+ >
67
+ <h4>
68
+ {!formState.warning
69
+ ? intl.formatMessage(messages.success)
70
+ : intl.formatMessage(messages.success_warning)}
71
+ </h4>
52
72
  <br />
53
73
  {/* Custom message */}
54
- {data.send_message && (
74
+ {!formState.warning ? (
75
+ data.send_message && (
76
+ <>
77
+ <p
78
+ dangerouslySetInnerHTML={{
79
+ __html: replaceMessage(
80
+ data.send_message,
81
+ formState.result.data,
82
+ ),
83
+ }}
84
+ />
85
+ <br />
86
+ </>
87
+ )
88
+ ) : (
55
89
  <>
56
- <p
57
- dangerouslySetInnerHTML={{
58
- __html: replaceMessage(data.send_message, formState.result.data),
59
- }}
60
- />
61
- <br />
90
+ <p>{intl.formatMessage(messages.success_warning_description)}</p>
62
91
  </>
63
92
  )}
93
+
64
94
  <Button
65
95
  color="primary"
66
96
  outline