diff --git a/create-job.php b/create-job.php
new file mode 100644
index 0000000..3c6661b
--- /dev/null
+++ b/create-job.php
@@ -0,0 +1,132 @@
+prepare("SELECT id, name FROM clients WHERE company_id = ? AND is_active = 1 ORDER BY name ASC");
+$stmt->execute([$companyId]);
+$clients = $stmt->fetchAll();
+
+// Fetch statuses for selection
+$stmt = db()->prepare("SELECT id, name, is_default FROM job_statuses WHERE company_id = ? ORDER BY sort_order ASC");
+$stmt->execute([$companyId]);
+$statuses = $stmt->fetchAll();
+
+// Fetch company settings
+$stmt = db()->prepare("SELECT uprn_required FROM companies WHERE id = ?");
+$stmt->execute([$companyId]);
+$company = $stmt->fetch();
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ $clientId = $_POST['client_id'] ?? '';
+ $statusId = $_POST['status_id'] ?? '';
+ $uprn = $_POST['uprn'] ?? '';
+ $address = $_POST['address'] ?? '';
+ $description = $_POST['description'] ?? '';
+
+ if (empty($clientId) || empty($statusId) || empty($address)) {
+ $error = 'Please fill in all required fields.';
+ } elseif ($company['uprn_required'] && empty($uprn)) {
+ $error = 'UPRN is required for this company.';
+ } else {
+ try {
+ db()->beginTransaction();
+
+ // 1. Insert Job
+ $stmt = db()->prepare("
+ INSERT INTO jobs (company_id, client_id, status_id, uprn, address, description)
+ VALUES (?, ?, ?, ?, ?, ?)
+ ");
+ $stmt->execute([$companyId, $clientId, $statusId, $uprn, $address, $description]);
+ $jobId = db()->lastInsertId();
+
+ // 2. Add Mandatory Folders
+ $stmt = db()->prepare("SELECT name FROM required_folders WHERE company_id = ?");
+ $stmt->execute([$companyId]);
+ $reqFolders = $stmt->fetchAll();
+
+ $folderStmt = db()->prepare("INSERT INTO job_folders (job_id, name, is_required) VALUES (?, ?, ?)");
+ foreach ($reqFolders as $rf) {
+ $folderStmt->execute([$jobId, $rf['name'], 1]);
+ }
+
+ // 3. Log activity
+ $logStmt = db()->prepare("INSERT INTO job_logs (job_id, user_id, action, details) VALUES (?, ?, ?, ?)");
+ $logStmt->execute([$jobId, $user['id'], 'created', 'Job created manually by user.']);
+
+ db()->commit();
+ header('Location: dashboard.php');
+ exit;
+ } catch (Exception $e) {
+ db()->rollBack();
+ $error = "Database error: " . $e->getMessage();
+ }
+ }
+}
+
+$pageTitle = "Create New Job";
+require_once __DIR__ . '/includes/header.php';
+?>
+
+
+
+
+
+
+
+
= htmlspecialchars($error) ?>
+
+
+
+
+
+
+
+
+
diff --git a/dashboard.php b/dashboard.php
new file mode 100644
index 0000000..e096e46
--- /dev/null
+++ b/dashboard.php
@@ -0,0 +1,82 @@
+prepare("
+ SELECT j.*, c.name as client_name, s.name as status_name
+ FROM jobs j
+ JOIN clients c ON j.client_id = c.id
+ JOIN job_statuses s ON j.status_id = s.id
+ WHERE j.company_id = ?
+ ORDER BY j.created_at DESC
+");
+$stmt->execute([$companyId]);
+$jobs = $stmt->fetchAll();
+
+require_once __DIR__ . '/includes/header.php';
+?>
+
+
+
Jobs Overview
+
+ Create New Job
+
+
+
+
+
+
+
+
+
No jobs found
+
Get started by creating your first repair job.
+
+
+
+
+
+
+
+
+ | Job ID |
+ Client |
+ Address |
+ Status |
+ UPRN |
+ Created |
+ Actions |
+
+
+
+
+
+ | #= $job['id'] ?> |
+ = htmlspecialchars($job['client_name']) ?> |
+ = htmlspecialchars($job['address']) ?> |
+
+ = htmlspecialchars($job['status_name']) ?>
+ |
+ = htmlspecialchars($job['uprn'] ?? 'N/A') ?> |
+ = date('d M Y', strtotime($job['created_at'])) ?> |
+
+ View Details
+ |
+
+
+
+
+
+
+
+
+
diff --git a/db/init.sql b/db/init.sql
index 50405f2..cf71c7b 100644
--- a/db/init.sql
+++ b/db/init.sql
@@ -56,4 +56,58 @@ CREATE TABLE IF NOT EXISTS clients (
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
UNIQUE KEY (company_id, name) -- Ensure client names are unique per company
-);
\ No newline at end of file
+);
+
+-- Jobs Table: Core entity for the application.
+CREATE TABLE IF NOT EXISTS jobs (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ company_id INT NOT NULL,
+ client_id INT NOT NULL,
+ status_id INT NOT NULL,
+ uprn VARCHAR(255) DEFAULT NULL, -- Unique Property Reference Number
+ address TEXT NOT NULL,
+ description TEXT,
+ works_approved BOOLEAN DEFAULT FALSE,
+ is_completed BOOLEAN DEFAULT FALSE,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE,
+ FOREIGN KEY (client_id) REFERENCES clients(id),
+ FOREIGN KEY (status_id) REFERENCES job_statuses(id)
+);
+
+-- Job Folders Table: Mandatory and custom folders for each job.
+CREATE TABLE IF NOT EXISTS job_folders (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ job_id INT NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ is_required BOOLEAN DEFAULT FALSE, -- If true, it's a company-wide mandatory folder.
+ is_completed BOOLEAN DEFAULT FALSE,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE
+);
+
+-- Job Files Table: Files uploaded to job folders.
+CREATE TABLE IF NOT EXISTS job_files (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ folder_id INT NOT NULL,
+ user_id INT NOT NULL,
+ filename VARCHAR(255) NOT NULL,
+ file_path VARCHAR(255) NOT NULL,
+ file_size INT NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (folder_id) REFERENCES job_folders(id) ON DELETE CASCADE,
+ FOREIGN KEY (user_id) REFERENCES users(id)
+);
+
+-- Job Logs Table: Server-side logging for all job activities.
+CREATE TABLE IF NOT EXISTS job_logs (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ job_id INT NOT NULL,
+ user_id INT NOT NULL,
+ action VARCHAR(255) NOT NULL, -- e.g., 'created', 'status_updated', 'file_uploaded'
+ details TEXT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE,
+ FOREIGN KEY (user_id) REFERENCES users(id)
+);
diff --git a/includes/auth.php b/includes/auth.php
new file mode 100644
index 0000000..e8b9360
--- /dev/null
+++ b/includes/auth.php
@@ -0,0 +1,35 @@
+prepare("SELECT u.*, c.name as company_name FROM users u JOIN companies c ON u.company_id = c.id WHERE u.id = ?");
+ $stmt->execute([$_SESSION['user_id']]);
+ $user = $stmt->fetch();
+ }
+ return $user;
+}
+
+function logout(): void {
+ session_destroy();
+ header('Location: login.php');
+ exit;
+}
diff --git a/includes/footer.php b/includes/footer.php
new file mode 100644
index 0000000..05471db
--- /dev/null
+++ b/includes/footer.php
@@ -0,0 +1,8 @@
+
+
+
+
+