277 lines
14 KiB
PHP
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">×</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">×</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">×</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">×</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">×</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>
|