@strapi/admin 4.2.0-beta.3 → 4.2.0-beta.4

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 (89) hide show
  1. package/admin/src/components/ConfigurationsProvider/index.js +51 -0
  2. package/admin/src/components/ConfigurationsProvider/reducer.js +28 -0
  3. package/admin/src/components/LeftMenu/index.js +12 -2
  4. package/admin/src/components/Providers/index.js +8 -4
  5. package/admin/src/components/UnauthenticatedLogo/index.js +4 -2
  6. package/admin/src/pages/App/index.js +7 -2
  7. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/index.js +85 -0
  8. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/init.js +13 -0
  9. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/reducer.js +43 -0
  10. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/index.js +118 -0
  11. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/reducer.js +28 -0
  12. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/stepper.js +25 -0
  13. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/AddLogoDialog.js +67 -0
  14. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromComputerForm.js +176 -0
  15. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromUrlForm.js +82 -0
  16. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/ImageCardAsset.js +51 -0
  17. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/PendingLogoDialog.js +97 -0
  18. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/index.js +85 -0
  19. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/reducer.js +28 -0
  20. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +153 -91
  21. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +16 -0
  22. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/constants.js +3 -0
  23. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/getFormData.js +17 -0
  24. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/parseFileMetadatas.js +76 -0
  25. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/prefixAllUrls.js +17 -0
  26. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/urlToFile.js +21 -0
  27. package/admin/src/translations/en.json +26 -0
  28. package/build/1541.6c1c96f9.chunk.js +307 -0
  29. package/build/3214.9196aeff.chunk.js +235 -0
  30. package/build/3865.21cec9de.chunk.js +310 -0
  31. package/build/{4073.41ac1235.chunk.js → 4073.e144a91a.chunk.js} +1 -1
  32. package/build/{210.014495c1.chunk.js → 472.0350a5bd.chunk.js} +32 -32
  33. package/build/4800.d3ebc81d.chunk.js +1 -0
  34. package/build/4982.f53b78a4.chunk.js +308 -0
  35. package/build/7351.b95e65ae.chunk.js +428 -0
  36. package/build/7418.6db737ce.chunk.js +112 -0
  37. package/build/8826.58e236d4.chunk.js +1057 -0
  38. package/build/9066.118ecccd.chunk.js +101 -0
  39. package/build/{7191.3bde3cbf.chunk.js → 9298.aff28744.chunk.js} +85 -86
  40. package/build/948.d64fb515.chunk.js +2 -0
  41. package/build/9988.f84412d9.chunk.js +162 -0
  42. package/build/Admin-authenticatedApp.162a5805.chunk.js +80 -0
  43. package/build/{Admin_homePage.f157e33e.chunk.js → Admin_homePage.0ac648e8.chunk.js} +2 -2
  44. package/build/Admin_marketplace.0bb91ec8.chunk.js +11 -0
  45. package/build/{Admin_profilePage.62c203ad.chunk.js → Admin_profilePage.27191ed2.chunk.js} +1 -1
  46. package/build/Admin_settingsPage.23e873f0.chunk.js +178 -0
  47. package/build/{admin-edit-roles-page.94e1403b.chunk.js → admin-edit-roles-page.fb374555.chunk.js} +1 -1
  48. package/build/admin-edit-users.a360deaf.chunk.js +10 -0
  49. package/build/admin-users.47d06d24.chunk.js +11 -0
  50. package/build/api-tokens-create-page.698f132d.chunk.js +1 -0
  51. package/build/api-tokens-edit-page.afece2fe.chunk.js +1 -0
  52. package/build/{api-tokens-list-page.340750a6.chunk.js → api-tokens-list-page.46d96dee.chunk.js} +1 -1
  53. package/build/{content-manager.6cdcfb6e.chunk.js → content-manager.7cd28f84.chunk.js} +14 -14
  54. package/build/{content-type-builder.e73879b9.chunk.js → content-type-builder.7456cabe.chunk.js} +10 -10
  55. package/build/en-json.40ee00aa.chunk.js +1 -0
  56. package/build/index.html +1 -1
  57. package/build/main.b632a0d6.js +11625 -0
  58. package/build/runtime~main.38d418e9.js +2 -0
  59. package/build/{sso-settings-page.e9034e22.chunk.js → sso-settings-page.dfb0b917.chunk.js} +1 -1
  60. package/build/webhook-edit-page.a7ae6e3b.chunk.js +23 -0
  61. package/build/webhook-list-page.83297d98.chunk.js +133 -0
  62. package/package.json +7 -7
  63. package/server/config/admin-actions.js +14 -0
  64. package/server/controllers/admin.js +33 -1
  65. package/server/routes/admin.js +28 -0
  66. package/server/services/index.js +1 -0
  67. package/server/services/project-settings.js +173 -0
  68. package/server/utils/index.d.ts +2 -0
  69. package/server/validation/project-settings.js +39 -0
  70. package/build/1709.ceed0e18.chunk.js +0 -503
  71. package/build/20.cf744c35.chunk.js +0 -308
  72. package/build/2135.95ee6de1.chunk.js +0 -162
  73. package/build/2524.688d0355.chunk.js +0 -1
  74. package/build/4761.3eabdf46.chunk.js +0 -101
  75. package/build/6281.f10a7e3a.chunk.js +0 -1
  76. package/build/7009.79fce86d.chunk.js +0 -164
  77. package/build/7863.bc7a8f3a.chunk.js +0 -112
  78. package/build/Admin-authenticatedApp.4ce8d292.chunk.js +0 -80
  79. package/build/Admin_marketplace.1e3393c9.chunk.js +0 -11
  80. package/build/Admin_settingsPage.924a7816.chunk.js +0 -170
  81. package/build/admin-edit-users.6c2bf718.chunk.js +0 -10
  82. package/build/admin-users.e03db115.chunk.js +0 -11
  83. package/build/api-tokens-create-page.787ab302.chunk.js +0 -1
  84. package/build/api-tokens-edit-page.e4010c0c.chunk.js +0 -1
  85. package/build/en-json.3e1a222e.chunk.js +0 -1
  86. package/build/main.45472ea9.js +0 -8404
  87. package/build/runtime~main.e7611418.js +0 -2
  88. package/build/webhook-edit-page.2fa94db3.chunk.js +0 -23
  89. package/build/webhook-list-page.b594db49.chunk.js +0 -133
@@ -0,0 +1,176 @@
1
+ import React, { useState, useRef } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useIntl } from 'react-intl';
4
+ import styled from 'styled-components';
5
+ import { Box } from '@strapi/design-system/Box';
6
+ import { Stack } from '@strapi/design-system/Stack';
7
+ import { Flex } from '@strapi/design-system/Flex';
8
+ import { Icon } from '@strapi/design-system/Icon';
9
+ import { Typography } from '@strapi/design-system/Typography';
10
+ import { ModalFooter } from '@strapi/design-system/ModalLayout';
11
+ import { Button } from '@strapi/design-system/Button';
12
+ import { Field, FieldError, FieldInput } from '@strapi/design-system/Field';
13
+ import PicturePlus from '@strapi/icons/PicturePlus';
14
+ import { parseFileMetadatas } from '../../utils/parseFileMetadatas';
15
+ import { ACCEPTED_FORMAT, SIZE, DIMENSION } from '../../utils/constants';
16
+
17
+ const FileInput = styled(FieldInput)`
18
+ opacity: 0;
19
+ position: absolute;
20
+ top: 0;
21
+ bottom: 0;
22
+ left: 0;
23
+ right: 0;
24
+ z-index: 1;
25
+ `;
26
+
27
+ const FromComputerForm = ({ setLocalImage, goTo, next, onClose }) => {
28
+ const { formatMessage } = useIntl();
29
+ const [dragOver, setDragOver] = useState(false);
30
+ const [fileError, setFileError] = useState(undefined);
31
+ const inputRef = useRef(null);
32
+
33
+ const handleDragEnter = () => setDragOver(true);
34
+ const handleDragLeave = () => setDragOver(false);
35
+
36
+ const handleClick = e => {
37
+ e.preventDefault();
38
+ inputRef.current.click();
39
+ };
40
+
41
+ const handleChange = async () => {
42
+ handleDragLeave();
43
+ const file = inputRef.current.files[0];
44
+
45
+ if (!file) {
46
+ return;
47
+ }
48
+
49
+ try {
50
+ const asset = await parseFileMetadatas(file);
51
+ setLocalImage(asset);
52
+ goTo(next);
53
+ } catch (err) {
54
+ if (err.displayMessage) {
55
+ setFileError(formatMessage(err.displayMessage, { size: SIZE, dimension: DIMENSION }));
56
+ inputRef.current.focus();
57
+ } else {
58
+ throw err;
59
+ }
60
+ }
61
+ };
62
+
63
+ const getBorderColor = () => {
64
+ if (dragOver) {
65
+ return 'primary500';
66
+ }
67
+ if (fileError) {
68
+ return 'danger600';
69
+ }
70
+
71
+ return 'neutral300';
72
+ };
73
+
74
+ return (
75
+ <>
76
+ <form>
77
+ <Box paddingLeft={8} paddingRight={8} paddingTop={6} paddingBottom={6}>
78
+ <Field name="logo-upload" error={fileError}>
79
+ <label htmlFor="logo-upload">
80
+ <Stack spacing={2}>
81
+ <Flex
82
+ paddingTop={9}
83
+ paddingBottom={7}
84
+ hasRadius
85
+ justifyContent="center"
86
+ direction="column"
87
+ background={dragOver ? 'primary100' : 'neutral100'}
88
+ borderColor={getBorderColor()}
89
+ borderStyle="dashed"
90
+ borderWidth="1px"
91
+ position="relative"
92
+ onDragEnter={handleDragEnter}
93
+ onDragLeave={handleDragLeave}
94
+ >
95
+ <Icon
96
+ color="primary600"
97
+ width={`${60 / 16}rem`}
98
+ height={`${60 / 16}rem`}
99
+ as={PicturePlus}
100
+ aria-hidden
101
+ />
102
+
103
+ <Box paddingTop={3} paddingBottom={5}>
104
+ <Typography variant="delta" as="span">
105
+ {formatMessage({
106
+ id: 'Settings.application.customization.modal.upload.drag-drop',
107
+ defaultMessage: 'Drag and Drop here or',
108
+ })}
109
+ </Typography>
110
+ </Box>
111
+
112
+ <FileInput
113
+ accept={ACCEPTED_FORMAT}
114
+ cursor="pointer"
115
+ as="input"
116
+ type="file"
117
+ name="files"
118
+ tabIndex={-1}
119
+ zIndex={1}
120
+ onChange={handleChange}
121
+ ref={inputRef}
122
+ id="logo-upload"
123
+ />
124
+
125
+ <Button type="button" onClick={handleClick}>
126
+ {formatMessage({
127
+ id: 'Settings.application.customization.modal.upload.cta.browse',
128
+ defaultMessage: 'Browse files',
129
+ })}
130
+ </Button>
131
+
132
+ <Box paddingTop={6}>
133
+ <Typography variant="pi" textColor="neutral600">
134
+ {formatMessage(
135
+ {
136
+ id: 'Settings.application.customization.modal.upload.file-validation',
137
+ defaultMessage:
138
+ 'Max dimension: {dimension}x{dimension}, Max size: {size}KB',
139
+ },
140
+ { size: SIZE, dimension: DIMENSION }
141
+ )}
142
+ </Typography>
143
+ </Box>
144
+ </Flex>
145
+ <FieldError />
146
+ </Stack>
147
+ </label>
148
+ </Field>
149
+ </Box>
150
+ </form>
151
+ <ModalFooter
152
+ startActions={
153
+ <Button onClick={onClose} variant="tertiary">
154
+ {formatMessage({
155
+ id: 'Settings.application.customization.modal.cancel',
156
+ defaultMessage: 'Cancel',
157
+ })}
158
+ </Button>
159
+ }
160
+ />
161
+ </>
162
+ );
163
+ };
164
+
165
+ FromComputerForm.defaultProps = {
166
+ next: null,
167
+ };
168
+
169
+ FromComputerForm.propTypes = {
170
+ goTo: PropTypes.func.isRequired,
171
+ next: PropTypes.string,
172
+ onClose: PropTypes.func.isRequired,
173
+ setLocalImage: PropTypes.func.isRequired,
174
+ };
175
+
176
+ export default FromComputerForm;
@@ -0,0 +1,82 @@
1
+ import React, { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useIntl } from 'react-intl';
4
+ import { Box } from '@strapi/design-system/Box';
5
+ import { Button } from '@strapi/design-system/Button';
6
+ import { TextInput } from '@strapi/design-system/TextInput';
7
+ import { ModalFooter } from '@strapi/design-system/ModalLayout';
8
+ import urlToFile from '../../utils/urlToFile';
9
+ import { parseFileMetadatas } from '../../utils/parseFileMetadatas';
10
+ import { SIZE, DIMENSION } from '../../utils/constants';
11
+
12
+ const FromUrlForm = ({ goTo, next, onClose, setLocalImage }) => {
13
+ const { formatMessage } = useIntl();
14
+ const [logoUrl, setLogoUrl] = useState('');
15
+ const [error, setError] = useState(null);
16
+
17
+ const handleChange = e => {
18
+ setLogoUrl(e.target.value);
19
+ };
20
+
21
+ const handleSubmit = async e => {
22
+ e.preventDefault();
23
+ try {
24
+ const file = await urlToFile(logoUrl);
25
+ const asset = await parseFileMetadatas(file);
26
+
27
+ setLocalImage(asset);
28
+ goTo(next);
29
+ } catch (err) {
30
+ if (err.displayMessage) {
31
+ setError(formatMessage(err.displayMessage, { size: SIZE, dimension: DIMENSION }));
32
+ } else {
33
+ throw err;
34
+ }
35
+ }
36
+ };
37
+
38
+ return (
39
+ <form onSubmit={handleSubmit}>
40
+ <Box paddingLeft={8} paddingRight={8} paddingTop={6} paddingBottom={6}>
41
+ <TextInput
42
+ label={formatMessage({
43
+ id: 'Settings.application.customization.modal.upload.from-url.input-label',
44
+ defaultMessage: 'URL',
45
+ })}
46
+ error={error}
47
+ onChange={handleChange}
48
+ value={logoUrl}
49
+ name="logo-url"
50
+ />
51
+ </Box>
52
+ <ModalFooter
53
+ startActions={
54
+ <Button onClick={onClose} variant="tertiary">
55
+ {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}
56
+ </Button>
57
+ }
58
+ endActions={
59
+ <Button type="submit">
60
+ {formatMessage({
61
+ id: 'Settings.application.customization.modal.upload.next',
62
+ defaultMessage: 'Next',
63
+ })}
64
+ </Button>
65
+ }
66
+ />
67
+ </form>
68
+ );
69
+ };
70
+
71
+ FromUrlForm.defaultProps = {
72
+ next: null,
73
+ };
74
+
75
+ FromUrlForm.propTypes = {
76
+ goTo: PropTypes.func.isRequired,
77
+ next: PropTypes.string,
78
+ onClose: PropTypes.func.isRequired,
79
+ setLocalImage: PropTypes.func.isRequired,
80
+ };
81
+
82
+ export default FromUrlForm;
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import PropTypes from 'prop-types';
4
+ import {
5
+ Card,
6
+ CardAsset,
7
+ CardBadge,
8
+ CardBody,
9
+ CardContent,
10
+ CardHeader,
11
+ CardTitle,
12
+ CardSubtitle,
13
+ } from '@strapi/design-system/Card';
14
+
15
+ const ImageCardAsset = ({ asset }) => {
16
+ const { formatMessage } = useIntl();
17
+
18
+ return (
19
+ <Card>
20
+ <CardHeader>
21
+ <CardAsset size="S" src={asset.url} />
22
+ </CardHeader>
23
+ <CardBody>
24
+ <CardContent>
25
+ <CardTitle>{asset.name}</CardTitle>
26
+ <CardSubtitle>
27
+ {`${asset.ext.toUpperCase()} - ${asset.width}✕${asset.height}`}
28
+ </CardSubtitle>
29
+ </CardContent>
30
+ <CardBadge>
31
+ {formatMessage({
32
+ id: 'Settings.application.customization.modal.pending.card-badge',
33
+ defaultMessage: 'image',
34
+ })}
35
+ </CardBadge>
36
+ </CardBody>
37
+ </Card>
38
+ );
39
+ };
40
+
41
+ ImageCardAsset.propTypes = {
42
+ asset: PropTypes.shape({
43
+ name: PropTypes.string,
44
+ url: PropTypes.string,
45
+ width: PropTypes.number,
46
+ height: PropTypes.number,
47
+ ext: PropTypes.string,
48
+ }).isRequired,
49
+ };
50
+
51
+ export default ImageCardAsset;
@@ -0,0 +1,97 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useIntl } from 'react-intl';
4
+ import { pxToRem } from '@strapi/helper-plugin';
5
+ import { Box } from '@strapi/design-system/Box';
6
+ import { Flex } from '@strapi/design-system/Flex';
7
+ import { Button } from '@strapi/design-system/Button';
8
+ import { ModalFooter } from '@strapi/design-system/ModalLayout';
9
+ import { Typography } from '@strapi/design-system/Typography';
10
+ import ImageCardAsset from './ImageCardAsset';
11
+
12
+ const PendingLogoDialog = ({ onClose, asset, prev, next, goTo, setLocalImage, onChangeLogo }) => {
13
+ const { formatMessage } = useIntl();
14
+
15
+ const handleGoBack = () => {
16
+ setLocalImage(undefined);
17
+ goTo(prev);
18
+ };
19
+
20
+ const handleUpload = () => {
21
+ onChangeLogo(asset);
22
+ goTo(next);
23
+ };
24
+
25
+ return (
26
+ <>
27
+ <Box paddingLeft={8} paddingRight={8} paddingTop={6} paddingBottom={6}>
28
+ <Flex justifyContent="space-between" paddingBottom={6}>
29
+ <Flex direction="column" alignItems="flex-start">
30
+ <Typography variant="pi" fontWeight="bold">
31
+ {formatMessage({
32
+ id: 'Settings.application.customization.modal.pending.title',
33
+ defaultMessage: 'Logo ready to upload',
34
+ })}
35
+ </Typography>
36
+ <Typography variant="pi" textColor="neutral500">
37
+ {formatMessage({
38
+ id: 'Settings.application.customization.modal.pending.subtitle',
39
+ defaultMessage: 'Manage the chosen logo before uploading it',
40
+ })}
41
+ </Typography>
42
+ </Flex>
43
+ <Button onClick={handleGoBack} variant="secondary">
44
+ {formatMessage({
45
+ id: 'Settings.application.customization.modal.pending.choose-another',
46
+ defaultMessage: 'Choose another logo',
47
+ })}
48
+ </Button>
49
+ </Flex>
50
+ <Box maxWidth={pxToRem(180)}>
51
+ <ImageCardAsset asset={asset} />
52
+ </Box>
53
+ </Box>
54
+ <ModalFooter
55
+ startActions={
56
+ <Button onClick={onClose} variant="tertiary">
57
+ {formatMessage({
58
+ id: 'Settings.application.customization.modal.cancel',
59
+ defaultMessage: 'Cancel',
60
+ })}
61
+ </Button>
62
+ }
63
+ endActions={
64
+ <Button onClick={handleUpload}>
65
+ {formatMessage({
66
+ id: 'Settings.application.customization.modal.pending.upload',
67
+ defaultMessage: 'Upload logo',
68
+ })}
69
+ </Button>
70
+ }
71
+ />
72
+ </>
73
+ );
74
+ };
75
+
76
+ PendingLogoDialog.defaultProps = {
77
+ next: null,
78
+ prev: null,
79
+ };
80
+
81
+ PendingLogoDialog.propTypes = {
82
+ goTo: PropTypes.func.isRequired,
83
+ asset: PropTypes.shape({
84
+ name: PropTypes.string,
85
+ url: PropTypes.string,
86
+ width: PropTypes.number,
87
+ height: PropTypes.number,
88
+ ext: PropTypes.string,
89
+ }).isRequired,
90
+ next: PropTypes.string,
91
+ onClose: PropTypes.func.isRequired,
92
+ onChangeLogo: PropTypes.func.isRequired,
93
+ prev: PropTypes.string,
94
+ setLocalImage: PropTypes.func.isRequired,
95
+ };
96
+
97
+ export default PendingLogoDialog;
@@ -0,0 +1,85 @@
1
+ import React, { useReducer } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useIntl } from 'react-intl';
4
+ import { ModalLayout, ModalHeader } from '@strapi/design-system/ModalLayout';
5
+ import { Typography } from '@strapi/design-system/Typography';
6
+ import reducer, { initialState } from './reducer';
7
+
8
+ const LogoModalStepper = ({
9
+ onChangeLogo,
10
+ customLogo,
11
+ goTo,
12
+ Component,
13
+ modalTitle,
14
+ next,
15
+ prev,
16
+ currentStep,
17
+ }) => {
18
+ const [{ localImage }, dispatch] = useReducer(reducer, initialState);
19
+ const { formatMessage } = useIntl();
20
+
21
+ const setLocalImage = asset => {
22
+ dispatch({
23
+ type: 'SET_LOCAL_IMAGE',
24
+ value: asset,
25
+ });
26
+ };
27
+
28
+ const handleCloseModal = () => {
29
+ goTo(null);
30
+ };
31
+
32
+ if (!currentStep) {
33
+ return null;
34
+ }
35
+
36
+ return (
37
+ <ModalLayout labelledBy="modal" onClose={handleCloseModal}>
38
+ <ModalHeader>
39
+ <Typography fontWeight="bold" as="h2" id="modal">
40
+ {formatMessage(modalTitle)}
41
+ </Typography>
42
+ </ModalHeader>
43
+ <Component
44
+ setLocalImage={setLocalImage}
45
+ goTo={goTo}
46
+ next={next}
47
+ prev={prev}
48
+ onClose={handleCloseModal}
49
+ asset={localImage || customLogo}
50
+ onChangeLogo={onChangeLogo}
51
+ />
52
+ </ModalLayout>
53
+ );
54
+ };
55
+
56
+ LogoModalStepper.defaultProps = {
57
+ Component: undefined,
58
+ currentStep: undefined,
59
+ customLogo: undefined,
60
+ modalTitle: undefined,
61
+ next: null,
62
+ prev: null,
63
+ };
64
+
65
+ LogoModalStepper.propTypes = {
66
+ Component: PropTypes.elementType,
67
+ currentStep: PropTypes.string,
68
+ customLogo: PropTypes.shape({
69
+ name: PropTypes.string,
70
+ url: PropTypes.string,
71
+ width: PropTypes.number,
72
+ height: PropTypes.number,
73
+ ext: PropTypes.string,
74
+ }),
75
+ goTo: PropTypes.func.isRequired,
76
+ modalTitle: PropTypes.shape({
77
+ id: PropTypes.string,
78
+ defaultMessage: PropTypes.string,
79
+ }),
80
+ next: PropTypes.string,
81
+ onChangeLogo: PropTypes.func.isRequired,
82
+ prev: PropTypes.string,
83
+ };
84
+
85
+ export default LogoModalStepper;
@@ -0,0 +1,28 @@
1
+ /* eslint-disable consistent-return */
2
+ /*
3
+ *
4
+ * LogoModalStepper reducer
5
+ *
6
+ */
7
+
8
+ import produce from 'immer';
9
+
10
+ const initialState = {
11
+ localImage: undefined,
12
+ };
13
+
14
+ const reducer = (state = initialState, action) =>
15
+ produce(state, draftState => {
16
+ switch (action.type) {
17
+ case 'SET_LOCAL_IMAGE': {
18
+ draftState.localImage = action.value;
19
+ break;
20
+ }
21
+ default: {
22
+ return draftState;
23
+ }
24
+ }
25
+ });
26
+
27
+ export default reducer;
28
+ export { initialState };