« Back to History
today_work_report.php
|
20260721_154033.php
Initial Bulk Import
Copy Code
<?php error_reporting(E_ALL); ini_set('display_errors', 1); require_once __DIR__ . '/modules/auth/page_acl.php'; $ctx = page_require_access('dashboard'); $pdo = $ctx['pdo']; $company_id = (int)$ctx['company_id']; $today_date = date('Y-m-d'); function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function get_report_task_status(array $task): string { $status = trim(strtolower((string)($task['status'] ?? ''))); if ($status === 'in_progress') { return 'in progress'; } return $status === '' ? 'pending' : $status; } // --- ACTION: AJAX REMARK UPDATE (For Clean UI) --- if (isset($_GET['ajax_update_remark'])) { $tid = (int)$_GET['tid']; $remark = $_GET['remark']; $pdo->prepare("UPDATE daily_tasks SET remark = ? WHERE id = ? AND company_id = ?") ->execute([$remark, $tid, $company_id]); echo "OK"; exit; } // --- 1. ACTION: STATUS UPDATE --- if (isset($_GET['set_status'])) { $tid = (int)$_GET['tid']; $new_status = trim((string)$_GET['set_status']); $pdo->prepare("UPDATE daily_tasks SET status = ?, last_reset_date = ? WHERE id = ? AND company_id = ?") ->execute([$new_status, $today_date, $tid, $company_id]); header("Location: today_work_report.php"); exit; } // --- 2. ACTION: ADD TO TODAY (Reactivate Old Temp Task) --- if (isset($_GET['add_to_today'])) { $tid = (int)$_GET['add_to_today']; $pdo->prepare("UPDATE daily_tasks SET last_reset_date = ?, status = 'pending' WHERE id = ? AND company_id = ? AND task_type = 'temp'") ->execute([$today_date, $tid, $company_id]); header("Location: today_work_report.php"); exit; } // --- 3. ACTION: DELETE TASK --- if (isset($_POST['delete_task'])) { $tid = (int)$_POST['delete_task']; $pdo->prepare("DELETE FROM daily_tasks WHERE id = ? AND company_id = ?") ->execute([$tid, $company_id]); header('Location: today_work_report.php'); exit; } // --- 4. ACTION: SAVE/UPDATE TEMP TASK --- if (isset($_POST['save_task'])) { $name = trim($_POST['task_name']); $tid = !empty($_POST['task_id']) ? (int)$_POST['task_id'] : null; if ($tid) { $pdo->prepare("UPDATE daily_tasks SET task_name=? WHERE id=? AND company_id=? AND task_type='temp'") ->execute([$name, $tid, $company_id]); } else { $default_status = 'pending'; $pdo->prepare("INSERT INTO daily_tasks (company_id, task_name, task_type, last_reset_date, status) VALUES (?, ?, 'temp', ?, ?)") ->execute([$company_id, $name, $today_date, $default_status]); } header("Location: today_work_report.php"); exit; } // --- 5. AUTO RESET & PERSISTENCE LOGIC (Specific to temp tasks) --- // Delete old completed temp tasks that were reset before today $pdo->prepare("DELETE FROM daily_tasks WHERE company_id = ? AND task_type = 'temp' AND status = 'done' AND last_reset_date != ?") ->execute([$company_id, $today_date]); // Keep incomplete temp tasks by updating their reset date to today $pdo->prepare("UPDATE daily_tasks SET last_reset_date = ? WHERE company_id = ? AND task_type = 'temp' AND status != 'done' AND last_reset_date != ?") ->execute([$today_date, $company_id, $today_date]); // --- 6. DATA FETCHING --- // Fetch only Today's Temp Tasks for the main report $st = $pdo->prepare("SELECT * FROM daily_tasks WHERE company_id = ? AND task_type = 'temp' AND last_reset_date = ? ORDER BY id ASC"); $st->execute([$company_id, $today_date]); $report_tasks = $st->fetchAll(PDO::FETCH_ASSOC); // Fetch all Temp Tasks for Master List $st_all = $pdo->prepare("SELECT * FROM daily_tasks WHERE company_id = ? AND task_type = 'temp' ORDER BY id DESC"); $st_all->execute([$company_id]); $all_tasks = $st_all->fetchAll(PDO::FETCH_ASSOC); require_once __DIR__ . '/partials/header.php'; ?> <style> .remark-box { width: 100%; border: none; background: transparent; font-weight: 700; text-transform: uppercase; color: inherit; outline: none; padding: 5px; font-size: 13px; min-height: 30px; } .remark-box::placeholder { color: transparent; } .task-field-label { display: block; font-size: 11px; font-weight: 700; text-transform: uppercase; color: #495057; margin-bottom: 4px; } .task-action-group { display: flex; flex-wrap: wrap; gap: 6px; } .task-action-inline { display: inline; } .status-track { position: absolute; inset: 0; display: flex; align-items: center; justify-content: stretch; z-index: 1; pointer-events: none; } .status-option-label { flex: 1; text-align: center; font-size: 9px; font-weight: 800; text-transform: uppercase; color: #5c636a; line-height: 1; pointer-events: none; position: relative; z-index: 11; transition: color .15s ease; } .status-option-label.is-active { color: #fff; } .status-click-zone { position: absolute; top: 0; bottom: 0; width: 33.3333%; z-index: 3; } .status-click-zone-left { left: 0; } .status-click-zone-center { left: 33.3333%; } .status-click-zone-right { right: 0; } </style> <div class="container-fluid py-4"> <!-- Add/Edit Form for Temp Tasks --> <div class="card mb-4 no-print border-0 shadow-sm" style="background: #f8f9fa; border: 1px solid #ccc !important;"> <div class="card-body"> <h6 style="font-weight: 900; color: #0d6efd;">ADD TEMPORARY TASK FOR TODAY</h6> <form method="post" class="row g-2 align-items-end"> <input type="hidden" name="task_id" id="edit_id"> <div class="col-md-9"> <label class="task-field-label" for="edit_name">Task Description</label> <input type="text" name="task_name" id="edit_name" placeholder="Enter today's temporary task..." class="form-control form-control-sm" required> </div> <div class="col-md-3"> <button type="submit" name="save_task" id="save_task_btn" class="btn btn-primary btn-sm w-100 fw-bold">SAVE TASK</button> </div> </form> <div class="mt-2" style="font-size: 11px; color: #6c757d; font-weight: 600;"> Note: Tasks added here will automatically show up in today's report and will be cleared automatically the day after they are marked as done. </div> </div> </div> <!-- PNG Export Area --> <div id="captureArea" style="background: #fff; padding: 20px; border: 2px solid #000; border-radius: 10px;"> <h2 style="text-align: center; font-weight: 900; margin-bottom: 20px; color: #0d6efd;">TODAY'S TEMPORARY TASKS (<?= date('d-m-Y') ?>)</h2> <table style="width: 100%; border-collapse: collapse; border: 2px solid #000;"> <thead> <tr style="background: #000; color: #fff;"> <th style="padding: 10px; border: 1px solid #444; width: 50px; text-align: center;">SR</th> <th style="padding: 10px; border: 1px solid #444; text-align: left;">WORK DESCRIPTION</th> <th style="padding: 10px; border: 1px solid #444; width: 170px;">STATUS</th> <th style="padding: 10px; border: 1px solid #444;">REMARK</th> </tr> </thead> <tbody> <?php if (empty($report_tasks)): ?> <tr> <td colspan="4" style="padding: 15px; border: 1px solid #000; text-align: center; font-weight: bold; color: #6c757d;">No temporary tasks assigned for today.</td> </tr> <?php else: ?> <?php foreach($report_tasks as $i => $t): $st = get_report_task_status($t); $bg = "#f8d7da"; $txt = "#842029"; $p = "4px"; $c = "#dc3545"; $active_index = 0; $status_links = [ ['pending', '?set_status=pending&tid=' . $t['id']], ['progress', '?set_status=in progress&tid=' . $t['id']], ['done', '?set_status=done&tid=' . $t['id']], ]; $status_text_labels = ['PEND', 'PROG', 'DONE']; if ($st === 'in progress' || $st === 'in_progress') { $active_index = 1; $bg = "#fff3cd"; $txt = "#856404"; $p = "54px"; $c = "#ffc107"; } elseif ($st === 'done' || $st === 'complete') { $active_index = 2; $bg = "#d1e7dd"; $txt = "#0f5132"; $p = "104px"; $c = "#198754"; } ?> <tr style="background-color: <?= $bg ?>; color: <?= $txt ?>;"> <td style="padding: 10px; border: 1px solid #000; text-align: center; font-weight: bold;"><?= $i+1 ?></td> <td class="task-name-cell" style="padding: 10px; border: 1px solid #000; font-weight: 900; text-transform: uppercase;"> <?= h($t['task_name']) ?> </td> <td style="padding: 10px; border: 1px solid #000; text-align: center;"> <div class="status-shell" style="width: 160px; height: 36px; background: #eee; border: 2px solid #333; border-radius: 20px; position: relative; display: flex; align-items: center; margin: 0 auto; cursor: pointer;"> <div class="status-track"> <?php foreach ($status_text_labels as $label_index => $status_text_label): ?> <span class="status-option-label <?= $label_index === $active_index ? 'is-active' : '' ?>"><?= h($status_text_label) ?></span> <?php endforeach; ?> </div> <?php foreach ($status_links as $status_index => $status_link): ?> <a href="<?= h($status_link[1]) ?>" class="status-click-zone <?= $status_index === 0 ? 'status-click-zone-left' : ($status_index === 1 ? 'status-click-zone-center' : 'status-click-zone-right') ?>" aria-label="<?= h($status_link[0]) ?>"></a> <?php endforeach; ?> <div style="position: absolute; left: <?= $p ?>; width: 52px; height: 28px; border-radius: 15px; background: <?= $c ?>; pointer-events: none; z-index: 10; border: 1px solid rgba(0,0,0,0.2);"></div> </div> </td> <td style="padding: 0; border: 1px solid #000;"> <input type="text" value="<?= h($t['remark']) ?>" class="remark-box" onchange="saveRemark(<?= $t['id'] ?>, this.value)" placeholder="Type here..."> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> <div class="mt-4 no-print text-center"> <button onclick="downloadPNG()" class="btn btn-success fw-bold px-5">DOWNLOAD PNG</button> </div> <!-- Master List of Temp Tasks --> <div class="mt-5 no-print"> <h5 style="font-weight: 900; border-bottom: 2px solid #000;">TEMP TASKS MASTER LIST</h5> <div class="table-responsive mt-3"> <table class="table table-sm table-bordered"> <thead class="table-dark"> <tr> <th style="width: 80px;">ID</th> <th>Task Name</th> <th style="width: 150px;">Created / Active On</th> <th style="width: 250px;">Action</th> </tr> </thead> <tbody> <?php foreach($all_tasks as $at): ?> <tr> <td><?= $at['id'] ?></td> <td style="font-weight: 600;"><?= h($at['task_name']) ?></td> <td><?= h($at['last_reset_date']) ?></td> <td> <div class="task-action-group"> <button type="button" class="btn btn-primary btn-sm" onclick='editTask(<?= json_encode($at) ?>)'>EDIT</button> <?php if($at['last_reset_date'] !== $today_date): ?> <a href="?add_to_today=<?= $at['id'] ?>" class="btn btn-success btn-sm">ADD TO TODAY</a> <?php endif; ?> <form method="post" class="task-action-inline" onsubmit="return confirm('Delete this temporary task forever?');"> <input type="hidden" name="delete_task" value="<?= $at['id'] ?>"> <button type="submit" class="btn btn-danger btn-sm">DELETE</button> </form> </div> </td> </tr> <?php endforeach; ?> <?php if (empty($all_tasks)): ?> <tr> <td colspan="4" class="text-center text-muted">No temporary tasks found in the database.</td> </tr> <?php endif; ?> </tbody> </table> </div> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> <script> function saveRemark(tid, val) { fetch(`?ajax_update_remark=1&tid=${tid}&remark=${encodeURIComponent(val)}`) .then(r => console.log('Saved')); } function editTask(t) { document.getElementById('edit_id').value = t.id; document.getElementById('edit_name').value = t.task_name; document.getElementById('save_task_btn').textContent = "UPDATE TASK"; window.scrollTo({top: 0, behavior: 'smooth'}); } function downloadPNG() { const captureArea = document.getElementById('captureArea'); const table = captureArea.querySelector('table'); const originalAreaStyle = captureArea.getAttribute('style'); const originalTableStyle = table.getAttribute('style'); const remarkEls = Array.from(captureArea.querySelectorAll('.remark-box')); const saved = remarkEls.map(el => ({ el, placeholder: el.getAttribute('placeholder') || '', value: el.value })); remarkEls.forEach(el => el.setAttribute('placeholder', '')); if (document.activeElement && document.activeElement.blur) document.activeElement.blur(); captureArea.style.cssText = "background: #fff; padding: 10px; border: 2px solid #000; border-radius: 10px; width: 600px; margin: 0 auto;"; table.style.cssText = "width: 100%; border-collapse: collapse; border: 2px solid #000; font-size: 11px;"; html2canvas(captureArea, { scale: 3 }).then(canvas => { const link = document.createElement('a'); link.download = 'Today_Temp_Report_<?= date('d_m_Y') ?>.png'; link.href = canvas.toDataURL(); link.click(); saved.forEach(s => { if (s.placeholder) s.el.setAttribute('placeholder', s.placeholder); else s.el.removeAttribute('placeholder'); s.el.value = s.value; }); captureArea.setAttribute('style', originalAreaStyle); table.setAttribute('style', originalTableStyle); }); } </script> <?php require_once __DIR__ . '/partials/footer.php'; ?>