317 lines
16 KiB
PHP
317 lines
16 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/includes/layout.php';
|
|
|
|
$userId = (int)($_GET['id'] ?? 0);
|
|
if ($userId <= 0) {
|
|
header('Location: admin_truck_owners.php');
|
|
exit;
|
|
}
|
|
|
|
$errors = [];
|
|
$flash = null;
|
|
|
|
// Fetch Truck Owner Profile
|
|
$stmt = db()->prepare("
|
|
SELECT u.id, u.email, u.full_name, u.status, u.role,
|
|
p.phone, p.address_line, p.country_id, p.city_id,
|
|
p.truck_type, p.load_capacity, p.plate_no, p.bank_account, p.bank_name, p.bank_branch,
|
|
p.id_card_path, p.truck_pic_path, p.registration_path
|
|
FROM users u
|
|
LEFT JOIN truck_owner_profiles p ON u.id = p.user_id
|
|
WHERE u.id = ? AND u.role = 'truck_owner'
|
|
");
|
|
$stmt->execute([$userId]);
|
|
$owner = $stmt->fetch();
|
|
|
|
if (!$owner) {
|
|
header('Location: admin_truck_owners.php');
|
|
exit;
|
|
}
|
|
|
|
$countries = db()->query("SELECT id, name_en, name_ar FROM countries ORDER BY name_en ASC")->fetchAll();
|
|
$cities = db()->query("SELECT id, country_id, name_en, name_ar FROM cities ORDER BY name_en ASC")->fetchAll();
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$fullName = trim($_POST['full_name'] ?? '');
|
|
$email = trim($_POST['email'] ?? '');
|
|
$phone = trim($_POST['phone'] ?? '');
|
|
$countryId = (int)($_POST['country_id'] ?? 0);
|
|
$cityId = (int)($_POST['city_id'] ?? 0);
|
|
$addressLine = trim($_POST['address_line'] ?? '');
|
|
|
|
$truckType = trim($_POST['truck_type'] ?? '');
|
|
$loadCapacity = trim($_POST['load_capacity'] ?? '');
|
|
$plateNo = trim($_POST['plate_no'] ?? '');
|
|
$status = trim($_POST['status'] ?? '');
|
|
$password = $_POST['password'] ?? '';
|
|
|
|
$bankAccount = trim($_POST['bank_account'] ?? '');
|
|
$bankName = trim($_POST['bank_name'] ?? '');
|
|
$bankBranch = trim($_POST['bank_branch'] ?? '');
|
|
|
|
if ($fullName === '') $errors[] = 'Full name is required.';
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = 'Valid email is required.';
|
|
if ($phone === '') $errors[] = 'Phone number is required.';
|
|
if (!in_array($status, ['pending', 'active', 'rejected'], true)) $errors[] = 'Invalid status.';
|
|
|
|
if ($truckType === '' || $loadCapacity === '' || $plateNo === '') {
|
|
$errors[] = 'Truck type, load capacity, and plate number are required.';
|
|
} elseif (!is_numeric($loadCapacity) || (float)$loadCapacity <= 0) {
|
|
$errors[] = 'Load capacity must be a positive number.';
|
|
}
|
|
|
|
if ($countryId <= 0 || $cityId <= 0) {
|
|
$errors[] = 'Please select country and city.';
|
|
} else {
|
|
$cityCheck = db()->prepare("SELECT COUNT(*) FROM cities WHERE id = ? AND country_id = ?");
|
|
$cityCheck->execute([$cityId, $countryId]);
|
|
if ((int)$cityCheck->fetchColumn() === 0) {
|
|
$errors[] = 'Selected city does not belong to selected country.';
|
|
}
|
|
}
|
|
|
|
if (!$errors) {
|
|
try {
|
|
db()->beginTransaction();
|
|
|
|
$stmtUser = db()->prepare("UPDATE users SET full_name = ?, email = ?, status = ? WHERE id = ? AND role = 'truck_owner'");
|
|
$stmtUser->execute([$fullName, $email, $status, $userId]);
|
|
|
|
if ($password !== '') {
|
|
$stmtPass = db()->prepare("UPDATE users SET password = ? WHERE id = ? AND role = 'truck_owner'");
|
|
$stmtPass->execute([password_hash($password, PASSWORD_DEFAULT), $userId]);
|
|
}
|
|
|
|
$stmtProfile = db()->prepare("
|
|
UPDATE truck_owner_profiles
|
|
SET phone = ?, address_line = ?, country_id = ?, city_id = ?,
|
|
truck_type = ?, load_capacity = ?, plate_no = ?,
|
|
bank_account = ?, bank_name = ?, bank_branch = ?
|
|
WHERE user_id = ?
|
|
");
|
|
$stmtProfile->execute([$phone, $addressLine, $countryId, $cityId, $truckType, $loadCapacity, $plateNo, $bankAccount, $bankName, $bankBranch, $userId]);
|
|
|
|
db()->commit();
|
|
$flash = 'Truck Owner profile updated successfully.';
|
|
|
|
// Refresh data
|
|
$owner['full_name'] = $fullName;
|
|
$owner['email'] = $email;
|
|
$owner['status'] = $status;
|
|
$owner['phone'] = $phone;
|
|
$owner['address_line'] = $addressLine;
|
|
$owner['country_id'] = $countryId;
|
|
$owner['city_id'] = $cityId;
|
|
$owner['truck_type'] = $truckType;
|
|
$owner['load_capacity'] = $loadCapacity;
|
|
$owner['plate_no'] = $plateNo;
|
|
$owner['bank_account'] = $bankAccount;
|
|
$owner['bank_name'] = $bankName;
|
|
$owner['bank_branch'] = $bankBranch;
|
|
|
|
} catch (Throwable $e) {
|
|
db()->rollBack();
|
|
if (stripos($e->getMessage(), 'Duplicate entry') !== false) {
|
|
$errors[] = 'This email is already in use by another account.';
|
|
} else {
|
|
$errors[] = 'Failed to update truck owner profile. Please try again.';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$idCards = json_decode($owner['id_card_path'] ?? '[]', true) ?: [];
|
|
$regs = json_decode($owner['registration_path'] ?? '[]', true) ?: [];
|
|
$pic = $owner['truck_pic_path'];
|
|
|
|
render_header('Edit Truck Owner', 'admin', true);
|
|
?>
|
|
|
|
<div class="row g-0">
|
|
<div class="col-md-2 bg-white border-end min-vh-100">
|
|
<?php render_admin_sidebar('truck_owners'); ?>
|
|
</div>
|
|
<div class="col-md-10 p-4">
|
|
<div class="page-intro d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-4">
|
|
<div>
|
|
<a href="admin_truck_owners.php" class="text-decoration-none small text-muted mb-2 d-inline-block">← Back to Truck Owners</a>
|
|
<h1 class="section-title mb-1">Edit Truck Owner</h1>
|
|
<p class="muted mb-0">Update profile information for <?= e($owner['full_name']) ?>.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($flash): ?>
|
|
<div class="alert alert-success" data-auto-dismiss="true"><?= e($flash) ?></div>
|
|
<?php endif; ?>
|
|
<?php if ($errors): ?>
|
|
<div class="alert alert-warning"><?= e(implode('<br>', $errors)) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="panel p-4">
|
|
<form method="post">
|
|
<h5 class="mb-3">Personal Details</h5>
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="full_name">Full Name</label>
|
|
<input type="text" name="full_name" id="full_name" class="form-control" value="<?= e((string)$owner['full_name']) ?>" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="email">Email</label>
|
|
<input type="email" name="email" id="email" class="form-control" value="<?= e((string)$owner['email']) ?>" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="phone">Phone</label>
|
|
<input type="text" name="phone" id="phone" class="form-control" value="<?= e((string)$owner['phone']) ?>" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="password">Password <small class="text-muted">(leave blank to keep)</small></label>
|
|
<input type="password" name="password" id="password" class="form-control" autocomplete="new-password">
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="status">Account Status</label>
|
|
<select name="status" id="status" class="form-select" required>
|
|
<option value="pending" <?= $owner['status'] === 'pending' ? 'selected' : '' ?>>Pending</option>
|
|
<option value="active" <?= $owner['status'] === 'active' ? 'selected' : '' ?>>Active</option>
|
|
<option value="rejected" <?= $owner['status'] === 'rejected' ? 'selected' : '' ?>>Rejected</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<h5 class="mb-3">Location</h5>
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="country_id">Country</label>
|
|
<select name="country_id" id="country_id" class="form-select" onchange="syncCities()" required>
|
|
<option value="">Select country</option>
|
|
<?php foreach ($countries as $country): ?>
|
|
<option value="<?= e((string)$country['id']) ?>" <?= (string)$owner['country_id'] === (string)$country['id'] ? 'selected' : '' ?>>
|
|
<?= e($lang === 'ar' && !empty($country['name_ar']) ? $country['name_ar'] : $country['name_en']) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="city_id">City</label>
|
|
<select name="city_id" id="city_id" class="form-select" required data-selected="<?= e((string)$owner['city_id']) ?>">
|
|
<option value="">Select city</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="address_line">Address Line</label>
|
|
<input type="text" name="address_line" id="address_line" class="form-control" value="<?= e((string)$owner['address_line']) ?>" required>
|
|
</div>
|
|
</div>
|
|
|
|
<h5 class="mb-3">Truck Details</h5>
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="truck_type">Truck Type</label>
|
|
<input type="text" name="truck_type" id="truck_type" class="form-control" value="<?= e((string)$owner['truck_type']) ?>" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="load_capacity">Load Capacity (tons)</label>
|
|
<input type="number" step="0.01" min="0.1" name="load_capacity" id="load_capacity" class="form-control" value="<?= e((string)$owner['load_capacity']) ?>" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="plate_no">Plate Number</label>
|
|
<input type="text" name="plate_no" id="plate_no" class="form-control" value="<?= e((string)$owner['plate_no']) ?>" required>
|
|
</div>
|
|
</div>
|
|
|
|
<h5 class="mb-3 mt-5 border-top pt-4">Bank Details</h5>
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="bank_account">Bank Account / IBAN</label>
|
|
<input type="text" name="bank_account" id="bank_account" class="form-control" value="<?= e((string)($owner['bank_account'] ?? '')) ?>">
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="bank_name">Bank Name</label>
|
|
<input type="text" name="bank_name" id="bank_name" class="form-control" value="<?= e((string)($owner['bank_name'] ?? '')) ?>">
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="bank_branch">Bank Branch</label>
|
|
<input type="text" name="bank_branch" id="bank_branch" class="form-control" value="<?= e((string)($owner['bank_branch'] ?? '')) ?>">
|
|
</div>
|
|
</div>
|
|
|
|
<h5 class="mb-3 mt-5 border-top pt-4">Uploaded Documents</h5>
|
|
<div class="row g-4 mb-4">
|
|
<div class="col-md-4">
|
|
<h6 class="text-muted mb-2">ID Card</h6>
|
|
<?php if ($idCards): ?>
|
|
<div class="d-flex flex-wrap gap-2">
|
|
<?php foreach ($idCards as $path): ?>
|
|
<a href="<?= e('/' . $path) ?>" target="_blank" class="d-block border rounded overflow-hidden" style="width: 100px; height: 100px;">
|
|
<img src="<?= e('/' . $path) ?>" alt="ID Card" class="w-100 h-100 object-fit-cover" style="object-fit: cover;">
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php else: ?>
|
|
<p class="small text-muted">No ID card uploaded.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<h6 class="text-muted mb-2">Truck Picture</h6>
|
|
<?php if ($pic): ?>
|
|
<a href="<?= e('/' . $pic) ?>" target="_blank" class="d-block border rounded overflow-hidden" style="width: 100px; height: 100px;">
|
|
<img src="<?= e('/' . $pic) ?>" alt="Truck Picture" class="w-100 h-100 object-fit-cover" style="object-fit: cover;">
|
|
</a>
|
|
<?php else: ?>
|
|
<p class="small text-muted">No picture uploaded.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<h6 class="text-muted mb-2">Registration</h6>
|
|
<?php if ($regs): ?>
|
|
<div class="d-flex flex-wrap gap-2">
|
|
<?php foreach ($regs as $path): ?>
|
|
<a href="<?= e('/' . $path) ?>" target="_blank" class="d-block border rounded overflow-hidden" style="width: 100px; height: 100px;">
|
|
<img src="<?= e('/' . $path) ?>" alt="Registration" class="w-100 h-100 object-fit-cover" style="object-fit: cover;">
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php else: ?>
|
|
<p class="small text-muted">No registration uploaded.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<button type="submit" class="btn btn-primary">Save Changes</button>
|
|
<a href="admin_truck_owners.php" class="btn btn-outline-dark ms-2">Cancel</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const allCities = <?= json_encode($cities, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
|
|
function syncCities() {
|
|
const countryId = document.getElementById('country_id').value;
|
|
const citySelect = document.getElementById('city_id');
|
|
const selectedValue = citySelect.dataset.selected || '';
|
|
citySelect.innerHTML = '<option value="">Select city</option>';
|
|
|
|
allCities.forEach((city) => {
|
|
if (String(city.country_id) !== String(countryId)) {
|
|
return;
|
|
}
|
|
const option = document.createElement('option');
|
|
option.value = city.id;
|
|
option.textContent = <?= $lang === 'ar' ? '(city.name_ar || city.name_en)' : '(city.name_en || city.name_ar)' ?>;
|
|
if (String(city.id) === String(selectedValue)) {
|
|
option.selected = true;
|
|
}
|
|
citySelect.appendChild(option);
|
|
});
|
|
// clear selected after first render
|
|
citySelect.dataset.selected = '';
|
|
}
|
|
syncCities();
|
|
</script>
|
|
|
|
<?php render_footer(); ?>
|