diff --git a/export_pdf.php b/export_pdf.php
new file mode 100644
index 0000000..a79f406
--- /dev/null
+++ b/export_pdf.php
@@ -0,0 +1,264 @@
+prepare($query);
+ $stmt->execute($params);
+ $results = $stmt->fetchAll();
+}
+
+// Handle Calendar Report
+$calendarData = [];
+$cal_month = $_GET['month'] ?? date('Y-m');
+if ($report_type === 'calendar') {
+ $stmt = db()->prepare("
+ SELECT entry_date, SUM(hours) as total_hours
+ FROM labour_entries
+ WHERE tenant_id = ? AND DATE_FORMAT(entry_date, '%Y-%m') = ?
+ GROUP BY entry_date
+ ");
+ $stmt->execute([$tenant_id, $cal_month]);
+ $calendarData = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
+}
+
+// Fetch filter names for header (Labour Export only)
+$employee_name = 'All Employees';
+if ($report_type === 'labour_export') {
+ if ($f_employee) {
+ $stmt = db()->prepare("SELECT name FROM employees WHERE id = ?");
+ $stmt->execute([$f_employee]);
+ $employee_name = $stmt->fetchColumn() ?: 'All Employees';
+ }
+
+ $project_names = 'All Projects';
+ if (!empty($f_projects)) {
+ $placeholders = implode(',', array_fill(0, count($f_projects), '?'));
+ $stmt = db()->prepare("SELECT name FROM projects WHERE id IN ($placeholders)");
+ $stmt->execute($f_projects);
+ $p_list = $stmt->fetchAll(PDO::FETCH_COLUMN);
+ $project_names = implode(', ', $p_list);
+ }
+}
+
+// Generate HTML
+$html = '
+
+
+
+
+
+
+
+ ';
+
+if ($report_type === 'labour_export') {
+ $html .= '
+
+
+
+ | Period: |
+ ' . date('M j, Y', strtotime($f_start)) . ' to ' . date('M j, Y', strtotime($f_end)) . ' |
+ Employee: |
+ ' . htmlspecialchars($employee_name) . ' |
+
+
+ | Projects: |
+ ' . htmlspecialchars($project_names) . ' |
+
+
+
+
+
+
+
+ | Date |
+ Employee |
+ Project |
+ Activity |
+ Hours |
+
+
+ ';
+
+ $total_hours = 0;
+ foreach ($results as $row) {
+ $total_hours += (float)$row['hours'];
+ $html .= '
+
+ | ' . $row['entry_date'] . ' |
+ ' . htmlspecialchars($row['employee_name']) . ' |
+ ' . htmlspecialchars($row['project_name']) . ' |
+ ' . htmlspecialchars($row['labour_type'] ?? 'Uncategorized') . ' |
+ ' . number_format((float)$row['hours'], 2) . ' |
+
';
+ }
+
+ if (empty($results)) {
+ $html .= '| No records found. |
';
+ }
+
+ $html .= '
+
+
+
+ | Total Hours: |
+ ' . number_format($total_hours, 2) . ' |
+
+
+
';
+} else {
+ // Calendar View
+ $html .= '
+
+ ' . date('F Y', strtotime($cal_month)) . '
+
+
+
+
+
+ | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
+
+
+ ';
+
+ $first_day = date('Y-m-01', strtotime($cal_month));
+ $days_in_month = (int)date('t', strtotime($cal_month));
+ $start_day_of_week = (int)date('w', strtotime($first_day));
+
+ $cal_day_count = 0;
+ $html .= '';
+ // Fill empty days before first of month
+ for ($i = 0; $i < $start_day_of_week; $i++) {
+ $html .= ' | ';
+ $cal_day_count++;
+ }
+
+ // Days of month
+ for ($day = 1; $day <= $days_in_month; $day++) {
+ if ($cal_day_count > 0 && ($cal_day_count % 7) == 0) {
+ $html .= '
';
+ }
+
+ $current_date = date('Y-m-', strtotime($cal_month)) . str_pad((string)$day, 2, '0', STR_PAD_LEFT);
+ $hours = $calendarData[$current_date] ?? 0;
+
+ $html .= '| ';
+ $html .= '' . $day . '';
+ if ($hours > 0) {
+ $html .= '' . number_format((float)$hours, 1) . 'h';
+ }
+ $html .= ' | ';
+ $cal_day_count++;
+ }
+
+ // Fill remaining days to complete grid
+ while ($cal_day_count % 7 != 0) {
+ $html .= ' | ';
+ $cal_day_count++;
+ }
+ $html .= '
';
+
+ $html .= '
+
+
';
+}
+
+$html .= '
+
+
+';
+
+// Setup Dompdf
+$options = new Options();
+$options->set('isHtml5ParserEnabled', true);
+$options->set('isRemoteEnabled', true);
+
+$dompdf = new Dompdf($options);
+$dompdf->loadHtml($html);
+$dompdf->setPaper('A4', 'portrait');
+$dompdf->render();
+
+// Output the PDF
+$prefix = $report_type === 'calendar' ? 'Monthly_Calendar_' : 'Labour_Report_';
+$filename = $prefix . date('Ymd_His') . '.pdf';
+$dompdf->stream($filename, ['Attachment' => true]);
diff --git a/reports.php b/reports.php
index 2d77d2f..9230dcd 100644
--- a/reports.php
+++ b/reports.php
@@ -229,7 +229,10 @@ $labourTypeList = $labourTypes->fetchAll();
@@ -309,8 +312,12 @@ $labourTypeList = $labourTypes->fetchAll();
-