groovinads-ui 1.2.60 → 1.2.62
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.
- package/README.md +43 -5
- package/dist/index.es.js +3 -3
- package/dist/index.js +3 -3
- package/package.json +1 -1
- package/src/components/Inputs/InputEmail.jsx +166 -0
- package/src/components/Inputs/index.js +2 -1
- package/src/components/Navigation/Sidebar.jsx +1 -1
- package/src/components/index.js +2 -1
- package/src/services/components.services.js +15 -7
- package/src/services/helpers.js +1 -1
- package/src/stories/InputEmail.stories.jsx +27 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "groovinads-ui",
|
|
3
3
|
"description": "Groovinads UI is a React component library designed exclusively for Groovinads applications. It provides ready-to-use UI elements styled according to Groovinads design guidelines to facilitate rapid development.",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.62",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
7
7
|
"sass",
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
4
|
+
// COMPONENTS GROOVINADS
|
|
5
|
+
import Input from './Input';
|
|
6
|
+
import { Button } from '../Button';
|
|
7
|
+
|
|
8
|
+
import { ComponentsService } from '../../services';
|
|
9
|
+
import { Icon, Spinner } from '../Labels';
|
|
10
|
+
|
|
11
|
+
const InputEmail = ({
|
|
12
|
+
showModal = true,
|
|
13
|
+
titleList = 'Added emails',
|
|
14
|
+
label = 'Email addresses',
|
|
15
|
+
textButton = 'Add',
|
|
16
|
+
textError = 'You must enter a valid email address',
|
|
17
|
+
apiGetEmail,
|
|
18
|
+
apiPostEmail,
|
|
19
|
+
apiDeleteEmail,
|
|
20
|
+
}) => {
|
|
21
|
+
// STATE
|
|
22
|
+
const [notifications, setNotifications] = useState([]);
|
|
23
|
+
const [newEmail, setNewEmail] = useState('');
|
|
24
|
+
|
|
25
|
+
const [selectedButton, setSelectedButton] = useState([]);
|
|
26
|
+
|
|
27
|
+
const [emailInvalid, setEmailInvalid] = useState(false);
|
|
28
|
+
|
|
29
|
+
// VARIABLES
|
|
30
|
+
const validEmailPattern = /^\w+([.-_+]?\w+)*@\w+([.-]?\w+)*(\.\w{2,10})+$/;
|
|
31
|
+
|
|
32
|
+
// GET, Returns a list of emails
|
|
33
|
+
const fetchNotifications = async () => {
|
|
34
|
+
const resp = await ComponentsService.getInfo(apiGetEmail);
|
|
35
|
+
setNotifications(resp || []);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// POST, Receives a list of emails
|
|
39
|
+
const handleAddEmail = async () => {
|
|
40
|
+
const emails = newEmail
|
|
41
|
+
.split(/[;, ]+/)
|
|
42
|
+
.map((email) => email.trim())
|
|
43
|
+
.filter((email) => email.length > 0);
|
|
44
|
+
|
|
45
|
+
// Filter invalid emails
|
|
46
|
+
const invalidEmails = emails.filter(
|
|
47
|
+
(email) => !validEmailPattern.test(email),
|
|
48
|
+
);
|
|
49
|
+
const validEmails = emails.filter((email) => validEmailPattern.test(email));
|
|
50
|
+
|
|
51
|
+
if (invalidEmails.length) {
|
|
52
|
+
setNewEmail(invalidEmails.join(' ')); // if there are multiple invalid emails, they are joined in the array and separated by a space
|
|
53
|
+
setEmailInvalid(true);
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
setEmailInvalid(false);
|
|
56
|
+
}, 3000);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// update total list of emails validated
|
|
60
|
+
if (validEmails.length) {
|
|
61
|
+
const resp = await ComponentsService.postInfo(apiPostEmail, [
|
|
62
|
+
...notifications,
|
|
63
|
+
...validEmails,
|
|
64
|
+
]);
|
|
65
|
+
setNotifications(resp);
|
|
66
|
+
}
|
|
67
|
+
setNewEmail(invalidEmails.join(' '));
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const handleInputChange = (e) => {
|
|
71
|
+
const value = e.target.value.replace(/\. +/g, ' '); // removes the dot and space, replacing it with ' '
|
|
72
|
+
setNewEmail(value);
|
|
73
|
+
|
|
74
|
+
if (!value.trim() || validEmailPattern.test(value)) {
|
|
75
|
+
setEmailInvalid(false);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// DELETE, Receives a list of emails
|
|
80
|
+
const handleDeleteEmail = async (emailToDelete) => {
|
|
81
|
+
setSelectedButton([...selectedButton, emailToDelete]);
|
|
82
|
+
const resp = await ComponentsService.deleteEmails(
|
|
83
|
+
apiDeleteEmail,
|
|
84
|
+
emailToDelete,
|
|
85
|
+
);
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
setSelectedButton(
|
|
88
|
+
selectedButton.filter((email) => email !== emailToDelete),
|
|
89
|
+
);
|
|
90
|
+
setNotifications(resp);
|
|
91
|
+
}, 1000);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
if (showModal) fetchNotifications();
|
|
96
|
+
}, [showModal]);
|
|
97
|
+
return (
|
|
98
|
+
<>
|
|
99
|
+
{/* SECTIONS ADD EMAILS */}
|
|
100
|
+
<div className={'mb-3'}>
|
|
101
|
+
<div
|
|
102
|
+
className={`mb-3 input-group w-100 mb-4 ${
|
|
103
|
+
emailInvalid ? 'not-validated' : ''
|
|
104
|
+
}`}
|
|
105
|
+
data-error={textError}
|
|
106
|
+
>
|
|
107
|
+
<Input
|
|
108
|
+
label={label}
|
|
109
|
+
value={newEmail}
|
|
110
|
+
onChange={(e) => {
|
|
111
|
+
handleInputChange(e);
|
|
112
|
+
}}
|
|
113
|
+
/>
|
|
114
|
+
{/* ADD BUTTON */}
|
|
115
|
+
<Button
|
|
116
|
+
onClick={handleAddEmail}
|
|
117
|
+
className={`${newEmail.trim() ? '' : 'disabled'}`}
|
|
118
|
+
>
|
|
119
|
+
{textButton}
|
|
120
|
+
</Button>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
{/* SECTIONS LIST ADDED EMAILS */}
|
|
124
|
+
{notifications.length ? (
|
|
125
|
+
<div className='shared-users-list'>
|
|
126
|
+
<h3>{titleList}</h3>
|
|
127
|
+
{notifications.map((email, index) => (
|
|
128
|
+
<div key={`email${index}`} className='shared-user-item'>
|
|
129
|
+
<div className='shared-user'>
|
|
130
|
+
<Icon iconName='user-circle' scale={2} />
|
|
131
|
+
<span>{email}</span>
|
|
132
|
+
</div>
|
|
133
|
+
{selectedButton.some(
|
|
134
|
+
(selectedEmail) => selectedEmail === email,
|
|
135
|
+
) ? (
|
|
136
|
+
<div className='spinner-wrapper'>
|
|
137
|
+
<Spinner scale={1} />
|
|
138
|
+
</div>
|
|
139
|
+
) : (
|
|
140
|
+
<Button
|
|
141
|
+
variant='terciary'
|
|
142
|
+
style='danger'
|
|
143
|
+
icon='trash-can'
|
|
144
|
+
onClick={() => handleDeleteEmail(email)}
|
|
145
|
+
/>
|
|
146
|
+
)}
|
|
147
|
+
</div>
|
|
148
|
+
))}
|
|
149
|
+
</div>
|
|
150
|
+
) : null}
|
|
151
|
+
</>
|
|
152
|
+
);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
InputEmail.propTypes = {
|
|
156
|
+
showModal: PropTypes.bool,
|
|
157
|
+
apiGetEmail: PropTypes.string.isRequired,
|
|
158
|
+
apiPostEmail: PropTypes.string.isRequired,
|
|
159
|
+
apiDeleteEmail: PropTypes.string.isRequired,
|
|
160
|
+
titleList: PropTypes.string.isRequired,
|
|
161
|
+
label: PropTypes.string,
|
|
162
|
+
textButton: PropTypes.string,
|
|
163
|
+
textError: PropTypes.string,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export default InputEmail;
|
|
@@ -4,5 +4,6 @@ import Radio from './Radio';
|
|
|
4
4
|
import Switch from './Switch';
|
|
5
5
|
import Textarea from './Textarea';
|
|
6
6
|
import InputChip from './InputChip';
|
|
7
|
+
import InputEmail from './InputEmail';
|
|
7
8
|
|
|
8
|
-
export { Checkbox, Input, Radio, Switch, Textarea, InputChip };
|
|
9
|
+
export { Checkbox, Input, Radio, Switch, Textarea, InputChip, InputEmail };
|
package/src/components/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import Button from "./Button/Button";
|
|
|
5
5
|
import { DropdownComponent, DropdownMultiSelect, DropdownDatePicker, DropdownFilter, DropdownSimpleDatePicker } from './Dropdowns';
|
|
6
6
|
|
|
7
7
|
// Inputs
|
|
8
|
-
import { Checkbox, Input, Radio, Switch, Textarea } from './Inputs';
|
|
8
|
+
import { Checkbox, Input, Radio, Switch, Textarea, InputEmail } from './Inputs';
|
|
9
9
|
|
|
10
10
|
// Labels
|
|
11
11
|
import { Alert, Icon, LoginSource, PillComponent, Spinner, StatusIcon } from './Labels';
|
|
@@ -31,6 +31,7 @@ export {
|
|
|
31
31
|
Radio,
|
|
32
32
|
Switch,
|
|
33
33
|
Textarea,
|
|
34
|
+
InputEmail,
|
|
34
35
|
// Labels
|
|
35
36
|
Alert,
|
|
36
37
|
Icon,
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
import urlPath, { basePath } from './url.path';
|
|
2
2
|
import { POST, GET, DELETE } from './helpers';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// GETS
|
|
5
|
+
export const getInfo = async (apiGetInfo) => await GET({ url: `${basePath}${apiGetInfo}`}); // (Sidebar and InputEmail)
|
|
5
6
|
|
|
6
|
-
export const
|
|
7
|
+
export const authStatus = async () => await GET({ url: urlPath.authStatus });
|
|
7
8
|
|
|
8
9
|
export const applications = async () => await GET({ url: urlPath.applications });
|
|
9
10
|
|
|
10
|
-
export const
|
|
11
|
+
export const getClientsList = async () => await GET({ url: urlPath.clients });
|
|
11
12
|
|
|
12
|
-
export const
|
|
13
|
+
export const getCustomReportsList = async () => await GET(`${urlPath.customReports}/?sort=id_report.desc&offset=0&limit=100`);
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
// POSTS
|
|
16
|
+
export const postInfo = async (apiPostInfo, data) => await POST({ url: `${basePath}${apiPostInfo}`, data }); // update emails RETAIL MEDIA (notifications)
|
|
17
|
+
|
|
18
|
+
export const authLogout = async () => await POST({ url: urlPath.authLogout });
|
|
19
|
+
|
|
20
|
+
export const favApplication = async (appToFav) => await POST({url: `${urlPath.favApps}/${appToFav}`, data: appToFav})
|
|
15
21
|
|
|
16
22
|
export const clientsLogin = async (clientId) => await POST({ url: urlPath.clientsLogin, data:{ id_client: clientId }});
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
// DELETES
|
|
25
|
+
export const unfavApplication = async (appToUnfav) => await DELETE({url: `${urlPath.favApps}/${appToUnfav}`});
|
|
26
|
+
|
|
27
|
+
export const deleteEmails = async (apiDeleteEmail, email) => await DELETE({ url: `${basePath}${apiDeleteEmail}/${email}` }); // delete emails RETAIL MEDIA (notifications)
|
|
19
28
|
|
|
20
|
-
export const getCustomReportsList = async () => await GET(`${urlPath.customReports}/?sort=id_report.desc&offset=0&limit=100`);
|
|
21
29
|
|
package/src/services/helpers.js
CHANGED
|
@@ -27,6 +27,6 @@ export const PUT = async ({ url, data }) => {
|
|
|
27
27
|
export const DELETE = async ({ url }) => {
|
|
28
28
|
return await axios
|
|
29
29
|
.delete(url, urlPath.headers)
|
|
30
|
-
.then((data) => data)
|
|
30
|
+
.then(({data}) => data)
|
|
31
31
|
.catch((response) => Promise.reject(response || 'error en la url'));
|
|
32
32
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
// COMPONENTS
|
|
4
|
+
import { InputEmail } from '../components';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Inputs/InputEmail',
|
|
8
|
+
component: InputEmail,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const Template = (args) => {
|
|
12
|
+
// const [showModal, setShowModal] = useState(false);
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
{/* <Button onClick={() => setShowModal(!showModal)}>Cambiar show</Button> */}
|
|
16
|
+
<InputEmail
|
|
17
|
+
{...args}
|
|
18
|
+
apiGetEmail={'v2/retail-media/retailers/settings/notifications'}
|
|
19
|
+
apiPostEmail={'v2/retail-media/retailers/settings/notifications'}
|
|
20
|
+
apiDeleteEmail={'v2/retail-media/retailers/settings/notifications'}
|
|
21
|
+
// showModal={showModal}
|
|
22
|
+
/>
|
|
23
|
+
</>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const Default = Template.bind({});
|