@visns-studio/visns-components 5.10.11 → 5.11.2

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 (55) hide show
  1. package/README.md +85 -0
  2. package/package.json +7 -7
  3. package/src/components/cms/DataGrid.jsx +8 -8
  4. package/src/components/cms/DropZone.jsx +1 -1
  5. package/src/components/cms/Form.jsx +1 -1
  6. package/src/components/cms/Gallery.jsx +1 -1
  7. package/src/components/cms/sorting/Item.jsx +1 -1
  8. package/src/components/crm/Autocomplete.jsx +3 -3
  9. package/src/components/crm/Breadcrumb.jsx +4 -4
  10. package/src/components/crm/BusinessCardOcr.jsx +681 -95
  11. package/src/components/crm/DataGrid.jsx +34 -32
  12. package/src/components/crm/Field.jsx +12 -12
  13. package/src/components/crm/Form.jsx +2 -2
  14. package/src/components/crm/Navigation.jsx +11 -11
  15. package/src/components/crm/Notification.jsx +2 -2
  16. package/src/components/crm/QuickAction.jsx +3 -3
  17. package/src/components/crm/SectionHeader.jsx +1 -1
  18. package/src/components/crm/SwitchAccount.jsx +4 -4
  19. package/src/components/crm/auth/ClientLogin.jsx +2 -2
  20. package/src/components/crm/auth/ClientOTPVerify.jsx +2 -2
  21. package/src/components/crm/auth/Login.jsx +3 -3
  22. package/src/components/crm/auth/Reset.jsx +2 -2
  23. package/src/components/crm/auth/TwoFactorAuth.jsx +2 -2
  24. package/src/components/crm/columns/ColumnRenderers.jsx +320 -259
  25. package/src/components/crm/controls/DataGridSearch.jsx +5 -5
  26. package/src/components/crm/generic/AlternativeActionModal.jsx +100 -0
  27. package/src/components/crm/generic/ContactSelectorModal.jsx +423 -0
  28. package/src/components/crm/generic/DatePickerDialog.jsx +302 -0
  29. package/src/components/crm/generic/DateRangeSelectorModal.jsx +181 -0
  30. package/src/components/crm/generic/GenericClientPortal.jsx +1 -1
  31. package/src/components/crm/generic/GenericDashboard.jsx +4 -4
  32. package/src/components/crm/generic/GenericDetail.jsx +6 -6
  33. package/src/components/crm/generic/GenericDynamic.jsx +3 -3
  34. package/src/components/crm/generic/GenericEditableTable.jsx +4 -4
  35. package/src/components/crm/generic/GenericFormBuilder.jsx +6 -6
  36. package/src/components/crm/generic/GenericGrid.jsx +2888 -0
  37. package/src/components/crm/generic/GenericIndex.jsx +5 -1255
  38. package/src/components/crm/generic/GenericReport.jsx +966 -646
  39. package/src/components/crm/generic/GenericReportForm.jsx +194 -0
  40. package/src/components/crm/generic/NotificationList.jsx +1 -1
  41. package/src/components/crm/generic/ReasonCollectorModal.jsx +194 -0
  42. package/src/components/crm/generic/SortableQuoteItems.jsx +3 -3
  43. package/src/components/crm/generic/shared/formatters.js +231 -0
  44. package/src/components/crm/generic/shared/gridUtils.js +194 -0
  45. package/src/components/crm/generic/styles/AlternativeActionModal.css +127 -0
  46. package/src/components/crm/generic/styles/ContactSelectorModal.css +367 -0
  47. package/src/components/crm/generic/styles/DatePickerDialog.css +84 -0
  48. package/src/components/crm/generic/styles/DateRangeSelectorModal.css +115 -0
  49. package/src/components/crm/generic/styles/GenericIndex.module.scss +382 -0
  50. package/src/components/crm/generic/styles/GenericReport.module.scss +96 -0
  51. package/src/components/crm/generic/styles/ReasonCollectorModal.css +217 -0
  52. package/src/components/crm/modals/GalleryModal.jsx +2 -2
  53. package/src/components/crm/sorting/Item.jsx +3 -3
  54. package/src/components/crm/styles/BusinessCardOcr.module.scss +197 -4
  55. package/src/index.js +4 -0
@@ -0,0 +1,302 @@
1
+ import React from 'react';
2
+ import Swal from 'sweetalert2';
3
+ import './styles/SweetAlert.module.css';
4
+ import './styles/DatePickerDialog.css';
5
+ import moment from 'moment';
6
+
7
+ /**
8
+ * A utility function that shows a date picker confirmation dialog using SweetAlert2
9
+ *
10
+ * @param {Object} options - Configuration options
11
+ * @param {string} options.title - The title of the dialog (default: 'Select Date')
12
+ * @param {string} options.message - The message to display in the dialog
13
+ * @param {string} options.confirmLabel - Label for the confirm button (default: 'Confirm')
14
+ * @param {string} options.cancelLabel - Label for the cancel button (default: 'Cancel')
15
+ * @param {Function} options.onConfirm - Function to call when confirmed with selected date
16
+ * @param {Function} options.onCancel - Function to call when cancelled
17
+ * @param {string} options.defaultDate - Default date value (ISO string or 'now')
18
+ * @param {string} options.dateFormat - Date format for display (default: 'YYYY-MM-DD')
19
+ * @param {Object} options.data - Optional data object to pass context
20
+ * @param {string} options.timezone - Timezone to use ('auto', 'Australia/Perth', or specific timezone)
21
+ * @param {boolean} options.forcePerth - Force Australia/Perth timezone (default: false)
22
+ * @param {boolean} options.dateOnly - Return date string only for DATE fields (default: auto-detect)
23
+ * @returns {Promise} - A promise that resolves when the dialog is closed
24
+ */
25
+ export const showDatePickerDialog = ({
26
+ title = 'Select Date',
27
+ message = 'Please select a date:',
28
+ confirmLabel = 'Confirm',
29
+ cancelLabel = 'Cancel',
30
+ onConfirm = () => {},
31
+ onCancel = () => {},
32
+ defaultDate = null,
33
+ dateFormat = 'YYYY-MM-DD',
34
+ data = null,
35
+ timezone = 'auto',
36
+ forcePerth = false,
37
+ dateOnly = 'auto',
38
+ }) => {
39
+ // Timezone detection and handling
40
+ const getTargetTimezone = () => {
41
+ if (forcePerth) {
42
+ return 'Australia/Perth';
43
+ }
44
+
45
+ if (timezone === 'auto') {
46
+ // Try to detect browser timezone
47
+ try {
48
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
49
+ } catch (e) {
50
+ console.warn('Could not detect timezone, falling back to Australia/Perth');
51
+ return 'Australia/Perth';
52
+ }
53
+ }
54
+
55
+ return timezone;
56
+ };
57
+
58
+ const targetTimezone = getTargetTimezone();
59
+
60
+ // Auto-detect if this should be a date-only field based on field name or explicit config
61
+ const shouldUseDateOnly = () => {
62
+ if (dateOnly === true || dateOnly === false) {
63
+ return dateOnly; // Explicit configuration
64
+ }
65
+
66
+ // Auto-detection based on field name patterns
67
+ const fieldName = data?.name || '';
68
+ const dateOnlyPatterns = [
69
+ /^date_/i, // date_sent, date_delivered, etc.
70
+ /^quarter_/i, // quarter_1, quarter_2, etc.
71
+ /_date$/i, // send_date, delivery_date, etc.
72
+ /^(start|end)_/i, // start_date, end_date, etc.
73
+ /^(birth|death)_/i, // birth_date, death_date, etc.
74
+ /^due_/i, // due_date, etc.
75
+ /^expiry/i, // expiry_date, etc.
76
+ ];
77
+
78
+ const isDateField = dateOnlyPatterns.some(pattern => pattern.test(fieldName));
79
+
80
+ console.log(`Auto-detecting field type for "${fieldName}": ${isDateField ? 'DATE' : 'DATETIME'} field`);
81
+
82
+ return isDateField;
83
+ };
84
+
85
+ const useDateOnly = shouldUseDateOnly();
86
+
87
+ // Get timezone offset in hours for a given timezone
88
+ const getTimezoneOffsetHours = (tz) => {
89
+ try {
90
+ // For Australia/Perth, it's UTC+8
91
+ if (tz === 'Australia/Perth') {
92
+ return 8; // +8 hours
93
+ }
94
+
95
+ // For other timezones, calculate the offset
96
+ const now = new Date();
97
+ const utc = new Date(now.getTime() + (now.getTimezoneOffset() * 60000));
98
+ const targetTime = new Date(utc.toLocaleString("en-US", {timeZone: tz}));
99
+ return (targetTime.getTime() - utc.getTime()) / (1000 * 60 * 60); // Convert to hours
100
+ } catch (e) {
101
+ console.warn('Could not calculate timezone offset, using +8 for Perth:', e);
102
+ return 8; // Default to Perth time
103
+ }
104
+ };
105
+
106
+ // Convert UTC date to target timezone for display
107
+ const convertToDisplayDate = (utcDate) => {
108
+ if (!utcDate) return moment().format(dateFormat);
109
+
110
+ try {
111
+ // If it's a UTC ISO string, convert to target timezone
112
+ if (typeof utcDate === 'string' && (utcDate.includes('T') || utcDate.includes('Z'))) {
113
+ const offsetHours = getTimezoneOffsetHours(targetTimezone);
114
+ // Add the offset to convert FROM UTC TO local timezone
115
+ return moment.utc(utcDate).add(offsetHours, 'hours').format(dateFormat);
116
+ }
117
+ // If it's already a date string (YYYY-MM-DD), treat it as local date
118
+ return moment(utcDate).format(dateFormat);
119
+ } catch (e) {
120
+ console.warn('Error converting date, using current date:', e);
121
+ return moment().format(dateFormat);
122
+ }
123
+ };
124
+
125
+ // Convert selected date for API calls
126
+ const convertForAPI = (localDateString) => {
127
+ try {
128
+ // If useDateOnly is true, just return the date string as-is for DATE fields
129
+ if (useDateOnly) {
130
+ console.log(`Date-only field: returning ${localDateString} as-is for DATE field`);
131
+ return localDateString;
132
+ }
133
+
134
+ // For DATETIME fields, convert to UTC
135
+ const offsetHours = getTimezoneOffsetHours(targetTimezone);
136
+
137
+ // Create a UTC moment object from the date string, then treat it as if it were in the target timezone
138
+ // This means: "2025-06-18" becomes "2025-06-18T00:00:00 in target timezone"
139
+ const naiveMoment = moment.utc(localDateString, dateFormat);
140
+
141
+ // Now subtract the offset to get the actual UTC time
142
+ // If it's Perth (+8), we subtract 8 hours to get UTC
143
+ const utcMoment = naiveMoment.clone().subtract(offsetHours, 'hours');
144
+
145
+ console.log(`Converting: ${localDateString} midnight in ${targetTimezone}`);
146
+ console.log(`Naive UTC: ${naiveMoment.toISOString()}`);
147
+ console.log(`Offset: -${offsetHours} hours`);
148
+ console.log(`Final UTC: ${utcMoment.toISOString()}`);
149
+
150
+ return utcMoment.toISOString();
151
+ } catch (e) {
152
+ console.warn('Error converting date, using as-is:', e);
153
+ // Fallback: return the date string as-is
154
+ return localDateString;
155
+ }
156
+ };
157
+
158
+ // Get default date value with timezone handling
159
+ let initialDate = '';
160
+ if (defaultDate === 'now') {
161
+ initialDate = convertToDisplayDate(moment().toISOString());
162
+ } else if (defaultDate) {
163
+ initialDate = convertToDisplayDate(defaultDate);
164
+ } else {
165
+ initialDate = convertToDisplayDate(moment().toISOString());
166
+ }
167
+
168
+ // Enhanced message with item details if available
169
+ let enhancedMessage = message;
170
+ if (data) {
171
+ const identifiers = ['name', 'label', 'title', 'id'];
172
+ for (const id of identifiers) {
173
+ if (data[id] && typeof data[id] === 'string' && data[id].trim() !== '') {
174
+ if (!message.includes(data[id])) {
175
+ enhancedMessage = `${message} (${data[id]})`;
176
+ }
177
+ break;
178
+ }
179
+ }
180
+ }
181
+
182
+ // Create HTML content with compact date input
183
+ const htmlContent = `
184
+ <div style="text-align: left; margin: 8px 0; max-width: 100%; overflow: hidden;">
185
+ <p style="margin-bottom: 8px; color: #374151; word-wrap: break-word; font-size: 14px;">${enhancedMessage}</p>
186
+ <div style="margin: 8px 0; width: 100%;">
187
+ <label for="swal-date-input" style="display: block; margin-bottom: 4px; font-weight: 500; color: #374151; font-size: 13px;">
188
+ Date <span style="font-size: 11px; color: #6b7280; font-weight: normal;">(${targetTimezone})</span>:
189
+ </label>
190
+ <input
191
+ id="swal-date-input"
192
+ type="date"
193
+ value="${initialDate}"
194
+ class="swal2-input"
195
+ style="
196
+ width: 100% !important;
197
+ max-width: 100% !important;
198
+ box-sizing: border-box !important;
199
+ padding: 8px 10px !important;
200
+ border: 1px solid #d1d5db !important;
201
+ border-radius: 4px !important;
202
+ font-size: 13px !important;
203
+ font-family: inherit !important;
204
+ background-color: #ffffff !important;
205
+ outline: none !important;
206
+ transition: border-color 0.2s ease !important;
207
+ margin: 0 !important;
208
+ display: block !important;
209
+ height: 34px !important;
210
+ "
211
+ onfocus="this.style.borderColor='#4f46e5'"
212
+ onblur="this.style.borderColor='#d1d5db'">
213
+ </div>
214
+ </div>
215
+ `;
216
+
217
+ // Configure SweetAlert2 options
218
+ const swalOptions = {
219
+ title: title,
220
+ html: htmlContent,
221
+ icon: 'question',
222
+ showCancelButton: true,
223
+ confirmButtonText: confirmLabel,
224
+ cancelButtonText: cancelLabel,
225
+ confirmButtonColor: 'var(--primary-color, #4f46e5)',
226
+ cancelButtonColor: '#6b7280',
227
+ allowOutsideClick: true,
228
+ allowEscapeKey: true,
229
+ reverseButtons: true,
230
+ focusCancel: false,
231
+ buttonsStyling: true,
232
+ width: 'auto',
233
+ padding: '0.75rem',
234
+ customClass: {
235
+ popup: 'date-picker-dialog',
236
+ htmlContainer: 'date-picker-content'
237
+ },
238
+ preConfirm: () => {
239
+ const dateInput = document.getElementById('swal-date-input');
240
+ const selectedDate = dateInput.value;
241
+
242
+ if (!selectedDate) {
243
+ Swal.showValidationMessage('Please select a date');
244
+ return false;
245
+ }
246
+
247
+ // Validate the date
248
+ if (!moment(selectedDate).isValid()) {
249
+ Swal.showValidationMessage('Please enter a valid date');
250
+ return false;
251
+ }
252
+
253
+ return selectedDate;
254
+ },
255
+ didOpen: () => {
256
+ // Focus on the date input when dialog opens
257
+ const dateInput = document.getElementById('swal-date-input');
258
+ if (dateInput) {
259
+ // Additional CSS to ensure the input stays within bounds
260
+ dateInput.style.setProperty('width', '100%', 'important');
261
+ dateInput.style.setProperty('max-width', '100%', 'important');
262
+ dateInput.style.setProperty('box-sizing', 'border-box', 'important');
263
+ dateInput.style.setProperty('overflow', 'hidden', 'important');
264
+
265
+ // Focus the input
266
+ dateInput.focus();
267
+ }
268
+
269
+ // Apply additional container styling
270
+ const popup = document.querySelector('.date-picker-dialog');
271
+ if (popup) {
272
+ popup.style.setProperty('max-width', '90vw', 'important');
273
+ popup.style.setProperty('width', 'auto', 'important');
274
+ popup.style.setProperty('min-width', '320px', 'important');
275
+ }
276
+
277
+ const htmlContainer = document.querySelector('.date-picker-content');
278
+ if (htmlContainer) {
279
+ htmlContainer.style.setProperty('overflow', 'hidden', 'important');
280
+ htmlContainer.style.setProperty('word-wrap', 'break-word', 'important');
281
+ }
282
+ }
283
+ };
284
+
285
+ // Show SweetAlert2 dialog
286
+ return Swal.fire(swalOptions).then((result) => {
287
+ if (result.isConfirmed && result.value) {
288
+ // Convert the selected date for API calls (either date string or UTC datetime)
289
+ const selectedDateForAPI = convertForAPI(result.value);
290
+ const selectedDateLocal = result.value;
291
+
292
+ // Log for debugging
293
+ console.log(`Date selected: ${selectedDateLocal} (${targetTimezone}) -> ${selectedDateForAPI} (${useDateOnly ? 'DATE' : 'UTC'})`);
294
+
295
+ onConfirm(selectedDateForAPI, selectedDateLocal, targetTimezone);
296
+ } else if (result.dismiss === Swal.DismissReason.cancel) {
297
+ onCancel();
298
+ }
299
+ });
300
+ };
301
+
302
+ export default showDatePickerDialog;
@@ -0,0 +1,181 @@
1
+ import Swal from 'sweetalert2';
2
+ import moment from 'moment';
3
+ import './styles/SweetAlert.module.css';
4
+ import './styles/DateRangeSelectorModal.css';
5
+
6
+ /**
7
+ * Show a date range selector modal for selecting start and end dates
8
+ * @param {Object} options - Configuration options
9
+ * @param {string} options.title - Modal title
10
+ * @param {string} options.message - Modal message
11
+ * @param {string} options.confirmLabel - Confirm button label
12
+ * @param {string} options.cancelLabel - Cancel button label
13
+ * @param {string|null} options.defaultStartDate - Default start date value
14
+ * @param {string|null} options.defaultEndDate - Default end date value
15
+ * @param {Object} options.data - Additional data to pass to callbacks
16
+ * @param {string} options.timezone - Timezone for date handling
17
+ * @param {boolean} options.forcePerth - Force Australia/Perth timezone
18
+ * @param {boolean} options.dateOnly - Return date only (no time conversion)
19
+ * @param {Function} options.onConfirm - Callback when confirmed
20
+ * @param {Function} options.onCancel - Callback when cancelled
21
+ */
22
+ export const showDateRangeSelectorModal = async ({
23
+ title = 'Select Date Range',
24
+ message = 'Please select start and end dates:',
25
+ confirmLabel = 'Next: Select Contacts',
26
+ cancelLabel = 'Cancel',
27
+ defaultStartDate = null,
28
+ defaultEndDate = null,
29
+ data = {},
30
+ timezone = 'auto',
31
+ forcePerth = false,
32
+ dateOnly = false,
33
+ onConfirm,
34
+ onCancel
35
+ }) => {
36
+ // Determine timezone
37
+ let userTimezone = 'UTC';
38
+ if (forcePerth) {
39
+ userTimezone = 'Australia/Perth';
40
+ } else if (timezone === 'auto') {
41
+ userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
42
+ } else if (timezone && timezone !== 'auto') {
43
+ userTimezone = timezone;
44
+ }
45
+
46
+ console.log('Date Range Selector - Timezone Configuration:', {
47
+ inputTimezone: timezone,
48
+ forcePerth,
49
+ resolvedTimezone: userTimezone,
50
+ dateOnly
51
+ });
52
+
53
+ // Convert UTC dates to local timezone for display
54
+ const convertUTCToLocal = (utcDateString) => {
55
+ if (!utcDateString || utcDateString === 'now') return '';
56
+
57
+ try {
58
+ const utcMoment = moment.utc(utcDateString);
59
+ if (!utcMoment.isValid()) return '';
60
+
61
+ if (dateOnly) {
62
+ // For DATE fields, just return the date part
63
+ return utcMoment.format('YYYY-MM-DD');
64
+ } else {
65
+ // For DATETIME fields, convert to local timezone
66
+ const localMoment = utcMoment.clone().tz(userTimezone);
67
+ return localMoment.format('YYYY-MM-DD');
68
+ }
69
+ } catch (error) {
70
+ console.error('Error converting UTC to local:', error);
71
+ return '';
72
+ }
73
+ };
74
+
75
+ // Convert local date to UTC for API
76
+ const convertLocalToUTC = (localDateString) => {
77
+ if (!localDateString) return null;
78
+
79
+ try {
80
+ if (dateOnly) {
81
+ // For DATE fields, return just the date string
82
+ return localDateString;
83
+ } else {
84
+ // For DATETIME fields, convert to UTC
85
+ const localMoment = moment.tz(localDateString, userTimezone);
86
+ return localMoment.utc().toISOString();
87
+ }
88
+ } catch (error) {
89
+ console.error('Error converting local to UTC:', error);
90
+ return localDateString;
91
+ }
92
+ };
93
+
94
+ // Prepare default values
95
+ const displayStartDate = convertUTCToLocal(defaultStartDate);
96
+ const displayEndDate = convertUTCToLocal(defaultEndDate);
97
+
98
+ const timezoneLabel = userTimezone === 'Australia/Perth' ? ' (Perth Time)' : userTimezone !== 'UTC' ? ` (${userTimezone})` : '';
99
+
100
+ const result = await Swal.fire({
101
+ title: title,
102
+ html: `
103
+ <div class="date-range-selector-modal">
104
+ <p class="date-range-message">${message}</p>
105
+ <div class="date-range-inputs">
106
+ <div class="date-input-group">
107
+ <label for="start-date-input" class="date-input-label">
108
+ Start Date${timezoneLabel}:
109
+ </label>
110
+ <input
111
+ type="date"
112
+ id="start-date-input"
113
+ class="date-range-input"
114
+ value="${displayStartDate}"
115
+ />
116
+ </div>
117
+ <div class="date-input-group">
118
+ <label for="end-date-input" class="date-input-label">
119
+ End Date${timezoneLabel}:
120
+ </label>
121
+ <input
122
+ type="date"
123
+ id="end-date-input"
124
+ class="date-range-input"
125
+ value="${displayEndDate}"
126
+ />
127
+ </div>
128
+ </div>
129
+ </div>
130
+ `,
131
+ showCancelButton: true,
132
+ confirmButtonText: confirmLabel,
133
+ cancelButtonText: cancelLabel,
134
+ customClass: {
135
+ container: 'date-range-swal-container',
136
+ popup: 'date-range-swal-popup',
137
+ content: 'date-range-swal-content',
138
+ confirmButton: 'date-range-swal-confirm',
139
+ cancelButton: 'date-range-swal-cancel'
140
+ },
141
+ preConfirm: () => {
142
+ const startDateInput = document.getElementById('start-date-input');
143
+ const endDateInput = document.getElementById('end-date-input');
144
+ const startDate = startDateInput.value;
145
+ const endDate = endDateInput.value;
146
+
147
+ if (!startDate) {
148
+ Swal.showValidationMessage('Please select a start date');
149
+ return false;
150
+ }
151
+
152
+ if (!endDate) {
153
+ Swal.showValidationMessage('Please select an end date');
154
+ return false;
155
+ }
156
+
157
+ if (moment(startDate).isAfter(moment(endDate))) {
158
+ Swal.showValidationMessage('Start date must be before end date');
159
+ return false;
160
+ }
161
+
162
+ console.log('Date Range Selected:', {
163
+ startDate: startDate,
164
+ endDate: endDate,
165
+ timezone: userTimezone,
166
+ dateOnly: dateOnly
167
+ });
168
+
169
+ return {
170
+ startDate: convertLocalToUTC(startDate),
171
+ endDate: convertLocalToUTC(endDate)
172
+ };
173
+ }
174
+ });
175
+
176
+ if (result.isConfirmed && onConfirm) {
177
+ await onConfirm(result.value.startDate, result.value.endDate);
178
+ } else if (result.isDismissed && onCancel) {
179
+ onCancel();
180
+ }
181
+ };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Routes, Route, useNavigate } from 'react-router-dom';
3
3
  import { toast } from 'react-toastify';
4
- import { SignOut } from 'akar-icons';
4
+ import { LogOut as SignOut } from 'lucide-react';
5
5
 
6
6
  import CustomFetch from '../Fetch';
7
7
 
@@ -8,7 +8,7 @@ import Popup from 'reactjs-popup';
8
8
  import dayjs from 'dayjs';
9
9
  import parse from 'html-react-parser';
10
10
  import { createSwapy } from 'swapy';
11
- import { CircleX, Minus, Plus, Star, TrashCan } from 'akar-icons';
11
+ import { X, Minus, Plus, Star, Trash2 } from 'lucide-react';
12
12
  import { confirmDialog } from '../../utils/ConfirmDialog';
13
13
 
14
14
  import CustomFetch from '../../crm/Fetch';
@@ -1320,7 +1320,7 @@ function GenericDashboard({ setting, userProfile, dynamicDashboard = false }) {
1320
1320
  <button
1321
1321
  onClick={() => confirmDelete(widget.id)}
1322
1322
  >
1323
- <TrashCan strokeWidth={2} size={12} />
1323
+ <Trash2 strokeWidth={2} size={12} />
1324
1324
  </button>
1325
1325
  </div>
1326
1326
  </div>
@@ -1370,7 +1370,7 @@ function GenericDashboard({ setting, userProfile, dynamicDashboard = false }) {
1370
1370
  className="modal__close"
1371
1371
  onClick={closeModal}
1372
1372
  >
1373
- <CircleX strokeWidth={1} size={24} />
1373
+ <X strokeWidth={1} size={24} />
1374
1374
  </button>
1375
1375
  </div>
1376
1376
  <div className="modal__content">
@@ -1397,7 +1397,7 @@ function GenericDashboard({ setting, userProfile, dynamicDashboard = false }) {
1397
1397
  className="modal__close"
1398
1398
  onClick={() => setShowAddWidgetModal(false)}
1399
1399
  >
1400
- <CircleX strokeWidth={1} size={24} />
1400
+ <X strokeWidth={1} size={24} />
1401
1401
  </button>
1402
1402
  </div>
1403
1403
  <div className="modal__content">
@@ -49,14 +49,14 @@ import { toast } from 'react-toastify';
49
49
  import imageCompression from 'browser-image-compression';
50
50
  import fetchUtil from '../../../utils/fetchUtil';
51
51
  import {
52
- CircleCheck,
52
+ CheckCircle as CircleCheck,
53
53
  Copy,
54
- EyeOpen,
55
- EyeSlashed,
54
+ Eye as EyeOpen,
55
+ EyeOff as EyeSlashed,
56
56
  File,
57
- Pencil,
58
- TrashCan,
59
- } from 'akar-icons';
57
+ Edit as Pencil,
58
+ Trash2 as TrashCan,
59
+ } from 'lucide-react';
60
60
  import { confirmDialog } from '../../utils/ConfirmDialog';
61
61
 
62
62
  import 'react-big-calendar/lib/css/react-big-calendar.css';
@@ -3,7 +3,7 @@ import moment from 'moment';
3
3
  import { toast } from 'react-toastify';
4
4
  import { saveAs } from 'file-saver';
5
5
  import parse from 'html-react-parser';
6
- import { Backspace, CloudDownload } from 'akar-icons';
6
+ import { Delete, Download as DownloadIcon } from 'lucide-react';
7
7
  import { confirmDialog } from '../../utils/ConfirmDialog';
8
8
 
9
9
  import CustomFetch from '../Fetch';
@@ -1056,7 +1056,7 @@ const GenericDynamic = ({
1056
1056
  )
1057
1057
  }
1058
1058
  >
1059
- <CloudDownload
1059
+ <DownloadIcon
1060
1060
  strokeWidth={
1061
1061
  2
1062
1062
  }
@@ -1077,7 +1077,7 @@ const GenericDynamic = ({
1077
1077
  )
1078
1078
  }
1079
1079
  >
1080
- <Backspace
1080
+ <Delete
1081
1081
  strokeWidth={
1082
1082
  2
1083
1083
  }
@@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
2
2
  import ReactDOM from 'react-dom';
3
3
  import debounce from 'lodash.debounce';
4
4
  import { toast } from 'react-toastify';
5
- import { TrashCan, ArrowUp, ArrowDown, Copy, Water } from 'akar-icons';
5
+ import { Trash2, ArrowUp, ArrowDown, Copy, Droplets } from 'lucide-react';
6
6
  import { CompactPicker } from 'react-color';
7
7
  import { confirmDialog } from '../../utils/ConfirmDialog';
8
8
 
@@ -65,7 +65,7 @@ const ColourPicker = ({ value, columnId, keyCounter, onChange }) => {
65
65
  setColorPickerShow(!colorPickerShow);
66
66
  }}
67
67
  >
68
- <Water size={20} style={{ color: 'black' }} />
68
+ <Droplets size={20} style={{ color: 'black' }} />
69
69
  </button>
70
70
 
71
71
  {colorPickerShow &&
@@ -1059,7 +1059,7 @@ const GenericEditableTable = ({
1059
1059
  }}
1060
1060
  />
1061
1061
  )}
1062
- <TrashCan
1062
+ <Trash2
1063
1063
  size={16}
1064
1064
  onClick={() =>
1065
1065
  handleDeleteRow(
@@ -1199,7 +1199,7 @@ const GenericEditableTable = ({
1199
1199
  style={{ cursor: 'pointer' }}
1200
1200
  />
1201
1201
  )}
1202
- <TrashCan
1202
+ <Trash2
1203
1203
  size={16}
1204
1204
  onClick={() =>
1205
1205
  handleDeleteRow(entry)
@@ -28,12 +28,12 @@ import { v4 as uuidv4 } from 'uuid';
28
28
  import { Editor } from '@tinymce/tinymce-react';
29
29
  import { Tooltip } from 'react-tooltip';
30
30
  import {
31
- CirclePlus,
32
- CircleX,
33
- TrashCan,
34
- Pencil,
35
- ChevronVertical,
36
- } from 'akar-icons';
31
+ PlusCircle as CirclePlus,
32
+ X as CircleX,
33
+ Trash2 as TrashCan,
34
+ Edit as Pencil,
35
+ GripVertical as ChevronVertical,
36
+ } from 'lucide-react';
37
37
  import { confirmDialog } from '../../utils/ConfirmDialog';
38
38
 
39
39
  import 'react-toggle/style.css';