PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.0
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.0
2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.2 All 57 releases
← All changes | templates/clients-page.php +72 -123 2.3.6 → 2.4.0 View file →
@@ -1,5 +1,8 @@
1 1 <?php
2 +if ( ! defined( 'ABSPATH' ) ) {
3 + exit;
4 +}
2 5 // Extract data passed from controller
3 6 $clients = $clients ?? [];
4 7 $stats = $stats ?? [];
5 8 $current_page = $current_page ?? 1;
@@ -9,14 +12,23 @@
9 12
10 13 // $clients variable contains Client objects
11 14
12 15 ?>
16 +<style>
17 +<?php if (!easy_invoice_user_can('ei_manage_clients')) : ?>.client-list-table a[href*="client-edit"], .client-list-table .delete-client { display: none; }<?php endif; ?>
18 +/* Eight columns do not fit a laptop; the username and role are the least useful. */
19 +.client-list-table th, .client-list-table td { padding-left: 0.875rem; padding-right: 0.875rem; }
20 +@media (max-width: 1700px) {
21 + .client-list-table th:nth-child(6), .client-list-table td:nth-child(6),
22 + .client-list-table th:nth-child(7), .client-list-table td:nth-child(7) { display: none; }
23 +}
24 +</style>
13 25 <div class="p-8">
14 26 <div class="ei-app-page-header bg-white border-b border-gray-200 px-6" style="margin-left: -2rem; margin-top: -2rem; padding-left:2rem; padding-right:2rem; margin-right: -2rem;">
15 27 <div class="flex items-center justify-between">
16 28 <div>
17 - <h1 class="text-2xl font-bold text-gray-900"><?php _e('Clients', 'easy-invoice'); ?></h1>
18 - <p class="mt-1 text-sm text-gray-500"><?php _e('Manage all client records', 'easy-invoice'); ?></p>
29 + <h1 class="text-2xl font-bold text-gray-900"><?php esc_html_e('Clients', 'easy-invoice'); ?></h1>
30 + <p class="mt-1 text-sm text-gray-500"><?php esc_html_e('Manage all client records', 'easy-invoice'); ?></p>
19 31 </div>
20 32 <div class="flex items-center space-x-3">
21 33 <?php
22 34 // "Export All" is part of the bulk_operations addon
@@ -26,14 +38,14 @@
26 38 ?>
27 39 <?php if ($ei_bulk_ops_loaded): ?>
28 40 <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline;">
29 41 <input type="hidden" name="action" value="easy_invoice_export_all_clients" />
30 - <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('easy_invoice_export_all_clients'); ?>" />
42 + <input type="hidden" name="_wpnonce" value="<?php echo esc_attr(wp_create_nonce('easy_invoice_export_all_clients')); ?>" />
31 43 <button type="submit" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
32 44 <svg class="w-4 h-4 mr-2 text-indigo-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
33 45 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
34 46 </svg>
35 - <?php _e('Export All', 'easy-invoice'); ?>
47 + <?php esc_html_e('Export All', 'easy-invoice'); ?>
36 48 </button>
37 49 </form>
38 50 <?php elseif (!easy_invoice_has_pro()): ?>
39 51 <button type="button" id="export-all-clients-btn" class="premium-export-btn inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors duration-200 relative">
@@ -39,9 +51,9 @@
39 51 <button type="button" id="export-all-clients-btn" class="premium-export-btn inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors duration-200 relative">
40 52 <svg class="w-4 h-4 mr-2 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
41 53 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
42 54 </svg>
43 - <?php _e('Export All', 'easy-invoice'); ?>
55 + <?php esc_html_e('Export All', 'easy-invoice'); ?>
44 56 <svg class="ml-2 w-5 h-5 text-purple-600 crown-icon" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
45 57 <path d="M12 8L15 13.2L18 10.5L17.3 14H6.7L6 10.5L9 13.2L12 8M12 4L8.5 10L3 5L5 16H19L21 5L15.5 10L12 4Z"/>
46 58 </svg>
47 59 </button>
@@ -57,14 +69,16 @@
57 69 });
58 70 });
59 71 </script>
60 72 <?php endif; ?>
61 - <button id="add-new-client-btn" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
73 + <?php if (easy_invoice_user_can('ei_manage_clients')) : ?>
74 +<button id="add-new-client-btn" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
62 75 <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
63 76 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
64 77 </svg>
65 - <?php _e('Add New Client', 'easy-invoice'); ?>
78 + <?php esc_html_e('Add New Client', 'easy-invoice'); ?>
66 79 </button>
80 +<?php endif; ?>
67 81 </div>
68 82 </div>
69 83 </div>
70 84
@@ -79,10 +93,10 @@
79 93 <path d="M16.32 11.6722C18.36 11.6722 20 10.0322 20 7.99219C20 5.95219 18.36 4.31219 16.32 4.31219" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
80 94 </svg>
81 95 </div>
82 96 <div>
83 - <h3 class="text-sm font-medium text-gray-500">Total Clients</h3>
84 - <p class="mt-1 text-2xl font-bold text-gray-900"><?php echo isset($stats['total_clients']) ? $stats['total_clients'] : count($clients); ?></p>
97 + <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e('Total Clients', 'easy-invoice'); ?></h3>
98 + <p class="mt-1 text-2xl font-bold text-gray-900"><?php echo (int) (isset($stats['total_clients']) ? $stats['total_clients'] : count($clients)); ?></p>
85 99 </div>
86 100 </div>
87 101 </div>
88 102 <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
@@ -92,10 +106,10 @@
92 106 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
93 107 </svg>
94 108 </div>
95 109 <div>
96 - <h3 class="text-sm font-medium text-gray-500">Total Invoices</h3>
97 - <p class="mt-1 text-2xl font-bold text-gray-900"><?php echo isset($stats['total_invoices']) ? $stats['total_invoices'] : 0; ?></p>
110 + <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e('Total Invoices', 'easy-invoice'); ?></h3>
111 + <p class="mt-1 text-2xl font-bold text-gray-900"><?php echo esc_html(isset($stats['total_invoices']) ? $stats['total_invoices'] : 0); ?></p>
98 112 </div>
99 113 </div>
100 114 </div>
101 115 <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
@@ -105,9 +119,9 @@
105 119 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
106 120 </svg>
107 121 </div>
108 122 <div>
109 - <h3 class="text-sm font-medium text-gray-500">Total Revenue</h3>
123 + <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e('Total Revenue', 'easy-invoice'); ?></h3>
110 124 <?php if (is_array($stats['total_revenue']) && !empty($stats['total_revenue'])): ?>
111 125 <div class="mt-1">
112 126 <?php
113 127 $currency_count = count($stats['total_revenue']);
@@ -116,10 +130,10 @@
116 130 // Get currency code from the data array or use a fallback
117 131 $currency_code = isset($data['currency_code']) ? $data['currency_code'] : 'USD';
118 132 ?>
119 133 <div class="<?php echo $currency_count > 1 ? 'text-sm' : 'text-lg'; ?> font-bold text-gray-900 <?php echo !$is_last ? 'mb-1' : ''; ?>">
120 - <?php echo $data['symbol'] . number_format($data['amount'], 2); ?>
121 - <span class="text-xs font-normal text-gray-500"><?php echo strtoupper($currency_code ?? 'USD'); ?></span>
134 + <?php echo esc_html($data['symbol'] . number_format($data['amount'], 2)); ?>
135 + <span class="text-xs font-normal text-gray-500"><?php echo esc_html(strtoupper($currency_code ?? 'USD')); ?></span>
122 136 </div>
123 137 <?php endforeach; ?>
124 138 </div>
125 139 <?php else: ?>
@@ -135,10 +149,10 @@
135 149 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
136 150 </svg>
137 151 </div>
138 152 <div>
139 - <h3 class="text-sm font-medium text-gray-500">Pending Invoices</h3>
140 - <p class="mt-1 text-2xl font-bold text-yellow-600"><?php echo isset($stats['pending_invoices']) ? $stats['pending_invoices'] : 0; ?></p>
153 + <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e('Pending Invoices', 'easy-invoice'); ?></h3>
154 + <p class="mt-1 text-2xl font-bold text-yellow-600"><?php echo esc_html(isset($stats['pending_invoices']) ? $stats['pending_invoices'] : 0); ?></p>
141 155 </div>
142 156 </div>
143 157 </div>
144 158 </div>
@@ -198,9 +212,9 @@
198 212 if ($link && strpos($link, 'bg-indigo-50') === false && strpos($link, 'bg-white') === false) {
199 213 $link = easy_invoice_str_replace('border-gray-300', 'border-gray-300 bg-white text-gray-500 hover:bg-gray-50', $link);
200 214 }
201 215
202 - echo $link;
216 + echo wp_kses_post($link);
203 217 }
204 218 echo '</div>';
205 219 }
206 220 ?>
@@ -210,8 +224,16 @@
210 224 </div>
211 225 <?php endif; ?>
212 226
213 227 <div class="bg-white rounded-lg shadow">
228 + <div class="px-4 py-3 border-b border-gray-200 flex items-center justify-between gap-3 flex-wrap">
229 + <label for="client-search" class="sr-only"><?php esc_html_e('Search clients', 'easy-invoice'); ?></label>
230 + <div class="relative w-full sm:w-80">
231 + <svg class="absolute left-3 top-2.5 h-4 w-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-4.35-4.35M17 11A6 6 0 115 11a6 6 0 0112 0z"/></svg>
232 + <input type="search" id="client-search" placeholder="<?php esc_attr_e('Search by name, company, email or phone…', 'easy-invoice'); ?>" class="block w-full pl-9 pr-3 py-2 border border-gray-300 rounded-md text-sm focus:ring-indigo-500 focus:border-indigo-500">
233 + </div>
234 + <span id="client-search-count" class="text-sm text-gray-500"></span>
235 + </div>
214 236 <div class="overflow-x-auto">
215 237 <table class="min-w-full divide-y divide-gray-200 client-list-table">
216 238 <thead class="bg-gray-50">
217 239 <tr>
@@ -216,9 +238,9 @@
216 238 <thead class="bg-gray-50">
217 239 <tr>
218 240 <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="id">
219 241 <div class="flex items-center space-x-1">
220 - <span>Client ID</span>
242 + <span><?php esc_html_e('Client ID', 'easy-invoice'); ?></span>
221 243 <div class="sort-indicator">
222 244 <i class="fas fa-sort text-gray-400"></i>
223 245 </div>
224 246 </div>
@@ -224,9 +246,9 @@
224 246 </div>
225 247 </th>
226 248 <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="business_name">
227 249 <div class="flex items-center space-x-1">
228 - <span>Business Name</span>
250 + <span><?php esc_html_e('Business Name', 'easy-invoice'); ?></span>
229 251 <div class="sort-indicator">
230 252 <i class="fas fa-sort text-gray-400"></i>
231 253 </div>
232 254 </div>
@@ -232,9 +254,9 @@
232 254 </div>
233 255 </th>
234 256 <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="name">
235 257 <div class="flex items-center space-x-1">
236 - <span>Client Name</span>
258 + <span><?php esc_html_e('Client Name', 'easy-invoice'); ?></span>
237 259 <div class="sort-indicator">
238 260 <i class="fas fa-sort text-gray-400"></i>
239 261 </div>
240 262 </div>
@@ -240,9 +262,9 @@
240 262 </div>
241 263 </th>
242 264 <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="email">
243 265 <div class="flex items-center space-x-1">
244 - <span>Email</span>
266 + <span><?php esc_html_e('Email', 'easy-invoice'); ?></span>
245 267 <div class="sort-indicator">
246 268 <i class="fas fa-sort text-gray-400"></i>
247 269 </div>
248 270 </div>
@@ -248,9 +270,9 @@
248 270 </div>
249 271 </th>
250 272 <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="phone">
251 273 <div class="flex items-center space-x-1">
252 - <span>Phone</span>
274 + <span><?php esc_html_e('Phone', 'easy-invoice'); ?></span>
253 275 <div class="sort-indicator">
254 276 <i class="fas fa-sort text-gray-400"></i>
255 277 </div>
256 278 </div>
@@ -256,9 +278,9 @@
256 278 </div>
257 279 </th>
258 280 <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="username">
259 281 <div class="flex items-center space-x-1">
260 - <span>Username</span>
282 + <span><?php esc_html_e('Username', 'easy-invoice'); ?></span>
261 283 <div class="sort-indicator">
262 284 <i class="fas fa-sort text-gray-400"></i>
263 285 </div>
264 286 </div>
@@ -264,9 +286,9 @@
264 286 </div>
265 287 </th>
266 288 <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:bg-gray-100" data-sort="role">
267 289 <div class="flex items-center space-x-1">
268 - <span>Role</span>
290 + <span><?php esc_html_e('Role', 'easy-invoice'); ?></span>
269 291 <div class="sort-indicator">
270 292 <i class="fas fa-sort text-gray-400"></i>
271 293 </div>
272 294 </div>
@@ -350,10 +372,10 @@
350 372 <td class="px-6 py-4 whitespace-nowrap">
351 373 <div class="text-sm text-gray-500"><?php echo esc_html($client->getUsername()); ?></div>
352 374 </td>
353 375 <td class="px-6 py-4 whitespace-nowrap">
354 - <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium <?php echo $role_class; ?>">
355 - <i class="<?php echo $role_icon; ?> mr-1"></i>
376 + <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium <?php echo esc_attr($role_class); ?>">
377 + <i class="<?php echo esc_attr($role_icon); ?> mr-1"></i>
356 378 <?php echo esc_html(ucfirst($client_role)); ?>
357 379 </span>
358 380 </td>
359 381 <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
@@ -363,14 +385,20 @@
363 385 title="View Client">
364 386 <i class="fas fa-eye mr-1"></i>
365 387 View
366 388 </a>
367 - <a href="?page=easy-invoice-client-edit&client_id=<?php echo esc_attr($clientId); ?>"
389 + <a href="?page=easy-invoice-client-edit&client_id=<?php echo esc_attr($clientId); ?>"
368 390 class="inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded text-blue-700 bg-blue-100 hover:bg-blue-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200"
369 391 title="Edit Client">
370 392 <i class="fas fa-edit mr-1"></i>
371 393 Edit
372 394 </a>
395 + <a href="<?php echo esc_url(\EasyInvoice\Controllers\StatementController::pageUrl((int) $clientId)); ?>"
396 + class="inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded text-gray-700 bg-gray-100 hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-colors duration-200"
397 + title="<?php esc_attr_e('Statement of account', 'easy-invoice'); ?>">
398 + <i class="fas fa-file-invoice-dollar mr-1"></i>
399 + <?php esc_html_e('Statement', 'easy-invoice'); ?>
400 + </a>
373 401 <?php if ($client_role === 'administrator'): ?>
374 402 <button type="button"
375 403 class="inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded text-gray-400 bg-gray-100 cursor-not-allowed opacity-50"
376 404 title="Cannot delete administrator"
@@ -451,9 +479,9 @@
451 479 if ($link && strpos($link, 'bg-indigo-50') === false && strpos($link, 'bg-white') === false) {
452 480 $link = easy_invoice_str_replace('border-gray-300', 'border-gray-300 bg-white text-gray-500 hover:bg-gray-50', $link);
453 481 }
454 482
455 - echo $link;
483 + echo wp_kses_post($link);
456 484 }
457 485 echo '</div>';
458 486 }
459 487 ?>
@@ -467,9 +495,9 @@
467 495 <div class="bg-white rounded-lg shadow-xl max-w-3xl w-full p-6 relative">
468 496 <button class="close-modal absolute top-4 right-4 text-gray-400 hover:text-gray-500">
469 497 <i class="fas fa-times"></i>
470 498 </button>
471 - <h2 class="text-xl font-medium text-gray-900 mb-4">Add New Client</h2>
499 + <h2 class="text-xl font-medium text-gray-900 mb-4"><?php esc_html_e('Add New Client', 'easy-invoice'); ?></h2>
472 500
473 501 <?php
474 502 // Unset the $client variable from the foreach loop to ensure clean add form
475 503 unset($client);
@@ -576,101 +604,22 @@
576 604 // Initialize sorting
577 605 initSorting();
578 606
579 607 // Delete client functionality
580 - $(".delete-client").on("click", function(e) {
581 - e.preventDefault();
582 -
583 - const clientId = $(this).data("id");
584 - const clientName = $(this).closest("tr").find("td:first-child div").text().trim();
585 -
586 - // Use the new confirmation system instead of browser confirm
587 - if (typeof EasyInvoiceConfirmation !== 'undefined') {
588 - EasyInvoiceConfirmation.confirmAction('delete', 'client "' + clientName + '"', function() {
589 - $.ajax({
590 - url: easyInvoice.ajaxUrl,
591 - type: "POST",
592 - data: {
593 - action: "easy_invoice_delete_client",
594 - client_id: clientId,
595 - nonce: easyInvoice.nonce
596 - },
597 - success: function(response) {
598 - if (response.success) {
599 - EasyInvoiceToast.success(response.data.message || 'Client deleted successfully');
600 - $("[data-id='" + clientId + "']").closest("tr").fadeOut(400, function() {
601 - $(this).remove();
602 -
603 - // Update total clients count
604 - var currentCount = parseInt($("h3:contains('Total Clients')").next().text()) || 0;
605 - $("h3:contains('Total Clients')").next().text(Math.max(0, currentCount - 1));
606 -
607 - // Check if table is empty and show "No clients found"
608 - if ($("tbody tr").length === 0) {
609 - $("tbody").html('<tr><td colspan="8" class="px-6 py-4 whitespace-nowrap text-center text-sm text-gray-500">No clients found</td></tr>');
610 - }
611 - });
612 - } else {
613 - EasyInvoiceToast.error(response.data.message || 'Error deleting client');
614 - }
615 - },
616 - error: function() {
617 - EasyInvoiceToast.error('Error connecting to server');
618 - }
619 - });
608 + // Filter the rows as you type; no request, the list is already here.
609 + (function () {
610 + var $input = $('#client-search'), $count = $('#client-search-count');
611 + if (!$input.length) { return; }
612 + $input.on('input', function () {
613 + var q = $.trim($(this).val()).toLowerCase(), shown = 0, total = 0;
614 + $('.client-list-table tbody tr').each(function () {
615 + var $tr = $(this); if ($tr.find('td').length < 3) { return; }
616 + total++;
617 + var hit = !q || $tr.text().toLowerCase().indexOf(q) !== -1;
618 + $tr.toggle(hit); if (hit) { shown++; }
620 619 });
621 - } else {
622 - // Fallback to browser confirm if toast system not available
623 - if (confirm("Are you sure you want to delete the client \"" + clientName + "\"? This action cannot be undone.")) {
624 - $.ajax({
625 - url: easyInvoice.ajaxUrl,
626 - type: "POST",
627 - data: {
628 - action: "easy_invoice_delete_client",
629 - client_id: clientId,
630 - nonce: easyInvoice.nonce
631 - },
632 - success: function(response) {
633 - if (response.success) {
634 - // Use unified toast system
635 - if (typeof EasyInvoiceToast !== 'undefined') {
636 - EasyInvoiceToast.success("Client \"" + clientName + "\" has been deleted");
637 - } else {
638 - alert("Client \"" + clientName + "\" has been deleted");
639 - }
640 -
641 - // Remove the row from the table
642 - $("[data-id='" + clientId + "']").closest("tr").fadeOut(300, function() {
643 - $(this).remove();
644 -
645 - // Update total clients count
646 - var currentCount = parseInt($("h3:contains('Total Clients')").next().text()) || 0;
647 - $("h3:contains('Total Clients')").next().text(Math.max(0, currentCount - 1));
648 -
649 - // Check if table is empty and show "No clients found"
650 - if ($("tbody tr").length === 0) {
651 - $("tbody").html('<tr><td colspan="8" class="px-6 py-4 whitespace-nowrap text-center text-sm text-gray-500">No clients found</td></tr>');
652 - }
653 - });
654 - } else {
655 - // Use unified toast system
656 - if (typeof EasyInvoiceToast !== 'undefined') {
657 - EasyInvoiceToast.error(response.data.message || "Error deleting client");
658 - } else {
659 - alert(response.data.message || "Error deleting client");
660 - }
661 - }
662 - },
663 - error: function() {
664 - // Use unified toast system
665 - if (typeof EasyInvoiceToast !== 'undefined') {
666 - EasyInvoiceToast.error("Error connecting to server");
667 - } else {
668 - alert("Error connecting to server");
669 - }
670 - }
671 - });
672 - }
673 - }
674 - });
620 + $count.text(q ? shown + ' / ' + total : '');
621 + });
622 + })();
623 + // Delete is handled by assets/js/clients.js (choice of keeping or removing the client's documents).
675 624 });
676 625 </script>