diff --git a/src/components/App.stories.jsx b/src/components/App.stories.jsx
index d2f33b0cd..19ca4c49b 100644
--- a/src/components/App.stories.jsx
+++ b/src/components/App.stories.jsx
@@ -113,6 +113,7 @@ const render = args => {
explanationTemplate: '
Toelichtingssjabloon...
',
submissionAllowed: args['submissionAllowed'],
hideNonApplicableSteps: args['hideNonApplicableSteps'],
+ submissionLimitReached: args['form.submissionLimitReached'],
steps: args['steps'],
});
return ;
@@ -409,3 +410,19 @@ export const SeveralStepsInMobileViewport = {
},
},
};
+
+export const MaximumSubmissionsReached = {
+ render,
+ decorators: [LayoutDecorator],
+ args: {
+ 'form.submissionLimitReached': true,
+ },
+};
+
+export const MaximumSubmissionsNotReached = {
+ render,
+ decorators: [LayoutDecorator],
+ args: {
+ 'form.submissionLimitReached': false,
+ },
+};
diff --git a/src/components/Errors/ErrorBoundary.jsx b/src/components/Errors/ErrorBoundary.jsx
index db66a834d..ef6309ce7 100644
--- a/src/components/Errors/ErrorBoundary.jsx
+++ b/src/components/Errors/ErrorBoundary.jsx
@@ -4,6 +4,7 @@ import {FormattedMessage, useIntl} from 'react-intl';
import Body from 'components/Body';
import Card from 'components/Card';
+import FormMaximumSubmissions from 'components/FormMaximumSubmissions';
import Link from 'components/Link';
import MaintenanceMode from 'components/MaintenanceMode';
import {PermissionDenied, ServiceUnavailable, UnprocessableEntity} from 'errors';
@@ -138,21 +139,28 @@ const UnprocessableEntityError = ({wrapper: Wrapper, error}) => {
UnprocessableEntityError.propTypes = GenericError.propTypes;
const ServiceUnavailableError = ({wrapper: Wrapper, error}) => {
- if (error.code !== 'form-maintenance') {
+ if (!['form-maintenance', 'form-maximum-submissions'].includes(error.code)) {
return ;
}
// handle maintenance mode forms
- return (
-
- }
- />
- );
+ if (error.code === 'form-maintenance') {
+ return (
+
+ }
+ />
+ );
+ }
+
+ // handle submission limit forms
+ if (error.code === 'form-maximum-submissions') {
+ return ;
+ }
};
// map the error class to the component to render it
diff --git a/src/components/FormMaximumSubmissions.jsx b/src/components/FormMaximumSubmissions.jsx
new file mode 100644
index 000000000..5e7bd70da
--- /dev/null
+++ b/src/components/FormMaximumSubmissions.jsx
@@ -0,0 +1,17 @@
+import React from 'react';
+import {FormattedMessage} from 'react-intl';
+
+import ErrorMessage from 'components/Errors/ErrorMessage';
+
+const FormMaximumSubmissions = () => {
+ return (
+
+
+
+ );
+};
+
+export default FormMaximumSubmissions;
diff --git a/src/components/FormStart/index.jsx b/src/components/FormStart/index.jsx
index d0713c563..d2c42eca4 100644
--- a/src/components/FormStart/index.jsx
+++ b/src/components/FormStart/index.jsx
@@ -6,6 +6,7 @@ import {useAsync} from 'react-use';
import Body from 'components/Body';
import Card from 'components/Card';
import ExistingSubmissionOptions from 'components/ExistingSubmissionOptions';
+import FormMaximumSubmissions from 'components/FormMaximumSubmissions';
import {LiteralsProvider} from 'components/Literal';
import Loader from 'components/Loader';
import LoginOptions from 'components/LoginOptions';
@@ -112,6 +113,7 @@ const FormStart = ({form, submission, onFormStart, onDestroySession, initialData
return (
+ {form.submissionLimitReached ? : null}
{userIsFormDesigner && form.maintenanceMode && }
{!!authErrors ? : null}
diff --git a/src/i18n/compiled/en.json b/src/i18n/compiled/en.json
index 9e339b390..57369b270 100644
--- a/src/i18n/compiled/en.json
+++ b/src/i18n/compiled/en.json
@@ -2127,6 +2127,12 @@
"value": "Abort submission"
}
],
+ "uPtko4": [
+ {
+ "type": 0,
+ "value": "Unfortunately, this form is no longer available for submissions."
+ }
+ ],
"uZBPwA": [
{
"type": 0,
diff --git a/src/i18n/compiled/nl.json b/src/i18n/compiled/nl.json
index 627ec0d88..d1b913dc1 100644
--- a/src/i18n/compiled/nl.json
+++ b/src/i18n/compiled/nl.json
@@ -2131,6 +2131,12 @@
"value": "Afbreken"
}
],
+ "uPtko4": [
+ {
+ "type": 0,
+ "value": "Unfortunately, this form is no longer available for submissions."
+ }
+ ],
"uZBPwA": [
{
"type": 0,
diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json
index 357439cf0..f45c3e209 100644
--- a/src/i18n/messages/en.json
+++ b/src/i18n/messages/en.json
@@ -1009,6 +1009,11 @@
"description": "Button label to abort submission",
"originalDefault": "Abort submission"
},
+ "uPtko4": {
+ "defaultMessage": "Unfortunately, this form is no longer available for submissions.",
+ "description": "Maximum form submissions error message",
+ "originalDefault": "Unfortunately, this form is no longer available for submissions."
+ },
"uZBPwA": {
"defaultMessage": "Number must be {exact, select, true {exactly equal to} other {{inclusive, select, true {less than or equal to} other {less than}}} } {maximum}.",
"description": "ZOD 'too_big' error message, for numbers",
diff --git a/src/i18n/messages/nl.json b/src/i18n/messages/nl.json
index ba1fddba7..afafa0561 100644
--- a/src/i18n/messages/nl.json
+++ b/src/i18n/messages/nl.json
@@ -1021,6 +1021,11 @@
"description": "Button label to abort submission",
"originalDefault": "Abort submission"
},
+ "uPtko4": {
+ "defaultMessage": "Unfortunately, this form is no longer available for submissions.",
+ "description": "Maximum form submissions error message",
+ "originalDefault": "Unfortunately, this form is no longer available for submissions."
+ },
"uZBPwA": {
"defaultMessage": "Het getal moet {exact, select, true {exact gelijk aan} other {{inclusive, select, true {minder dan of gelijk aan} other {minder dan}}} } {maximum} zijn.",
"description": "ZOD 'too_big' error message, for numbers",