@visns-studio/visns-components 5.7.8 → 5.7.9

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/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  "react-dom": "^17.0.0 || ^18.0.0"
83
83
  },
84
84
  "name": "@visns-studio/visns-components",
85
- "version": "5.7.8",
85
+ "version": "5.7.9",
86
86
  "description": "Various packages to assist in the development of our Custom Applications.",
87
87
  "main": "src/index.js",
88
88
  "files": [
@@ -9,7 +9,7 @@ function ActionButtons({ actions, onActionClick }) {
9
9
  <button
10
10
  key={`action-${action.id}`}
11
11
  className={styles.actionButton}
12
- onClick={() => onActionClick(action.id)}
12
+ onClick={() => onActionClick(action)}
13
13
  title={action.label}
14
14
  >
15
15
  {action.label}
@@ -1,24 +1,45 @@
1
1
  import '../../styles/global.css';
2
2
 
3
3
  import React, { useState, useEffect } from 'react';
4
- import { useParams } from 'react-router-dom';
4
+ import { useParams, useNavigate } from 'react-router-dom';
5
+ import Popup from 'reactjs-popup';
5
6
  import moment from 'moment';
6
7
  import get from 'lodash/get';
7
8
 
8
9
  import CustomFetch from '../../crm/Fetch';
9
10
  import ActionButtons from './ActionButtons';
11
+ import Form from '../../crm/Form';
10
12
  import { formatCurrency } from './utils/formatters';
11
13
 
12
14
  import styles from './styles/GenericQuote.module.scss';
13
15
 
14
16
  function GenericQuote({ logo, setting, urlParam }) {
15
17
  const routeParams = useParams();
18
+ const navigate = useNavigate();
16
19
 
17
- const { actions: actionItems, page, tables } = setting;
20
+ const { actions: actionItems, page, tables, form } = setting;
18
21
 
19
22
  const [data, setData] = useState({});
20
23
  const [actions, setActions] = useState(actionItems || []);
21
24
 
25
+ // Modal state variables
26
+ const [modalShow, setModalShow] = useState(false);
27
+ const [formType, setFormType] = useState('');
28
+ const [formId, setFormId] = useState(0);
29
+ const [formData, setFormData] = useState({});
30
+
31
+ // Modal functions
32
+ const modalOpen = (type, id) => {
33
+ setModalShow(true);
34
+ setFormType(type);
35
+ setFormId(id);
36
+ setFormData(form);
37
+ };
38
+
39
+ const modalClose = () => {
40
+ setModalShow(false);
41
+ };
42
+
22
43
  useEffect(() => {
23
44
  if (actionItems && actionItems.length > 0) {
24
45
  setActions(actionItems);
@@ -44,31 +65,74 @@ function GenericQuote({ logo, setting, urlParam }) {
44
65
  fetchData();
45
66
  }, [routeParams['*']]);
46
67
 
47
- const handleActionClick = (actionId) => {
48
- // Handle different actions based on actionId
49
- switch (actionId) {
68
+ const handleActionClick = (action) => {
69
+ // Handle different actions based on action properties
70
+ console.log(`Action ${action.id} clicked:`, action);
71
+
72
+ // Check if action has a type property
73
+ if (action.type === 'link' && action.url) {
74
+ // Handle link type actions
75
+ let url = action.url;
76
+
77
+ // If urlParam is specified, append the corresponding data value
78
+ if (action.urlParam && data[action.urlParam]) {
79
+ url = `${url}${data[action.urlParam]}`;
80
+ }
81
+
82
+ // Navigate to the URL using React Router
83
+ navigate(url);
84
+ return;
85
+ }
86
+
87
+ // Handle editModal type
88
+ if (action.type === 'editModal') {
89
+ // Open the edit modal with the current quote data
90
+ modalOpen('update', data.id);
91
+ return;
92
+ }
93
+
94
+ // Handle windowOpen type - opens URL in a new browser window/tab
95
+ if (action.type === 'windowOpen' && action.url) {
96
+ // Handle window open actions
97
+ let url = action.url;
98
+
99
+ // If urlParam is specified, append the corresponding data value
100
+ if (action.urlParam && data[action.urlParam]) {
101
+ url = `${url}${data[action.urlParam]}`;
102
+ }
103
+
104
+ // Open the URL in a new window/tab
105
+ window.open(url, '_blank');
106
+ return;
107
+ }
108
+
109
+ // Handle other actions based on their id if no specific type is defined
110
+ switch (action.id) {
50
111
  case 'addItem':
51
112
  // Handle add item action
52
113
  console.log('Add item clicked');
53
114
  break;
54
115
  case 'editQuote':
55
- // Handle edit quote action
56
- console.log('Edit quote clicked');
57
- break;
58
- case 'viewTicket':
59
- // Handle view ticket action
60
- console.log('View ticket clicked');
116
+ // If no type is specified but id is editQuote, default to opening the edit modal
117
+ if (!action.type) {
118
+ modalOpen('update', data.id);
119
+ }
61
120
  break;
62
121
  case 'saveAsPdf':
63
- // Handle save as PDF action
64
- console.log('Save as PDF clicked');
122
+ // If no type is specified but id is saveAsPdf, default to opening PDF in new window
123
+ if (!action.type) {
124
+ console.log('Save as PDF clicked');
125
+ // You could implement a default PDF generation here if needed
126
+ }
65
127
  break;
66
128
  case 'saveToTicket':
67
129
  // Handle save to ticket action
68
130
  console.log('Save to ticket clicked');
69
131
  break;
70
132
  default:
71
- console.log(`Action ${actionId} clicked`);
133
+ console.log(
134
+ `Action ${action.id} clicked with no specific handler`
135
+ );
72
136
  }
73
137
  };
74
138
 
@@ -345,7 +409,69 @@ function GenericQuote({ logo, setting, urlParam }) {
345
409
  );
346
410
  })}
347
411
  </div>
412
+
413
+ {/* Terms and Condition Section */}
414
+ {data.terms_and_condition && (
415
+ <div className={styles.termsSection}>
416
+ <h3 className={styles.termsTitle}>
417
+ Terms and Conditions
418
+ </h3>
419
+ <div className={styles.termsContent}>
420
+ {data.terms_and_condition}
421
+ </div>
422
+ </div>
423
+ )}
348
424
  </div>
425
+
426
+ {/* Form Modal */}
427
+ <Popup
428
+ open={modalShow}
429
+ onClose={modalClose}
430
+ closeOnDocumentClick={false}
431
+ contentStyle={{ width: '80vw', maxWidth: '1200px' }}
432
+ >
433
+ <div className="modalwrap top--modal modalWide">
434
+ <div className="modal">
435
+ <Form
436
+ closeModal={modalClose}
437
+ columnId={formId}
438
+ fetchTable={() => {
439
+ // Reload the quote data after form submission
440
+ const fetchData = async () => {
441
+ if (
442
+ routeParams[urlParam] &&
443
+ routeParams[urlParam] > 0
444
+ ) {
445
+ try {
446
+ const res = await CustomFetch(
447
+ `${page.fetchUrl}/${routeParams[urlParam]}`,
448
+ 'GET',
449
+ {}
450
+ );
451
+ setData(res.data);
452
+ } catch (error) {
453
+ console.error(
454
+ 'Error fetching data:',
455
+ error
456
+ );
457
+ }
458
+ }
459
+ };
460
+ fetchData();
461
+ }}
462
+ formSettings={formData}
463
+ formType={formType}
464
+ style={form.style || {}}
465
+ updateForm={setFormData}
466
+ paramValue={
467
+ routeParams[urlParam]
468
+ ? routeParams[urlParam]
469
+ : 0
470
+ }
471
+ />
472
+ </div>
473
+ </div>
474
+ </Popup>
349
475
  </div>
350
476
  );
351
477
  }
@@ -521,6 +521,30 @@
521
521
  margin-top: 30px;
522
522
  }
523
523
 
524
+ .termsSection {
525
+ margin-top: 30px;
526
+ padding: 20px;
527
+ border-top: 1px solid rgba(var(--primary-rgb), 0.1);
528
+ background-color: rgba(var(--primary-rgb), 0.02);
529
+ border-radius: var(--br, 4px);
530
+ }
531
+
532
+ .termsTitle {
533
+ font-size: 1rem;
534
+ font-weight: 600;
535
+ color: var(--primary-color);
536
+ margin: 0 0 15px 0;
537
+ padding-bottom: 8px;
538
+ border-bottom: 1px dashed rgba(var(--primary-rgb), 0.1);
539
+ }
540
+
541
+ .termsContent {
542
+ font-size: 0.9rem;
543
+ line-height: 1.6;
544
+ color: var(--paragraph-color);
545
+ white-space: pre-wrap;
546
+ }
547
+
524
548
  .quoteTableSection {
525
549
  margin-bottom: 25px;
526
550
  }
@@ -752,4 +776,19 @@
752
776
  padding: 8px 10px;
753
777
  font-size: 0.85rem;
754
778
  }
779
+
780
+ .termsSection {
781
+ padding: 15px;
782
+ margin-top: 20px;
783
+ }
784
+
785
+ .termsTitle {
786
+ font-size: 0.9rem;
787
+ margin-bottom: 10px;
788
+ }
789
+
790
+ .termsContent {
791
+ font-size: 0.85rem;
792
+ line-height: 1.5;
793
+ }
755
794
  }