Autosave: 20260215-013327

This commit is contained in:
Flatlogic Bot 2026-02-15 01:33:27 +00:00
parent 2c1612942a
commit 87b38e5dfa
7 changed files with 447 additions and 93 deletions

88
expense_files.php Normal file
View File

@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/db/config.php';
$tenant_id = 1;
// Fetch Expense Files
$stmt = db()->prepare("
SELECT a.*, ex.entry_date, s.name as supplier_name, p.name as project_name
FROM attachments a
JOIN expenses ex ON a.entity_id = ex.id
JOIN suppliers s ON ex.supplier_id = s.id
JOIN projects p ON ex.project_id = p.id
WHERE a.tenant_id = ? AND a.entity_type = 'expense'
ORDER BY a.created_at DESC
");
$stmt->execute([$tenant_id]);
$files = $stmt->fetchAll();
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
$pageTitle = "SR&ED Manager - Expense Files";
include __DIR__ . '/includes/header.php';
?>
<div class="container-fluid py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="fw-bold mb-0">Expense Files</h2>
</div>
<div class="card border-0 shadow-sm">
<div class="table-responsive">
<table class="table align-middle mb-0">
<thead class="bg-light">
<tr>
<th>Filename</th>
<th>Size</th>
<th>Uploaded By</th>
<th>Created At</th>
<th>Linked Entry</th>
<th class="text-end">Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($files)): ?>
<tr><td colspan="6" class="text-center py-5 text-muted">No expense files found.</td></tr>
<?php endif; ?>
<?php foreach ($files as $f): ?>
<tr>
<td>
<i class="bi bi-file-earmark-pdf me-2 text-danger"></i>
<strong><?= htmlspecialchars($f['file_name']) ?></strong>
</td>
<td><small class="text-muted"><?= formatBytes((int)$f['file_size']) ?></small></td>
<td>
<div class="d-flex align-items-center">
<div class="bg-light rounded-circle p-1 me-2" style="width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;">
<i class="bi bi-person small"></i>
</div>
<small><?= htmlspecialchars($f['uploaded_by'] ?? 'System') ?></small>
</div>
</td>
<td class="small text-muted"><?= date('M j, Y H:i', strtotime($f['created_at'])) ?></td>
<td>
<div class="small">
<span class="fw-bold text-dark"><?= $f['entry_date'] ?></span><br>
<span class="text-muted"><?= htmlspecialchars($f['supplier_name']) ?> - <?= htmlspecialchars($f['project_name']) ?></span>
</div>
</td>
<td class="text-end">
<a href="<?= htmlspecialchars($f['file_path']) ?>" target="_blank" class="btn btn-sm btn-outline-primary">View</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php include __DIR__ . '/includes/footer.php'; ?>

View File

@ -32,7 +32,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_expense'])) {
if (!is_dir('uploads')) mkdir('uploads', 0775, true);
if (move_uploaded_file($tmp_name, $file_path)) {
$stmt = db()->prepare("INSERT INTO attachments (tenant_id, entity_type, entity_id, file_name, file_path, file_size, mime_type) VALUES (?, 'expense', ?, ?, ?, ?, ?)");
$stmt = db()->prepare("INSERT INTO attachments (tenant_id, entity_type, entity_id, file_name, file_path, file_size, mime_type, uploaded_by) VALUES (?, 'expense', ?, ?, ?, ?, ?, 'John Manager')");
$stmt->execute([$tenant_id, $expense_id, $file_name, $file_path, $file_size, $mime_type]);
}
}

97
files.php Normal file
View File

@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/db/config.php';
$tenant_id = 1;
// Fetch All Files with their related context
$stmt = db()->prepare("
SELECT a.*,
CASE
WHEN a.entity_type = 'labour_entry' THEN (SELECT CONCAT(le.entry_date, ' - ', e.name, ' - ', p.name) FROM labour_entries le JOIN employees e ON le.employee_id = e.id JOIN projects p ON le.project_id = p.id WHERE le.id = a.entity_id)
WHEN a.entity_type = 'expense' THEN (SELECT CONCAT(ex.entry_date, ' - ', s.name, ' - ', p.name) FROM expenses ex JOIN suppliers s ON ex.supplier_id = s.id JOIN projects p ON ex.project_id = p.id WHERE ex.id = a.entity_id)
ELSE 'Other'
END as linked_entry_info
FROM attachments a
WHERE a.tenant_id = ?
ORDER BY a.created_at DESC
");
$stmt->execute([$tenant_id]);
$files = $stmt->fetchAll();
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
$pageTitle = "SR&ED Manager - All Files Report";
include __DIR__ . '/includes/header.php';
?>
<div class="container-fluid py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="fw-bold mb-0">System Files Report</h2>
</div>
<div class="card border-0 shadow-sm">
<div class="table-responsive">
<table class="table align-middle mb-0">
<thead class="bg-light">
<tr>
<th>Type</th>
<th>Filename</th>
<th>Size</th>
<th>Uploaded By</th>
<th>Created At</th>
<th>Linked Entry</th>
<th class="text-end">Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($files)): ?>
<tr><td colspan="7" class="text-center py-5 text-muted">No files found in the system.</td></tr>
<?php endif; ?>
<?php foreach ($files as $f): ?>
<tr>
<td>
<?php if ($f['entity_type'] === 'labour_entry'): ?>
<span class="badge bg-soft-primary text-primary border">Labour</span>
<?php elseif ($f['entity_type'] === 'expense'): ?>
<span class="badge bg-soft-success text-success border">Expense</span>
<?php else: ?>
<span class="badge bg-soft-secondary text-secondary border"><?= ucfirst($f['entity_type']) ?></span>
<?php endif; ?>
</td>
<td>
<strong><?= htmlspecialchars($f['file_name']) ?></strong>
</td>
<td><small class="text-muted"><?= formatBytes((int)$f['file_size']) ?></small></td>
<td><small><?= htmlspecialchars($f['uploaded_by'] ?? 'System') ?></small></td>
<td class="small text-muted"><?= date('M j, Y', strtotime($f['created_at'])) ?></td>
<td>
<small class="text-muted text-truncate d-inline-block" style="max-width: 300px;">
<?= htmlspecialchars($f['linked_entry_info'] ?? 'N/A') ?>
</small>
</td>
<td class="text-end">
<a href="<?= htmlspecialchars($f['file_path']) ?>" target="_blank" class="btn btn-sm btn-outline-primary">View</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<style>
.bg-soft-primary { background-color: rgba(59, 130, 246, 0.1); }
.bg-soft-success { background-color: rgba(34, 197, 94, 0.1); }
.bg-soft-secondary { background-color: rgba(107, 114, 128, 0.1); }
</style>
<?php include __DIR__ . '/includes/footer.php'; ?>

View File

@ -41,17 +41,35 @@ $currentPage = basename($_SERVER['PHP_SELF']);
<li class="nav-item">
<a class="nav-link <?= $currentPage === 'projects.php' ? 'active' : '' ?>" href="projects.php">Projects</a>
</li>
<li class="nav-item">
<a class="nav-link <?= $currentPage === 'labour.php' ? 'active' : '' ?>" href="labour.php">Labour</a>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle <?= in_array($currentPage, ['labour.php', 'labour_files.php']) ? 'active' : '' ?>" href="#" role="button" data-bs-toggle="dropdown">
Labour
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-menu-item dropdown-item" href="labour.php">Labour Tracking</a></li>
<li><a class="dropdown-menu-item dropdown-item" href="labour_files.php">Labour Files</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link <?= $currentPage === 'expenses.php' ? 'active' : '' ?>" href="expenses.php">Expenses</a>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle <?= in_array($currentPage, ['expenses.php', 'expense_files.php']) ? 'active' : '' ?>" href="#" role="button" data-bs-toggle="dropdown">
Expenses
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-menu-item dropdown-item" href="expenses.php">Expense Logs</a></li>
<li><a class="dropdown-menu-item dropdown-item" href="expense_files.php">Expense Files</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link <?= $currentPage === 'employees.php' ? 'active' : '' ?>" href="employees.php">Employees</a>
</li>
<li class="nav-item">
<a class="nav-link <?= $currentPage === 'reports.php' ? 'active' : '' ?>" href="reports.php">Reports</a>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle <?= in_array($currentPage, ['reports.php', 'files.php']) ? 'active' : '' ?>" href="#" role="button" data-bs-toggle="dropdown">
Reports
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-menu-item dropdown-item" href="reports.php">Summary Reports</a></li>
<li><a class="dropdown-menu-item dropdown-item" href="files.php">Files</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link <?= $currentPage === 'settings.php' ? 'active' : '' ?>" href="settings.php">Settings</a>

View File

@ -32,7 +32,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_labour'])) {
if (!is_dir('uploads')) mkdir('uploads', 0775, true);
if (move_uploaded_file($tmp_name, $file_path)) {
$stmt = db()->prepare("INSERT INTO attachments (tenant_id, entity_type, entity_id, file_name, file_path, file_size, mime_type) VALUES (?, 'labour_entry', ?, ?, ?, ?, ?)");
$stmt = db()->prepare("INSERT INTO attachments (tenant_id, entity_type, entity_id, file_name, file_path, file_size, mime_type, uploaded_by) VALUES (?, 'labour_entry', ?, ?, ?, ?, ?, 'John Manager')");
$stmt->execute([$tenant_id, $labour_entry_id, $file_name, $file_path, $file_size, $mime_type]);
}
}

88
labour_files.php Normal file
View File

@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/db/config.php';
$tenant_id = 1;
// Fetch Labour Files
$stmt = db()->prepare("
SELECT a.*, le.entry_date, e.name as employee_name, p.name as project_name
FROM attachments a
JOIN labour_entries le ON a.entity_id = le.id
JOIN employees e ON le.employee_id = e.id
JOIN projects p ON le.project_id = p.id
WHERE a.tenant_id = ? AND a.entity_type = 'labour_entry'
ORDER BY a.created_at DESC
");
$stmt->execute([$tenant_id]);
$files = $stmt->fetchAll();
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
$pageTitle = "SR&ED Manager - Labour Files";
include __DIR__ . '/includes/header.php';
?>
<div class="container-fluid py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="fw-bold mb-0">Labour Files</h2>
</div>
<div class="card border-0 shadow-sm">
<div class="table-responsive">
<table class="table align-middle mb-0">
<thead class="bg-light">
<tr>
<th>Filename</th>
<th>Size</th>
<th>Uploaded By</th>
<th>Created At</th>
<th>Linked Entry</th>
<th class="text-end">Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($files)): ?>
<tr><td colspan="6" class="text-center py-5 text-muted">No labour files found.</td></tr>
<?php endif; ?>
<?php foreach ($files as $f): ?>
<tr>
<td>
<i class="bi bi-file-earmark-text me-2 text-primary"></i>
<strong><?= htmlspecialchars($f['file_name']) ?></strong>
</td>
<td><small class="text-muted"><?= formatBytes((int)$f['file_size']) ?></small></td>
<td>
<div class="d-flex align-items-center">
<div class="bg-light rounded-circle p-1 me-2" style="width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;">
<i class="bi bi-person small"></i>
</div>
<small><?= htmlspecialchars($f['uploaded_by'] ?? 'System') ?></small>
</div>
</td>
<td class="small text-muted"><?= date('M j, Y H:i', strtotime($f['created_at'])) ?></td>
<td>
<div class="small">
<span class="fw-bold text-dark"><?= $f['entry_date'] ?></span><br>
<span class="text-muted"><?= htmlspecialchars($f['employee_name']) ?> - <?= htmlspecialchars($f['project_name']) ?></span>
</div>
</td>
<td class="text-end">
<a href="<?= htmlspecialchars($f['file_path']) ?>" target="_blank" class="btn btn-sm btn-outline-primary">View</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php include __DIR__ . '/includes/footer.php'; ?>

View File

@ -10,28 +10,83 @@ $tenant_id = 1;
// Handle Form Submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
$id = (int)($_POST['id'] ?? 0);
$name = $_POST['name'] ?? '';
$error = '';
if ($action === 'add_labour_type' && $name) {
$stmt = db()->prepare("INSERT INTO labour_types (tenant_id, name) VALUES (?, ?)");
$stmt->execute([$tenant_id, $name]);
} elseif ($action === 'add_evidence_type' && $name) {
} elseif ($action === 'edit_labour_type' && $id && $name) {
$stmt = db()->prepare("UPDATE labour_types SET name = ? WHERE id = ? AND tenant_id = ?");
$stmt->execute([$name, $id, $tenant_id]);
} elseif ($action === 'delete_labour_type' && $id) {
$check = db()->prepare("SELECT COUNT(*) FROM labour_entries WHERE labour_type_id = ? AND tenant_id = ?");
$check->execute([$id, $tenant_id]);
if ($check->fetchColumn() > 0) {
$error = "Cannot delete: Labour type is used in labour entries.";
} else {
$stmt = db()->prepare("DELETE FROM labour_types WHERE id = ? AND tenant_id = ?");
$stmt->execute([$id, $tenant_id]);
}
}
elseif ($action === 'add_evidence_type' && $name) {
$stmt = db()->prepare("INSERT INTO evidence_types (tenant_id, name) VALUES (?, ?)");
$stmt->execute([$tenant_id, $name]);
} elseif ($action === 'add_expense_type' && $name) {
$stmt = db()->prepare("INSERT INTO expense_types (tenant_id, name) VALUES (?, ?)");
$stmt->execute([$tenant_id, $name]);
} elseif ($action === 'add_team' && $name) {
$stmt = db()->prepare("INSERT INTO teams (tenant_id, name) VALUES (?, ?)");
$stmt->execute([$tenant_id, $name]);
} elseif ($action === 'add_supplier' && $name) {
$type = $_POST['type'] ?? 'supplier';
$contact = $_POST['contact_info'] ?? '';
$stmt = db()->prepare("INSERT INTO suppliers (tenant_id, name, type, contact_info) VALUES (?, ?, ?, ?)");
$stmt->execute([$tenant_id, $name, $type, $contact]);
} elseif ($action === 'edit_evidence_type' && $id && $name) {
$stmt = db()->prepare("UPDATE evidence_types SET name = ? WHERE id = ? AND tenant_id = ?");
$stmt->execute([$name, $id, $tenant_id]);
} elseif ($action === 'delete_evidence_type' && $id) {
$check = db()->prepare("SELECT COUNT(*) FROM labour_entries WHERE evidence_type_id = ? AND tenant_id = ?");
$check->execute([$id, $tenant_id]);
if ($check->fetchColumn() > 0) {
$error = "Cannot delete: Evidence type is used in labour entries.";
} else {
$stmt = db()->prepare("DELETE FROM evidence_types WHERE id = ? AND tenant_id = ?");
$stmt->execute([$id, $tenant_id]);
}
}
header("Location: settings.php?success=1");
elseif ($action === 'add_expense_type' && $name) {
$stmt = db()->prepare("INSERT INTO expense_types (tenant_id, name) VALUES (?, ?)");
$stmt->execute([$tenant_id, $name]);
} elseif ($action === 'edit_expense_type' && $id && $name) {
$stmt = db()->prepare("UPDATE expense_types SET name = ? WHERE id = ? AND tenant_id = ?");
$stmt->execute([$name, $id, $tenant_id]);
} elseif ($action === 'delete_expense_type' && $id) {
$check = db()->prepare("SELECT COUNT(*) FROM expenses WHERE expense_type_id = ? AND tenant_id = ?");
$check->execute([$id, $tenant_id]);
if ($check->fetchColumn() > 0) {
$error = "Cannot delete: Expense type is used in expense logs.";
} else {
$stmt = db()->prepare("DELETE FROM expense_types WHERE id = ? AND tenant_id = ?");
$stmt->execute([$id, $tenant_id]);
}
}
elseif ($action === 'add_team' && $name) {
$stmt = db()->prepare("INSERT INTO teams (tenant_id, name) VALUES (?, ?)");
$stmt->execute([$tenant_id, $name]);
} elseif ($action === 'edit_team' && $id && $name) {
$stmt = db()->prepare("UPDATE teams SET name = ? WHERE id = ? AND tenant_id = ?");
$stmt->execute([$name, $id, $tenant_id]);
} elseif ($action === 'delete_team' && $id) {
$check = db()->prepare("SELECT COUNT(*) FROM employee_teams WHERE team_id = ? AND tenant_id = ?");
$check->execute([$id, $tenant_id]);
if ($check->fetchColumn() > 0) {
$error = "Cannot delete: Team has assigned employees.";
} else {
$stmt = db()->prepare("DELETE FROM teams WHERE id = ? AND tenant_id = ?");
$stmt->execute([$id, $tenant_id]);
}
}
if ($error) {
header("Location: settings.php?error=" . urlencode($error));
} else {
header("Location: settings.php?success=1");
}
exit;
}
@ -52,10 +107,6 @@ $teams = db()->prepare("SELECT * FROM teams WHERE tenant_id = ? ORDER BY name");
$teams->execute([$tenant_id]);
$teamList = $teams->fetchAll();
$suppliers = db()->prepare("SELECT * FROM suppliers WHERE tenant_id = ? ORDER BY name");
$suppliers->execute([$tenant_id]);
$supplierList = $suppliers->fetchAll();
$pageTitle = "SR&ED Manager - Settings";
include __DIR__ . '/includes/header.php';
?>
@ -65,9 +116,14 @@ include __DIR__ . '/includes/header.php';
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h4 class="fw-bold mb-0">System Settings & Datasets</h4>
<?php if (isset($_GET['success'])): ?>
<span class="badge bg-success">Dataset updated successfully</span>
<?php endif; ?>
<div class="d-flex gap-2">
<?php if (isset($_GET['success'])): ?>
<span class="badge bg-success py-2 px-3">Dataset updated successfully</span>
<?php endif; ?>
<?php if (isset($_GET['error'])): ?>
<span class="badge bg-danger py-2 px-3"><?= htmlspecialchars($_GET['error']) ?></span>
<?php endif; ?>
</div>
</div>
<div class="row">
@ -80,10 +136,16 @@ include __DIR__ . '/includes/header.php';
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead><tr><th>Name</th></tr></thead>
<thead><tr><th>Name</th><th class="text-end">Actions</th></tr></thead>
<tbody>
<?php foreach ($labourTypeList as $item): ?>
<tr><td><?= htmlspecialchars($item['name']) ?></td></tr>
<tr>
<td><?= htmlspecialchars($item['name']) ?></td>
<td class="text-end">
<button class="btn btn-sm btn-link text-primary p-0 me-2" onclick="editItem('edit_labour_type', <?= $item['id'] ?>, '<?= addslashes($item['name']) ?>')">Edit</button>
<button class="btn btn-sm btn-link text-danger p-0" onclick="deleteItem('delete_labour_type', <?= $item['id'] ?>)">Delete</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
@ -100,10 +162,16 @@ include __DIR__ . '/includes/header.php';
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead><tr><th>Name</th></tr></thead>
<thead><tr><th>Name</th><th class="text-end">Actions</th></tr></thead>
<tbody>
<?php foreach ($evidenceTypeList as $item): ?>
<tr><td><?= htmlspecialchars($item['name']) ?></td></tr>
<tr>
<td><?= htmlspecialchars($item['name']) ?></td>
<td class="text-end">
<button class="btn btn-sm btn-link text-primary p-0 me-2" onclick="editItem('edit_evidence_type', <?= $item['id'] ?>, '<?= addslashes($item['name']) ?>')">Edit</button>
<button class="btn btn-sm btn-link text-danger p-0" onclick="deleteItem('delete_evidence_type', <?= $item['id'] ?>)">Delete</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
@ -120,10 +188,16 @@ include __DIR__ . '/includes/header.php';
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead><tr><th>Name</th></tr></thead>
<thead><tr><th>Name</th><th class="text-end">Actions</th></tr></thead>
<tbody>
<?php foreach ($expenseTypeList as $item): ?>
<tr><td><?= htmlspecialchars($item['name']) ?></td></tr>
<tr>
<td><?= htmlspecialchars($item['name']) ?></td>
<td class="text-end">
<button class="btn btn-sm btn-link text-primary p-0 me-2" onclick="editItem('edit_expense_type', <?= $item['id'] ?>, '<?= addslashes($item['name']) ?>')">Edit</button>
<button class="btn btn-sm btn-link text-danger p-0" onclick="deleteItem('delete_expense_type', <?= $item['id'] ?>)">Delete</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
@ -140,39 +214,15 @@ include __DIR__ . '/includes/header.php';
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead><tr><th>Name</th></tr></thead>
<thead><tr><th>Name</th><th class="text-end">Actions</th></tr></thead>
<tbody>
<?php foreach ($teamList as $item): ?>
<tr><td><?= htmlspecialchars($item['name']) ?></td></tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Suppliers -->
<div class="col-12 mb-4">
<div class="card border-0 shadow-sm">
<div class="card-header bg-white d-flex justify-content-between align-items-center">
<span class="fw-bold">Suppliers & Contractors</span>
<button class="btn btn-sm btn-outline-primary" data-bs-toggle="modal" data-bs-target="#addSupplierModal">+ Add</button>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Contact Info</th>
</tr>
</thead>
<tbody>
<?php foreach ($supplierList as $item): ?>
<tr>
<td><strong><?= htmlspecialchars($item['name']) ?></strong></td>
<td><span class="badge bg-light text-dark border"><?= ucfirst($item['type']) ?></span></td>
<td><small class="text-muted"><?= htmlspecialchars($item['contact_info'] ?? '') ?></small></td>
<td><?= htmlspecialchars($item['name']) ?></td>
<td class="text-end">
<button class="btn btn-sm btn-link text-primary p-0 me-2" onclick="editItem('edit_team', <?= $item['id'] ?>, '<?= addslashes($item['name']) ?>')">Edit</button>
<button class="btn btn-sm btn-link text-danger p-0" onclick="deleteItem('delete_team', <?= $item['id'] ?>)">Delete</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
@ -185,6 +235,48 @@ include __DIR__ . '/includes/header.php';
</div>
</div>
<div class="modal fade" id="editItemModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow">
<div class="modal-header"><h5 class="modal-title fw-bold" id="editItemTitle">Edit Item</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<form method="POST">
<div class="modal-body">
<input type="hidden" name="action" id="editItemAction">
<input type="hidden" name="id" id="editItemId">
<div class="mb-3">
<label class="form-label small fw-bold">Name</label>
<input type="text" name="name" id="editItemName" class="form-control" required>
</div>
</div>
<div class="modal-footer border-0"><button type="submit" class="btn btn-primary px-4">Save Changes</button></div>
</form>
</div>
</div>
</div>
<form id="deleteForm" method="POST" style="display:none;">
<input type="hidden" name="action" id="deleteAction">
<input type="hidden" name="id" id="deleteId">
</form>
<script>
function editItem(action, id, name) {
document.getElementById('editItemAction').value = action;
document.getElementById('editItemId').value = id;
document.getElementById('editItemName').value = name;
document.getElementById('editItemTitle').innerText = 'Edit ' + action.replace('edit_', '').replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase());
new bootstrap.Modal(document.getElementById('editItemModal')).show();
}
function deleteItem(action, id) {
if (confirm('Are you sure you want to delete this item? This action cannot be undone.')) {
document.getElementById('deleteAction').value = action;
document.getElementById('deleteId').value = id;
document.getElementById('deleteForm').submit();
}
}
</script>
<!-- Modals -->
<?php
$modals = [
@ -214,33 +306,4 @@ foreach ($modals as $m):
</div>
<?php endforeach; ?>
<div class="modal fade" id="addSupplierModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow">
<div class="modal-header"><h5 class="modal-title fw-bold">Add Supplier/Contractor</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<form method="POST">
<div class="modal-body">
<input type="hidden" name="action" value="add_supplier">
<div class="mb-3">
<label class="form-label small fw-bold">Name</label>
<input type="text" name="name" class="form-control" placeholder="Company name" required>
</div>
<div class="mb-3">
<label class="form-label small fw-bold">Type</label>
<select name="type" class="form-select">
<option value="supplier">Supplier</option>
<option value="contractor">Contractor</option>
</select>
</div>
<div class="mb-3">
<label class="form-label small fw-bold">Contact Info</label>
<textarea name="contact_info" class="form-control" rows="2" placeholder="Address, Phone, Email..."></textarea>
</div>
</div>
<div class="modal-footer border-0"><button type="submit" class="btn btn-primary px-4">Add Supplier</button></div>
</form>
</div>
</div>
</div>
<?php include __DIR__ . '/includes/footer.php'; ?>