37762-vm/setup.php
Flatlogic Bot 55c4d7eddb Next steps
2026-01-23 20:06:08 +00:00

277 lines
14 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/db/config.php';
session_start();
$error = '';
$success = '';
$step = $_GET['step'] ?? 1;
$companyId = $_SESSION['company_id'] ?? null;
// Redirect to index if setup is complete and companyId is not in session
if ($step > 1 && !$companyId) {
header('Location: index.php');
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($step == 1) {
$companyName = $_POST['company_name'] ?? '';
$uprnRequired = isset($_POST['uprn_required']) ? 1 : 0;
$statuses = $_POST['statuses'] ?? [];
$folders = $_POST['folders'] ?? [];
$defaultStatusIndex = (int)($_POST['default_status'] ?? 0);
if (empty($companyName)) {
$error = "Company name is required.";
} elseif (empty(array_filter($statuses, 'trim'))) {
$error = "At least one job status is required.";
} elseif (empty(array_filter($folders, 'trim'))) {
$error = "At least one required folder is required.";
} else {
try {
db()->beginTransaction();
// 1. Create Company
$stmt = db()->prepare("INSERT INTO companies (name, uprn_required) VALUES (?, ?)");
$stmt->execute([$companyName, $uprnRequired]);
$companyId = db()->lastInsertId();
$_SESSION['company_id'] = $companyId; // Store company ID in session for next steps
// 2. Insert Statuses
$stmt = db()->prepare("INSERT INTO job_statuses (company_id, name, is_default, sort_order) VALUES (?, ?, ?, ?)");
foreach ($statuses as $index => $statusName) {
$statusName = trim($statusName);
if ($statusName === '') continue;
$isDefault = ($index === $defaultStatusIndex) ? 1 : 0;
$stmt->execute([$companyId, $statusName, $isDefault, $index]);
}
// 3. Insert Folders
$stmt = db()->prepare("INSERT INTO required_folders (company_id, name) VALUES (?, ?)");
foreach ($folders as $folderName) {
$folderName = trim($folderName);
if ($folderName === '') continue;
$stmt->execute([$companyId, $folderName]);
}
// 4. Create first Admin user (simplified for demo)
$adminEmail = 'admin@' . strtolower(str_replace(' ', '', $companyName)) . '.com';
$stmt = db()->prepare("INSERT INTO users (company_id, name, email, password, role) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$companyId, 'Admin User', $adminEmail, password_hash('password123', PASSWORD_DEFAULT), 'admin']);
db()->commit();
header('Location: setup.php?step=2'); // Redirect to next step
exit;
} catch (Exception $e) {
db()->rollBack();
$error = "Database error: " . $e->getMessage();
}
}
} elseif ($step == 2) {
// Step 2: Client Setup
$clientNames = $_POST['client_names'] ?? [];
$contactPeople = $_POST['contact_people'] ?? [];
$clientEmails = $_POST['client_emails'] ?? [];
$clientPhones = $_POST['client_phones'] ?? [];
if (empty(array_filter($clientNames, 'trim'))) {
$error = "At least one client is required.";
} else {
try {
db()->beginTransaction();
$stmt = db()->prepare("INSERT INTO clients (company_id, name, contact_person, email, phone) VALUES (?, ?, ?, ?, ?)");
foreach ($clientNames as $index => $clientName) {
$clientName = trim($clientName);
if ($clientName === '') continue;
$contactPerson = trim($contactPeople[$index] ?? '');
$clientEmail = trim($clientEmails[$index] ?? '');
$clientPhone = trim($clientPhones[$index] ?? '');
$stmt->execute([$companyId, $clientName, $contactPerson, $clientEmail, $clientPhone]);
}
db()->commit();
session_destroy(); // Clear session after successful setup
$success = "Company setup successfully! You can now log in.";
header('Refresh: 2; URL=index.php'); // Redirect to index
exit;
} catch (Exception $e) {
db()->rollBack();
$error = "Database error: " . $e->getMessage();
}
}
}
}
$pageTitle = "Company Onboarding";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $pageTitle ?> - RepairsPro</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time() ?>">
<style>
.setup-container { max-width: 800px; margin: 50px auto; }
.dynamic-row { display: flex; gap: 10px; margin-bottom: 10px; align-items: center; }
.client-input-group { display: flex; gap: 10px; flex-wrap: wrap; }
</style>
</head>
<body>
<div class="container">
<div class="setup-container">
<div class="card p-4">
<h2 class="fw-bold mb-4">Company Onboarding - Step <?= $step ?></h2>
<?php if ($error): ?>
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success"><?= htmlspecialchars($success) ?></div>
<?php else: // Display forms if not success ?>
<?php if ($step == 1): // Step 1: Company Info, Statuses, Folders ?>
<form method="POST" id="onboardingFormStep1">
<div class="mb-4">
<label class="form-label fw-bold">Company Name</label>
<input type="text" name="company_name" class="form-control" placeholder="e.g. London Repairs Ltd" required>
</div>
<div class="mb-4">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" name="uprn_required" id="uprnCheck">
<label class="form-check-label fw-bold" for="uprnCheck">Require Job UPRN?</label>
</div>
<small class="text-secondary">If enabled, every job must have a unique UPRN.</small>
</div>
<hr>
<div class="mb-4">
<label class="form-label fw-bold">Job Statuses</label>
<p class="small text-secondary">Define the workflow stages for your jobs.</p>
<div id="status-container">
<div class="dynamic-row">
<input type="radio" name="default_status" value="0" checked title="Set as default">
<input type="text" name="statuses[]" class="form-control" value="To Be Surveyed" required>
</div>
<div class="dynamic-row">
<input type="radio" name="default_status" value="1" title="Set as default">
<input type="text" name="statuses[]" class="form-control" value="Booking Required">
<button type="button" class="btn btn-sm btn-outline-danger remove-btn">&times;</button>
</div>
</div>
<button type="button" class="btn btn-sm btn-outline-primary mt-2" onclick="addRow('status-container', 'statuses[]', true)">+ Add Status</button>
</div>
<hr>
<div class="mb-4">
<label class="form-label fw-bold">Required Folders</label>
<p class="small text-secondary">These folders will appear on every job automatically.</p>
<div id="folder-container">
<div class="dynamic-row">
<input type="text" name="folders[]" class="form-control" value="Photos" required>
</div>
<div class="dynamic-row">
<input type="text" name="folders[]" class="form-control" value="Quote">
<button type="button" class="btn btn-sm btn-outline-danger remove-btn">&times;</button>
</div>
</div>
<button type="button" class="btn btn-sm btn-outline-primary mt-2" onclick="addRow('folder-container', 'folders[]', false)">+ Add Folder</button>
</div>
<div class="d-grid gap-2 mt-5">
<button type="submit" class="btn btn-primary btn-lg">Next: Setup Clients</button>
</div>
</form>
<?php elseif ($step == 2): // Step 2: Client Setup ?>
<form method="POST" id="onboardingFormStep2">
<p class="small text-secondary">Add your initial clients. You can add more later.</p>
<div id="client-container">
<div class="dynamic-row client-input-group">
<input type="text" name="client_names[]" class="form-control flex-grow-1" placeholder="Client Name" required>
<input type="text" name="contact_people[]" class="form-control" placeholder="Contact Person">
<input type="email" name="client_emails[]" class="form-control" placeholder="Email">
<input type="text" name="client_phones[]" class="form-control" placeholder="Phone">
<button type="button" class="btn btn-sm btn-outline-danger remove-btn">&times;</button>
</div>
</div>
<button type="button" class="btn btn-sm btn-outline-primary mt-2" onclick="addClientRow()">+ Add Client</button>
<div class="d-grid gap-2 mt-5">
<button type="submit" class="btn btn-success btn-lg">Complete Onboarding</button>
</div>
</form>
<?php endif; ?>
<?php endif; // End of forms ?>
</div>
</div>
</div>
<script>
function addRow(containerId, name, hasRadio) {
const container = document.getElementById(containerId);
const count = container.children.length;
const div = document.createElement('div');
div.className = 'dynamic-row';
let html = '';
if (hasRadio) {
html += `<input type="radio" name="default_status" value="${count}">`;
}
html += `<input type="text" name="${name}" class="form-control" required>`;
html += `<button type="button" class="btn btn-sm btn-outline-danger remove-btn">&times;</button>`;
div.innerHTML = html;
container.appendChild(div);
div.querySelector('.remove-btn').onclick = function() {
div.remove();
// Re-index radios if necessary
if (hasRadio) {
Array.from(container.children).forEach((row, idx) => {
const radio = row.querySelector('input[type="radio"]');
if (radio) radio.value = idx;
});
}
};
}
function addClientRow() {
const container = document.getElementById('client-container');
const div = document.createElement('div');
div.className = 'dynamic-row client-input-group';
div.innerHTML = `
<input type="text" name="client_names[]" class="form-control flex-grow-1" placeholder="Client Name" required>
<input type="text" name="contact_people[]" class="form-control" placeholder="Contact Person">
<input type="email" name="client_emails[]" class="form-control" placeholder="Email">
<input type="text" name="client_phones[]" class="form-control" placeholder="Phone">
<button type="button" class="btn btn-sm btn-outline-danger remove-btn">&times;</button>
`;
container.appendChild(div);
div.querySelector('.remove-btn').onclick = function() { div.remove(); };
}
// Attach remove events to existing buttons (for statuses and folders initially)
document.querySelectorAll('#status-container .remove-btn, #folder-container .remove-btn').forEach(btn => {
btn.onclick = function() { btn.parentElement.remove(); };
});
// Initial client row for step 2 if no clients are pre-filled
if (document.getElementById('client-container') && document.getElementById('client-container').children.length === 0) {
// addClientRow(); // Only add if step 2 is active and no existing clients (for initial load)
}
</script>
</body>
</html>