prepare(" SELECT * FROM projects WHERE id = ? AND client_id = ? "); $stmt->execute([$project_id, $_SESSION['client_id']]); $project = $stmt->fetch(); if (!$project) { header('Location: projects-list.php'); exit; } // If project is already Closed, no more edits if ($project['status'] === 'Closed') { header('Location: view-project.php?id=' . $project_id); exit; } $page_title = 'Edit Project'; $success = ''; $error = ''; // Get industries $industriesStmt = $pdo->query("SELECT industry_name, industry_code FROM industry_codes ORDER BY industry_name"); $industries = $industriesStmt->fetchAll(); // Handle form submission if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_project'])) { $project_name = trim($_POST['project_name'] ?? ''); $client_reference = trim($_POST['client_reference'] ?? ''); $industry = $_POST['industry'] ?? ''; $deadline_date = $_POST['deadline_date'] ?? ''; $deadline_time = $_POST['deadline_time'] ?? ''; $eloi = intval($_POST['eloi'] ?? 0); $sample_size = intval($_POST['sample_size'] ?? 0); $description = trim($_POST['description'] ?? ''); $status = $_POST['status'] ?? $project['status']; // Server-side status transition enforcement: // Created/Targeted: no manual status change allowed (system-managed) // Live/On hold: can only toggle between Live and On hold // Closed: already blocked at top of file if (in_array($project['status'], ['Created', 'Targeted'])) { $status = $project['status']; // force keep current } elseif (in_array($project['status'], ['Live', 'On hold'])) { if (!in_array($status, ['Live', 'On hold'])) { $status = $project['status']; // only Live <-> On hold allowed } } // Validation if (empty($project_name) || empty($industry) || empty($deadline_date) || empty($deadline_time)) { $error = 'Please fill in all required fields.'; } elseif ($eloi <= 0 || $sample_size <= 0) { $error = 'eLOI and Sample Size must be greater than 0.'; } elseif (strlen($client_reference) > 16) { $error = 'Client reference must be 16 characters or less.'; } else { try { // Combine deadline date and time $deadline = $deadline_date . ' ' . $deadline_time . ':00'; // made_live_at is set automatically when invitations are first sent // No need to update it on Live <-> On hold toggle $made_live_at = $project['made_live_at']; // Update project $updateStmt = $pdo->prepare(" UPDATE projects SET project_name = ?, client_reference = ?, industry = ?, deadline = ?, eloi = ?, sample_size = ?, description = ?, status = ?, made_live_at = ? WHERE id = ? AND client_id = ? "); $updateStmt->execute([ $project_name, $client_reference, $industry, $deadline, $eloi, $sample_size, $description, $status, $made_live_at, $project_id, $_SESSION['client_id'] ]); // Log activity $logStmt = $pdo->prepare(" INSERT INTO project_activity_log (project_id, client_id, action, details, ip_address) VALUES (?, ?, 'updated', ?, ?) "); $logStmt->execute([ $project_id, $_SESSION['client_id'], "Updated project: $project_name. Status: $status.", $_SERVER['REMOTE_ADDR'] ?? 'unknown' ]); $success = 'Project updated successfully!'; // Refresh project data $stmt->execute([$project_id, $_SESSION['client_id']]); $project = $stmt->fetch(); } catch (Exception $e) { error_log("Update project error: " . $e->getMessage()); $error = 'An error occurred while updating the project. Please try again.'; } } } include 'client-portal-header.php'; $currentStatus = $project['status']; ?>
Update project details for