| @@ -90,15 +90,30 @@ | ||
| 90 | 90 | $amount = isset($data['amount']) && is_numeric($data['amount']) ? $data['amount'] : 0; |
| 91 | 91 | $symbol = isset($data['symbol']) ? $data['symbol'] : ''; |
| 92 | 92 | ?> |
| 93 | 93 | <div class="<?php echo $currency_count > 0 ? 'text-sm' : 'text-lg'; ?> font-bold text-gray-900 <?php echo !$is_last ? 'mb-1' : ''; ?>"> |
| 94 | - <?php echo $symbol . number_format($amount, 2); ?> | |
| 94 | + <?php echo esc_html($symbol . number_format($amount, 2)); ?> | |
| 95 | 95 | <span class="text-xs font-normal text-gray-500"><?php echo esc_html(strtoupper((string)($currency ?? 'USD'))); ?></span> |
| 96 | 96 | </div> |
| 97 | 97 | <?php endforeach; ?> |
| 98 | 98 | </div> |
| 99 | 99 | <?php else: ?> |
| 100 | - <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> | |
| 101 | 116 | <?php endif; ?> |
| 102 | 117 | </div> |
| 103 | 118 | </div> |
| 104 | 119 | </div> |
| @@ -111,8 +126,11 @@ | ||
| 111 | 126 | </div> |
| 112 | 127 | <div> |
| 113 | 128 | <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e( 'Unpaid Invoices', 'easy-invoice' ); ?></h3> |
| 114 | 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; ?> | |
| 115 | 133 | </div> |
| 116 | 134 | </div> |
| 117 | 135 | </div> |
| 118 | 136 | <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1"> |
| @@ -124,14 +142,21 @@ | ||
| 124 | 142 | </div> |
| 125 | 143 | <div> |
| 126 | 144 | <h3 class="text-sm font-medium text-gray-500"><?php esc_html_e( 'Overdue Invoices', 'easy-invoice' ); ?></h3> |
| 127 | 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; ?> | |
| 128 | 149 | </div> |
| 129 | 150 | </div> |
| 130 | 151 | </div> |
| 131 | 152 | </div> |
| 132 | 153 | |
| 133 | - <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"> | |
| 134 | 159 | <div class="bg-white rounded-lg shadow p-6 transition-transform duration-300 hover:shadow-md hover:-translate-y-1"> |
| 135 | 160 | <div class="flex items-center"> |
| 136 | 161 | <div class="rounded-full bg-blue-100 p-3 mr-4"> |
| 137 | 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"> |
| @@ -206,28 +231,16 @@ | ||
| 206 | 231 | </thead> |
| 207 | 232 | <tbody class="bg-white divide-y divide-gray-200"> |
| 208 | 233 | <?php if (!empty($recent_invoices)) : ?> |
| 209 | 234 | <?php foreach ($recent_invoices as $invoice): |
| 210 | - $statusClass = [ | |
| 211 | - 'paid' => 'bg-green-100 text-green-800', | |
| 212 | - 'unpaid' => 'bg-yellow-100 text-yellow-800', | |
| 213 | - 'overdue' => 'bg-red-100 text-red-800', | |
| 214 | - 'draft' => 'bg-gray-100 text-gray-800' | |
| 215 | - ][$invoice->getStatus()] ?? 'bg-gray-100 text-gray-800'; | |
| 216 | - | |
| 217 | 235 | $invoiceId = $invoice->getId(); |
| 218 | 236 | $invoiceNumber = $invoice->getNumber() ?: ('INV-' . $invoiceId); |
| 219 | 237 | $invoiceTotal = $invoice->getTotal(); |
| 220 | 238 | $clientName = $invoice->getCustomerName() ?: __( 'Client', 'easy-invoice' ); |
| 221 | - $dueDate = $invoice->getDueDate() ?: date('Y-m-d'); | |
| 222 | - $raw_status = $invoice->getStatus(); | |
| 223 | - $status_map = array( | |
| 224 | - 'paid' => __( 'Paid', 'easy-invoice' ), | |
| 225 | - 'unpaid' => __( 'Unpaid', 'easy-invoice' ), | |
| 226 | - 'overdue' => __( 'Overdue', 'easy-invoice' ), | |
| 227 | - 'draft' => __( 'Draft', 'easy-invoice' ), | |
| 228 | - ); | |
| 229 | - $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 ); | |
| 230 | 243 | ?> |
| 231 | 244 | <tr> |
| 232 | 245 | <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"><?php echo esc_html($invoiceNumber); ?></td> |
| 233 | 246 | <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><?php echo esc_html($clientName); ?></td> |
| @@ -242,10 +255,20 @@ | ||
| 242 | 255 | </span> |
| 243 | 256 | </td> |
| 244 | 257 | <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><?php echo esc_html($dueDate); ?></td> |
| 245 | 258 | <td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> |
| 246 | - <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> | |
| 247 | - <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> | |
| 248 | 271 | </td> |
| 249 | 272 | </tr> |
| 250 | 273 | <?php endforeach; ?> |
| 251 | 274 | <?php else: ?> |