diff --git a/admin_company_profile.php b/admin_company_profile.php
index 128f35c..95efdff 100644
--- a/admin_company_profile.php
+++ b/admin_company_profile.php
@@ -13,12 +13,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$companyEmail = trim($_POST['company_email'] ?? '');
$companyPhone = trim($_POST['company_phone'] ?? '');
$companyAddress = trim($_POST['company_address'] ?? '');
+ $platformCharge = trim($_POST['platform_charge_percentage'] ?? '0');
$updates = [
'company_name' => $companyName,
'company_email' => $companyEmail,
'company_phone' => $companyPhone,
'company_address' => $companyAddress,
+ 'platform_charge_percentage' => $platformCharge,
];
// Handle file uploads
@@ -73,6 +75,7 @@ $currentName = $settings['company_name'] ?? t('app_name');
$currentEmail = $settings['company_email'] ?? '';
$currentPhone = $settings['company_phone'] ?? '';
$currentAddress = $settings['company_address'] ?? '';
+$currentPlatformCharge = $settings['platform_charge_percentage'] ?? '0';
$currentLogo = $settings['logo_path'] ?? '';
$currentFavicon = $settings['favicon_path'] ?? '';
@@ -86,7 +89,7 @@ render_header('Company Profile', 'admin');
Company Profile
-
Update your app name, logo, favicon, and contact details.
+
Update your app name, logo, favicon, contact details, and platform charge.
@@ -122,6 +125,19 @@ render_header('Company Profile', 'admin');
Displayed in the footer.
+
+
+
+
+ %
+
+
Percentage applied as a platform fee.
+
+
+
+
+
+
@@ -152,4 +168,4 @@ render_header('Company Profile', 'admin');
-
+
\ No newline at end of file
diff --git a/admin_truck_owner_edit.php b/admin_truck_owner_edit.php
index dd2929c..13750e8 100644
--- a/admin_truck_owner_edit.php
+++ b/admin_truck_owner_edit.php
@@ -16,7 +16,7 @@ $flash = null;
$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.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
@@ -45,6 +45,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$loadCapacity = trim($_POST['load_capacity'] ?? '');
$plateNo = trim($_POST['plate_no'] ?? '');
$status = trim($_POST['status'] ?? '');
+ $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.';
@@ -77,10 +80,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$stmtProfile = db()->prepare("
UPDATE truck_owner_profiles
SET phone = ?, address_line = ?, country_id = ?, city_id = ?,
- truck_type = ?, load_capacity = ?, plate_no = ?
+ truck_type = ?, load_capacity = ?, plate_no = ?,
+ bank_account = ?, bank_name = ?, bank_branch = ?
WHERE user_id = ?
");
- $stmtProfile->execute([$phone, $addressLine, $countryId, $cityId, $truckType, $loadCapacity, $plateNo, $userId]);
+ $stmtProfile->execute([$phone, $addressLine, $countryId, $cityId, $truckType, $loadCapacity, $plateNo, $bankAccount, $bankName, $bankBranch, $userId]);
db()->commit();
$flash = 'Truck Owner profile updated successfully.';
@@ -96,6 +100,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$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();
@@ -202,6 +209,22 @@ render_header('Edit Truck Owner', 'admin');
+ Bank Details
+
+
Uploaded Documents
diff --git a/db/migrations/add_profile_picture_to_users.php b/db/migrations/add_profile_picture_to_users.php
new file mode 100644
index 0000000..678759a
--- /dev/null
+++ b/db/migrations/add_profile_picture_to_users.php
@@ -0,0 +1,15 @@
+exec("ALTER TABLE users ADD COLUMN profile_picture VARCHAR(255) NULL AFTER full_name");
+ echo "Added profile_picture column to users table.\n";
+} catch (PDOException $e) {
+ if ($e->getCode() == '42S21') {
+ echo "profile_picture column already exists.\n";
+ } else {
+ echo "Error: " . $e->getMessage() . "\n";
+ }
+}
+
diff --git a/db/migrations/add_settings_table.php b/db/migrations/add_settings_table.php
index 3b53e07..d4dbd5a 100644
--- a/db/migrations/add_settings_table.php
+++ b/db/migrations/add_settings_table.php
@@ -12,11 +12,11 @@ try {
('company_email', 'info@example.com'),
('company_phone', '+1234567890'),
('company_address', '123 Transport St, City, Country'),
+ ('platform_charge_percentage', '0'),
('logo_path', ''),
('favicon_path', '');
");
- echo "Settings table created.\n";
+ echo "Settings table created/updated.\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
-}
-
+}
\ No newline at end of file
diff --git a/includes/app.php b/includes/app.php
index d811604..1af88b7 100644
--- a/includes/app.php
+++ b/includes/app.php
@@ -184,6 +184,7 @@ CREATE TABLE IF NOT EXISTS shipments (
SQL;
db()->exec($sql);
try { db()->exec("ALTER TABLE users ADD COLUMN status ENUM('pending','active','rejected') NOT NULL DEFAULT 'active'"); } catch (Exception $e) {}
+ try { db()->exec("ALTER TABLE users ADD COLUMN profile_picture VARCHAR(255) NULL AFTER full_name"); } catch (Exception $e) {}
db()->exec(
@@ -194,6 +195,7 @@ SQL;
full_name VARCHAR(255) NOT NULL,
role ENUM('admin','shipper','truck_owner') NOT NULL,
status ENUM('pending','active','rejected') NOT NULL DEFAULT 'active',
+ profile_picture VARCHAR(255) NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
);
diff --git a/includes/layout.php b/includes/layout.php
index 8fad3c6..45a1ef9 100644
--- a/includes/layout.php
+++ b/includes/layout.php
@@ -66,36 +66,58 @@ function render_header(string $title, string $active = ''): void
@@ -261,4 +283,4 @@ function render_admin_sidebar(string $active = 'dashboard'): void
prepare("SELECT id, password, role, status FROM users WHERE email = ? LIMIT 1");
+ $stmt->execute([$email]);
+ $user = $stmt->fetch();
+
+ if ($user && password_verify($password, $user['password'])) {
+ if ($user['status'] === 'pending') {
+ $errors[] = 'Your account is pending approval.';
+ } elseif ($user['status'] === 'rejected') {
+ $errors[] = 'Your account has been rejected.';
+ } elseif ($user['status'] === 'suspended') {
+ $errors[] = 'Your account has been suspended.';
+ } else {
+ // Login successful
+ $_SESSION['user_id'] = $user['id'];
+ $_SESSION['user_role'] = $user['role'];
+
+ // Redirect based on role
+ if ($user['role'] === 'admin') {
+ header('Location: ' . url_with_lang('admin_dashboard.php'));
+ } elseif ($user['role'] === 'shipper') {
+ header('Location: ' . url_with_lang('shipper_dashboard.php'));
+ } else {
+ header('Location: ' . url_with_lang('truck_owner_dashboard.php'));
+ }
+ exit;
+ }
+ } else {
+ $errors[] = 'Invalid email or password.';
+ }
+ }
+ } elseif (isset($_POST['action']) && $_POST['action'] === 'reset_password') {
+ $email = trim($_POST['reset_email'] ?? '');
+ if ($email === '') {
+ $errors[] = 'Please enter your email to reset password.';
+ } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ $errors[] = 'Please enter a valid email address.';
+ } else {
+ $stmt = db()->prepare("SELECT id FROM users WHERE email = ? LIMIT 1");
+ $stmt->execute([$email]);
+ if ($stmt->fetch()) {
+ // In a real app we'd send an email with a reset token here.
+ // Since this is a demo, we will just show a success message.
+ $successMessage = 'A password reset link has been sent to your email address (simulated).';
+ } else {
+ // To prevent email enumeration, still say a link was sent.
+ $successMessage = 'A password reset link has been sent to your email address (simulated).';
+ }
+ }
+ }
+}
+
+render_header('Login / Reset Password', 'login');
+?>
+
+
+
+
+
+
+
+
+
+ = e($successMessage) ?>
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/logout.php b/logout.php
new file mode 100644
index 0000000..5681bf3
--- /dev/null
+++ b/logout.php
@@ -0,0 +1,23 @@
+ '',", " 'plate_no' => '',\n 'bank_account' => '',\n 'bank_name' => '',\n 'bank_branch' => '',")
-
-# 2
-content = content.replace(" 'plate_no' => trim($_POST['plate_no'] ?? ''),", " 'plate_no' => trim($_POST['plate_no'] ?? ''),\n 'bank_account' => trim($_POST['bank_account'] ?? ''),\n 'bank_name' => trim($_POST['bank_name'] ?? ''),\n 'bank_branch' => trim($_POST['bank_branch'] ?? ''),")
-
-# 3
-content = content.replace(" $plateNo = trim($_POST['plate_no'] ?? '');", " $plateNo = trim($_POST['plate_no'] ?? '');\n $bankAccount = trim($_POST['bank_account'] ?? '');\n $bankName = trim($_POST['bank_name'] ?? '');\n $bankBranch = trim($_POST['bank_branch'] ?? '');")
-
-# 4
-s4 = " if ($truckType === '' || $loadCapacity === '' || $plateNo === '') {\n $errors[] = 'Please complete truck details.';\n } elseif (!is_numeric($loadCapacity) || (float)$loadCapacity <= 0) {"
-r4 = " if ($truckType === '' || $loadCapacity === '' || $plateNo === '') {\n $errors[] = 'Please complete truck details.';\n } elseif ($bankAccount === '' || $bankName === '' || $bankBranch === '') {\n $errors[] = 'Please complete bank account details.';\n } elseif (!is_numeric($loadCapacity) || (float)$loadCapacity <= 0) {"
-content = content.replace(s4, r4)
-
-# 5
-s5 = " $ownerStmt = $pdo->prepare(
- \"INSERT INTO truck_owner_profiles (user_id, phone, country_id, city_id, address_line, truck_type, load_capacity, plate_no, id_card_path, truck_pic_path, registration_path)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\"
- );
- $ownerStmt->execute([
- $userId,
- $phone,
- $countryId,
- $cityId,
- $addressLine,
- $truckType,
- $loadCapacity,
- $plateNo,
- json_encode($idCardPaths, JSON_UNESCAPED_SLASHES),
- $truckPic,
- json_encode($regPaths, JSON_UNESCAPED_SLASHES),
- ]);"
-r5 = " $ownerStmt = $pdo->prepare(
- \"INSERT INTO truck_owner_profiles (user_id, phone, country_id, city_id, address_line, truck_type, load_capacity, plate_no, bank_account, bank_name, bank_branch, id_card_path, truck_pic_path, registration_path)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\"
- );
- $ownerStmt->execute([
- $userId,
- $phone,
- $countryId,
- $cityId,
- $addressLine,
- $truckType,
- $loadCapacity,
- $plateNo,
- $bankAccount,
- $bankName,
- $bankBranch,
- json_encode($idCardPaths, JSON_UNESCAPED_SLASHES),
- $truckPic,
- json_encode($regPaths, JSON_UNESCAPED_SLASHES),
- ]);"
-content = content.replace(s5, r5)
-
-# 6
-s6 = " 'plate_no' => '',"
-r6 = " 'plate_no' => '',\n 'bank_account' => '',\n 'bank_name' => '',\n 'bank_branch' => '',"
-# careful not to replace the first one again
-parts = content.split(s6)
-if len(parts) == 3:
- content = parts[0] + s6 + parts[1] + r6 + parts[2]
-elif len(parts) == 2:
- # meaning the first one was already replaced by s1/r1 (which is the same search string!)
- # wait, s1 and s6 are exactly the same?
- # No, s1 is " 'plate_no' => ''," and s6 is " 'plate_no' => ''," (more spaces)
- content = parts[0] + r6 + parts[1]
-
-
-# 7
-s7 = "
-
- \">
-
"
-r7 = "
-
- \">
-
-
- Bank Details for Payouts
-
-
- \" required>
-
-
-
- \" required>
-
-
-
- \" required>
-
"
-content = content.replace(s7, r7)
-
-with open('register.php', 'w') as f:
- f.write(content)
-
-print("Replaced in register.php")
diff --git a/profile.php b/profile.php
new file mode 100644
index 0000000..c45c4a4
--- /dev/null
+++ b/profile.php
@@ -0,0 +1,176 @@
+prepare("SELECT * FROM users WHERE id = :id");
+ $stmt->execute([':id' => $userId]);
+ $user = $stmt->fetch();
+ if (!$user) {
+ die("Demo user not found. Please register an account first.");
+ }
+} catch (Throwable $e) {
+ die("Database error: " . $e->getMessage());
+}
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'update_profile') {
+ $fullName = trim($_POST['full_name'] ?? '');
+
+ if ($fullName === '') {
+ $errors[] = t('error_required');
+ }
+
+ $profilePicPath = $user['profile_picture'];
+
+ // Handle file upload
+ if (isset($_FILES['profile_picture']) && $_FILES['profile_picture']['error'] === UPLOAD_ERR_OK) {
+ $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
+ $fileInfo = finfo_open(FILEINFO_MIME_TYPE);
+ $mimeType = finfo_file($fileInfo, $_FILES['profile_picture']['tmp_name']);
+ finfo_close($fileInfo);
+
+ if (!in_array($mimeType, $allowedTypes)) {
+ $errors[] = "Invalid image format. Please upload JPG, PNG, GIF, or WEBP.";
+ } else {
+ $uploadDir = __DIR__ . '/uploads/profiles/';
+ if (!is_dir($uploadDir)) {
+ mkdir($uploadDir, 0775, true);
+ }
+
+ $extension = pathinfo($_FILES['profile_picture']['name'], PATHINFO_EXTENSION);
+ $filename = 'profile_' . $userId . '_' . time() . '.' . $extension;
+ $destination = $uploadDir . $filename;
+
+ if (move_uploaded_file($_FILES['profile_picture']['tmp_name'], $destination)) {
+ $profilePicPath = '/uploads/profiles/' . $filename;
+ } else {
+ $errors[] = "Failed to save uploaded file.";
+ }
+ }
+ }
+
+ if (!$errors) {
+ try {
+ $updateStmt = db()->prepare("UPDATE users SET full_name = :name, profile_picture = :pic WHERE id = :id");
+ $updateStmt->execute([
+ ':name' => $fullName,
+ ':pic' => $profilePicPath,
+ ':id' => $userId
+ ]);
+ set_flash('success', "Profile updated successfully.");
+ header("Location: " . url_with_lang('profile.php'));
+ exit;
+ } catch (Throwable $e) {
+ $errors[] = "Database update failed: " . $e->getMessage();
+ }
+ }
+}
+
+render_header('My Profile', 'profile');
+$flash = get_flash();
+?>
+
+
+
+
+
+
+
My Profile
+
+
+
+
+ = e($flash['message']) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/register.php b/register.php
index e61dc27..bc94614 100644
--- a/register.php
+++ b/register.php
@@ -19,6 +19,9 @@ $values = [
'truck_type' => '',
'load_capacity' => '',
'plate_no' => '',
+ 'bank_account' => '',
+ 'bank_name' => '',
+ 'bank_branch' => '',
];
$countries = db()->query("SELECT id, name_en, name_ar FROM countries ORDER BY name_en ASC")->fetchAll();
@@ -165,8 +168,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!$errors) {
$ownerStmt = $pdo->prepare(
- "INSERT INTO truck_owner_profiles (user_id, phone, country_id, city_id, address_line, truck_type, load_capacity, plate_no, id_card_path, truck_pic_path, registration_path)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+ "INSERT INTO truck_owner_profiles (user_id, phone, country_id, city_id, address_line, truck_type, load_capacity, plate_no, bank_account, bank_name, bank_branch, id_card_path, truck_pic_path, registration_path)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
);
$ownerStmt->execute([
$userId,
@@ -177,6 +180,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$truckType,
$loadCapacity,
$plateNo,
+ $bankAccount,
+ $bankName,
+ $bankBranch,
json_encode($idCardPaths, JSON_UNESCAPED_SLASHES),
$truckPic,
json_encode($regPaths, JSON_UNESCAPED_SLASHES),
@@ -202,6 +208,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'truck_type' => '',
'load_capacity' => '',
'plate_no' => '',
+ 'bank_account' => '',
+ 'bank_name' => '',
+ 'bank_branch' => '',
];
}
} catch (Throwable $e) {
@@ -311,6 +320,19 @@ render_header('Shipper & Truck Owner Registration');
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tmp_edit.php b/tmp_edit.php
deleted file mode 100644
index db9d736..0000000
--- a/tmp_edit.php
+++ /dev/null
@@ -1,16 +0,0 @@
- '',";
-$r1 = " 'plate_no' => '',\n 'bank_account' => '',\n 'bank_name' => '',\n 'bank_branch' => '',";
-
-$s2 = " 'plate_no' => trim(\"
-$_POST['plate_no'] ?? ''\"),";
-$r2 = " 'plate_no' => trim(\"
-$_POST['plate_no'] ?? ''\"),\n 'bank_account' => trim(\"
-$_POST['bank_account'] ?? ''\"),\n 'bank_name' => trim(\"
-$_POST['bank_name'] ?? ''\"),\n 'bank_branch' => trim(\"
-$_POST['bank_branch'] ?? ''\"),";
-
-$s3 = " $plateNo = trim(\"
-$_POST['plate_no'] ?? ''\");";
-$r3 = " $plateNo = trim(\"
-$_POST['plate_no'] ?? ''\");\n $bankAccount = trim(\"
-$_POST['bank_account'] ?? ''\");\n $bankName = trim(\"
-$_POST['bank_name'] ?? ''\");\n $bankBranch = trim(\"
-$_POST['bank_branch'] ?? ''\");";
-
-$s4 = " if ($truckType === '' || $loadCapacity === '' || $plateNo === '') {\n $errors[] = 'Please complete truck details.';\n } elseif (!is_numeric($loadCapacity) || (float)$loadCapacity <= 0) {";
-$r4 = " if ($truckType === '' || $loadCapacity === '' || $plateNo === '') {\n $errors[] = 'Please complete truck details.';\n } elseif ($bankAccount === '' || $bankName === '' || $bankBranch === '') {\n $errors[] = 'Please complete bank account details.';\n } elseif (!is_numeric($loadCapacity) || (float)$loadCapacity <= 0) {";
-
-$s5 = <<
prepare(
- "INSERT INTO truck_owner_profiles (user_id, phone, country_id, city_id, address_line, truck_type, load_capacity, plate_no, id_card_path, truck_pic_path, registration_path)"
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
- );
- $ownerStmt->execute([
- $userId,
- $phone,
- $countryId,
- $cityId,
- $addressLine,
- $truckType,
- $loadCapacity,
- $plateNo,
- json_encode($idCardPaths, JSON_UNESCAPED_SLASHES),
- $truckPic,
- json_encode($regPaths, JSON_UNESCAPED_SLASHES),
- ]);
-PHP;
-$r5 = <<prepare(
- "INSERT INTO truck_owner_profiles (user_id, phone, country_id, city_id, address_line, truck_type, load_capacity, plate_no, bank_account, bank_name, bank_branch, id_card_path, truck_pic_path, registration_path)"
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
- );
- $ownerStmt->execute([
- $userId,
- $phone,
- $countryId,
- $cityId,
- $addressLine,
- $truckType,
- $loadCapacity,
- $plateNo,
- $bankAccount,
- $bankName,
- $bankBranch,
- json_encode($idCardPaths, JSON_UNESCAPED_SLASHES),
- $truckPic,
- json_encode($regPaths, JSON_UNESCAPED_SLASHES),
- ]);
-PHP;
-
-$s7 = <<
-
-
-
-HTML;
-
-$r7 = <<
-
-
-
-
- Bank Details for Payouts
-
-
-
-
-
-
-
-
-
-
-
-
-HTML;
-
-$content = str_replace($s1, $r1, $content);
-$content = str_replace($s2, $r2, $content);
-$content = str_replace($s3, $r3, $content);
-$content = str_replace($s4, $r4, $content);
-$content = str_replace($s5, $r5, $content);
-$content = str_replace($s7, $r7, $content);
-
-file_put_contents('register.php', $content);
-echo "Replaced in register.php\n";
-