PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.2
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.2
2.4.3 2.4.4 2.4.2 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 All 60 releases
← All changes | templates/dashboard-page.php +44 -26 2.1.21 → 2.4.2 View file →
@@ -48,9 +48,8 @@
48 48 $invoices_list_url = admin_url('admin.php?page=' . PagesSlugs::ALL_INVOICES);
49 49 ?>
50 50
51 51 <div class="p-8">
52 - <!-- Page Header -->
53 52 <div class="ei-app-page-header bg-white border-b border-gray-200 px-6 easy-invoice-admin-page-header">
54 53 <div class="flex items-center justify-between">
55 54 <div>
56 55 <h1 class="text-2xl font-bold text-gray-900"><?php esc_html_e( 'Dashboard', 'easy-invoice' ); ?></h1>
@@ -58,9 +57,8 @@
58 57 </div>
59 58 </div>
60 59 </div>
61 60
62 - <!-- Stats Cards -->
63 61 <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8 mt-8">
64 62 <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
65 63 <div class="flex items-center">
66 64 <div class="rounded-full bg-indigo-100 p-3 mr-4">
@@ -92,15 +90,30 @@
92 90 $amount = isset($data['amount']) && is_numeric($data['amount']) ? $data['amount'] : 0;
93 91 $symbol = isset($data['symbol']) ? $data['symbol'] : '';
94 92 ?>
95 93 <div class="<?php echo $currency_count > 0 ? 'text-sm' : 'text-lg'; ?> font-bold text-gray-900 <?php echo !$is_last ? 'mb-1' : ''; ?>">
96 - <?php echo $symbol . number_format($amount, 2); ?>
94 + <?php echo esc_html($symbol . number_format($amount, 2)); ?>
97 95 <span class="text-xs font-normal text-gray-500"><?php echo esc_html(strtoupper((string)($currency ?? 'USD'))); ?></span>
98 96 </div>
99 97 <?php endforeach; ?>
100 98 </div>
101 99 <?php else: ?>
102 - <p class="mt-1 text-lg font-bold text-gray-500"><?php esc_html_e( 'No revenue recorded', 'easy-invoice' ); ?></p>
100 + <?php
101 + // Show a formatted zero, not a sentence. Every sibling tile on
102 + // this row displays a number ("0"), so putting the prose
103 + // "No revenue recorded" here broke the row's visual rhythm and
104 + // wrapped onto two lines, making this card read as taller and
105 + // more important than the others. The zero carries the same
106 + // meaning and stays scannable alongside them.
107 + $ei_zero_symbol = function_exists('easy_invoice_get_currency_symbol') ? easy_invoice_get_currency_symbol() : '';
108 + $ei_zero_code = function_exists('easy_invoice_get_currency_code') ? easy_invoice_get_currency_code() : '';
109 + ?>
110 + <div class="text-lg font-bold text-gray-900">
111 + <?php echo esc_html($ei_zero_symbol . number_format(0, 2)); ?>
112 + <?php if ($ei_zero_code) : ?>
113 + <span class="text-xs font-normal text-gray-500"><?php echo esc_html(strtoupper((string) $ei_zero_code)); ?></span>
114 + <?php endif; ?>
115 + </div>
103 116 <?php endif; ?>
104 117 </div>
105 118 </div>
106 119 </div>
@@ -113,8 +126,11 @@
113 126 </div>
114 127 <div>
115 128 <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e( 'Unpaid Invoices', 'easy-invoice' ); ?></h3>
116 129 <p class="mt-1 text-2xl font-bold text-yellow-600"><?php echo esc_html($unpaid_invoices); ?></p>
130 + <?php foreach ((array) ($unpaid_amount ?? []) as $ei_cur => $ei_amt) : ?>
131 + <p class="text-xs text-gray-500" style="font-variant-numeric: tabular-nums;"><?php echo esc_html(easy_invoice_format_money((float) $ei_amt, null, (string) $ei_cur)); ?> <?php esc_html_e('outstanding', 'easy-invoice'); ?></p>
132 + <?php endforeach; ?>
117 133 </div>
118 134 </div>
119 135 </div>
120 136 <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
@@ -126,15 +142,21 @@
126 142 </div>
127 143 <div>
128 144 <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e( 'Overdue Invoices', 'easy-invoice' ); ?></h3>
129 145 <p class="mt-1 text-2xl font-bold text-red-600"><?php echo esc_html($overdue_invoices); ?></p>
146 + <?php foreach ((array) ($overdue_amount ?? []) as $ei_cur => $ei_amt) : ?>
147 + <p class="text-xs text-gray-500" style="font-variant-numeric: tabular-nums;"><?php echo esc_html(easy_invoice_format_money((float) $ei_amt, null, (string) $ei_cur)); ?> <?php esc_html_e('past due', 'easy-invoice'); ?></p>
148 + <?php endforeach; ?>
130 149 </div>
131 150 </div>
132 151 </div>
133 152 </div>
134 153
135 - <!-- Client Stats Cards -->
136 - <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
154 + <?php // Same 4-column track as the stat row above (grid-cols-4 at lg), so the two
155 + // client cards line up under the first four instead of stretching to half the
156 + // page each. They are the same kind of tile and were rendering at roughly
157 + // double the width of their siblings, which read as unintentional. ?>
158 + <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
137 159 <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1">
138 160 <div class="flex items-center">
139 161 <div class="rounded-full bg-blue-100 p-3 mr-4">
140 162 <svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@@ -164,9 +186,8 @@
164 186 </div>
165 187 </div>
166 188 </div>
167 189
168 - <!-- Monthly Revenue Chart -->
169 190 <div class="bg-white rounded-lg shadow p-6 mb-8 border border-gray-100">
170 191 <h2 class="text-lg font-medium text-gray-900 mb-1"><?php esc_html_e( 'Monthly Revenue', 'easy-invoice' ); ?></h2>
171 192 <?php if ($easy_invoice_has_chart_data) : ?>
172 193 <p class="text-sm text-gray-500 mb-4"><?php esc_html_e( 'Paid amounts recorded over the last twelve months, by currency.', 'easy-invoice' ); ?></p>
@@ -191,9 +212,8 @@
191 212 </div>
192 213 <?php endif; ?>
193 214 </div>
194 215
195 - <!-- Recent Invoices -->
196 216 <div class="bg-white rounded-lg shadow">
197 217 <div class="px-6 py-4 border-b border-gray-200">
198 218 <h2 class="text-lg font-medium text-gray-900"><?php esc_html_e( 'Recent Invoices', 'easy-invoice' ); ?></h2>
199 219 </div>
@@ -211,28 +231,16 @@
211 231 </thead>
212 232 <tbody class="bg-white divide-y divide-gray-200">
213 233 <?php if (!empty($recent_invoices)) : ?>
214 234 <?php foreach ($recent_invoices as $invoice):
215 - $statusClass = [
216 - 'paid' => 'bg-green-100 text-green-800',
217 - 'unpaid' => 'bg-yellow-100 text-yellow-800',
218 - 'overdue' => 'bg-red-100 text-red-800',
219 - 'draft' => 'bg-gray-100 text-gray-800'
220 - ][$invoice->getStatus()] ?? 'bg-gray-100 text-gray-800';
221 -
222 235 $invoiceId = $invoice->getId();
223 236 $invoiceNumber = $invoice->getNumber() ?: ('INV-' . $invoiceId);
224 237 $invoiceTotal = $invoice->getTotal();
225 238 $clientName = $invoice->getCustomerName() ?: __( 'Client', 'easy-invoice' );
226 - $dueDate = $invoice->getDueDate() ?: date('Y-m-d');
227 - $raw_status = $invoice->getStatus();
228 - $status_map = array(
229 - 'paid' => __( 'Paid', 'easy-invoice' ),
230 - 'unpaid' => __( 'Unpaid', 'easy-invoice' ),
231 - 'overdue' => __( 'Overdue', 'easy-invoice' ),
232 - 'draft' => __( 'Draft', 'easy-invoice' ),
233 - );
234 - $status = isset( $status_map[ $raw_status ] ) ? $status_map[ $raw_status ] : esc_html( ucfirst( (string) $raw_status ) );
239 + $dueDate = $invoice->getDueDate() ?: current_time('Y-m-d');
240 + $status_key = \EasyInvoice\Helpers\InvoiceStatus::displayKeyFor( $invoice );
241 + $statusClass = \EasyInvoice\Helpers\InvoiceStatus::badgeClass( $status_key );
242 + $status = \EasyInvoice\Helpers\InvoiceStatus::label( $status_key );
235 243 ?>
236 244 <tr>
237 245 <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"><?php echo esc_html($invoiceNumber); ?></td>
238 246 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><?php echo esc_html($clientName); ?></td>
@@ -247,10 +255,20 @@
247 255 </span>
248 256 </td>
249 257 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><?php echo esc_html($dueDate); ?></td>
250 258 <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
251 - <a href="<?php echo admin_url('admin.php?page=easy-invoice-invoices&view=edit&invoice_id=' . $invoiceId); ?>" class="text-indigo-600 hover:text-indigo-900 mr-3"><?php esc_html_e( 'Edit', 'easy-invoice' ); ?></a>
252 - <a href="<?php echo admin_url('admin.php?page=easy-invoice-invoices&view=view&invoice_id=' . $invoiceId); ?>" class="text-indigo-600 hover:text-indigo-900"><?php esc_html_e( 'View', 'easy-invoice' ); ?></a>
259 + <?php
260 + // Both links pointed at `page=easy-invoice-invoices`, which is
261 + // not a registered admin page — the invoice list is
262 + // `easy-invoice-all` and the editor is `easy-invoice-builder`.
263 + // Every Edit and View link on the dashboard returned a 403
264 + // "you do not have permission" screen.
265 + //
266 + // Now matching what the invoice listing itself uses: Edit opens
267 + // the builder, View opens the public invoice permalink.
268 + ?>
269 + <a href="<?php echo esc_url(admin_url('admin.php?page=easy-invoice-builder&invoice_id=' . $invoiceId)); ?>" class="text-indigo-600 hover:text-indigo-900 mr-3"><?php esc_html_e( 'Edit', 'easy-invoice' ); ?></a>
270 + <a href="<?php echo esc_url(get_permalink($invoiceId)); ?>" target="_blank" rel="noopener" class="text-indigo-600 hover:text-indigo-900"><?php esc_html_e( 'View', 'easy-invoice' ); ?></a>
253 271 </td>
254 272 </tr>
255 273 <?php endforeach; ?>
256 274 <?php else: ?>