PluginProbe
Taskbuilder – Project Management & Task Management Tool With Kanban Board / 6.0.6
Taskbuilder – Project Management & Task Management Tool With Kanban Board v6.0.6
6.0.6 6.0.5 6.0.2 6.0.3 6.0.4 6.0.1 6.0.0 5.0.8 5.0.9 4.0.9 5.0.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 All 58 releases
taskbuilder / includes / admin / dashboard.php

dashboard.php in Taskbuilder – Project Management & Task Management Tool With Kanban Board 6.0.6, at includes/admin/dashboard.php

976 lines 41.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit; // Exit if accessed directly
4 }
5 global $wpdb,$current_user;
6 $current_user_id = get_current_user_id();
7 $wppm_project_time = get_option('wppm_project_time');
8 $wppm_task_time = get_option('wppm_task_time');
9 $wppm_task_statuses = $wpdb->get_results("SELECT id,name,bg_color FROM {$wpdb->prefix}wppm_task_statuses");
10 $wppm_project_statuses = $wpdb->get_results("SELECT id,name,bg_color FROM {$wpdb->prefix}wppm_project_statuses");
11 $wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true );
12 $is_admin = ( $wppm_current_user_capability === 'wppm_admin' || current_user_can('manage_options') ) ? 1 : 0;
13 $query = $wpdb->prepare(
14 "SELECT COUNT(DISTINCT p.id)
15 FROM {$wpdb->prefix}wppm_project p
16 LEFT JOIN {$wpdb->prefix}wppm_project_users pu
17 ON p.id = pu.proj_id
18 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
19 ON p.id = pm.project_id AND pm.meta_key = 'public_project'
20 WHERE (
21 FIND_IN_SET(%d, p.users)
22 OR p.created_by = %d
23 OR %d = 1
24 OR pm.meta_value = '1'
25 )
26 AND p.status != %d",
27 $current_user_id,
28 $current_user_id,
29 $is_admin,
30 4
31 );
32 $active_projects = $wpdb->get_var($query);
33 $query = $wpdb->prepare(
34 "SELECT DISTINCT Task.*
35 FROM {$wpdb->prefix}wppm_task AS Task
36 WHERE (
37 FIND_IN_SET(%d, Task.users)
38 OR Task.created_by = %d
39 )
40 AND Task.status != %d
41 AND Task.active = 1
42 AND Task.is_archived = 0
43 AND Task.parent_task_id = 0
44 LIMIT 5",
45 $current_user_id, // for JOIN pu
46 $current_user_id, // role_id
47 4 // status
48 );
49 $tasks = $wpdb->get_results($query);
50 $query = $wpdb->prepare(
51 "SELECT DISTINCT Task.*
52 FROM {$wpdb->prefix}wppm_task AS Task
53 LEFT JOIN {$wpdb->prefix}wppm_project p
54 ON Task.project = p.id
55 LEFT JOIN {$wpdb->prefix}wppm_project_users pu
56 ON p.id = pu.proj_id AND pu.user_id = %d
57 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
58 ON p.id = pm.project_id AND pm.meta_key = 'public_project'
59 WHERE (
60 %d = 1
61 OR FIND_IN_SET(%d, Task.users)
62 OR Task.created_by = %d
63 OR p.created_by = %d
64 OR (FIND_IN_SET(%d, p.users) AND pu.role_id = %d)
65 OR pm.meta_value = '1'
66 )
67 AND Task.status = %d
68 AND Task.active = 1
69 AND Task.is_archived = 0
70 AND Task.parent_task_id = 0
71 LIMIT 5",
72
73 $current_user_id, // 1 → pu.user_id
74 $is_admin, // 2
75 $current_user_id, // 3
76 $current_user_id, // 4
77 $current_user_id, // 5
78 $current_user_id, // 6
79 2, // 7 → role_id
80 4 // 8 → status
81 );
82 $completed_tasks = $wpdb->get_results($query);
83 $query = $wpdb->prepare(
84 "SELECT COUNT(DISTINCT Task.id)
85 FROM {$wpdb->prefix}wppm_task AS Task
86 LEFT JOIN {$wpdb->prefix}wppm_project p
87 ON Task.project = p.id
88 LEFT JOIN {$wpdb->prefix}wppm_project_users pu
89 ON p.id = pu.proj_id AND pu.user_id = %d
90 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
91 ON p.id = pm.project_id AND pm.meta_key = 'public_project'
92 WHERE (
93 %d = 1
94 OR FIND_IN_SET(%d, Task.users)
95 OR Task.created_by = %d
96 OR p.created_by = %d
97 OR (FIND_IN_SET(%d, p.users) AND pu.role_id = %d)
98 OR pm.meta_value = '1'
99 )
100 AND Task.status = %d
101 AND Task.active = 1
102 AND Task.is_archived = 0
103 AND Task.parent_task_id = 0",
104
105 $current_user_id, // pu.user_id
106 $is_admin,
107 $current_user_id,
108 $current_user_id,
109 $current_user_id,
110 $current_user_id,
111 2, // role_id �
112 FIXED
113 4 // status
114 );
115 $completed_task_count = $wpdb->get_var($query);
116 $query = $wpdb->prepare(
117 "SELECT DISTINCT count(*) AS task_count
118 FROM {$wpdb->prefix}wppm_task AS Task
119 WHERE (
120 FIND_IN_SET(%d, Task.users)
121 OR Task.created_by = %d
122 )
123 AND Task.status != %d
124 AND Task.active = 1
125 AND Task.is_archived = 0
126 AND Task.parent_task_id = 0
127 LIMIT 5",
128 $current_user_id, // for JOIN pu
129 $current_user_id, // role_id
130 4 // status
131 );
132 $task_count = $wpdb->get_var($query);
133 $query = $wpdb->prepare(
134 "SELECT DISTINCT Task.*,p.project_name
135 FROM {$wpdb->prefix}wppm_task AS Task
136 LEFT JOIN {$wpdb->prefix}wppm_project p
137 ON Task.project = p.id
138 LEFT JOIN {$wpdb->prefix}wppm_project_users pu
139 ON p.id = pu.proj_id AND pu.user_id = %d
140 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
141 ON p.id = pm.project_id AND pm.meta_key = 'public_project'
142 WHERE (
143 %d = 1
144 OR FIND_IN_SET(%d, Task.users)
145 OR Task.created_by = %d
146 OR p.created_by = %d
147 OR (FIND_IN_SET(%d, p.users) AND pu.role_id = %d)
148 OR pm.meta_value = '1'
149 )
150 AND DATE(Task.end_date) = CURDATE()
151 AND Task.status != %d
152 AND Task.active = 1
153 AND Task.is_archived = 0
154 AND Task.parent_task_id = 0
155 LIMIT 5",
156 $current_user_id, // for JOIN pu
157 $is_admin,
158 $current_user_id,
159 $current_user_id,
160 $current_user_id,
161 $current_user_id,
162 2, // role_id
163 4 // status
164 );
165 $todays_tasks = $wpdb->get_results($query);
166 $status_counts = [];
167 $task_bg_color = [];
168 $project_status_counts = [];
169 $project_bg_color = [];
170 if(!empty($wppm_task_statuses)){
171 foreach($wppm_task_statuses as $key => $status){
172 $count = $wpdb->get_var($wpdb->prepare(
173 "SELECT DISTINCT COUNT(DISTINCT Task.id)
174 FROM {$wpdb->prefix}wppm_task AS Task
175 LEFT JOIN {$wpdb->prefix}wppm_project p
176 ON Task.project = p.id
177 LEFT JOIN {$wpdb->prefix}wppm_project_users pu
178 ON p.id = pu.proj_id AND pu.user_id = %d
179 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
180 ON p.id = pm.project_id AND pm.meta_key = 'public_project'
181 WHERE (
182 %d = 1
183 OR FIND_IN_SET(%d, Task.users)
184 OR Task.created_by = %d
185 OR p.created_by = %d
186 OR (FIND_IN_SET(%d, p.users) AND pu.role_id = %d)
187 OR pm.meta_value = '1'
188 )
189 AND Task.status = %d
190 AND Task.active = 1
191 AND Task.is_archived = 0
192 AND Task.parent_task_id = 0
193 LIMIT 5",
194 $current_user_id, // for JOIN pu
195 $is_admin,
196 $current_user_id,
197 $current_user_id,
198 $current_user_id,
199 $current_user_id,
200 2, // role_id
201 $status->id // status
202 )
203 );
204 $status_counts[$status->name] = $count;
205 $task_bg_color[$status->name] = $status->bg_color;
206 }
207 }
208 if(!empty($wppm_project_statuses)){
209 foreach($wppm_project_statuses as $key => $status){
210 $count = $wpdb->get_var(
211 $wpdb->prepare(
212 "SELECT COUNT(DISTINCT p.id)
213 FROM {$wpdb->prefix}wppm_project p
214 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
215 ON p.id = pm.project_id
216 AND pm.meta_key = 'public_project'
217 WHERE (
218 FIND_IN_SET(%d, p.users)
219 OR p.created_by = %d
220 OR %d = 1
221 OR pm.meta_value = '1'
222 )
223 AND p.status = %d",
224 $current_user_id,
225 $current_user_id,
226 $is_admin,
227 $status->id
228 )
229 );
230 $project_status_counts[$status->name] = $count;
231 $project_bg_color[$status->name] = $status->bg_color;
232 }
233 }
234 $overdue = $wpdb->get_var(
235 $wpdb->prepare(
236 "SELECT COUNT(DISTINCT t.id)
237 FROM {$wpdb->prefix}wppm_task t
238 LEFT JOIN {$wpdb->prefix}wppm_project p
239 ON t.project = p.id
240 LEFT JOIN {$wpdb->prefix}wppm_project_users pu
241 ON p.id = pu.proj_id
242 AND pu.user_id = %d
243 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
244 ON p.id = pm.project_id
245 AND pm.meta_key = 'public_project'
246 WHERE
247 t.end_date < CURDATE()
248 AND t.status != 4
249 AND t.active = 1
250 AND t.is_archived = 0
251 AND t.parent_task_id = 0
252 AND (
253 %d = 1
254 OR FIND_IN_SET(%d, t.users)
255 OR t.created_by = %d
256 OR p.created_by = %d
257 OR pu.role_id = %d
258 OR pm.meta_value = '1'
259 )",
260 $current_user_id, // pu.user_id
261 $is_admin,
262 $current_user_id,
263 $current_user_id,
264 $current_user_id,
265 2 // role_id
266 )
267 );
268 $labels = array_keys($status_counts);
269 $data = array_values($status_counts);
270 $task_bg_colors = array_values($task_bg_color);
271 $project_overdue = $wpdb->get_var(
272 $wpdb->prepare(
273 "SELECT COUNT(DISTINCT p.id)
274 FROM {$wpdb->prefix}wppm_project p
275 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
276 ON p.id = pm.project_id
277 AND pm.meta_key = 'public_project'
278 WHERE (
279 FIND_IN_SET(%d, p.users)
280 OR p.created_by = %d
281 OR %d = 1
282 OR pm.meta_value = '1'
283 )
284 AND p.status != %d AND p.end_date < CURDATE()",
285 $current_user_id,
286 $current_user_id,
287 $is_admin,
288 4
289 )
290 );
291 $project_labels = array_keys($project_status_counts);
292 $project_data = array_values($project_status_counts);
293 $project_bg_colors = array_values($project_bg_color);
294 $labels[] = 'Overdue';
295 $data[] = $overdue;
296 $task_bg_colors [] = '#e74c3c';
297 $project_labels[] = 'Overdue';
298 $project_data[] = $project_overdue;
299 $project_bg_colors[] = '#e74c3c';
300 ?>
301 <div class="wppm-dashboard">
302 <div class="wppm-dashboard-top">
303 <div class="wppm-small-widget">
304 <div class="wppm-widget-icon">📁</div>
305 <h3><?php echo esc_html_e('Active Projects', 'taskbuilder'); ?></h3>
306 <span class="wppm-number"><?php echo intval($active_projects); ?></span>
307 </div>
308 <div class="wppm-small-widget">
309 <div class="wppm-widget-icon">📝</div>
310 <h3><?php echo esc_html_e('My Tasks', 'taskbuilder'); ?></h3>
311 <span class="wppm-number"><?php echo intval($task_count); ?></span>
312 </div>
313 <div class="wppm-small-widget">
314 <div class="wppm-widget-icon">�
315 </div>
316 <h3><?php echo esc_html_e('Completed Tasks', 'taskbuilder'); ?></h3>
317 <span class="wppm-number"><?php echo intval($completed_task_count); ?></span>
318 </div>
319 <div class="wppm-small-widget overdue">
320 <div class="wppm-widget-icon"></div>
321 <h3><?php echo esc_html_e('Overdue Tasks', 'taskbuilder'); ?></h3>
322 <span class="wppm-number"><?php echo intval($overdue); ?></span>
323 </div>
324 </div>
325 <div class="wppm-divider"></div>
326 <div class="wppm-row">
327 <div class="wppm-widget">
328 <h2><?php echo esc_html_e('Today\'s Tasks', 'taskbuilder'); ?><a href="<?php echo esc_url(admin_url('admin.php?page=wppm-tasks&wppm_task_filter=today')); ?>" class="wppm-view-all" target="_blank"><?php echo esc_html_e('View All', 'taskbuilder'); ?></a></h2>
329 <form id="wppm_get_my_tasks_frm" name="wppm_get_my_tasks_frm">
330 <div class="table-responsive">
331 <table id="tbl_todays_tasks" class="table table-striped table-bordered" cellspacing="0" width="100%">
332 <thead>
333 <tr>
334 <th class="wppm_table_header"><?php echo esc_html_e('Task Name','taskbuilder');?> </th>
335 <th class="wppm_table_header"><?php echo esc_html_e('Task Status','taskbuilder');?> </th>
336 <th class="wppm_table_header"><?php echo esc_html_e('Project','taskbuilder');?> </th>
337 <th class="wppm_table_header"><?php echo esc_html_e('Due date','taskbuilder');?> </th>
338 <th class="wppm_table_header"><?php echo esc_html_e('Progress','taskbuilder');?> </th>
339 </tr>
340 </thead>
341 <tbody>
342 <?php
343 if(!empty($todays_tasks)){
344 foreach ($todays_tasks as $task) {
345 $status = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wppm_task_statuses WHERE id = %d", (int) $task->status ) );
346 $users = array();
347 if($task->users != null){
348 $users = explode(",",$task->users);
349 }
350 if(!empty($task->project)){
351 $project = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wppm_project WHERE id = %d",(int) $task->project));
352 }
353 if($wppm_task_time == 1){
354 $task_end_date = $task->end_date;
355 } elseif($wppm_task_time == 0){
356 $teDate = new DateTime($task->end_date);
357 $task_end_date = $teDate->format('Y-m-d');
358 }
359 $priority_color = $wpdb->get_var(
360 $wpdb->prepare(
361 "SELECT bg_color
362 FROM {$wpdb->prefix}wppm_task_priorities
363 WHERE id = %d",
364 (int) $task->priority
365 )
366 );
367 // fallback color if not found
368 if(empty($priority_color)){
369 $priority_color = '#cccccc';
370 }
371 ?>
372 <tr onclick="wppm_open_task(<?php echo esc_attr($task->id); ?>)" class="wppm-task-row" data-task="<?php echo esc_attr($task->id); ?>" data-project="<?php echo esc_attr($task->project); ?>">
373 <td>
374 <span class="wppm-priority-dot" style="background: <?php echo esc_attr($priority_color); ?>;"></span>
375 <?php echo esc_html($task->task_name); ?>
376 </td>
377 <td>
378 <span class="wppm_td_task_status" style="background-color:<?php echo (isset($status->bg_color))? esc_attr($status->bg_color):"";?>; color: <?php echo (isset($status->color))? esc_attr($status->color):""; ?>"><?php echo (isset($status->name))? esc_html($status->name):"" ?></span>
379 </td>
380 <td>
381 <?php echo esc_html($project->project_name); ?>
382 </td>
383 <td>
384 <?php echo (isset($task_end_date))? esc_html($task_end_date):""?>
385 </td>
386 <td>
387 <?php
388 $checklists = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_checklist where task_id = %d",$task->id) );
389 $row = $wpdb->get_row(
390 $wpdb->prepare(
391 "SELECT
392 COUNT(Items.id) as total,
393 SUM(CASE WHEN Items.checked = 1 THEN 1 ELSE 0 END) as completed
394 FROM {$wpdb->prefix}wppm_checklist_items AS Items
395 LEFT JOIN {$wpdb->prefix}wppm_checklist checklist
396 ON Items.checklist_id = checklist.id
397 WHERE checklist.task_id = %d",
398 $task->id
399 )
400 );
401 $total = $row->total;
402 $total_checked_items = intval($row->completed);
403 $progress = ($total > 0) ? round(($total_checked_items / $total) * 100) : 0;
404 $color = '#ef4444'; // red
405 if($progress >= 50){
406 $color = '#f59e0b'; // orange
407 }
408 if($progress >= 80){
409 $color = '#22c55e'; // green
410 }
411 ?>
412 <div class="dashboard-progress-wrapper">
413 <div class="dashboard-progress-bar">
414 <div class="dashboard-progress" style="width: <?php echo esc_attr($progress); ?>%; background: <?php echo esc_attr($color); ?>;"></div>
415 </div>
416 <span class="dashboard-progress-text"><?php echo esc_html($progress); ?>%</span>
417 </div>
418 </td>
419 </tr>
420 <?php }
421 }
422 ?>
423 </tbody>
424 </table>
425 </div>
426 </form>
427 </div>
428 <div class="wppm-widget">
429 <h2><?php echo esc_html__('Upcoming Tasks(Next 7 Days)', 'taskbuilder'); ?> <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-tasks&wppm_task_filter=upcoming')); ?>" class="wppm-view-all" target="_blank"><?php echo esc_html__('View All','taskbuilder');?></a></h2>
430 <?php
431 $query = $wpdb->prepare(
432 "SELECT t.*, p.project_name
433 FROM {$wpdb->prefix}wppm_task t
434 LEFT JOIN {$wpdb->prefix}wppm_project p
435 ON t.project = p.id
436 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
437 ON p.id = pm.project_id
438 AND pm.meta_key = 'public_project'
439 WHERE
440 (
441 FIND_IN_SET(%d, t.users)
442 OR t.created_by = %d
443 OR %d = 1
444 OR pm.meta_value = '1'
445 OR t.project IN (
446 SELECT id FROM {$wpdb->prefix}wppm_project
447 WHERE created_by = %d
448 OR FIND_IN_SET(%d, users)
449 )
450 )
451 AND DATE(t.end_date) BETWEEN CURDATE()
452 AND DATE_ADD(CURDATE(), INTERVAL 7 DAY)
453 AND t.status != 4
454 AND t.active = 1
455 AND t.is_archived = 0
456 AND t.parent_task_id = 0
457
458 ORDER BY t.end_date ASC
459 LIMIT 5",
460 $current_user_id,
461 $current_user_id,
462 $is_admin,
463 $current_user_id,
464 $current_user_id
465 );
466 $upcoming_tasks = $wpdb->get_results($query);?>
467 <form id="wppm_get_upcoming_tasks_frm" name="wppm_get_upcoming_tasks_frm">
468 <div class="table-responsive">
469 <table id="tbl_upcoming_tasks" class="table table-striped table-bordered" cellspacing="0" width="100%">
470 <thead>
471 <tr>
472 <th class="wppm_table_header"><?php echo esc_html_e('Name','taskbuilder');?> </th>
473 <th class="wppm_table_header"><?php echo esc_html_e('Status','taskbuilder');?> </th>
474 <th class="wppm_table_header"><?php echo esc_html_e('Project','taskbuilder');?> </th>
475 <th class="wppm_table_header"><?php echo esc_html_e('Due date','taskbuilder');?> </th>
476 <th class="wppm_table_header"><?php echo esc_html_e('Progress','taskbuilder');?> </th>
477 </tr>
478 </thead>
479 <tbody>
480 <?php
481 if(!empty($upcoming_tasks)){
482 foreach ($upcoming_tasks as $task) {
483 $status = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wppm_task_statuses WHERE id = %d", (int) $task->status ) );
484 $users = array();
485 if($task->users != null){
486 $users = explode(",",$task->users);
487 }
488 if(!empty($task->project)){
489 $project = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wppm_project WHERE id = %d",(int) $task->project));
490 }
491 if($wppm_task_time == 1){
492 $task_end_date = $task->end_date;
493 } elseif($wppm_task_time == 0){
494 $teDate = new DateTime($task->end_date);
495 $task_end_date = $teDate->format('Y-m-d');
496 }
497 $priority_color = $wpdb->get_var(
498 $wpdb->prepare(
499 "SELECT bg_color
500 FROM {$wpdb->prefix}wppm_task_priorities
501 WHERE id = %d",
502 (int) $task->priority
503 )
504 );
505 // fallback color if not found
506 if(empty($priority_color)){
507 $priority_color = '#cccccc';
508 }
509 ?>
510 <tr onclick="wppm_open_task(<?php echo esc_attr($task->id);?>)" class="wppm-task-row" data-task="<?php echo esc_attr($task->id); ?>" data-project="<?php echo esc_attr($task->project); ?> ">
511 <td>
512 <span class="wppm-priority-dot" style="background: <?php echo esc_attr($priority_color); ?>;"></span>
513 <?php echo esc_html($task->task_name); ?>
514 </td>
515 <td>
516 <span class="wppm_td_task_status" style="background-color:<?php echo (isset($status->bg_color))? esc_attr($status->bg_color):"";?>; color: <?php echo (isset($status->color))? esc_attr($status->color):""; ?>"><?php echo (isset($status->name))? esc_html($status->name):"" ?></span>
517 </td>
518 <td>
519 <?php echo esc_html($project->project_name); ?>
520 </td>
521 <td>
522 <?php echo (isset($task_end_date))? esc_html($task_end_date):""?>
523 </td>
524 <td>
525 <?php
526 $checklists = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_checklist where task_id = %d",$task->id) );
527 $row = $wpdb->get_row(
528 $wpdb->prepare(
529 "SELECT
530 COUNT(Items.id) as total,
531 SUM(CASE WHEN Items.checked = 1 THEN 1 ELSE 0 END) as completed
532 FROM {$wpdb->prefix}wppm_checklist_items AS Items
533 LEFT JOIN {$wpdb->prefix}wppm_checklist checklist
534 ON Items.checklist_id = checklist.id
535 WHERE checklist.task_id = %d",
536 $task->id
537 )
538 );
539
540 $total = $row->total;
541 $total_checked_items = intval($row->completed);
542
543 $progress = ($total > 0) ? round(($total_checked_items / $total) * 100) : 0;
544 $color = '#ef4444'; // red
545 if($progress >= 50){
546 $color = '#f59e0b'; // orange
547 }
548 if($progress >= 80){
549 $color = '#22c55e'; // green
550 }
551 ?>
552 <div class="dashboard-progress-wrapper">
553 <div class="dashboard-progress-bar">
554 <div class="dashboard-progress" style="width: <?php echo esc_attr($progress); ?>%; background: <?php echo esc_attr($color); ?>;"></div>
555 </div>
556 <span class="dashboard-progress-text"><?php echo esc_html($progress); ?>%</span>
557 </div>
558 </td>
559 </tr>
560 <?php }
561 }
562 ?>
563 </tbody>
564 </table>
565 </div>
566 </form>
567 </div>
568 </div>
569 <div class="wppm-row">
570 <div class="wppm-widget">
571 <h2><?php echo esc_html_e('My Tasks','taskbuilder'); ?> <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-tasks&wppm_task_filter=mytasks')); ?>" class="wppm-view-all" target="_blank"><?php echo esc_html_e('View All','taskbuilder'); ?></a></h2>
572 <form id="wppm_get_my_tasks_frm" name="wppm_get_my_tasks_frm">
573 <div class="table-responsive">
574 <table id="tbl_my_tasks" class="table table-striped table-bordered" cellspacing="0" width="100%">
575 <thead>
576 <tr>
577 <th class="wppm_table_header"><?php echo esc_html_e('Task Name','taskbuilder');?> </th>
578 <th class="wppm_table_header"><?php echo esc_html_e('Task Status','taskbuilder');?> </th>
579 <th class="wppm_table_header"><?php echo esc_html_e('Project','taskbuilder');?> </th>
580 <th class="wppm_table_header"><?php echo esc_html_e('Due date','taskbuilder');?> </th>
581 <th class="wppm_table_header"><?php echo esc_html_e('Progress','taskbuilder');?> </th>
582 </tr>
583 </thead>
584 <tbody>
585 <?php
586 if(!empty($tasks)){
587 foreach ($tasks as $task) {
588 $status = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wppm_task_statuses WHERE id = %d", (int) $task->status ) );
589 $users = array();
590 if($task->users != null){
591 $users = explode(",",$task->users);
592 }
593 if(!empty($task->project)){
594 $project = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wppm_project WHERE id = %d",(int) $task->project));
595 }
596 if($wppm_task_time == 1){
597 $task_end_date = $task->end_date;
598 } elseif($wppm_task_time == 0){
599 $teDate = new DateTime($task->end_date);
600 $task_end_date = $teDate->format('Y-m-d');
601 }
602 $priority_color = $wpdb->get_var( $wpdb->prepare(
603 "SELECT bg_color
604 FROM {$wpdb->prefix}wppm_task_priorities
605 WHERE id = %d",
606 (int) $task->priority
607 )
608 );
609 // fallback color if not found
610 if(empty($priority_color)){
611 $priority_color = '#cccccc';
612 }
613 ?>
614 <tr class="wppm-task-row" data-task="<?php echo esc_attr($task->id); ?>" data-project="<?php echo esc_attr($task->project); ?>">
615 <td>
616 <span class="wppm-priority-dot" style="background: <?php echo esc_attr($priority_color); ?>;"></span>
617 <?php echo esc_html($task->task_name); ?>
618 </td>
619 <td>
620 <span class="wppm_td_task_status" style="background-color:<?php echo (isset($status->bg_color))? esc_attr($status->bg_color):"";?>; color: <?php echo (isset($status->color))? esc_attr($status->color):""; ?>"><?php echo (isset($status->name))? esc_html($status->name):"" ?></span>
621 </td>
622 <td>
623 <?php echo esc_html($project->project_name); ?>
624 </td>
625 <td>
626 <?php echo (isset($task_end_date))? esc_html($task_end_date):""?>
627 </td>
628 <td>
629 <?php
630 $checklists = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_checklist where task_id = %d",$task->id) );
631 $row = $wpdb->get_row(
632 $wpdb->prepare(
633 "SELECT
634 COUNT(Items.id) as total,
635 SUM(CASE WHEN Items.checked = 1 THEN 1 ELSE 0 END) as completed
636 FROM {$wpdb->prefix}wppm_checklist_items AS Items
637 LEFT JOIN {$wpdb->prefix}wppm_checklist checklist
638 ON Items.checklist_id = checklist.id
639 WHERE checklist.task_id = %d",
640 $task->id
641 )
642 );
643 $total = $row->total;
644 $total_checked_items = intval($row->completed);
645
646 $progress = ($total > 0) ? round(($total_checked_items / $total) * 100) : 0;
647 $color = '#ef4444'; // red
648 if($progress >= 50){
649 $color = '#f59e0b'; // orange
650 }
651 if($progress >= 80){
652 $color = '#22c55e'; // green
653 }
654 ?>
655 <div class="dashboard-progress-wrapper">
656 <div class="dashboard-progress-bar">
657 <div class="dashboard-progress" style="width: <?php echo esc_attr($progress); ?>%; background: <?php echo esc_attr($color); ?>;"></div>
658 </div>
659 <span class="dashboard-progress-text"><?php echo esc_html($progress); ?>%</span>
660 </div>
661 </td>
662 </tr>
663 <?php }
664 }
665 ?>
666 </tbody>
667 </table>
668 </div>
669 </form>
670 </div>
671 <div class="wppm-widget">
672 <h2><?php echo esc_html_e('Active Projects','taskbuilder'); ?> <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-projects&wppm_project_filter=active')); ?>" class="wppm-view-all" target="_blank"><?php echo esc_html_e('View All','taskbuilder'); ?></a></h2>
673 <?php
674 $query = $wpdb->prepare(
675 "SELECT
676 p.id,
677 p.project_name AS name,
678 ps.name AS status_name,
679 ps.bg_color AS status_color,
680 ps.color AS status_text_color,
681 p.end_date,
682 COUNT(t.id) AS total_tasks,
683 SUM(CASE WHEN t.status = '4' THEN 1 ELSE 0 END) AS completed_tasks
684 FROM {$wpdb->prefix}wppm_project p
685 LEFT JOIN {$wpdb->prefix}wppm_project_statuses ps
686 ON p.status = ps.id
687 LEFT JOIN {$wpdb->prefix}wppm_project_users pu
688 ON p.id = pu.proj_id
689 LEFT JOIN {$wpdb->prefix}wppm_task t
690 ON p.id = t.project AND t.parent_task_id = 0
691 LEFT JOIN {$wpdb->prefix}wppm_project_meta pm
692 ON p.id = pm.project_id
693 AND pm.meta_key = 'public_project'
694 WHERE (FIND_IN_SET(%d, p.users) OR p.created_by = %d OR %d = 1 OR pm.meta_value = 1)
695 AND p.status != %d
696 GROUP BY p.id
697 ORDER BY p.end_date ASC
698 LIMIT 5",
699 $current_user_id,
700 $current_user_id,
701 $is_admin,
702 4
703 );
704 $projects = $wpdb->get_results($query);
705 ?>
706 <form id="wppm_get_active_projects_frm" name="wppm_get_active_projects_frm">
707 <div class="table-responsive">
708 <table id="tbl_active_projects" class="table table-striped table-bordered" cellspacing="0" width="100%">
709 <thead>
710 <tr>
711 <th class="wppm_table_header"><?php echo esc_html_e('Name','taskbuilder');?> </th>
712 <th class="wppm_table_header"><?php echo esc_html_e('Status','taskbuilder');?> </th>
713 <th class="wppm_table_header"><?php echo esc_html_e('Due date','taskbuilder');?> </th>
714 <th class="wppm_table_header"><?php echo esc_html_e('Progress','taskbuilder');?> </th>
715 </tr>
716 </thead>
717 <tbody>
718 <?php
719 if(!empty($projects)){
720 foreach ($projects as $project) {
721 if($wppm_project_time == 1){
722 $project_end_date = $project->end_date;
723 } elseif($wppm_project_time == 0){
724 $peDate = new DateTime($project->end_date);
725 $project_end_date = $peDate->format('Y-m-d');
726 }
727 ?>
728 <tr onclick= "wppm_open_project(<?php echo esc_attr($project->id) ?>)" class="wppm-project-row" data-project="<?php echo esc_attr($project->id); ?>">
729 <td>
730 <?php echo esc_html($project->name); ?>
731 </td>
732 <td>
733 <span class="wppm_td_project_status" style="background-color:<?php echo (isset($project->status_color))? esc_attr($project->status_color):"";?>; color: <?php echo (isset($project->status_text_color))? esc_attr($project->status_text_color):""; ?>"><?php echo (isset($project->status_name))? esc_html($project->status_name):"" ?></span>
734 </td>
735 <td>
736 <?php echo esc_html($project_end_date); ?>
737 </td>
738 <td>
739 <?php
740 $total = $project->total_tasks;
741 $completed = $project->completed_tasks;
742 if($total > 0){
743 $proj_progress = round(($completed / $total) * 100);
744 }else{
745 $proj_progress = 0;
746 }
747 $color = '#ef4444'; // red
748 if($proj_progress >= 50){
749 $color = '#f59e0b'; // orange
750 }
751 if($proj_progress >= 80){
752 $color = '#22c55e'; // green
753 }
754 ?>
755 <div class="dashboard-progress-wrapper">
756 <div class="dashboard-progress-bar">
757 <div class="dashboard-progress" style="width:<?php echo esc_attr($proj_progress); ?>%; background: <?php echo esc_attr($color); ?>;"></div>
758 </div>
759 <span class="dashboard-progress-text"><?php echo esc_html($proj_progress); ?>%</span>
760 </div>
761 </div>
762 </td>
763 </tr>
764 <?php }
765 }?>
766 </tbody>
767 </table>
768 </div>
769 </form>
770 </div>
771 </div>
772 <div class="wppm-row">
773 <div class="wppm-widget">
774 <h2><?php echo esc_html_e('Project Overview', 'taskbuilder'); ?></h2>
775 <canvas id="wppm_project_chart"></canvas>
776 </div>
777 <div class="wppm-widget">
778 <h2><?php echo esc_html_e('Task Overview', 'taskbuilder'); ?></h2>
779 <canvas id="wppm_task_chart"></canvas>
780 </div>
781 </div>
782 <div class="wppm-row">
783 <div class="wppm-widget">
784 <h2><?php echo esc_html_e('User Workload', 'taskbuilder'); ?></h2>
785 <?php
786 $query = $wpdb->prepare( "SELECT u.ID, u.display_name,
787 COUNT(DISTINCT t.id) AS total_tasks
788 FROM {$wpdb->users} u
789 INNER JOIN {$wpdb->prefix}wppm_project_users pu
790 ON u.ID = pu.user_id
791 INNER JOIN {$wpdb->prefix}wppm_task t
792 ON FIND_IN_SET(u.ID, t.users)
793 AND t.project = pu.proj_id AND pu.role_id!=3
794 WHERE
795 t.status != 4
796 AND t.active = 1
797 AND t.is_archived = 0
798 AND t.parent_task_id = 0
799 AND (
800 %d = 1
801 OR EXISTS (
802 SELECT 1
803 FROM {$wpdb->prefix}wppm_project_users current_pu
804 LEFT JOIN {$wpdb->prefix}wppm_project p
805 ON current_pu.proj_id = p.id
806 WHERE (current_pu.proj_id = pu.proj_id
807 AND current_pu.user_id = %d
808 AND current_pu.role_id != 3 OR p.created_by = %d )
809 )
810 )
811 GROUP BY u.ID
812 HAVING total_tasks > 0
813 ORDER BY total_tasks DESC
814 LIMIT 5",
815 $is_admin,
816 $current_user_id,
817 $current_user_id
818 );
819
820 $workloads = $wpdb->get_results($query);
821 // Get max task count
822 $max_tasks = 0;
823 if(!empty($workloads)){
824 foreach($workloads as $w){
825 if($w->total_tasks > $max_tasks){
826 $max_tasks = $w->total_tasks;
827 }
828 }
829 }
830 ?>
831 <ul class="wppm-workload-list">
832 <?php
833 if(!empty($workloads)){
834 foreach($workloads as $workload){
835 $percent = 0;
836 if($max_tasks > 0){
837 $percent = ($workload->total_tasks / $max_tasks) * 100;
838 }
839 $color = '#4CAF50';
840 if($percent > 80){
841 $color = '#ff4d4d';
842 }elseif($percent > 50){
843 $color = '#ffa500';
844 }?>
845 <li>
846 <span><?php echo esc_html($workload->display_name); ?></span>
847 <div class="wppm-workload-bar">
848 <div class="wppm-progress" style="width:<?php echo esc_attr($percent); ?>%; background:<?php echo esc_attr($color); ?>"></div>
849 </div>
850 <span><?php echo esc_html($workload->total_tasks); ?></span>
851 </li>
852 <?php }
853 }?>
854 </ul>
855 </div>
856 <div class="wppm-widget">
857 <h2><?php echo esc_html_e('Quick Actions', 'taskbuilder'); ?></h2>
858 <div class="wppm-quick-actions">
859 <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-projects&action=add')); ?>" class="wppm-add-new-btn btn-primary" target="_blank"> <?php echo esc_html_e('Add New Project', 'taskbuilder'); ?></a>
860 <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-projects&action=view')); ?>" class="wppm-add-new-btn btn-primary" target="_blank"> 📂 <?php echo esc_html_e('View Projects', 'taskbuilder'); ?></a>
861 <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-tasks&action=add')); ?>" class="wppm-add-new-btn btn-primary" target="_blank"> �
862 <?php echo esc_html_e('Add New Task', 'taskbuilder'); ?></a>
863 <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-tasks&action=view')); ?>" class="wppm-add-new-btn btn-primary" target="_blank"> 📋 <?php echo esc_html_e('View Tasks', 'taskbuilder'); ?></a>
864 </div>
865 </div>
866 </div>
867 </div>
868 </div>
869 <script type="text/javascript">
870 jQuery(document).ready(function() {
871 var table = jQuery('#tbl_my_tasks').DataTable({
872 "paging": false,
873 "ordering": false,
874 "info": false,
875 "searching": false,
876 "language": {
877 "emptyTable": "<?php echo esc_html_e('No tasks found','taskbuilder'); ?>"
878 }
879 });
880 var table = jQuery('#tbl_todays_tasks').DataTable({
881 "paging": false,
882 "ordering": false,
883 "info": false,
884 "searching": false,
885 "language": {
886 "emptyTable": "<?php echo esc_html_e('No tasks found','taskbuilder'); ?>"
887 }
888 });
889 var proj_table = jQuery('#tbl_active_projects').DataTable({
890 "paging": false,
891 "ordering": false,
892 "info": false,
893 "searching": false,
894 "language": {
895 "emptyTable": "<?php echo esc_html_e('No Projects found','taskbuilder'); ?>"
896 }
897 });
898 jQuery('div.dataTables_filter input', proj_table.table().container()).focus();
899 var upcoming_tasks_table = jQuery('#tbl_upcoming_tasks').DataTable({
900 "paging": false,
901 "ordering": false,
902 "info": false,
903 "searching": false,
904 "language": {
905 "emptyTable": "<?php echo esc_html_e('No Upcoming Tasks found','taskbuilder'); ?>"
906 }
907 });
908 //jQuery('div.dataTables_filter input', upcoming_tasks_table.table().container()).focus();
909 var ctx = document.getElementById('wppm_task_chart').getContext('2d');
910 new Chart(ctx, {
911 type: 'doughnut',
912 data: {
913 labels: <?php echo json_encode($labels); ?>,
914 datasets: [{
915 data:<?php echo json_encode($data); ?>,
916 backgroundColor: [
917 <?php
918 foreach($task_bg_colors as $color){
919 echo "'".esc_attr($color)."',";
920 }
921 ?>
922 ]
923 }]
924 },
925 options: {
926 responsive: true,
927 plugins: {
928 legend: {
929 position: 'bottom'
930 }
931 }
932 }
933 });
934 var ctx = document.getElementById('wppm_project_chart').getContext('2d');
935 new Chart(ctx, {
936 type: 'doughnut',
937 data: {
938 labels: <?php echo json_encode($project_labels); ?>,
939 datasets: [{
940 data: <?php echo json_encode($project_data); ?>,
941 backgroundColor: [
942 <?php
943 foreach($project_bg_colors as $color){
944 echo "'".esc_attr($color)."',";
945 }
946 ?>
947 ]
948 }]
949 },
950 options: {
951 responsive: true,
952 plugins: {
953 legend: {
954 position: 'bottom'
955 }
956 }
957 }
958 });
959 } );
960 jQuery(document).on('click','.wppm-task-row',function(){
961 var task_id = jQuery(this).data('task');
962 var project_id = jQuery(this).data('project');
963 event.stopPropagation();
964 window.location.href = '<?php echo admin_url("admin.php?page=wppm-tasks"); ?>' + '&task_id=' + task_id;
965 });
966 jQuery(document).on('click','.wppm-project-row',function(){
967 var project_id = jQuery(this).data('project');
968 event.stopPropagation();
969 window.location.href = '<?php echo admin_url("admin.php?page=wppm-projects"); ?>' + '&project_id=' + project_id;
970 });
971 </script>
972 <style type="text/css">
973 #wpfooter{
974 display: none;
975 }
976 </style>