PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.3.1
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.3.1
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
easy-invoice / templates / client-view-page.php

client-view-page.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.3.1, at templates/client-view-page.php

366 lines 22.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 // Client data and invoices are passed from the render_client_view_page method
8 ?>
9
10 <div class="p-8">
11 <div class="flex justify-between items-center mb-6">
12 <div>
13 <h1 class="text-2xl font-bold text-gray-900 flex items-center">
14 <i class="fas fa-user-tie text-gray-400 mr-3"></i>
15 <span><?php echo esc_html($client->getBusinessClientName() ?: $client->getFirstName() . ' ' . $client->getLastName()); ?></span>
16 </h1>
17 <p class="text-sm text-gray-500 mt-1">
18 Client Overview & Invoice History
19 </p>
20 </div>
21 <div>
22 <a href="?page=easy-invoice-clients" class="text-gray-600 hover:text-indigo-600 mr-4 font-medium text-sm">
23 <i class="fas fa-arrow-left mr-1"></i> Back to Clients
24 </a>
25 <a href="?page=easy-invoice-client-edit&client_id=<?php echo esc_attr($client->getId()); ?>" class="bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 text-sm font-semibold shadow-sm">
26 <i class="fas fa-pen mr-2"></i>Edit Client
27 </a>
28 </div>
29 </div>
30
31 <div class="bg-white p-6 rounded-xl border border-gray-200 shadow-sm mb-8">
32 <div class="flex items-center justify-between pb-4 border-b border-gray-200 mb-4">
33 <h4 class="text-lg font-semibold text-gray-800 flex items-center">
34 <i class="fas fa-user-check text-indigo-500 mr-3"></i>
35 <span><?php _e('Client Details', 'easy-invoice'); ?></span>
36 </h4>
37 </div>
38
39 <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-6 pt-2">
40 <div class="flex items-start group">
41 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-user-tie text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
42 <div class="ml-3">
43 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Full Name', 'easy-invoice'); ?></label>
44 <p class="text-sm font-semibold text-gray-800 mt-1"><?php echo esc_html($client->getFirstName() . ' ' . $client->getLastName()); ?></p>
45 </div>
46 </div>
47
48 <div class="flex items-start group">
49 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-building text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
50 <div class="ml-3">
51 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Company', 'easy-invoice'); ?></label>
52 <p class="text-sm font-semibold text-gray-800 mt-1"><?php echo esc_html($client->getBusinessClientName() ?: 'N/A'); ?></p>
53 </div>
54 </div>
55
56 <div class="flex items-start group">
57 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-envelope text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
58 <div class="ml-3">
59 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Email', 'easy-invoice'); ?></label>
60 <p class="text-sm text-gray-800 mt-1 break-all"><?php echo esc_html($client->getEmail()); ?></p>
61 </div>
62 </div>
63
64 <div class="flex items-start group">
65 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-phone-alt text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
66 <div class="ml-3">
67 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Phone', 'easy-invoice'); ?></label>
68 <p class="text-sm text-gray-800 mt-1"><?php echo esc_html($client->getPhone() ?: 'N/A'); ?></p>
69 </div>
70 </div>
71
72 <div class="flex items-start group">
73 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-at text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
74 <div class="ml-3">
75 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Username', 'easy-invoice'); ?></label>
76 <p class="text-sm text-gray-800 mt-1"><?php echo esc_html($client->getUsername()); ?></p>
77 </div>
78 </div>
79
80 <div class="flex items-start group">
81 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-id-card text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
82 <div class="ml-3">
83 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Client ID', 'easy-invoice'); ?></label>
84 <p class="text-sm text-gray-800 mt-1"><?php echo esc_html($client->getId()); ?></p>
85 </div>
86 </div>
87
88 <div class="flex items-start group">
89 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-user-shield text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
90 <div class="ml-3">
91 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Role', 'easy-invoice'); ?></label>
92 <div class="mt-1">
93 <?php
94 $role_class = 'bg-blue-100 text-blue-800';
95 $role_icon = 'fas fa-user';
96
97 if (isset($client_role)) {
98 switch ($client_role) {
99 case 'administrator':
100 $role_class = 'bg-red-100 text-red-800';
101 $role_icon = 'fas fa-crown';
102 break;
103 case 'editor':
104 $role_class = 'bg-purple-100 text-purple-800';
105 $role_icon = 'fas fa-user-edit';
106 break;
107 case 'author':
108 $role_class = 'bg-green-100 text-green-800';
109 $role_icon = 'fas fa-user-edit';
110 break;
111 case 'contributor':
112 $role_class = 'bg-yellow-100 text-yellow-800';
113 $role_icon = 'fas fa-user-plus';
114 break;
115 case 'subscriber':
116 $role_class = 'bg-gray-100 text-gray-800';
117 $role_icon = 'fas fa-user';
118 break;
119 default:
120 $role_class = 'bg-blue-100 text-blue-800';
121 $role_icon = 'fas fa-user';
122 }
123 }
124 ?>
125 <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium <?php echo $role_class; ?>">
126 <i class="<?php echo $role_icon; ?> mr-1"></i>
127 <?php echo esc_html(ucfirst($client_role ?? 'client')); ?>
128 </span>
129 </div>
130 </div>
131 </div>
132
133 <div class="flex items-start group">
134 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-globe-americas text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
135 <div class="ml-3">
136 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Website', 'easy-invoice'); ?></label>
137 <p class="text-sm text-gray-800 mt-1">
138 <?php if ($client->getWebsite()): ?>
139 <a href="<?php echo esc_url($client->getWebsite()); ?>" target="_blank" class="text-indigo-600 hover:text-indigo-800 hover:underline">
140 <?php echo esc_html($client->getWebsite()); ?>
141 </a>
142 <?php else: ?>
143 N/A
144 <?php endif; ?>
145 </p>
146 </div>
147 </div>
148
149 <div class="flex items-start group md:col-span-2 lg:col-span-3">
150 <div class="flex-shrink-0 w-8 text-center pt-1"><i class="fas fa-map-marker-alt text-gray-400 group-hover:text-indigo-500 transition-colors"></i></div>
151 <div class="ml-3">
152 <label class="block text-xs font-medium text-gray-500 uppercase tracking-wider"><?php _e('Address', 'easy-invoice'); ?></label>
153 <p class="text-sm text-gray-800 mt-1 whitespace-pre-wrap"><?php echo esc_html($client->getAddress() ?: 'N/A'); ?></p>
154 </div>
155 </div>
156 </div>
157
158 <?php if ($client->getExtraInfo()): ?>
159 <div class="mt-6 pt-6 border-t border-gray-200">
160 <h3 class="text-sm font-semibold text-gray-800 mb-2 flex items-center">
161 <i class="fas fa-info-circle text-gray-400 mr-2"></i>
162 <span><?php _e('Extra Info', 'easy-invoice'); ?></span>
163 </h3>
164 <div class="bg-gray-50 p-4 rounded-md text-sm text-gray-700 prose max-w-none">
165 <?php echo nl2br(esc_html($client->getExtraInfo())); ?>
166 </div>
167 </div>
168 <?php endif; ?>
169 </div>
170
171 <div class="bg-white shadow-sm rounded-xl border border-gray-200">
172 <div class="p-6 border-b border-gray-200">
173 <h2 class="text-lg font-semibold text-gray-800 flex items-center">
174 <i class="fas fa-file-invoice-dollar text-indigo-500 mr-3"></i>
175 <span>Invoices</span>
176 </h2>
177 </div>
178
179 <?php if (empty($invoices)): ?>
180 <div class="text-center py-12">
181 <div class="text-gray-400 mb-4"><i class="fas fa-file-invoice fa-4x"></i></div>
182 <p class="text-gray-500 font-medium mb-4">No invoices found for this client.</p>
183 </div>
184 <?php else: ?>
185 <div class="overflow-x-auto">
186 <table class="min-w-full divide-y divide-gray-200">
187 <thead class="bg-gray-50">
188 <tr>
189 <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Invoice</th>
190 <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
191 <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Due Date</th>
192 <th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th>
193 <th scope="col" class="px-6 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
194 <th scope="col" class="relative px-6 py-3">
195 <span class="sr-only">Actions</span>
196 </th>
197 </tr>
198 </thead>
199 <tbody class="bg-white divide-y divide-gray-200">
200 <?php foreach ($invoices as $invoice):
201 $status_class = '';
202 $status_icon = '';
203 switch ($invoice['status']) {
204 case 'paid':
205 $status_class = 'bg-green-100 text-green-800';
206 $status_icon = 'fas fa-check-circle';
207 break;
208 case 'pending':
209 $status_class = 'bg-yellow-100 text-yellow-800';
210 $status_icon = 'fas fa-hourglass-half';
211 break;
212 case 'overdue':
213 $status_class = 'bg-red-100 text-red-800';
214 $status_icon = 'fas fa-exclamation-triangle';
215 break;
216 default:
217 $status_class = 'bg-gray-100 text-gray-800';
218 $status_icon = 'fas fa-question-circle';
219 }
220 ?>
221 <tr>
222 <td class="px-6 py-4 whitespace-nowrap">
223 <div class="flex flex-col">
224 <div class="text-sm font-semibold text-indigo-600 hover:text-indigo-800">
225 <a href="<?php echo get_permalink($invoice['id']); ?>"><?php echo esc_html($invoice['title']); ?></a>
226 </div>
227 <div class="text-xs text-gray-500 font-mono">
228 <?php echo esc_html($invoice['invoice_number']); ?>
229 </div>
230 </div>
231 </td>
232 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
233 <?php echo esc_html(date("M d, Y", strtotime($invoice['date']))); ?>
234 </td>
235 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
236 <?php echo esc_html(date("M d, Y", strtotime($invoice['due_date']))); ?>
237 </td>
238 <td class="px-6 py-4 whitespace-nowrap text-right text-sm text-gray-800 font-medium">
239 <?php
240 // Use InvoiceFormatter for proper currency formatting
241 $formatter = new \EasyInvoice\Helpers\InvoiceFormatter();
242 echo esc_html($formatter->format($invoice['amount'] ?? 0));
243 ?>
244 </td>
245 <td class="px-6 py-4 whitespace-nowrap text-center">
246 <span class="px-3 py-1 inline-flex text-xs leading-5 font-semibold rounded-full <?php echo $status_class; ?>">
247 <i class="<?php echo $status_icon; ?> mr-1.5"></i>
248 <?php echo ucfirst(esc_html($invoice['status'])); ?>
249 </span>
250 </td>
251 <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium space-x-3">
252 <a href="<?php echo get_permalink($invoice['id']); ?>" class="text-indigo-600 hover:text-indigo-900" data-tooltip="View Invoice">
253 <i class="fas fa-eye"></i>
254 </a>
255 <a href="?page=easy-invoice-builder&invoice_id=<?php echo esc_attr($invoice['id']); ?>" class="text-gray-500 hover:text-indigo-900" data-tooltip="Edit Invoice">
256 <i class="fas fa-pen"></i>
257 </a>
258 </td>
259 </tr>
260 <?php endforeach; ?>
261 </tbody>
262 </table>
263 </div>
264 <?php endif; ?>
265 </div>
266
267 <div class="bg-white shadow-sm rounded-xl border border-gray-200 mt-6">
268 <div class="p-6 border-b border-gray-200">
269 <h2 class="text-lg font-semibold text-gray-800 flex items-center">
270 <i class="fas fa-file-contract text-green-500 mr-3"></i>
271 <span>Quotes</span>
272 </h2>
273 </div>
274
275 <?php if (empty($quotes)): ?>
276 <div class="text-center py-12">
277 <div class="text-gray-400 mb-4"><i class="fas fa-file-contract fa-4x"></i></div>
278 <p class="text-gray-500 font-medium mb-4">No quotes found for this client.</p>
279 </div>
280 <?php else: ?>
281 <div class="overflow-x-auto">
282 <table class="min-w-full divide-y divide-gray-200">
283 <thead class="bg-gray-50">
284 <tr>
285 <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Quote</th>
286 <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
287 <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Expiry Date</th>
288 <th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th>
289 <th scope="col" class="px-6 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
290 <th scope="col" class="relative px-6 py-3">
291 <span class="sr-only">Actions</span>
292 </th>
293 </tr>
294 </thead>
295 <tbody class="bg-white divide-y divide-gray-200">
296 <?php foreach ($quotes as $quote):
297 $status_class = '';
298 $status_icon = '';
299 switch ($quote['status']) {
300 case 'accepted':
301 $status_class = 'bg-green-100 text-green-800';
302 $status_icon = 'fas fa-check-circle';
303 break;
304 case 'pending':
305 $status_class = 'bg-yellow-100 text-yellow-800';
306 $status_icon = 'fas fa-hourglass-half';
307 break;
308 case 'declined':
309 $status_class = 'bg-red-100 text-red-800';
310 $status_icon = 'fas fa-times-circle';
311 break;
312 case 'expired':
313 $status_class = 'bg-gray-100 text-gray-800';
314 $status_icon = 'fas fa-clock';
315 break;
316 default:
317 $status_class = 'bg-gray-100 text-gray-800';
318 $status_icon = 'fas fa-question-circle';
319 }
320 ?>
321 <tr>
322 <td class="px-6 py-4 whitespace-nowrap">
323 <div class="flex flex-col">
324 <div class="text-sm font-semibold text-green-600 hover:text-green-800">
325 <a href="<?php echo get_permalink($quote['id']); ?>"><?php echo esc_html($quote['title']); ?></a>
326 </div>
327 <div class="text-xs text-gray-500 font-mono">
328 <?php echo esc_html($quote['quote_number']); ?>
329 </div>
330 </div>
331 </td>
332 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
333 <?php echo esc_html(date("M d, Y", strtotime($quote['date']))); ?>
334 </td>
335 <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
336 <?php echo esc_html(date("M d, Y", strtotime($quote['expiry_date']))); ?>
337 </td>
338 <td class="px-6 py-4 whitespace-nowrap text-right text-sm text-gray-800 font-medium">
339 <?php
340 // Use QuoteFormatter for proper currency formatting
341 $formatter = new \EasyInvoice\Helpers\QuoteFormatter();
342 echo esc_html($formatter->format($quote['amount'] ?? 0));
343 ?>
344 </td>
345 <td class="px-6 py-4 whitespace-nowrap text-center">
346 <span class="px-3 py-1 inline-flex text-xs leading-5 font-semibold rounded-full <?php echo $status_class; ?>">
347 <i class="<?php echo $status_icon; ?> mr-1.5"></i>
348 <?php echo ucfirst(esc_html($quote['status'])); ?>
349 </span>
350 </td>
351 <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium space-x-3">
352 <a href="<?php echo get_permalink($quote['id']); ?>" class="text-green-600 hover:text-green-900" data-tooltip="View Quote">
353 <i class="fas fa-eye"></i>
354 </a>
355 <a href="?page=easy-invoice-quote-builder&quote_id=<?php echo esc_attr($quote['id']); ?>" class="text-gray-500 hover:text-green-900" data-tooltip="Edit Quote">
356 <i class="fas fa-pen"></i>
357 </a>
358 </td>
359 </tr>
360 <?php endforeach; ?>
361 </tbody>
362 </table>
363 </div>
364 <?php endif; ?>
365 </div>
366 </div>