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