|
51 | 51 | let showConfirmModal = false; |
52 | 52 |
|
53 | 53 | // Function to get the full name of a lead |
| 54 | + /** |
| 55 | + * @param {any} lead |
| 56 | + */ |
54 | 57 | function getFullName(lead) { |
55 | 58 | return `${lead.firstName} ${lead.lastName}`.trim(); |
56 | 59 | } |
57 | 60 |
|
58 | 61 | // Function to format date |
| 62 | + /** |
| 63 | + * @param {string | Date | null | undefined} dateString |
| 64 | + */ |
59 | 65 | function formatDate(dateString) { |
60 | 66 | if (!dateString) return 'N/A'; |
61 | 67 | return new Date(dateString).toLocaleDateString('en-US', { |
|
68 | 74 | } |
69 | 75 |
|
70 | 76 | // Function to format date (short) |
| 77 | + /** |
| 78 | + * @param {string | Date | null | undefined} dateString |
| 79 | + */ |
71 | 80 | function formatDateShort(dateString) { |
72 | 81 | if (!dateString) return 'N/A'; |
73 | 82 | return new Date(dateString).toLocaleDateString('en-US', { |
|
78 | 87 | } |
79 | 88 |
|
80 | 89 | // Function to map lead status to colors |
| 90 | + /** |
| 91 | + * @param {string} status |
| 92 | + */ |
81 | 93 | function getStatusColor(status) { |
82 | 94 | switch (status) { |
83 | 95 | case 'NEW': |
|
98 | 110 | } |
99 | 111 |
|
100 | 112 | // Function to get lead source display name |
| 113 | + /** |
| 114 | + * @param {string | null | undefined} source |
| 115 | + */ |
101 | 116 | function getLeadSourceDisplay(source) { |
102 | 117 | if (!source) return 'Unknown'; |
103 | | - return source.replace('_', ' ').toLowerCase().replace(/\b\w/g, l => l.toUpperCase()); |
| 118 | + return source.replace('_', ' ').toLowerCase().replace(/\b\w/g, (/** @type {string} */ l) => l.toUpperCase()); |
104 | 119 | } |
105 | 120 |
|
106 | 121 | // Function to get initials for avatar |
| 122 | + /** |
| 123 | + * @param {any} lead |
| 124 | + */ |
107 | 125 | function getInitials(lead) { |
108 | 126 | const first = lead.firstName?.[0] || ''; |
109 | 127 | const last = lead.lastName?.[0] || ''; |
|
144 | 162 | function confirmConversion() { |
145 | 163 | showConfirmModal = false; |
146 | 164 | // Submit the form programmatically |
147 | | - document.getElementById('convertForm').requestSubmit(); |
| 165 | + const form = document.getElementById('convertForm'); |
| 166 | + if (form) { |
| 167 | + // Use dispatchEvent as a cross-browser solution |
| 168 | + const event = new Event('submit', { cancelable: true, bubbles: true }); |
| 169 | + form.dispatchEvent(event); |
| 170 | + } |
148 | 171 | } |
149 | 172 | |
150 | 173 | const enhanceConvertForm = () => { |
151 | 174 | isConverting = true; |
152 | | - return async ({ update }) => { |
| 175 | + return async (/** @type {{ update: any }} */ { update }) => { |
153 | 176 | await update({ reset: false }); |
154 | 177 | // Note: If conversion is successful, the server will redirect automatically |
155 | 178 | // This will only execute if there's an error |
|
159 | 182 |
|
160 | 183 | const enhanceCommentForm = () => { |
161 | 184 | isSubmittingComment = true; |
162 | | - return async ({ update }) => { |
| 185 | + return async (/** @type {{ update: any }} */ { update }) => { |
163 | 186 | await update({ reset: false }); |
164 | 187 | // Reset the loading state after update |
165 | 188 | isSubmittingComment = false; |
|
455 | 478 | </div> |
456 | 479 | {/if} |
457 | 480 |
|
458 | | - <!-- Annual Revenue --> |
459 | | - {#if lead.annualRevenue} |
460 | | - <div class="space-y-2"> |
461 | | - <div class="flex items-center gap-2"> |
462 | | - <DollarSign class="w-4 h-4 text-gray-400 dark:text-gray-500" /> |
463 | | - <span class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide">Annual Revenue</span> |
464 | | - </div> |
465 | | - <p class="text-sm text-gray-900 dark:text-gray-100 font-medium bg-gray-50 dark:bg-gray-700 px-3 py-2 rounded-lg"> |
466 | | - ${lead.annualRevenue.toLocaleString()} |
467 | | - </p> |
468 | | - </div> |
469 | | - {/if} |
470 | | -
|
471 | 481 | <!-- Lead Owner --> |
472 | 482 | <div class="space-y-2"> |
473 | 483 | <div class="flex items-center gap-2"> |
|
491 | 501 | </div> |
492 | 502 | </div> |
493 | 503 |
|
494 | | - <!-- Address --> |
495 | | - {#if lead.address} |
496 | | - <div class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700"> |
497 | | - <div class="flex items-center gap-2 mb-3"> |
498 | | - <Location class="w-5 h-5 text-gray-400 dark:text-gray-500" /> |
499 | | - <span class="text-sm font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide">Address</span> |
500 | | - </div> |
501 | | - <div class="bg-gray-50 dark:bg-gray-700 p-4 rounded-xl"> |
502 | | - <p class="text-sm text-gray-900 dark:text-gray-100 whitespace-pre-line leading-relaxed">{lead.address}</p> |
503 | | - </div> |
504 | | - </div> |
505 | | - {/if} |
506 | | -
|
507 | 504 | <!-- Description --> |
508 | 505 | {#if lead.description} |
509 | 506 | <div class="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700"> |
|
684 | 681 | <div class="flex justify-between items-center"> |
685 | 682 | <span class="text-sm text-gray-600 dark:text-gray-300">Days Since Created</span> |
686 | 683 | <span class="text-sm font-semibold text-gray-900 dark:text-gray-100"> |
687 | | - {Math.floor((new Date() - new Date(lead.createdAt)) / (1000 * 60 * 60 * 24))} |
| 684 | + {Math.floor((new Date().getTime() - new Date(lead.createdAt).getTime()) / (1000 * 60 * 60 * 24))} |
688 | 685 | </span> |
689 | 686 | </div> |
690 | 687 | {#if lead.convertedAt} |
691 | 688 | <div class="flex justify-between items-center"> |
692 | 689 | <span class="text-sm text-gray-600 dark:text-gray-300">Days to Convert</span> |
693 | 690 | <span class="text-sm font-semibold text-green-600 dark:text-green-400"> |
694 | | - {Math.floor((new Date(lead.convertedAt) - new Date(lead.createdAt)) / (1000 * 60 * 60 * 24))} |
| 691 | + {Math.floor((new Date(lead.convertedAt).getTime() - new Date(lead.createdAt).getTime()) / (1000 * 60 * 60 * 24))} |
695 | 692 | </span> |
696 | 693 | </div> |
697 | 694 | {/if} |
|
0 commit comments