@visns-studio/visns-components 1.8.4 → 2.0.0

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 (36) hide show
  1. package/.prettierrc.json +7 -0
  2. package/components/cms/{visns-data-grid.jsx → DataGrid.jsx} +2 -2
  3. package/components/cms/DropZone.jsx +161 -0
  4. package/components/cms/Field.jsx +747 -0
  5. package/components/cms/Form.jsx +475 -0
  6. package/components/cms/sorting/{list.jsx → List.jsx} +3 -3
  7. package/components/crm/{visns-async-select.jsx → AsyncSelect.jsx} +9 -9
  8. package/components/crm/Call.jsx +220 -0
  9. package/components/crm/{visns-data-grid.jsx → DataGrid.jsx} +263 -274
  10. package/components/crm/{visns-field.jsx → Field.jsx} +5 -5
  11. package/components/crm/{visns-form.jsx → Form.jsx} +302 -205
  12. package/components/crm/{visns-multi-select.jsx → MultiSelect.jsx} +1 -1
  13. package/components/crm/{visns-navigation.jsx → Navigation.jsx} +22 -18
  14. package/components/crm/{visns-notification.jsx → Notification.jsx} +1 -1
  15. package/components/crm/TableFilter.jsx +125 -0
  16. package/components/crm/auth/Login.jsx +158 -0
  17. package/components/crm/auth/Profile.jsx +163 -0
  18. package/components/crm/auth/Reset.jsx +87 -0
  19. package/components/crm/auth/Verify.jsx +162 -0
  20. package/components/crm/generic/GenericDetail.jsx +380 -0
  21. package/components/crm/generic/GenericIndex.jsx +112 -0
  22. package/components/crm/generic/NotificationList.jsx +64 -0
  23. package/index.js +37 -19
  24. package/package.json +6 -6
  25. package/components/cms/visns-dropzone.jsx +0 -161
  26. package/components/cms/visns-field.jsx +0 -747
  27. package/components/cms/visns-form.jsx +0 -475
  28. package/components/crm/visns-call.jsx +0 -220
  29. package/components/crm/visns-table-filter.jsx +0 -153
  30. /package/components/cms/sorting/{item.jsx → Item.jsx} +0 -0
  31. /package/components/crm/{visns-autocomplete.jsx → Autocomplete.jsx} +0 -0
  32. /package/components/crm/{visns-download.jsx → Download.jsx} +0 -0
  33. /package/components/crm/{visns-fetch.jsx → Fetch.jsx} +0 -0
  34. /package/components/crm/{visns-loader.jsx → Loader.jsx} +0 -0
  35. /package/components/crm/{visns-select.jsx → Select.jsx} +0 -0
  36. /package/components/crm/{visns-select-list.jsx → SelectList.jsx} +0 -0
@@ -1,475 +0,0 @@
1
- import React, { useState, useEffect } from "react";
2
- import CustomFetch from "../crm/visns-fetch";
3
- import Field from "./visns-field";
4
- import slugify from "react-slugify";
5
- import moment from "moment";
6
- import Reveal from "react-reveal/Reveal";
7
- import parse from "html-react-parser";
8
- import { confirmAlert } from "react-confirm-alert";
9
- import { toast } from "react-toastify";
10
- import { Copy, TrashBin } from "akar-icons";
11
-
12
- import "react-confirm-alert/src/react-confirm-alert.css";
13
-
14
- function Form(props) {
15
- const { dataId, navigate, form, setActiveNav } = props;
16
- const [data, setData] = useState({});
17
- const [dataClass, setDataClass] = useState({});
18
- const [audit, setAudit] = useState({
19
- createdBy: {},
20
- created: "",
21
- updatedBy: {},
22
- updated: "",
23
- });
24
- const [uploadProgress, setUploadProgress] = useState({});
25
-
26
- const handleChange = (e) => {
27
- if (e) {
28
- const { name, value } = e.target;
29
-
30
- switch (e.target.name) {
31
- case "title":
32
- setData((prevState) => ({
33
- ...prevState,
34
- [name]: value,
35
- }));
36
-
37
- setData((prevState) => ({
38
- ...prevState,
39
- slug: slugify(value),
40
- }));
41
- break;
42
- case "name":
43
- setData((prevState) => ({
44
- ...prevState,
45
- [name]: value,
46
- }));
47
-
48
- setData((prevState) => ({
49
- ...prevState,
50
- slug: slugify(value),
51
- }));
52
- break;
53
- default:
54
- if (name) {
55
- setData((prevState) => ({
56
- ...prevState,
57
- [name]: value,
58
- }));
59
- } else {
60
- setData((prevState) => ({
61
- ...prevState,
62
- [e.target.dataset.name]: value,
63
- }));
64
- }
65
- break;
66
- }
67
- }
68
- };
69
-
70
- const handleChangeDate = (date, id) => {
71
- setData((prevState) => ({
72
- ...prevState,
73
- [id]: date,
74
- }));
75
- };
76
-
77
- const handleChangeSelect = (value, action, id) => {
78
- if (value && action && id) {
79
- setData((prevState) => ({
80
- ...prevState,
81
- [id]: value,
82
- }));
83
- }
84
- };
85
-
86
- const handleChangeRicheditor = (value, name) => {
87
- setData((prevState) => ({
88
- ...prevState,
89
- [name]: value,
90
- }));
91
- };
92
-
93
- const handleChangeToggle = (e) => {
94
- if (!e) {
95
- return;
96
- }
97
-
98
- const { name, checked } = e.target;
99
-
100
- setData((prevState) => ({
101
- ...prevState,
102
- [name]: checked,
103
- }));
104
- };
105
-
106
- const handleChangeFile = (e) => {
107
- if (e) {
108
- setData((prevState) => ({
109
- ...prevState,
110
- [e.target.name]: e.target.files[0],
111
- }));
112
-
113
- Vapor.store(e.target.files[0], {
114
- progress: (progress) => {
115
- setUploadProgress((prevState) => ({
116
- ...prevState,
117
- [e.target.name]: progress * 100,
118
- }));
119
- },
120
- }).then((response) => {
121
- if (data.hasOwnProperty("files")) {
122
- let _files = data.files;
123
- let _new = true;
124
-
125
- data.files.forEach((a, b) => {
126
- if (e.target.name === a.field) {
127
- _files[b] = {
128
- field: e.target.name,
129
- uuid: response.uuid,
130
- key: response.key,
131
- bucket: response.bucket,
132
- filename: e.target.files[0].name,
133
- filesize: e.target.files[0].size,
134
- extension: response.extension,
135
- };
136
-
137
- _new = false;
138
- }
139
- });
140
-
141
- if (_new === true) {
142
- setData((prevState) => ({
143
- ...prevState,
144
- files: [
145
- ...prevState.files,
146
- {
147
- field: e.target.name,
148
- uuid: response.uuid,
149
- key: response.key,
150
- bucket: response.bucket,
151
- filename: e.target.files[0].name,
152
- filesize: e.target.files[0].size,
153
- extension: response.extension,
154
- },
155
- ],
156
- }));
157
- } else {
158
- setData((prevState) => ({
159
- ...prevState,
160
- files: _files,
161
- }));
162
- }
163
- } else {
164
- setData((prevState) => ({
165
- ...prevState,
166
- files: [
167
- {
168
- field: e.target.name,
169
- uuid: response.uuid,
170
- key: response.key,
171
- bucket: response.bucket,
172
- filename: e.target.files[0].name,
173
- filesize: e.target.files[0].size,
174
- extension: response.extension,
175
- },
176
- ],
177
- }));
178
- }
179
- });
180
- }
181
- };
182
-
183
- const handleSubmit = (e) => {
184
- if (e) {
185
- e.preventDefault();
186
-
187
- let error = "";
188
- let url = "";
189
- let method = "";
190
- let message = "";
191
-
192
- if (data.title === "") {
193
- error += "Please enter a title.<br />";
194
- }
195
-
196
- if (data.summary === "") {
197
- error += "Please enter a summary.<br />";
198
- }
199
-
200
- if (error === "") {
201
- if (dataId === "create") {
202
- url = form.url;
203
- method = "POST";
204
- message = "You have successfully created a new entry.";
205
- } else {
206
- url = form.url + "/" + dataId;
207
- method = "PUT";
208
- message = "You have successfully updated this entry.";
209
- }
210
-
211
- CustomFetch(url, method, data, function (result) {
212
- if (result.error === "") {
213
- let _uploadProgress = uploadProgress;
214
-
215
- Object.keys(_uploadProgress).forEach((a, b) => {
216
- setUploadProgress((prevState) => ({
217
- ...prevState,
218
- [b]: 0,
219
- }));
220
- });
221
-
222
- toast.success(message);
223
-
224
- if (dataId === "create") {
225
- navigate(
226
- form.url.replace("/ajax", "") +
227
- "/" +
228
- result.data.id,
229
- {
230
- state: {
231
- form: form,
232
- },
233
- }
234
- );
235
- }
236
- } else {
237
- toast.error(result.error);
238
- }
239
- });
240
- } else {
241
- toast.error(<div>{parse(error)}</div>);
242
- }
243
- }
244
- };
245
-
246
- const handleDelete = (e) => {
247
- if (e) {
248
- confirmAlert({
249
- title: "Delete this entry",
250
- message: "Are you sure you want to delete it?",
251
- buttons: [
252
- {
253
- label: "Yes",
254
- onClick: () =>
255
- CustomFetch(
256
- `${form.url}/${dataId}`,
257
- "DELETE",
258
- {},
259
- function (result) {
260
- if (result.error === "") {
261
- navigate(form.url.replace("/ajax", ""));
262
- toast.success(
263
- "You have successfully deleted this entry."
264
- );
265
- } else {
266
- toast.error(result.error);
267
- }
268
- }
269
- ),
270
- },
271
- {
272
- label: "No",
273
- onClick: () => close(),
274
- },
275
- ],
276
- });
277
- }
278
- };
279
-
280
- const fetchData = () => {
281
- form.fields.forEach((a) => {
282
- setData((prevState) => ({
283
- ...prevState,
284
- [a.id]: "",
285
- }));
286
- });
287
-
288
- if (dataId !== "create") {
289
- CustomFetch(
290
- `${form.url}/${dataId}`,
291
- "GET",
292
- {},
293
- function (result) {
294
- let now = moment();
295
- let created = moment.duration(
296
- now.diff(result.data.created_at)
297
- );
298
- let updated = moment.duration(
299
- now.diff(result.data.updated_at)
300
- );
301
-
302
- setData(result.data);
303
- setAudit((prevState) => ({
304
- ...prevState,
305
- createdBy: result.audit_first,
306
- created:
307
- created.hours() > 24
308
- ? created.days() +
309
- " Days " +
310
- created.hours() +
311
- " Hour(s) " +
312
- created.minutes() +
313
- " Minutes"
314
- : created.hours() +
315
- " Hour(s) " +
316
- created.minutes() +
317
- " Minutes",
318
- updatedBy: result.audit_latest,
319
- updated:
320
- updated.hours() > 24
321
- ? updated.days() +
322
- " Days " +
323
- updated.hours() +
324
- " Hour(s) " +
325
- updated.minutes() +
326
- " Minutes"
327
- : updated.hours() +
328
- " Hour(s) " +
329
- updated.minutes() +
330
- " Minutes",
331
- }));
332
- },
333
- function (error) {
334
- navigate("/");
335
-
336
- toast.error(String(error));
337
- }
338
- );
339
- }
340
- };
341
-
342
- useEffect(() => {
343
- form.fields.forEach((a) => {
344
- if (a.type === "image") {
345
- setUploadProgress((prevState) => ({
346
- ...prevState,
347
- [a.id]: 0,
348
- }));
349
- }
350
-
351
- setData((prevState) => ({
352
- ...prevState,
353
- [a.id]: "",
354
- }));
355
-
356
- setDataClass((prevState) => ({
357
- ...prevState,
358
- [a.id]: "",
359
- }));
360
- });
361
-
362
- fetchData();
363
- setActiveNav();
364
- }, [dataId]);
365
-
366
- return (
367
- <Reveal effect="fadeInUp">
368
- <div className="grid">
369
- <div className="grid__row">
370
- <div className="grid__full cmstitle">
371
- <h1>
372
- {data.title
373
- ? data.title
374
- : dataId !== "create"
375
- ? form.update.title
376
- : form.create.title}
377
- </h1>
378
- <div className="cmstitle__actions">
379
- <button
380
- className="btn actionbtn"
381
- onClick={handleSubmit}
382
- >
383
- <Copy size={18} strokeWidth={2} />{" "}
384
- {dataId !== "create" ? "Save" : "Create"}
385
- </button>
386
- </div>
387
- </div>
388
- </div>
389
- </div>
390
- <div className="dynamic">
391
- <div className="dynamic__left">
392
- <div className="formcontainer">
393
- <div className="dynamicform">
394
- {form.fields.map((a, b) => (
395
- <Field
396
- settings={a}
397
- key={
398
- b +
399
- "-fields-" +
400
- (a.hasOwnProperty("key")
401
- ? a.id + "-" + a.key
402
- : a.id)
403
- }
404
- inputValue={
405
- a.hasOwnProperty("key")
406
- ? data[a.key]
407
- : Array.isArray(data[a.id]) &&
408
- a.type === "image"
409
- ? data[a.id].length > 0
410
- ? data[a.id][0]
411
- : ""
412
- : data[a.id]
413
- }
414
- inputClass={dataClass}
415
- onChange={handleChange}
416
- onChangeDate={handleChangeDate}
417
- onChangeFile={handleChangeFile}
418
- onChangeRicheditor={handleChangeRicheditor}
419
- onChangeSelect={handleChangeSelect}
420
- onChangeToggle={handleChangeToggle}
421
- setFormData={setData}
422
- uploadProgress={uploadProgress}
423
- />
424
- ))}
425
- </div>
426
- </div>
427
- </div>
428
- <div className="dynamic__right">
429
- <h1>Information</h1>
430
- <ul>
431
- <li>
432
- Created: <span>{audit.created} Ago</span>
433
- </li>
434
- <li>
435
- By:{" "}
436
- <span>
437
- {audit &&
438
- audit.createdBy &&
439
- audit.createdBy.user
440
- ? audit.createdBy.user.name
441
- : null}
442
- </span>
443
- </li>
444
- <li>
445
- Last Update: <span>{audit.updated} Ago</span>
446
- </li>
447
- <li>
448
- by:{" "}
449
- <span>
450
- {audit &&
451
- audit.updatedBy &&
452
- audit.updatedBy.user
453
- ? audit.updatedBy.user.name
454
- : null}
455
- </span>
456
- </li>
457
- {dataId !== "create" ? (
458
- <li>
459
- <button
460
- className="btn actionbtn deletebtn"
461
- onClick={handleDelete}
462
- >
463
- <TrashBin size={14} strokeWidth={2} />{" "}
464
- Delete Entry
465
- </button>
466
- </li>
467
- ) : null}
468
- </ul>
469
- </div>
470
- </div>
471
- </Reveal>
472
- );
473
- }
474
-
475
- export default Form;
@@ -1,220 +0,0 @@
1
- import React, { useState, useEffect } from "react";
2
- import Popup from "reactjs-popup";
3
- import moment from "moment";
4
-
5
- import CustomFetch from "./visns-fetch";
6
-
7
- function CallPop(props) {
8
- const { incomingCallData } = props;
9
- const [modalShow, setModalShow] = useState(false);
10
- const [client, setClient] = useState({});
11
- const [tasks, setTasks] = useState([]);
12
- const [callShow, setCallShow] = useState(false);
13
- const [timerId, setTimerId] = useState(0);
14
-
15
- const formatPhone = (value) => {
16
- if (value) {
17
- let _value = value.replace("61", 0);
18
- let match;
19
- let type = _value.substr(0, 2);
20
-
21
- if (_value && _value !== "") {
22
- switch (type) {
23
- case "04":
24
- match = _value.match(/^(\d{4})(\d{3})(\d{3})$/);
25
- if (match) {
26
- _value = match[1] + " " + match[2] + " " + match[3];
27
- }
28
- break;
29
- default:
30
- match = _value.match(/^(\d{2})(\d{4})(\d{4})$/);
31
- if (match) {
32
- _value = match[1] + " " + match[2] + " " + match[3];
33
- }
34
- break;
35
- }
36
- }
37
-
38
- return _value;
39
- }
40
- };
41
-
42
- const viewModal = () => {
43
- setModalShow(true);
44
-
45
- if (timerId > 0) {
46
- clearTimeout(timerId);
47
- }
48
- };
49
-
50
- useEffect(() => {
51
- if (
52
- incomingCallData &&
53
- incomingCallData.number &&
54
- incomingCallData.number != ""
55
- ) {
56
- CustomFetch(
57
- "/incoming/check",
58
- "POST",
59
- {
60
- user_id: incomingCallData.user_id,
61
- },
62
- function (result) {
63
- if (result.show === true) {
64
- setCallShow(true);
65
-
66
- let _timerId = setTimeout(() => {
67
- setCallShow(false);
68
- }, 20000);
69
-
70
- setTimerId(_timerId);
71
-
72
- CustomFetch(
73
- "/company/call",
74
- "POST",
75
- {
76
- search: incomingCallData.number,
77
- },
78
- function (result) {
79
- setClient(result);
80
- }
81
- );
82
- } else {
83
- setCallShow(false);
84
- }
85
- }
86
- );
87
- }
88
- }, [incomingCallData]);
89
-
90
- return (
91
- <>
92
- {callShow === true ? (
93
- <>
94
- <div className="callpop callpop--alive">
95
- <div className="callpop__left">
96
- <span>
97
- <strong>Active Call:</strong>{" "}
98
- {formatPhone(incomingCallData.number)}{" "}
99
- <strong>Client:</strong>{" "}
100
- {setData
101
- ? setData.firstname === ""
102
- ? "No contacts found with the incoming number."
103
- : setData.firstname +
104
- " " +
105
- setData.surname +
106
- " (" +
107
- setData.customer.name +
108
- ")"
109
- : "No contacts found with the incoming number."}
110
- </span>
111
- </div>
112
- <div className="callpop__right">
113
- <button className="btn cpview" onClick={viewModal}>
114
- View{" "}
115
- <i className="cil-chevron-circle-up-alt "></i>
116
- </button>
117
- <button
118
- className="btn cpdismiss"
119
- onClick={() => {
120
- setCallShow(false);
121
- }}
122
- >
123
- Dismiss
124
- </button>
125
- </div>
126
- </div>
127
- <Popup
128
- open={modalShow}
129
- onClose={() => {
130
- setCallShow(false);
131
- setModalShow(false);
132
- }}
133
- >
134
- <div className="modalwrap">
135
- <div className="grid">
136
- <div className="grid__row">
137
- <div className="grid__full crmtitle callborder">
138
- <i className="cil-phone-in-talk"></i>
139
- <h1>
140
- Active Call:{" "}
141
- <span>
142
- {formatPhone(
143
- incomingCallData.number
144
- )}
145
- </span>{" "}
146
- Client:{" "}
147
- <span>
148
- {setData
149
- ? setData.firstname === ""
150
- ? "No contacts found with the incoming number."
151
- : setData.firstname +
152
- " " +
153
- setData.surname +
154
- " (" +
155
- setData.customer
156
- .name +
157
- ")"
158
- : "No contacts found with the incoming number."}
159
- </span>{" "}
160
- </h1>
161
- </div>
162
- </div>
163
- </div>
164
- <div className="grid">
165
- <div className="grid__row">
166
- <div className="grid__full">
167
- <table className="content-table">
168
- <thead>
169
- <tr className="grid-headers">
170
- <th>Ticket #</th>
171
- <th>Subject</th>
172
- <th>Status</th>
173
- <th>Created</th>
174
- </tr>
175
- </thead>
176
- <tbody>
177
- {data &&
178
- data.tickets &&
179
- data.tickets.length > 0 ? (
180
- data.tickets.map((a) => (
181
- <tr
182
- key={`task-id-${a.id}`}
183
- >
184
- <td>{a.id}</td>
185
- <td>{a.subject}</td>
186
- <td>
187
- {a.status.label}
188
- </td>
189
- <td>
190
- {moment(
191
- a.created_at
192
- ).format(
193
- "DD-MM-YYYY"
194
- )}
195
- </td>
196
- </tr>
197
- ))
198
- ) : (
199
- <tr colSpan="10">
200
- <td>
201
- No tickets found
202
- with the incoming
203
- number.
204
- </td>
205
- </tr>
206
- )}
207
- </tbody>
208
- </table>
209
- </div>
210
- </div>
211
- </div>
212
- </div>
213
- </Popup>
214
- </>
215
- ) : null}
216
- </>
217
- );
218
- }
219
-
220
- export default CallPop;